]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/rl78/rl78.c
52f41bee1434a8f46dc9e516574005222ee854c8
[thirdparty/binutils-gdb.git] / sim / rl78 / rl78.c
1 /* rl78.c --- opcode semantics for stand-alone RL78 simulator.
2
3 Copyright (C) 2008-2017 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 }