1 /* rl78.c --- opcode semantics for stand-alone RL78 simulator.
3 Copyright (C) 2008-2019 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
6 This file is part of the GNU simulators.
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.
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.
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/>.
30 #include "opcode/rl78.h"
35 static int opcode_pc = 0;
37 jmp_buf decode_jmp_buf;
38 #define DO_RETURN(x) longjmp (decode_jmp_buf, x)
40 #define tprintf if (trace) printf
42 #define WILD_JUMP_CHECK(new_pc) \
44 if (new_pc == 0 || new_pc > 0xfffff) \
47 fprintf (stderr, "Wild jump to 0x%x from 0x%x!\n", new_pc, pc); \
48 DO_RETURN (RL78_MAKE_HIT_BREAK ()); \
57 rl78_get_byte (void *vdata)
59 RL78_Data *rl78_data = (RL78_Data *)vdata;
60 int rv = mem_get_pc (rl78_data->dpc);
66 op_addr (const RL78_Opcode_Operand *o, int for_data)
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);
74 v |= (get_reg (RL78_Reg_ES) & 0xf) << 16;
82 get_op (const RL78_Opcode_Decoded *rd, int i, int for_data)
85 const RL78_Opcode_Operand *o = rd->op + i;
89 case RL78_Operand_None:
90 /* condition code does this. */
94 case RL78_Operand_Immediate:
99 case RL78_Operand_Register:
100 tprintf (" %s=", reg_names[o->reg]);
101 v = get_reg (o->reg);
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;
110 case RL78_Operand_Indirect:
111 v = op_addr (o, for_data);
112 tprintf (" [0x%x]=", v);
113 if (rd->size == RL78_Word)
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;
125 case RL78_Operand_PreDec:
126 r = get_reg (o->reg);
127 tprintf (" [--%s]", reg_names[o->reg]);
128 if (rd->size == RL78_Word)
131 v = mem_get_hi (r | 0xf0000);
136 v = mem_get_qi (r | 0xf0000);
141 case RL78_Operand_PostInc:
142 tprintf (" [%s++]", reg_names[o->reg]);
143 r = get_reg (o->reg);
144 if (rd->size == RL78_Word)
146 v = mem_get_hi (r | 0xf0000);
151 v = mem_get_qi (r | 0xf0000);
165 put_op (const RL78_Opcode_Decoded *rd, int i, int for_data, int v)
168 const RL78_Opcode_Operand *o = rd->op + i;
174 case RL78_Operand_Register:
175 tprintf ("%s", reg_names[o->reg]);
179 case RL78_Operand_Bit:
180 tprintf ("%s.%d", reg_names[o->reg], o->bit_number);
181 r = get_reg (o->reg);
183 r |= (1 << o->bit_number);
185 r &= ~(1 << o->bit_number);
189 case RL78_Operand_Indirect:
190 r = op_addr (o, for_data);
191 tprintf ("[0x%x]", r);
192 if (rd->size == RL78_Word)
198 case RL78_Operand_BitIndirect:
199 a = op_addr (o, for_data);
200 tprintf ("[0x%x].%d", a, o->bit_number);
203 r |= (1 << o->bit_number);
205 r &= ~(1 << o->bit_number);
209 case RL78_Operand_PreDec:
210 r = get_reg (o->reg);
211 tprintf ("[--%s]", reg_names[o->reg]);
212 if (rd->size == RL78_Word)
216 mem_put_hi (r | 0xf0000, v);
222 mem_put_qi (r | 0xf0000, v);
226 case RL78_Operand_PostInc:
227 tprintf ("[%s++]", reg_names[o->reg]);
228 r = get_reg (o->reg);
229 if (rd->size == RL78_Word)
231 mem_put_hi (r | 0xf0000, v);
236 mem_put_qi (r | 0xf0000, v);
249 op_flags (int before, int after, int mask, RL78_Size size)
251 int vmask, cmask, amask, avmask;
253 if (size == RL78_Word)
268 int psw = get_reg (RL78_Reg_PSW);
271 if (mask & RL78_PSW_CY)
273 if ((after & cmask) != (before & cmask))
276 if (mask & RL78_PSW_AC)
278 if ((after & amask) != (before & amask)
279 && (after & avmask) < (before & avmask))
282 if (mask & RL78_PSW_Z)
284 if (! (after & vmask))
288 set_reg (RL78_Reg_PSW, psw);
291 #define FLAGS(before,after) if (opcode.flags) op_flags (before, after, opcode.flags, opcode.size)
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)
298 #define GPC() gpc (&opcode, 0)
300 gpc (RL78_Opcode_Decoded *opcode, int idx)
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);
313 return (get_reg (RL78_Reg_PSW) & RL78_PSW_CY) ? 1 : 0;
319 int p = get_reg (RL78_Reg_PSW);
320 tprintf ("set_carry (%d)\n", c ? 1 : 0);
325 set_reg (RL78_Reg_PSW, p);
328 /* We simulate timer TM00 in interval mode, no clearing, with
329 interrupts. I.e. it's a cycle counter. */
331 unsigned int counts_per_insn[0x100000];
333 int pending_clocks = 0;
334 long long total_clocks = 0;
339 process_clock_tick (void)
342 unsigned short ivect;
352 counts_per_insn[opcode_pc] += pending_clocks;
353 total_clocks += pending_clocks;
355 while (pending_clocks)
358 cnt = mem_get_hi (TCR0);
360 mem_put_hi (TCR0, cnt);
365 psw = get_reg (RL78_Reg_PSW);
366 ivect = mem_get_hi (0x0002c);
367 mask = mem_get_hi (MK1);
369 if ((psw & RL78_PSW_IE)
373 unsigned short sp = get_reg (RL78_Reg_SP);
374 set_reg (RL78_Reg_SP, sp - 4);
376 mem_put_qi (sp | 0xf0000, psw);
378 mem_put_psi (sp | 0xf0000, pc);
380 set_reg (RL78_Reg_PSW, psw);
382 /* Spec says 9-14 clocks */
391 dump_counts_per_insn (const char * filename)
395 f = fopen (filename, "w");
401 for (i = 0; i < 0x100000; i ++)
403 if (counts_per_insn[i])
404 fprintf (f, "%05x %d\n", i, counts_per_insn[i]);
412 pending_clocks += n - 1;
419 RL78_Opcode_Decoded opcode;
426 isa = (rl78_g10_mode ? RL78_ISA_G10
427 : g14_multiply ? RL78_ISA_G14
428 : g13_multiply ? RL78_ISA_G13
432 opcode_size = rl78_decode_opcode (pc, &opcode,
433 rl78_get_byte, &rl78_data, isa);
438 trace_register_words = opcode.size == RL78_Word ? 1 : 0;
440 /* Used by shfit/rotate instructions */
441 obits = opcode.size == RL78_Word ? 16 : 8;
452 if (opcode.op[0].type == RL78_Operand_Indirect)
460 v = a + b + get_carry ();
463 if (opcode.op[0].type == RL78_Operand_Indirect)
474 if (opcode.op[0].type == RL78_Operand_Indirect)
478 case RLO_branch_cond:
479 case RLO_branch_cond_clear:
480 tprintf ("BRANCH_COND: ");
481 if (!condition_true (opcode.op[1].condition, GS ()))
483 tprintf (" false\n");
484 if (opcode.op[1].condition == RL78_Condition_T
485 || opcode.op[1].condition == RL78_Condition_F)
491 if (opcode.id == RLO_branch_cond_clear)
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 */
498 CLOCKS (2); /* note: adds one clock, total 4 clocks */
500 tprintf ("BRANCH: ");
504 tprintf (" => 0x%05x\n", pc);
512 DO_RETURN (RL78_MAKE_HIT_BREAK ());
514 DO_RETURN (RL78_MAKE_EXITED (1));
519 a = get_reg (RL78_Reg_SP);
520 set_reg (RL78_Reg_SP, a - 4);
521 mem_put_psi ((a - 4) | 0xf0000, pc);
526 /* Enable this code to dump the arguments for each call. */
531 for (i = 0; i < 8; i ++)
532 printf (" %02x", mem_get_qi (0xf0000 | (a + i)) & 0xff);
546 tprintf (" (%d)\n", v);
550 a = get_reg (RL78_Reg_AX);
551 b = get_reg (RL78_Reg_DE);
552 tprintf (" %d / %d = ", a, b);
555 tprintf ("%d rem %d\n", 0xffff, a);
556 set_reg (RL78_Reg_AX, 0xffff);
557 set_reg (RL78_Reg_DE, a);
563 tprintf ("%d rem %d\n", v, a);
564 set_reg (RL78_Reg_AX, v);
565 set_reg (RL78_Reg_DE, a);
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);
576 tprintf (" %lu / %lu = ", bcax, hlde);
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);
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);
601 DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A)));
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);
630 set_reg (RL78_Reg_PSW, a);
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);
649 set_reg (RL78_Reg_PSW, a);
655 a = get_reg (RL78_Reg_A);
656 b = get_reg (RL78_Reg_X);
658 tprintf (" %d * %d = %d\n", a, b, v);
659 set_reg (RL78_Reg_AX, v);
664 a = sign_ext (get_reg (RL78_Reg_AX), 16);
665 b = sign_ext (get_reg (RL78_Reg_BC), 16);
667 tprintf (" %d * %d = %d\n", a, b, v);
668 set_reg (RL78_Reg_BC, v >> 16);
669 set_reg (RL78_Reg_AX, v);
675 a = get_reg (RL78_Reg_AX);
676 b = get_reg (RL78_Reg_BC);
678 tprintf (" %d * %d = %d\n", a, b, v);
679 set_reg (RL78_Reg_BC, v >> 16);
680 set_reg (RL78_Reg_AX, v);
695 if (opcode.op[0].type == RL78_Operand_Indirect)
701 a = get_reg (RL78_Reg_SP);
702 v = mem_get_psi (a | 0xf0000);
705 set_reg (RL78_Reg_SP, a + 4);
707 /* Enable this code to dump the return values for each return. */
712 for (i = 0; i < 8; i ++)
713 printf (" %02x", mem_get_qi (0xffef0 + i) & 0xff);
723 a = get_reg (RL78_Reg_SP);
724 v = mem_get_psi (a | 0xf0000);
727 b = mem_get_qi ((a + 3) | 0xf0000);
728 set_reg (RL78_Reg_PSW, b);
729 set_reg (RL78_Reg_SP, a + 4);
734 tprintf ("ROL:"); /* d <<= s */
741 v |= (b >> (obits - 1)) & 1;
742 set_carry ((b >> (obits - 1)) & 1);
749 tprintf ("ROLC:"); /* d <<= s */
757 set_carry ((b >> (obits - 1)) & 1);
764 tprintf ("ROR:"); /* d >>= s */
771 v |= (b & 1) << (obits - 1);
779 tprintf ("RORC:"); /* d >>= s */
786 v |= (get_carry () << (obits - 1));
794 tprintf ("SAR:"); /* d >>= s */
801 v |= b & (1 << (obits - 1));
811 b = get_reg (RL78_Reg_PSW);
812 b &= ~(RL78_PSW_RBS1 | RL78_PSW_RBS0);
817 set_reg (RL78_Reg_PSW, b);
822 tprintf ("SHL%d:", obits); /* d <<= s */
829 tprintf ("b = 0x%x & 0x%x\n", b, 1<<(obits - 1));
830 set_carry (b & (1<<(obits - 1)));
837 tprintf ("SHR:"); /* d >>= s */
852 if (!condition_true (opcode.op[1].condition, GS ()))
854 tprintf (" false\n");
859 opcode_size = rl78_decode_opcode (pc, &opcode,
860 rl78_get_byte, &rl78_data, isa);
862 tprintf (" skipped: %s\n", opcode.syntax);
867 DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A)));
868 DO_RETURN (RL78_MAKE_HIT_BREAK ());
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)
886 v = b - a - get_carry ();
889 if (opcode.op[0].type == RL78_Operand_Indirect)
908 if (opcode.op[0].type == RL78_Operand_Indirect)
913 tprintf ("Unknown opcode?\n");
914 DO_RETURN (RL78_MAKE_HIT_BREAK ());
918 process_clock_tick ();
920 return RL78_MAKE_STEPPED ();