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