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