1 /* rl78.c --- opcode semantics for stand-alone RL78 simulator. 2 3 Copyright (C) 2008-2016 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 RL78_Dis_Isa isa; 425 426 isa = (rl78_g10_mode ? RL78_ISA_G10 427 : g14_multiply ? RL78_ISA_G14 428 : g13_multiply ? RL78_ISA_G13 429 : RL78_ISA_DEFAULT); 430 431 rl78_data.dpc = pc; 432 opcode_size = rl78_decode_opcode (pc, &opcode, 433 rl78_get_byte, &rl78_data, isa); 434 435 opcode_pc = pc; 436 pc += opcode_size; 437 438 trace_register_words = opcode.size == RL78_Word ? 1 : 0; 439 440 /* Used by shfit/rotate instructions */ 441 obits = opcode.size == RL78_Word ? 16 : 8; 442 443 switch (opcode.id) 444 { 445 case RLO_add: 446 tprintf ("ADD: "); 447 a = GS (); 448 b = GD (); 449 v = a + b; 450 FLAGS (b, v); 451 PD (v); 452 if (opcode.op[0].type == RL78_Operand_Indirect) 453 CLOCKS (2); 454 break; 455 456 case RLO_addc: 457 tprintf ("ADDC: "); 458 a = GS (); 459 b = GD (); 460 v = a + b + get_carry (); 461 FLAGS (b, v); 462 PD (v); 463 if (opcode.op[0].type == RL78_Operand_Indirect) 464 CLOCKS (2); 465 break; 466 467 case RLO_and: 468 tprintf ("AND: "); 469 a = GS (); 470 b = GD (); 471 v = a & b; 472 FLAGS (b, v); 473 PD (v); 474 if (opcode.op[0].type == RL78_Operand_Indirect) 475 CLOCKS (2); 476 break; 477 478 case RLO_branch_cond: 479 case RLO_branch_cond_clear: 480 tprintf ("BRANCH_COND: "); 481 if (!condition_true (opcode.op[1].condition, GS ())) 482 { 483 tprintf (" false\n"); 484 if (opcode.op[1].condition == RL78_Condition_T 485 || opcode.op[1].condition == RL78_Condition_F) 486 CLOCKS (3); 487 else 488 CLOCKS (2); 489 break; 490 } 491 if (opcode.id == RLO_branch_cond_clear) 492 PS (0); 493 tprintf (" "); 494 if (opcode.op[1].condition == RL78_Condition_T 495 || opcode.op[1].condition == RL78_Condition_F) 496 CLOCKS (3); /* note: adds two clocks, total 5 clocks */ 497 else 498 CLOCKS (2); /* note: adds one clock, total 4 clocks */ 499 case RLO_branch: 500 tprintf ("BRANCH: "); 501 v = GPC (); 502 WILD_JUMP_CHECK (v); 503 pc = v; 504 tprintf (" => 0x%05x\n", pc); 505 CLOCKS (3); 506 break; 507 508 case RLO_break: 509 tprintf ("BRK: "); 510 CLOCKS (5); 511 if (rl78_in_gdb) 512 DO_RETURN (RL78_MAKE_HIT_BREAK ()); 513 else 514 DO_RETURN (RL78_MAKE_EXITED (1)); 515 break; 516 517 case RLO_call: 518 tprintf ("CALL: "); 519 a = get_reg (RL78_Reg_SP); 520 set_reg (RL78_Reg_SP, a - 4); 521 mem_put_psi ((a - 4) | 0xf0000, pc); 522 v = GPC (); 523 WILD_JUMP_CHECK (v); 524 pc = v; 525 #if 0 526 /* Enable this code to dump the arguments for each call. */ 527 if (trace) 528 { 529 int i; 530 skip_init ++; 531 for (i = 0; i < 8; i ++) 532 printf (" %02x", mem_get_qi (0xf0000 | (a + i)) & 0xff); 533 skip_init --; 534 } 535 #endif 536 tprintf ("\n"); 537 CLOCKS (3); 538 break; 539 540 case RLO_cmp: 541 tprintf ("CMP: "); 542 a = GD (); 543 b = GS (); 544 v = a - b; 545 FLAGS (b, v); 546 tprintf (" (%d)\n", v); 547 break; 548 549 case RLO_divhu: 550 a = get_reg (RL78_Reg_AX); 551 b = get_reg (RL78_Reg_DE); 552 tprintf (" %d / %d = ", a, b); 553 if (b == 0) 554 { 555 tprintf ("%d rem %d\n", 0xffff, a); 556 set_reg (RL78_Reg_AX, 0xffff); 557 set_reg (RL78_Reg_DE, a); 558 } 559 else 560 { 561 v = a / b; 562 a = a % b; 563 tprintf ("%d rem %d\n", v, a); 564 set_reg (RL78_Reg_AX, v); 565 set_reg (RL78_Reg_DE, a); 566 } 567 CLOCKS (9); 568 break; 569 570 case RLO_divwu: 571 { 572 unsigned long bcax, hlde, quot, rem; 573 bcax = get_reg (RL78_Reg_AX) + 65536 * get_reg (RL78_Reg_BC); 574 hlde = get_reg (RL78_Reg_DE) + 65536 * get_reg (RL78_Reg_HL); 575 576 tprintf (" %lu / %lu = ", bcax, hlde); 577 if (hlde == 0) 578 { 579 tprintf ("%lu rem %lu\n", 0xffffLU, bcax); 580 set_reg (RL78_Reg_AX, 0xffffLU); 581 set_reg (RL78_Reg_BC, 0xffffLU); 582 set_reg (RL78_Reg_DE, bcax); 583 set_reg (RL78_Reg_HL, bcax >> 16); 584 } 585 else 586 { 587 quot = bcax / hlde; 588 rem = bcax % hlde; 589 tprintf ("%lu rem %lu\n", quot, rem); 590 set_reg (RL78_Reg_AX, quot); 591 set_reg (RL78_Reg_BC, quot >> 16); 592 set_reg (RL78_Reg_DE, rem); 593 set_reg (RL78_Reg_HL, rem >> 16); 594 } 595 } 596 CLOCKS (17); 597 break; 598 599 case RLO_halt: 600 tprintf ("HALT.\n"); 601 DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A))); 602 603 case RLO_mov: 604 tprintf ("MOV: "); 605 a = GS (); 606 FLAGS (a, a); 607 PD (a); 608 break; 609 610 #define MACR 0xffff0 611 case RLO_mach: 612 tprintf ("MACH:"); 613 a = sign_ext (get_reg (RL78_Reg_AX), 16); 614 b = sign_ext (get_reg (RL78_Reg_BC), 16); 615 v = sign_ext (mem_get_si (MACR), 32); 616 tprintf ("%08x %d + %d * %d = ", v, v, a, b); 617 v2 = sign_ext (v + a * b, 32); 618 tprintf ("%08x %d\n", v2, v2); 619 mem_put_si (MACR, v2); 620 a = get_reg (RL78_Reg_PSW); 621 v ^= v2; 622 if (v & (1<<31)) 623 a |= RL78_PSW_CY; 624 else 625 a &= ~RL78_PSW_CY; 626 if (v2 & (1 << 31)) 627 a |= RL78_PSW_AC; 628 else 629 a &= ~RL78_PSW_AC; 630 set_reg (RL78_Reg_PSW, a); 631 CLOCKS (3); 632 break; 633 634 case RLO_machu: 635 tprintf ("MACHU:"); 636 a = get_reg (RL78_Reg_AX); 637 b = get_reg (RL78_Reg_BC); 638 u = mem_get_si (MACR); 639 tprintf ("%08x %u + %u * %u = ", u, u, a, b); 640 u2 = (u + (unsigned)a * (unsigned)b) & 0xffffffffUL; 641 tprintf ("%08x %u\n", u2, u2); 642 mem_put_si (MACR, u2); 643 a = get_reg (RL78_Reg_PSW); 644 if (u2 < u) 645 a |= RL78_PSW_CY; 646 else 647 a &= ~RL78_PSW_CY; 648 a &= ~RL78_PSW_AC; 649 set_reg (RL78_Reg_PSW, a); 650 CLOCKS (3); 651 break; 652 653 case RLO_mulu: 654 tprintf ("MULU:"); 655 a = get_reg (RL78_Reg_A); 656 b = get_reg (RL78_Reg_X); 657 v = a * b; 658 tprintf (" %d * %d = %d\n", a, b, v); 659 set_reg (RL78_Reg_AX, v); 660 break; 661 662 case RLO_mulh: 663 tprintf ("MUL:"); 664 a = sign_ext (get_reg (RL78_Reg_AX), 16); 665 b = sign_ext (get_reg (RL78_Reg_BC), 16); 666 v = a * b; 667 tprintf (" %d * %d = %d\n", a, b, v); 668 set_reg (RL78_Reg_BC, v >> 16); 669 set_reg (RL78_Reg_AX, v); 670 CLOCKS (2); 671 break; 672 673 case RLO_mulhu: 674 tprintf ("MULHU:"); 675 a = get_reg (RL78_Reg_AX); 676 b = get_reg (RL78_Reg_BC); 677 v = a * b; 678 tprintf (" %d * %d = %d\n", a, b, v); 679 set_reg (RL78_Reg_BC, v >> 16); 680 set_reg (RL78_Reg_AX, v); 681 CLOCKS (2); 682 break; 683 684 case RLO_nop: 685 tprintf ("NOP.\n"); 686 break; 687 688 case RLO_or: 689 tprintf ("OR:"); 690 a = GS (); 691 b = GD (); 692 v = a | b; 693 FLAGS (b, v); 694 PD (v); 695 if (opcode.op[0].type == RL78_Operand_Indirect) 696 CLOCKS (2); 697 break; 698 699 case RLO_ret: 700 tprintf ("RET: "); 701 a = get_reg (RL78_Reg_SP); 702 v = mem_get_psi (a | 0xf0000); 703 WILD_JUMP_CHECK (v); 704 pc = v; 705 set_reg (RL78_Reg_SP, a + 4); 706 #if 0 707 /* Enable this code to dump the return values for each return. */ 708 if (trace) 709 { 710 int i; 711 skip_init ++; 712 for (i = 0; i < 8; i ++) 713 printf (" %02x", mem_get_qi (0xffef0 + i) & 0xff); 714 skip_init --; 715 } 716 #endif 717 tprintf ("\n"); 718 CLOCKS (6); 719 break; 720 721 case RLO_reti: 722 tprintf ("RETI: "); 723 a = get_reg (RL78_Reg_SP); 724 v = mem_get_psi (a | 0xf0000); 725 WILD_JUMP_CHECK (v); 726 pc = v; 727 b = mem_get_qi ((a + 3) | 0xf0000); 728 set_reg (RL78_Reg_PSW, b); 729 set_reg (RL78_Reg_SP, a + 4); 730 tprintf ("\n"); 731 break; 732 733 case RLO_rol: 734 tprintf ("ROL:"); /* d <<= s */ 735 a = GS (); 736 b = GD (); 737 v = b; 738 while (a --) 739 { 740 v = b << 1; 741 v |= (b >> (obits - 1)) & 1; 742 set_carry ((b >> (obits - 1)) & 1); 743 b = v; 744 } 745 PD (v); 746 break; 747 748 case RLO_rolc: 749 tprintf ("ROLC:"); /* d <<= s */ 750 a = GS (); 751 b = GD (); 752 v = b; 753 while (a --) 754 { 755 v = b << 1; 756 v |= get_carry (); 757 set_carry ((b >> (obits - 1)) & 1); 758 b = v; 759 } 760 PD (v); 761 break; 762 763 case RLO_ror: 764 tprintf ("ROR:"); /* d >>= s */ 765 a = GS (); 766 b = GD (); 767 v = b; 768 while (a --) 769 { 770 v = b >> 1; 771 v |= (b & 1) << (obits - 1); 772 set_carry (b & 1); 773 b = v; 774 } 775 PD (v); 776 break; 777 778 case RLO_rorc: 779 tprintf ("RORC:"); /* d >>= s */ 780 a = GS (); 781 b = GD (); 782 v = b; 783 while (a --) 784 { 785 v = b >> 1; 786 v |= (get_carry () << (obits - 1)); 787 set_carry (b & 1); 788 b = v; 789 } 790 PD (v); 791 break; 792 793 case RLO_sar: 794 tprintf ("SAR:"); /* d >>= s */ 795 a = GS (); 796 b = GD (); 797 v = b; 798 while (a --) 799 { 800 v = b >> 1; 801 v |= b & (1 << (obits - 1)); 802 set_carry (b & 1); 803 b = v; 804 } 805 PD (v); 806 break; 807 808 case RLO_sel: 809 tprintf ("SEL:"); 810 a = GS (); 811 b = get_reg (RL78_Reg_PSW); 812 b &= ~(RL78_PSW_RBS1 | RL78_PSW_RBS0); 813 if (a & 1) 814 b |= RL78_PSW_RBS0; 815 if (a & 2) 816 b |= RL78_PSW_RBS1; 817 set_reg (RL78_Reg_PSW, b); 818 tprintf ("\n"); 819 break; 820 821 case RLO_shl: 822 tprintf ("SHL%d:", obits); /* d <<= s */ 823 a = GS (); 824 b = GD (); 825 v = b; 826 while (a --) 827 { 828 v = b << 1; 829 tprintf ("b = 0x%x & 0x%x\n", b, 1<<(obits - 1)); 830 set_carry (b & (1<<(obits - 1))); 831 b = v; 832 } 833 PD (v); 834 break; 835 836 case RLO_shr: 837 tprintf ("SHR:"); /* d >>= s */ 838 a = GS (); 839 b = GD (); 840 v = b; 841 while (a --) 842 { 843 v = b >> 1; 844 set_carry (b & 1); 845 b = v; 846 } 847 PD (v); 848 break; 849 850 case RLO_skip: 851 tprintf ("SKIP: "); 852 if (!condition_true (opcode.op[1].condition, GS ())) 853 { 854 tprintf (" false\n"); 855 break; 856 } 857 858 rl78_data.dpc = pc; 859 opcode_size = rl78_decode_opcode (pc, &opcode, 860 rl78_get_byte, &rl78_data, isa); 861 pc += opcode_size; 862 tprintf (" skipped: %s\n", opcode.syntax); 863 break; 864 865 case RLO_stop: 866 tprintf ("STOP.\n"); 867 DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A))); 868 DO_RETURN (RL78_MAKE_HIT_BREAK ()); 869 870 case RLO_sub: 871 tprintf ("SUB: "); 872 a = GS (); 873 b = GD (); 874 v = b - a; 875 FLAGS (b, v); 876 PD (v); 877 tprintf ("%d (0x%x) - %d (0x%x) = %d (0x%x)\n", b, b, a, a, v, v); 878 if (opcode.op[0].type == RL78_Operand_Indirect) 879 CLOCKS (2); 880 break; 881 882 case RLO_subc: 883 tprintf ("SUBC: "); 884 a = GS (); 885 b = GD (); 886 v = b - a - get_carry (); 887 FLAGS (b, v); 888 PD (v); 889 if (opcode.op[0].type == RL78_Operand_Indirect) 890 CLOCKS (2); 891 break; 892 893 case RLO_xch: 894 tprintf ("XCH: "); 895 a = GS (); 896 b = GD (); 897 PD (a); 898 PS (b); 899 break; 900 901 case RLO_xor: 902 tprintf ("XOR:"); 903 a = GS (); 904 b = GD (); 905 v = a ^ b; 906 FLAGS (b, v); 907 PD (v); 908 if (opcode.op[0].type == RL78_Operand_Indirect) 909 CLOCKS (2); 910 break; 911 912 default: 913 tprintf ("Unknown opcode?\n"); 914 DO_RETURN (RL78_MAKE_HIT_BREAK ()); 915 } 916 917 if (timer_enabled) 918 process_clock_tick (); 919 920 return RL78_MAKE_STEPPED (); 921 } 922