sim: rl78: clean up various warnings
[deliverable/binutils-gdb.git] / sim / rl78 / rl78.c
1 /* rl78.c --- opcode semantics for stand-alone RL78 simulator.
2
3 Copyright (C) 2008-2021 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 int psw;
253
254 if (size == RL78_Word)
255 {
256 cmask = 0x10000;
257 vmask = 0xffff;
258 amask = 0x100;
259 avmask = 0x0ff;
260 }
261 else
262 {
263 cmask = 0x100;
264 vmask = 0xff;
265 amask = 0x10;
266 avmask = 0x0f;
267 }
268
269 psw = get_reg (RL78_Reg_PSW);
270 psw &= ~mask;
271
272 if (mask & RL78_PSW_CY)
273 {
274 if ((after & cmask) != (before & cmask))
275 psw |= RL78_PSW_CY;
276 }
277 if (mask & RL78_PSW_AC)
278 {
279 if ((after & amask) != (before & amask)
280 && (after & avmask) < (before & avmask))
281 psw |= RL78_PSW_AC;
282 }
283 if (mask & RL78_PSW_Z)
284 {
285 if (! (after & vmask))
286 psw |= RL78_PSW_Z;
287 }
288
289 set_reg (RL78_Reg_PSW, psw);
290 }
291
292 #define FLAGS(before,after) if (opcode.flags) op_flags (before, after, opcode.flags, opcode.size)
293
294 #define PD(x) put_op (&opcode, 0, 1, x)
295 #define PS(x) put_op (&opcode, 1, 1, x)
296 #define GD() get_op (&opcode, 0, 1)
297 #define GS() get_op (&opcode, 1, 1)
298
299 #define GPC() gpc (&opcode, 0)
300 static int
301 gpc (RL78_Opcode_Decoded *opcode, int idx)
302 {
303 int a = get_op (opcode, 0, 1);
304 if (opcode->op[idx].type == RL78_Operand_Register)
305 a =(a & 0x0ffff) | ((get_reg (RL78_Reg_CS) & 0x0f) << 16);
306 else
307 a &= 0xfffff;
308 return a;
309 }
310
311 static int
312 get_carry (void)
313 {
314 return (get_reg (RL78_Reg_PSW) & RL78_PSW_CY) ? 1 : 0;
315 }
316
317 static void
318 set_carry (int c)
319 {
320 int p = get_reg (RL78_Reg_PSW);
321 tprintf ("set_carry (%d)\n", c ? 1 : 0);
322 if (c)
323 p |= RL78_PSW_CY;
324 else
325 p &= ~RL78_PSW_CY;
326 set_reg (RL78_Reg_PSW, p);
327 }
328
329 /* We simulate timer TM00 in interval mode, no clearing, with
330 interrupts. I.e. it's a cycle counter. */
331
332 unsigned int counts_per_insn[0x100000];
333
334 int pending_clocks = 0;
335 long long total_clocks = 0;
336
337 #define TCR0 0xf0180
338 #define MK1 0xfffe6
339 static void
340 process_clock_tick (void)
341 {
342 unsigned short cnt;
343 unsigned short ivect;
344 unsigned short mask;
345 unsigned char psw;
346 int save_trace;
347
348 save_trace = trace;
349 trace = 0;
350
351 pending_clocks ++;
352
353 counts_per_insn[opcode_pc] += pending_clocks;
354 total_clocks += pending_clocks;
355
356 while (pending_clocks)
357 {
358 pending_clocks --;
359 cnt = mem_get_hi (TCR0);
360 cnt --;
361 mem_put_hi (TCR0, cnt);
362 if (cnt != 0xffff)
363 continue;
364
365 /* overflow. */
366 psw = get_reg (RL78_Reg_PSW);
367 ivect = mem_get_hi (0x0002c);
368 mask = mem_get_hi (MK1);
369
370 if ((psw & RL78_PSW_IE)
371 && (ivect != 0)
372 && !(mask & 0x0010))
373 {
374 unsigned short sp = get_reg (RL78_Reg_SP);
375 set_reg (RL78_Reg_SP, sp - 4);
376 sp --;
377 mem_put_qi (sp | 0xf0000, psw);
378 sp -= 3;
379 mem_put_psi (sp | 0xf0000, pc);
380 psw &= ~RL78_PSW_IE;
381 set_reg (RL78_Reg_PSW, psw);
382 pc = ivect;
383 /* Spec says 9-14 clocks */
384 pending_clocks += 9;
385 }
386 }
387
388 trace = save_trace;
389 }
390
391 void
392 dump_counts_per_insn (const char * filename)
393 {
394 int i;
395 FILE *f;
396 f = fopen (filename, "w");
397 if (!f)
398 {
399 perror (filename);
400 return;
401 }
402 for (i = 0; i < 0x100000; i ++)
403 {
404 if (counts_per_insn[i])
405 fprintf (f, "%05x %d\n", i, counts_per_insn[i]);
406 }
407 fclose (f);
408 }
409
410 static void
411 CLOCKS (int n)
412 {
413 pending_clocks += n - 1;
414 }
415
416 int
417 decode_opcode (void)
418 {
419 RL78_Data rl78_data;
420 RL78_Opcode_Decoded opcode;
421 int opcode_size;
422 int a, b, v, v2;
423 unsigned int u, u2;
424 int obits;
425 RL78_Dis_Isa isa;
426
427 isa = (rl78_g10_mode ? RL78_ISA_G10
428 : g14_multiply ? RL78_ISA_G14
429 : g13_multiply ? RL78_ISA_G13
430 : RL78_ISA_DEFAULT);
431
432 rl78_data.dpc = pc;
433 opcode_size = rl78_decode_opcode (pc, &opcode,
434 rl78_get_byte, &rl78_data, isa);
435
436 opcode_pc = pc;
437 pc += opcode_size;
438
439 trace_register_words = opcode.size == RL78_Word ? 1 : 0;
440
441 /* Used by shfit/rotate instructions */
442 obits = opcode.size == RL78_Word ? 16 : 8;
443
444 switch (opcode.id)
445 {
446 case RLO_add:
447 tprintf ("ADD: ");
448 a = GS ();
449 b = GD ();
450 v = a + b;
451 FLAGS (b, v);
452 PD (v);
453 if (opcode.op[0].type == RL78_Operand_Indirect)
454 CLOCKS (2);
455 break;
456
457 case RLO_addc:
458 tprintf ("ADDC: ");
459 a = GS ();
460 b = GD ();
461 v = a + b + get_carry ();
462 FLAGS (b, v);
463 PD (v);
464 if (opcode.op[0].type == RL78_Operand_Indirect)
465 CLOCKS (2);
466 break;
467
468 case RLO_and:
469 tprintf ("AND: ");
470 a = GS ();
471 b = GD ();
472 v = a & b;
473 FLAGS (b, v);
474 PD (v);
475 if (opcode.op[0].type == RL78_Operand_Indirect)
476 CLOCKS (2);
477 break;
478
479 case RLO_branch_cond:
480 case RLO_branch_cond_clear:
481 tprintf ("BRANCH_COND: ");
482 if (!condition_true (opcode.op[1].condition, GS ()))
483 {
484 tprintf (" false\n");
485 if (opcode.op[1].condition == RL78_Condition_T
486 || opcode.op[1].condition == RL78_Condition_F)
487 CLOCKS (3);
488 else
489 CLOCKS (2);
490 break;
491 }
492 if (opcode.id == RLO_branch_cond_clear)
493 PS (0);
494 tprintf (" ");
495 if (opcode.op[1].condition == RL78_Condition_T
496 || opcode.op[1].condition == RL78_Condition_F)
497 CLOCKS (3); /* note: adds two clocks, total 5 clocks */
498 else
499 CLOCKS (2); /* note: adds one clock, total 4 clocks */
500 case RLO_branch:
501 tprintf ("BRANCH: ");
502 v = GPC ();
503 WILD_JUMP_CHECK (v);
504 pc = v;
505 tprintf (" => 0x%05x\n", pc);
506 CLOCKS (3);
507 break;
508
509 case RLO_break:
510 tprintf ("BRK: ");
511 CLOCKS (5);
512 if (rl78_in_gdb)
513 DO_RETURN (RL78_MAKE_HIT_BREAK ());
514 else
515 DO_RETURN (RL78_MAKE_EXITED (1));
516 break;
517
518 case RLO_call:
519 tprintf ("CALL: ");
520 a = get_reg (RL78_Reg_SP);
521 set_reg (RL78_Reg_SP, a - 4);
522 mem_put_psi ((a - 4) | 0xf0000, pc);
523 v = GPC ();
524 WILD_JUMP_CHECK (v);
525 pc = v;
526 #if 0
527 /* Enable this code to dump the arguments for each call. */
528 if (trace)
529 {
530 int i;
531 skip_init ++;
532 for (i = 0; i < 8; i ++)
533 printf (" %02x", mem_get_qi (0xf0000 | (a + i)) & 0xff);
534 skip_init --;
535 }
536 #endif
537 tprintf ("\n");
538 CLOCKS (3);
539 break;
540
541 case RLO_cmp:
542 tprintf ("CMP: ");
543 a = GD ();
544 b = GS ();
545 v = a - b;
546 FLAGS (b, v);
547 tprintf (" (%d)\n", v);
548 break;
549
550 case RLO_divhu:
551 a = get_reg (RL78_Reg_AX);
552 b = get_reg (RL78_Reg_DE);
553 tprintf (" %d / %d = ", a, b);
554 if (b == 0)
555 {
556 tprintf ("%d rem %d\n", 0xffff, a);
557 set_reg (RL78_Reg_AX, 0xffff);
558 set_reg (RL78_Reg_DE, a);
559 }
560 else
561 {
562 v = a / b;
563 a = a % b;
564 tprintf ("%d rem %d\n", v, a);
565 set_reg (RL78_Reg_AX, v);
566 set_reg (RL78_Reg_DE, a);
567 }
568 CLOCKS (9);
569 break;
570
571 case RLO_divwu:
572 {
573 unsigned long bcax, hlde, quot, rem;
574 bcax = get_reg (RL78_Reg_AX) + 65536 * get_reg (RL78_Reg_BC);
575 hlde = get_reg (RL78_Reg_DE) + 65536 * get_reg (RL78_Reg_HL);
576
577 tprintf (" %lu / %lu = ", bcax, hlde);
578 if (hlde == 0)
579 {
580 tprintf ("%lu rem %lu\n", 0xffffLU, bcax);
581 set_reg (RL78_Reg_AX, 0xffffLU);
582 set_reg (RL78_Reg_BC, 0xffffLU);
583 set_reg (RL78_Reg_DE, bcax);
584 set_reg (RL78_Reg_HL, bcax >> 16);
585 }
586 else
587 {
588 quot = bcax / hlde;
589 rem = bcax % hlde;
590 tprintf ("%lu rem %lu\n", quot, rem);
591 set_reg (RL78_Reg_AX, quot);
592 set_reg (RL78_Reg_BC, quot >> 16);
593 set_reg (RL78_Reg_DE, rem);
594 set_reg (RL78_Reg_HL, rem >> 16);
595 }
596 }
597 CLOCKS (17);
598 break;
599
600 case RLO_halt:
601 tprintf ("HALT.\n");
602 DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A)));
603
604 case RLO_mov:
605 tprintf ("MOV: ");
606 a = GS ();
607 FLAGS (a, a);
608 PD (a);
609 break;
610
611 #define MACR 0xffff0
612 case RLO_mach:
613 tprintf ("MACH:");
614 a = sign_ext (get_reg (RL78_Reg_AX), 16);
615 b = sign_ext (get_reg (RL78_Reg_BC), 16);
616 v = sign_ext (mem_get_si (MACR), 32);
617 tprintf ("%08x %d + %d * %d = ", v, v, a, b);
618 v2 = sign_ext (v + a * b, 32);
619 tprintf ("%08x %d\n", v2, v2);
620 mem_put_si (MACR, v2);
621 a = get_reg (RL78_Reg_PSW);
622 v ^= v2;
623 if (v & (1<<31))
624 a |= RL78_PSW_CY;
625 else
626 a &= ~RL78_PSW_CY;
627 if (v2 & (1 << 31))
628 a |= RL78_PSW_AC;
629 else
630 a &= ~RL78_PSW_AC;
631 set_reg (RL78_Reg_PSW, a);
632 CLOCKS (3);
633 break;
634
635 case RLO_machu:
636 tprintf ("MACHU:");
637 a = get_reg (RL78_Reg_AX);
638 b = get_reg (RL78_Reg_BC);
639 u = mem_get_si (MACR);
640 tprintf ("%08x %u + %u * %u = ", u, u, a, b);
641 u2 = (u + (unsigned)a * (unsigned)b) & 0xffffffffUL;
642 tprintf ("%08x %u\n", u2, u2);
643 mem_put_si (MACR, u2);
644 a = get_reg (RL78_Reg_PSW);
645 if (u2 < u)
646 a |= RL78_PSW_CY;
647 else
648 a &= ~RL78_PSW_CY;
649 a &= ~RL78_PSW_AC;
650 set_reg (RL78_Reg_PSW, a);
651 CLOCKS (3);
652 break;
653
654 case RLO_mulu:
655 tprintf ("MULU:");
656 a = get_reg (RL78_Reg_A);
657 b = get_reg (RL78_Reg_X);
658 v = a * b;
659 tprintf (" %d * %d = %d\n", a, b, v);
660 set_reg (RL78_Reg_AX, v);
661 break;
662
663 case RLO_mulh:
664 tprintf ("MUL:");
665 a = sign_ext (get_reg (RL78_Reg_AX), 16);
666 b = sign_ext (get_reg (RL78_Reg_BC), 16);
667 v = a * b;
668 tprintf (" %d * %d = %d\n", a, b, v);
669 set_reg (RL78_Reg_BC, v >> 16);
670 set_reg (RL78_Reg_AX, v);
671 CLOCKS (2);
672 break;
673
674 case RLO_mulhu:
675 tprintf ("MULHU:");
676 a = get_reg (RL78_Reg_AX);
677 b = get_reg (RL78_Reg_BC);
678 v = a * b;
679 tprintf (" %d * %d = %d\n", a, b, v);
680 set_reg (RL78_Reg_BC, v >> 16);
681 set_reg (RL78_Reg_AX, v);
682 CLOCKS (2);
683 break;
684
685 case RLO_nop:
686 tprintf ("NOP.\n");
687 break;
688
689 case RLO_or:
690 tprintf ("OR:");
691 a = GS ();
692 b = GD ();
693 v = a | b;
694 FLAGS (b, v);
695 PD (v);
696 if (opcode.op[0].type == RL78_Operand_Indirect)
697 CLOCKS (2);
698 break;
699
700 case RLO_ret:
701 tprintf ("RET: ");
702 a = get_reg (RL78_Reg_SP);
703 v = mem_get_psi (a | 0xf0000);
704 WILD_JUMP_CHECK (v);
705 pc = v;
706 set_reg (RL78_Reg_SP, a + 4);
707 #if 0
708 /* Enable this code to dump the return values for each return. */
709 if (trace)
710 {
711 int i;
712 skip_init ++;
713 for (i = 0; i < 8; i ++)
714 printf (" %02x", mem_get_qi (0xffef0 + i) & 0xff);
715 skip_init --;
716 }
717 #endif
718 tprintf ("\n");
719 CLOCKS (6);
720 break;
721
722 case RLO_reti:
723 tprintf ("RETI: ");
724 a = get_reg (RL78_Reg_SP);
725 v = mem_get_psi (a | 0xf0000);
726 WILD_JUMP_CHECK (v);
727 pc = v;
728 b = mem_get_qi ((a + 3) | 0xf0000);
729 set_reg (RL78_Reg_PSW, b);
730 set_reg (RL78_Reg_SP, a + 4);
731 tprintf ("\n");
732 break;
733
734 case RLO_rol:
735 tprintf ("ROL:"); /* d <<= s */
736 a = GS ();
737 b = GD ();
738 v = b;
739 while (a --)
740 {
741 v = b << 1;
742 v |= (b >> (obits - 1)) & 1;
743 set_carry ((b >> (obits - 1)) & 1);
744 b = v;
745 }
746 PD (v);
747 break;
748
749 case RLO_rolc:
750 tprintf ("ROLC:"); /* d <<= s */
751 a = GS ();
752 b = GD ();
753 v = b;
754 while (a --)
755 {
756 v = b << 1;
757 v |= get_carry ();
758 set_carry ((b >> (obits - 1)) & 1);
759 b = v;
760 }
761 PD (v);
762 break;
763
764 case RLO_ror:
765 tprintf ("ROR:"); /* d >>= s */
766 a = GS ();
767 b = GD ();
768 v = b;
769 while (a --)
770 {
771 v = b >> 1;
772 v |= (b & 1) << (obits - 1);
773 set_carry (b & 1);
774 b = v;
775 }
776 PD (v);
777 break;
778
779 case RLO_rorc:
780 tprintf ("RORC:"); /* d >>= s */
781 a = GS ();
782 b = GD ();
783 v = b;
784 while (a --)
785 {
786 v = b >> 1;
787 v |= (get_carry () << (obits - 1));
788 set_carry (b & 1);
789 b = v;
790 }
791 PD (v);
792 break;
793
794 case RLO_sar:
795 tprintf ("SAR:"); /* d >>= s */
796 a = GS ();
797 b = GD ();
798 v = b;
799 while (a --)
800 {
801 v = b >> 1;
802 v |= b & (1 << (obits - 1));
803 set_carry (b & 1);
804 b = v;
805 }
806 PD (v);
807 break;
808
809 case RLO_sel:
810 tprintf ("SEL:");
811 a = GS ();
812 b = get_reg (RL78_Reg_PSW);
813 b &= ~(RL78_PSW_RBS1 | RL78_PSW_RBS0);
814 if (a & 1)
815 b |= RL78_PSW_RBS0;
816 if (a & 2)
817 b |= RL78_PSW_RBS1;
818 set_reg (RL78_Reg_PSW, b);
819 tprintf ("\n");
820 break;
821
822 case RLO_shl:
823 tprintf ("SHL%d:", obits); /* d <<= s */
824 a = GS ();
825 b = GD ();
826 v = b;
827 while (a --)
828 {
829 v = b << 1;
830 tprintf ("b = 0x%x & 0x%x\n", b, 1<<(obits - 1));
831 set_carry (b & (1<<(obits - 1)));
832 b = v;
833 }
834 PD (v);
835 break;
836
837 case RLO_shr:
838 tprintf ("SHR:"); /* d >>= s */
839 a = GS ();
840 b = GD ();
841 v = b;
842 while (a --)
843 {
844 v = b >> 1;
845 set_carry (b & 1);
846 b = v;
847 }
848 PD (v);
849 break;
850
851 case RLO_skip:
852 tprintf ("SKIP: ");
853 if (!condition_true (opcode.op[1].condition, GS ()))
854 {
855 tprintf (" false\n");
856 break;
857 }
858
859 rl78_data.dpc = pc;
860 opcode_size = rl78_decode_opcode (pc, &opcode,
861 rl78_get_byte, &rl78_data, isa);
862 pc += opcode_size;
863 tprintf (" skipped: %s\n", opcode.syntax);
864 break;
865
866 case RLO_stop:
867 tprintf ("STOP.\n");
868 DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A)));
869 DO_RETURN (RL78_MAKE_HIT_BREAK ());
870
871 case RLO_sub:
872 tprintf ("SUB: ");
873 a = GS ();
874 b = GD ();
875 v = b - a;
876 FLAGS (b, v);
877 PD (v);
878 tprintf ("%d (0x%x) - %d (0x%x) = %d (0x%x)\n", b, b, a, a, v, v);
879 if (opcode.op[0].type == RL78_Operand_Indirect)
880 CLOCKS (2);
881 break;
882
883 case RLO_subc:
884 tprintf ("SUBC: ");
885 a = GS ();
886 b = GD ();
887 v = b - a - get_carry ();
888 FLAGS (b, v);
889 PD (v);
890 if (opcode.op[0].type == RL78_Operand_Indirect)
891 CLOCKS (2);
892 break;
893
894 case RLO_xch:
895 tprintf ("XCH: ");
896 a = GS ();
897 b = GD ();
898 PD (a);
899 PS (b);
900 break;
901
902 case RLO_xor:
903 tprintf ("XOR:");
904 a = GS ();
905 b = GD ();
906 v = a ^ b;
907 FLAGS (b, v);
908 PD (v);
909 if (opcode.op[0].type == RL78_Operand_Indirect)
910 CLOCKS (2);
911 break;
912
913 default:
914 tprintf ("Unknown opcode?\n");
915 DO_RETURN (RL78_MAKE_HIT_BREAK ());
916 }
917
918 if (timer_enabled)
919 process_clock_tick ();
920
921 return RL78_MAKE_STEPPED ();
922 }
This page took 0.049821 seconds and 5 git commands to generate.