1/* rl78.c --- opcode semantics for stand-alone RL78 simulator. 2 3 Copyright (C) 2008-2023 Free Software Foundation, Inc. 4 Contributed by Red Hat, Inc. 5 6 This file is part of the GNU simulators. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22/* This must come before any other includes. */ 23#include "defs.h" 24 25#include <stdio.h> 26#include <stdlib.h> 27#include <string.h> 28#include <signal.h> 29#include <setjmp.h> 30#include <time.h> 31 32#include "opcode/rl78.h" 33#include "cpu.h" 34#include "mem.h" 35 36extern int skip_init; 37static int opcode_pc = 0; 38 39jmp_buf decode_jmp_buf; 40#define DO_RETURN(x) longjmp (decode_jmp_buf, x) 41 42#define tprintf if (trace) printf 43 44#define WILD_JUMP_CHECK(new_pc) \ 45 do { \ 46 if (new_pc == 0 || new_pc > 0xfffff) \ 47 { \ 48 pc = opcode_pc; \ 49 fprintf (stderr, "Wild jump to 0x%x from 0x%x!\n", new_pc, pc); \ 50 DO_RETURN (RL78_MAKE_HIT_BREAK ()); \ 51 } \ 52 } while (0) 53 54typedef struct { 55 unsigned long dpc; 56} RL78_Data; 57 58static int 59rl78_get_byte (void *vdata) 60{ 61 RL78_Data *rl78_data = (RL78_Data *)vdata; 62 int rv = mem_get_pc (rl78_data->dpc); 63 rl78_data->dpc ++; 64 return rv; 65} 66 67static int 68op_addr (const RL78_Opcode_Operand *o, int for_data) 69{ 70 int v = o->addend; 71 if (o->reg != RL78_Reg_None) 72 v += get_reg (o->reg); 73 if (o->reg2 != RL78_Reg_None) 74 v += get_reg (o->reg2); 75 if (o->use_es) 76 v |= (get_reg (RL78_Reg_ES) & 0xf) << 16; 77 else if (for_data) 78 v |= 0xf0000; 79 v &= 0xfffff; 80 return v; 81} 82 83static int 84get_op (const RL78_Opcode_Decoded *rd, int i, int for_data) 85{ 86 int v, r; 87 const RL78_Opcode_Operand *o = rd->op + i; 88 89 switch (o->type) 90 { 91 case RL78_Operand_None: 92 /* condition code does this. */ 93 v = 0; 94 break; 95 96 case RL78_Operand_Immediate: 97 tprintf (" #"); 98 v = o->addend; 99 break; 100 101 case RL78_Operand_Register: 102 tprintf (" %s=", reg_names[o->reg]); 103 v = get_reg (o->reg); 104 break; 105 106 case RL78_Operand_Bit: 107 tprintf (" %s.%d=", reg_names[o->reg], o->bit_number); 108 v = get_reg (o->reg); 109 v = (v & (1 << o->bit_number)) ? 1 : 0; 110 break; 111 112 case RL78_Operand_Indirect: 113 v = op_addr (o, for_data); 114 tprintf (" [0x%x]=", v); 115 if (rd->size == RL78_Word) 116 v = mem_get_hi (v); 117 else 118 v = mem_get_qi (v); 119 break; 120 121 case RL78_Operand_BitIndirect: 122 v = op_addr (o, for_data); 123 tprintf (" [0x%x].%d=", v, o->bit_number); 124 v = (mem_get_qi (v) & (1 << o->bit_number)) ? 1 : 0; 125 break; 126 127 case RL78_Operand_PreDec: 128 r = get_reg (o->reg); 129 tprintf (" [--%s]", reg_names[o->reg]); 130 if (rd->size == RL78_Word) 131 { 132 r -= 2; 133 v = mem_get_hi (r | 0xf0000); 134 } 135 else 136 { 137 r -= 1; 138 v = mem_get_qi (r | 0xf0000); 139 } 140 set_reg (o->reg, r); 141 break; 142 143 case RL78_Operand_PostInc: 144 tprintf (" [%s++]", reg_names[o->reg]); 145 r = get_reg (o->reg); 146 if (rd->size == RL78_Word) 147 { 148 v = mem_get_hi (r | 0xf0000); 149 r += 2; 150 } 151 else 152 { 153 v = mem_get_qi (r | 0xf0000); 154 r += 1; 155 } 156 set_reg (o->reg, r); 157 break; 158 159 default: 160 abort (); 161 } 162 tprintf ("%d", v); 163 return v; 164} 165 166static void 167put_op (const RL78_Opcode_Decoded *rd, int i, int for_data, int v) 168{ 169 int r, a; 170 const RL78_Opcode_Operand *o = rd->op + i; 171 172 tprintf (" -> "); 173 174 switch (o->type) 175 { 176 case RL78_Operand_Register: 177 tprintf ("%s", reg_names[o->reg]); 178 set_reg (o->reg, v); 179 break; 180 181 case RL78_Operand_Bit: 182 tprintf ("%s.%d", reg_names[o->reg], o->bit_number); 183 r = get_reg (o->reg); 184 if (v) 185 r |= (1 << o->bit_number); 186 else 187 r &= ~(1 << o->bit_number); 188 set_reg (o->reg, r); 189 break; 190 191 case RL78_Operand_Indirect: 192 r = op_addr (o, for_data); 193 tprintf ("[0x%x]", r); 194 if (rd->size == RL78_Word) 195 mem_put_hi (r, v); 196 else 197 mem_put_qi (r, v); 198 break; 199 200 case RL78_Operand_BitIndirect: 201 a = op_addr (o, for_data); 202 tprintf ("[0x%x].%d", a, o->bit_number); 203 r = mem_get_qi (a); 204 if (v) 205 r |= (1 << o->bit_number); 206 else 207 r &= ~(1 << o->bit_number); 208 mem_put_qi (a, r); 209 break; 210 211 case RL78_Operand_PreDec: 212 r = get_reg (o->reg); 213 tprintf ("[--%s]", reg_names[o->reg]); 214 if (rd->size == RL78_Word) 215 { 216 r -= 2; 217 set_reg (o->reg, r); 218 mem_put_hi (r | 0xf0000, v); 219 } 220 else 221 { 222 r -= 1; 223 set_reg (o->reg, r); 224 mem_put_qi (r | 0xf0000, v); 225 } 226 break; 227 228 case RL78_Operand_PostInc: 229 tprintf ("[%s++]", reg_names[o->reg]); 230 r = get_reg (o->reg); 231 if (rd->size == RL78_Word) 232 { 233 mem_put_hi (r | 0xf0000, v); 234 r += 2; 235 } 236 else 237 { 238 mem_put_qi (r | 0xf0000, v); 239 r += 1; 240 } 241 set_reg (o->reg, r); 242 break; 243 244 default: 245 abort (); 246 } 247 tprintf ("\n"); 248} 249 250static void 251op_flags (int before, int after, int mask, RL78_Size size) 252{ 253 int vmask, cmask, amask, avmask; 254 int psw; 255 256 if (size == RL78_Word) 257 { 258 cmask = 0x10000; 259 vmask = 0xffff; 260 amask = 0x100; 261 avmask = 0x0ff; 262 } 263 else 264 { 265 cmask = 0x100; 266 vmask = 0xff; 267 amask = 0x10; 268 avmask = 0x0f; 269 } 270 271 psw = get_reg (RL78_Reg_PSW); 272 psw &= ~mask; 273 274 if (mask & RL78_PSW_CY) 275 { 276 if ((after & cmask) != (before & cmask)) 277 psw |= RL78_PSW_CY; 278 } 279 if (mask & RL78_PSW_AC) 280 { 281 if ((after & amask) != (before & amask) 282 && (after & avmask) < (before & avmask)) 283 psw |= RL78_PSW_AC; 284 } 285 if (mask & RL78_PSW_Z) 286 { 287 if (! (after & vmask)) 288 psw |= RL78_PSW_Z; 289 } 290 291 set_reg (RL78_Reg_PSW, psw); 292} 293 294#define FLAGS(before,after) if (opcode.flags) op_flags (before, after, opcode.flags, opcode.size) 295 296#define PD(x) put_op (&opcode, 0, 1, x) 297#define PS(x) put_op (&opcode, 1, 1, x) 298#define GD() get_op (&opcode, 0, 1) 299#define GS() get_op (&opcode, 1, 1) 300 301#define GPC() gpc (&opcode, 0) 302static int 303gpc (RL78_Opcode_Decoded *opcode, int idx) 304{ 305 int a = get_op (opcode, 0, 1); 306 if (opcode->op[idx].type == RL78_Operand_Register) 307 a =(a & 0x0ffff) | ((get_reg (RL78_Reg_CS) & 0x0f) << 16); 308 else 309 a &= 0xfffff; 310 return a; 311} 312 313static int 314get_carry (void) 315{ 316 return (get_reg (RL78_Reg_PSW) & RL78_PSW_CY) ? 1 : 0; 317} 318 319static void 320set_carry (int c) 321{ 322 int p = get_reg (RL78_Reg_PSW); 323 tprintf ("set_carry (%d)\n", c ? 1 : 0); 324 if (c) 325 p |= RL78_PSW_CY; 326 else 327 p &= ~RL78_PSW_CY; 328 set_reg (RL78_Reg_PSW, p); 329} 330 331/* We simulate timer TM00 in interval mode, no clearing, with 332 interrupts. I.e. it's a cycle counter. */ 333 334unsigned int counts_per_insn[0x100000]; 335 336int pending_clocks = 0; 337long long total_clocks = 0; 338 339#define TCR0 0xf0180 340#define MK1 0xfffe6 341static void 342process_clock_tick (void) 343{ 344 unsigned short cnt; 345 unsigned short ivect; 346 unsigned short mask; 347 unsigned char psw; 348 int save_trace; 349 350 save_trace = trace; 351 trace = 0; 352 353 pending_clocks ++; 354 355 counts_per_insn[opcode_pc] += pending_clocks; 356 total_clocks += pending_clocks; 357 358 while (pending_clocks) 359 { 360 pending_clocks --; 361 cnt = mem_get_hi (TCR0); 362 cnt --; 363 mem_put_hi (TCR0, cnt); 364 if (cnt != 0xffff) 365 continue; 366 367 /* overflow. */ 368 psw = get_reg (RL78_Reg_PSW); 369 ivect = mem_get_hi (0x0002c); 370 mask = mem_get_hi (MK1); 371 372 if ((psw & RL78_PSW_IE) 373 && (ivect != 0) 374 && !(mask & 0x0010)) 375 { 376 unsigned short sp = get_reg (RL78_Reg_SP); 377 set_reg (RL78_Reg_SP, sp - 4); 378 sp --; 379 mem_put_qi (sp | 0xf0000, psw); 380 sp -= 3; 381 mem_put_psi (sp | 0xf0000, pc); 382 psw &= ~RL78_PSW_IE; 383 set_reg (RL78_Reg_PSW, psw); 384 pc = ivect; 385 /* Spec says 9-14 clocks */ 386 pending_clocks += 9; 387 } 388 } 389 390 trace = save_trace; 391} 392 393void 394dump_counts_per_insn (const char * filename) 395{ 396 int i; 397 FILE *f; 398 f = fopen (filename, "w"); 399 if (!f) 400 { 401 perror (filename); 402 return; 403 } 404 for (i = 0; i < 0x100000; i ++) 405 { 406 if (counts_per_insn[i]) 407 fprintf (f, "%05x %d\n", i, counts_per_insn[i]); 408 } 409 fclose (f); 410} 411 412static void 413CLOCKS (int n) 414{ 415 pending_clocks += n - 1; 416} 417 418int 419decode_opcode (void) 420{ 421 RL78_Data rl78_data; 422 RL78_Opcode_Decoded opcode; 423 int opcode_size; 424 int a, b, v, v2; 425 unsigned int u, u2; 426 int obits; 427 RL78_Dis_Isa isa; 428 429 isa = (rl78_g10_mode ? RL78_ISA_G10 430 : g14_multiply ? RL78_ISA_G14 431 : g13_multiply ? RL78_ISA_G13 432 : RL78_ISA_DEFAULT); 433 434 rl78_data.dpc = pc; 435 opcode_size = rl78_decode_opcode (pc, &opcode, 436 rl78_get_byte, &rl78_data, isa); 437 438 opcode_pc = pc; 439 pc += opcode_size; 440 441 trace_register_words = opcode.size == RL78_Word ? 1 : 0; 442 443 /* Used by shfit/rotate instructions */ 444 obits = opcode.size == RL78_Word ? 16 : 8; 445 446 switch (opcode.id) 447 { 448 case RLO_add: 449 tprintf ("ADD: "); 450 a = GS (); 451 b = GD (); 452 v = a + b; 453 FLAGS (b, v); 454 PD (v); 455 if (opcode.op[0].type == RL78_Operand_Indirect) 456 CLOCKS (2); 457 break; 458 459 case RLO_addc: 460 tprintf ("ADDC: "); 461 a = GS (); 462 b = GD (); 463 v = a + b + get_carry (); 464 FLAGS (b, v); 465 PD (v); 466 if (opcode.op[0].type == RL78_Operand_Indirect) 467 CLOCKS (2); 468 break; 469 470 case RLO_and: 471 tprintf ("AND: "); 472 a = GS (); 473 b = GD (); 474 v = a & b; 475 FLAGS (b, v); 476 PD (v); 477 if (opcode.op[0].type == RL78_Operand_Indirect) 478 CLOCKS (2); 479 break; 480 481 case RLO_branch_cond: 482 case RLO_branch_cond_clear: 483 tprintf ("BRANCH_COND: "); 484 if (!condition_true (opcode.op[1].condition, GS ())) 485 { 486 tprintf (" false\n"); 487 if (opcode.op[1].condition == RL78_Condition_T 488 || opcode.op[1].condition == RL78_Condition_F) 489 CLOCKS (3); 490 else 491 CLOCKS (2); 492 break; 493 } 494 if (opcode.id == RLO_branch_cond_clear) 495 PS (0); 496 tprintf (" "); 497 if (opcode.op[1].condition == RL78_Condition_T 498 || opcode.op[1].condition == RL78_Condition_F) 499 CLOCKS (3); /* note: adds two clocks, total 5 clocks */ 500 else 501 CLOCKS (2); /* note: adds one clock, total 4 clocks */ 502 case RLO_branch: 503 tprintf ("BRANCH: "); 504 v = GPC (); 505 WILD_JUMP_CHECK (v); 506 pc = v; 507 tprintf (" => 0x%05x\n", pc); 508 CLOCKS (3); 509 break; 510 511 case RLO_break: 512 tprintf ("BRK: "); 513 CLOCKS (5); 514 if (rl78_in_gdb) 515 DO_RETURN (RL78_MAKE_HIT_BREAK ()); 516 else 517 DO_RETURN (RL78_MAKE_EXITED (1)); 518 break; 519 520 case RLO_call: 521 tprintf ("CALL: "); 522 a = get_reg (RL78_Reg_SP); 523 set_reg (RL78_Reg_SP, a - 4); 524 mem_put_psi ((a - 4) | 0xf0000, pc); 525 v = GPC (); 526 WILD_JUMP_CHECK (v); 527 pc = v; 528#if 0 529 /* Enable this code to dump the arguments for each call. */ 530 if (trace) 531 { 532 int i; 533 skip_init ++; 534 for (i = 0; i < 8; i ++) 535 printf (" %02x", mem_get_qi (0xf0000 | (a + i)) & 0xff); 536 skip_init --; 537 } 538#endif 539 tprintf ("\n"); 540 CLOCKS (3); 541 break; 542 543 case RLO_cmp: 544 tprintf ("CMP: "); 545 a = GD (); 546 b = GS (); 547 v = a - b; 548 FLAGS (b, v); 549 tprintf (" (%d)\n", v); 550 break; 551 552 case RLO_divhu: 553 a = get_reg (RL78_Reg_AX); 554 b = get_reg (RL78_Reg_DE); 555 tprintf (" %d / %d = ", a, b); 556 if (b == 0) 557 { 558 tprintf ("%d rem %d\n", 0xffff, a); 559 set_reg (RL78_Reg_AX, 0xffff); 560 set_reg (RL78_Reg_DE, a); 561 } 562 else 563 { 564 v = a / b; 565 a = a % b; 566 tprintf ("%d rem %d\n", v, a); 567 set_reg (RL78_Reg_AX, v); 568 set_reg (RL78_Reg_DE, a); 569 } 570 CLOCKS (9); 571 break; 572 573 case RLO_divwu: 574 { 575 unsigned long bcax, hlde, quot, rem; 576 bcax = get_reg (RL78_Reg_AX) + 65536 * get_reg (RL78_Reg_BC); 577 hlde = get_reg (RL78_Reg_DE) + 65536 * get_reg (RL78_Reg_HL); 578 579 tprintf (" %lu / %lu = ", bcax, hlde); 580 if (hlde == 0) 581 { 582 tprintf ("%lu rem %lu\n", 0xffffLU, bcax); 583 set_reg (RL78_Reg_AX, 0xffffLU); 584 set_reg (RL78_Reg_BC, 0xffffLU); 585 set_reg (RL78_Reg_DE, bcax); 586 set_reg (RL78_Reg_HL, bcax >> 16); 587 } 588 else 589 { 590 quot = bcax / hlde; 591 rem = bcax % hlde; 592 tprintf ("%lu rem %lu\n", quot, rem); 593 set_reg (RL78_Reg_AX, quot); 594 set_reg (RL78_Reg_BC, quot >> 16); 595 set_reg (RL78_Reg_DE, rem); 596 set_reg (RL78_Reg_HL, rem >> 16); 597 } 598 } 599 CLOCKS (17); 600 break; 601 602 case RLO_halt: 603 tprintf ("HALT.\n"); 604 DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A))); 605 606 case RLO_mov: 607 tprintf ("MOV: "); 608 a = GS (); 609 FLAGS (a, a); 610 PD (a); 611 break; 612 613#define MACR 0xffff0 614 case RLO_mach: 615 tprintf ("MACH:"); 616 a = sign_ext (get_reg (RL78_Reg_AX), 16); 617 b = sign_ext (get_reg (RL78_Reg_BC), 16); 618 v = sign_ext (mem_get_si (MACR), 32); 619 tprintf ("%08x %d + %d * %d = ", v, v, a, b); 620 v2 = sign_ext (v + a * b, 32); 621 tprintf ("%08x %d\n", v2, v2); 622 mem_put_si (MACR, v2); 623 a = get_reg (RL78_Reg_PSW); 624 v ^= v2; 625 if (v & (1<<31)) 626 a |= RL78_PSW_CY; 627 else 628 a &= ~RL78_PSW_CY; 629 if (v2 & (1 << 31)) 630 a |= RL78_PSW_AC; 631 else 632 a &= ~RL78_PSW_AC; 633 set_reg (RL78_Reg_PSW, a); 634 CLOCKS (3); 635 break; 636 637 case RLO_machu: 638 tprintf ("MACHU:"); 639 a = get_reg (RL78_Reg_AX); 640 b = get_reg (RL78_Reg_BC); 641 u = mem_get_si (MACR); 642 tprintf ("%08x %u + %u * %u = ", u, u, a, b); 643 u2 = (u + (unsigned)a * (unsigned)b) & 0xffffffffUL; 644 tprintf ("%08x %u\n", u2, u2); 645 mem_put_si (MACR, u2); 646 a = get_reg (RL78_Reg_PSW); 647 if (u2 < u) 648 a |= RL78_PSW_CY; 649 else 650 a &= ~RL78_PSW_CY; 651 a &= ~RL78_PSW_AC; 652 set_reg (RL78_Reg_PSW, a); 653 CLOCKS (3); 654 break; 655 656 case RLO_mulu: 657 tprintf ("MULU:"); 658 a = get_reg (RL78_Reg_A); 659 b = get_reg (RL78_Reg_X); 660 v = a * b; 661 tprintf (" %d * %d = %d\n", a, b, v); 662 set_reg (RL78_Reg_AX, v); 663 break; 664 665 case RLO_mulh: 666 tprintf ("MUL:"); 667 a = sign_ext (get_reg (RL78_Reg_AX), 16); 668 b = sign_ext (get_reg (RL78_Reg_BC), 16); 669 v = a * b; 670 tprintf (" %d * %d = %d\n", a, b, v); 671 set_reg (RL78_Reg_BC, v >> 16); 672 set_reg (RL78_Reg_AX, v); 673 CLOCKS (2); 674 break; 675 676 case RLO_mulhu: 677 tprintf ("MULHU:"); 678 a = get_reg (RL78_Reg_AX); 679 b = get_reg (RL78_Reg_BC); 680 v = a * b; 681 tprintf (" %d * %d = %d\n", a, b, v); 682 set_reg (RL78_Reg_BC, v >> 16); 683 set_reg (RL78_Reg_AX, v); 684 CLOCKS (2); 685 break; 686 687 case RLO_nop: 688 tprintf ("NOP.\n"); 689 break; 690 691 case RLO_or: 692 tprintf ("OR:"); 693 a = GS (); 694 b = GD (); 695 v = a | b; 696 FLAGS (b, v); 697 PD (v); 698 if (opcode.op[0].type == RL78_Operand_Indirect) 699 CLOCKS (2); 700 break; 701 702 case RLO_ret: 703 tprintf ("RET: "); 704 a = get_reg (RL78_Reg_SP); 705 v = mem_get_psi (a | 0xf0000); 706 WILD_JUMP_CHECK (v); 707 pc = v; 708 set_reg (RL78_Reg_SP, a + 4); 709#if 0 710 /* Enable this code to dump the return values for each return. */ 711 if (trace) 712 { 713 int i; 714 skip_init ++; 715 for (i = 0; i < 8; i ++) 716 printf (" %02x", mem_get_qi (0xffef0 + i) & 0xff); 717 skip_init --; 718 } 719#endif 720 tprintf ("\n"); 721 CLOCKS (6); 722 break; 723 724 case RLO_reti: 725 tprintf ("RETI: "); 726 a = get_reg (RL78_Reg_SP); 727 v = mem_get_psi (a | 0xf0000); 728 WILD_JUMP_CHECK (v); 729 pc = v; 730 b = mem_get_qi ((a + 3) | 0xf0000); 731 set_reg (RL78_Reg_PSW, b); 732 set_reg (RL78_Reg_SP, a + 4); 733 tprintf ("\n"); 734 break; 735 736 case RLO_rol: 737 tprintf ("ROL:"); /* d <<= s */ 738 a = GS (); 739 b = GD (); 740 v = b; 741 while (a --) 742 { 743 v = b << 1; 744 v |= (b >> (obits - 1)) & 1; 745 set_carry ((b >> (obits - 1)) & 1); 746 b = v; 747 } 748 PD (v); 749 break; 750 751 case RLO_rolc: 752 tprintf ("ROLC:"); /* d <<= s */ 753 a = GS (); 754 b = GD (); 755 v = b; 756 while (a --) 757 { 758 v = b << 1; 759 v |= get_carry (); 760 set_carry ((b >> (obits - 1)) & 1); 761 b = v; 762 } 763 PD (v); 764 break; 765 766 case RLO_ror: 767 tprintf ("ROR:"); /* d >>= s */ 768 a = GS (); 769 b = GD (); 770 v = b; 771 while (a --) 772 { 773 v = b >> 1; 774 v |= (b & 1) << (obits - 1); 775 set_carry (b & 1); 776 b = v; 777 } 778 PD (v); 779 break; 780 781 case RLO_rorc: 782 tprintf ("RORC:"); /* d >>= s */ 783 a = GS (); 784 b = GD (); 785 v = b; 786 while (a --) 787 { 788 v = b >> 1; 789 v |= (get_carry () << (obits - 1)); 790 set_carry (b & 1); 791 b = v; 792 } 793 PD (v); 794 break; 795 796 case RLO_sar: 797 tprintf ("SAR:"); /* d >>= s */ 798 a = GS (); 799 b = GD (); 800 v = b; 801 while (a --) 802 { 803 v = b >> 1; 804 v |= b & (1 << (obits - 1)); 805 set_carry (b & 1); 806 b = v; 807 } 808 PD (v); 809 break; 810 811 case RLO_sel: 812 tprintf ("SEL:"); 813 a = GS (); 814 b = get_reg (RL78_Reg_PSW); 815 b &= ~(RL78_PSW_RBS1 | RL78_PSW_RBS0); 816 if (a & 1) 817 b |= RL78_PSW_RBS0; 818 if (a & 2) 819 b |= RL78_PSW_RBS1; 820 set_reg (RL78_Reg_PSW, b); 821 tprintf ("\n"); 822 break; 823 824 case RLO_shl: 825 tprintf ("SHL%d:", obits); /* d <<= s */ 826 a = GS (); 827 b = GD (); 828 v = b; 829 while (a --) 830 { 831 v = b << 1; 832 tprintf ("b = 0x%x & 0x%x\n", b, 1<<(obits - 1)); 833 set_carry (b & (1<<(obits - 1))); 834 b = v; 835 } 836 PD (v); 837 break; 838 839 case RLO_shr: 840 tprintf ("SHR:"); /* d >>= s */ 841 a = GS (); 842 b = GD (); 843 v = b; 844 while (a --) 845 { 846 v = b >> 1; 847 set_carry (b & 1); 848 b = v; 849 } 850 PD (v); 851 break; 852 853 case RLO_skip: 854 tprintf ("SKIP: "); 855 if (!condition_true (opcode.op[1].condition, GS ())) 856 { 857 tprintf (" false\n"); 858 break; 859 } 860 861 rl78_data.dpc = pc; 862 opcode_size = rl78_decode_opcode (pc, &opcode, 863 rl78_get_byte, &rl78_data, isa); 864 pc += opcode_size; 865 tprintf (" skipped: %s\n", opcode.syntax); 866 break; 867 868 case RLO_stop: 869 tprintf ("STOP.\n"); 870 DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A))); 871 DO_RETURN (RL78_MAKE_HIT_BREAK ()); 872 873 case RLO_sub: 874 tprintf ("SUB: "); 875 a = GS (); 876 b = GD (); 877 v = b - a; 878 FLAGS (b, v); 879 PD (v); 880 tprintf ("%d (0x%x) - %d (0x%x) = %d (0x%x)\n", b, b, a, a, v, v); 881 if (opcode.op[0].type == RL78_Operand_Indirect) 882 CLOCKS (2); 883 break; 884 885 case RLO_subc: 886 tprintf ("SUBC: "); 887 a = GS (); 888 b = GD (); 889 v = b - a - get_carry (); 890 FLAGS (b, v); 891 PD (v); 892 if (opcode.op[0].type == RL78_Operand_Indirect) 893 CLOCKS (2); 894 break; 895 896 case RLO_xch: 897 tprintf ("XCH: "); 898 a = GS (); 899 b = GD (); 900 PD (a); 901 PS (b); 902 break; 903 904 case RLO_xor: 905 tprintf ("XOR:"); 906 a = GS (); 907 b = GD (); 908 v = a ^ b; 909 FLAGS (b, v); 910 PD (v); 911 if (opcode.op[0].type == RL78_Operand_Indirect) 912 CLOCKS (2); 913 break; 914 915 default: 916 tprintf ("Unknown opcode?\n"); 917 DO_RETURN (RL78_MAKE_HIT_BREAK ()); 918 } 919 920 if (timer_enabled) 921 process_clock_tick (); 922 923 return RL78_MAKE_STEPPED (); 924} 925