xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/rl78/rl78.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* rl78.c --- opcode semantics for stand-alone RL78 simulator.
2 
3    Copyright (C) 2008-2023 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 /* This must come before any other includes.  */
23 #include "defs.h"
24 
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 
36 extern int skip_init;
37 static int opcode_pc = 0;
38 
39 jmp_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 
54 typedef struct {
55   unsigned long dpc;
56 } RL78_Data;
57 
58 static int
59 rl78_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 
67 static int
68 op_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 
83 static int
84 get_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 
166 static void
167 put_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 
250 static void
251 op_flags (int before, int after, int mask, RL78_Size size)
252 {
253   int vmask, cmask, amask, avmask;
254   int psw;
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 
271   psw = get_reg (RL78_Reg_PSW);
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)
302 static int
303 gpc (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 
313 static int
314 get_carry (void)
315 {
316   return (get_reg (RL78_Reg_PSW) & RL78_PSW_CY) ? 1 : 0;
317 }
318 
319 static void
320 set_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 
334 unsigned int counts_per_insn[0x100000];
335 
336 int pending_clocks = 0;
337 long long total_clocks = 0;
338 
339 #define TCR0	0xf0180
340 #define	MK1	0xfffe6
341 static void
342 process_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 
393 void
394 dump_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 
412 static void
413 CLOCKS (int n)
414 {
415   pending_clocks += n - 1;
416 }
417 
418 int
419 decode_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;
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);
433 
434   rl78_data.dpc = pc;
435   opcode_size = rl78_decode_opcode (pc, &opcode,
436 				    rl78_get_byte, &rl78_data, isa);
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 */
502     case RLO_branch:
503       tprintf ("BRANCH: ");
504       v = GPC ();
505       WILD_JUMP_CHECK (v);
506       pc = v;
507       tprintf (" => 0x%05x\n", pc);
508       CLOCKS (3);
509       break;
510 
511     case RLO_break:
512       tprintf ("BRK: ");
513       CLOCKS (5);
514       if (rl78_in_gdb)
515 	DO_RETURN (RL78_MAKE_HIT_BREAK ());
516       else
517 	DO_RETURN (RL78_MAKE_EXITED (1));
518       break;
519 
520     case RLO_call:
521       tprintf ("CALL: ");
522       a = get_reg (RL78_Reg_SP);
523       set_reg (RL78_Reg_SP, a - 4);
524       mem_put_psi ((a - 4) | 0xf0000, pc);
525       v = GPC ();
526       WILD_JUMP_CHECK (v);
527       pc = v;
528 #if 0
529       /* Enable this code to dump the arguments for each call.  */
530       if (trace)
531 	{
532 	  int i;
533 	  skip_init ++;
534 	  for (i = 0; i < 8; i ++)
535 	    printf (" %02x", mem_get_qi (0xf0000 | (a + i)) & 0xff);
536 	  skip_init --;
537 	}
538 #endif
539       tprintf ("\n");
540       CLOCKS (3);
541       break;
542 
543     case RLO_cmp:
544       tprintf ("CMP: ");
545       a = GD ();
546       b = GS ();
547       v = a - b;
548       FLAGS (b, v);
549       tprintf (" (%d)\n", v);
550       break;
551 
552     case RLO_divhu:
553       a = get_reg (RL78_Reg_AX);
554       b = get_reg (RL78_Reg_DE);
555       tprintf (" %d / %d = ", a, b);
556       if (b == 0)
557 	{
558 	  tprintf ("%d rem %d\n", 0xffff, a);
559 	  set_reg (RL78_Reg_AX, 0xffff);
560 	  set_reg (RL78_Reg_DE, a);
561 	}
562       else
563 	{
564 	  v = a / b;
565 	  a = a % b;
566 	  tprintf ("%d rem %d\n", v, a);
567 	  set_reg (RL78_Reg_AX, v);
568 	  set_reg (RL78_Reg_DE, a);
569 	}
570       CLOCKS (9);
571       break;
572 
573     case RLO_divwu:
574       {
575 	unsigned long bcax, hlde, quot, rem;
576 	bcax = get_reg (RL78_Reg_AX) + 65536 * get_reg (RL78_Reg_BC);
577 	hlde = get_reg (RL78_Reg_DE) + 65536 * get_reg (RL78_Reg_HL);
578 
579 	tprintf (" %lu / %lu = ", bcax, hlde);
580 	if (hlde == 0)
581 	  {
582 	    tprintf ("%lu rem %lu\n", 0xffffLU, bcax);
583 	    set_reg (RL78_Reg_AX, 0xffffLU);
584 	    set_reg (RL78_Reg_BC, 0xffffLU);
585 	    set_reg (RL78_Reg_DE, bcax);
586 	    set_reg (RL78_Reg_HL, bcax >> 16);
587 	  }
588 	else
589 	  {
590 	    quot = bcax / hlde;
591 	    rem = bcax % hlde;
592 	    tprintf ("%lu rem %lu\n", quot, rem);
593 	    set_reg (RL78_Reg_AX, quot);
594 	    set_reg (RL78_Reg_BC, quot >> 16);
595 	    set_reg (RL78_Reg_DE, rem);
596 	    set_reg (RL78_Reg_HL, rem >> 16);
597 	  }
598       }
599       CLOCKS (17);
600       break;
601 
602     case RLO_halt:
603       tprintf ("HALT.\n");
604       DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A)));
605 
606     case RLO_mov:
607       tprintf ("MOV: ");
608       a = GS ();
609       FLAGS (a, a);
610       PD (a);
611       break;
612 
613 #define MACR 0xffff0
614     case RLO_mach:
615       tprintf ("MACH:");
616       a = sign_ext (get_reg (RL78_Reg_AX), 16);
617       b = sign_ext (get_reg (RL78_Reg_BC), 16);
618       v = sign_ext (mem_get_si (MACR), 32);
619       tprintf ("%08x %d + %d * %d = ", v, v, a, b);
620       v2 = sign_ext (v + a * b, 32);
621       tprintf ("%08x %d\n", v2, v2);
622       mem_put_si (MACR, v2);
623       a = get_reg (RL78_Reg_PSW);
624       v ^= v2;
625       if (v & (1<<31))
626 	a |= RL78_PSW_CY;
627       else
628 	a &= ~RL78_PSW_CY;
629       if (v2 & (1 << 31))
630 	a |= RL78_PSW_AC;
631       else
632 	a &= ~RL78_PSW_AC;
633       set_reg (RL78_Reg_PSW, a);
634       CLOCKS (3);
635       break;
636 
637     case RLO_machu:
638       tprintf ("MACHU:");
639       a = get_reg (RL78_Reg_AX);
640       b = get_reg (RL78_Reg_BC);
641       u = mem_get_si (MACR);
642       tprintf ("%08x %u + %u * %u = ", u, u, a, b);
643       u2 = (u + (unsigned)a * (unsigned)b) & 0xffffffffUL;
644       tprintf ("%08x %u\n", u2, u2);
645       mem_put_si (MACR, u2);
646       a = get_reg (RL78_Reg_PSW);
647       if (u2 < u)
648 	a |= RL78_PSW_CY;
649       else
650 	a &= ~RL78_PSW_CY;
651       a &= ~RL78_PSW_AC;
652       set_reg (RL78_Reg_PSW, a);
653       CLOCKS (3);
654       break;
655 
656     case RLO_mulu:
657       tprintf ("MULU:");
658       a = get_reg (RL78_Reg_A);
659       b = get_reg (RL78_Reg_X);
660       v = a * b;
661       tprintf (" %d * %d = %d\n", a, b, v);
662       set_reg (RL78_Reg_AX, v);
663       break;
664 
665     case RLO_mulh:
666       tprintf ("MUL:");
667       a = sign_ext (get_reg (RL78_Reg_AX), 16);
668       b = sign_ext (get_reg (RL78_Reg_BC), 16);
669       v = a * b;
670       tprintf (" %d * %d = %d\n", a, b, v);
671       set_reg (RL78_Reg_BC, v >> 16);
672       set_reg (RL78_Reg_AX, v);
673       CLOCKS (2);
674       break;
675 
676     case RLO_mulhu:
677       tprintf ("MULHU:");
678       a = get_reg (RL78_Reg_AX);
679       b = get_reg (RL78_Reg_BC);
680       v = a * b;
681       tprintf (" %d * %d = %d\n", a, b, v);
682       set_reg (RL78_Reg_BC, v >> 16);
683       set_reg (RL78_Reg_AX, v);
684       CLOCKS (2);
685       break;
686 
687     case RLO_nop:
688       tprintf ("NOP.\n");
689       break;
690 
691     case RLO_or:
692       tprintf ("OR:");
693       a = GS ();
694       b = GD ();
695       v = a | b;
696       FLAGS (b, v);
697       PD (v);
698       if (opcode.op[0].type == RL78_Operand_Indirect)
699 	CLOCKS (2);
700       break;
701 
702     case RLO_ret:
703       tprintf ("RET: ");
704       a = get_reg (RL78_Reg_SP);
705       v = mem_get_psi (a | 0xf0000);
706       WILD_JUMP_CHECK (v);
707       pc = v;
708       set_reg (RL78_Reg_SP, a + 4);
709 #if 0
710       /* Enable this code to dump the return values for each return.  */
711       if (trace)
712 	{
713 	  int i;
714 	  skip_init ++;
715 	  for (i = 0; i < 8; i ++)
716 	    printf (" %02x", mem_get_qi (0xffef0 + i) & 0xff);
717 	  skip_init --;
718 	}
719 #endif
720       tprintf ("\n");
721       CLOCKS (6);
722       break;
723 
724     case RLO_reti:
725       tprintf ("RETI: ");
726       a = get_reg (RL78_Reg_SP);
727       v = mem_get_psi (a | 0xf0000);
728       WILD_JUMP_CHECK (v);
729       pc = v;
730       b = mem_get_qi ((a + 3) | 0xf0000);
731       set_reg (RL78_Reg_PSW, b);
732       set_reg (RL78_Reg_SP, a + 4);
733       tprintf ("\n");
734       break;
735 
736     case RLO_rol:
737       tprintf ("ROL:"); /* d <<= s */
738       a = GS ();
739       b = GD ();
740       v = b;
741       while (a --)
742 	{
743 	  v = b << 1;
744 	  v |= (b >> (obits - 1)) & 1;
745 	  set_carry ((b >> (obits - 1)) & 1);
746 	  b = v;
747 	}
748       PD (v);
749       break;
750 
751     case RLO_rolc:
752       tprintf ("ROLC:"); /* d <<= s */
753       a = GS ();
754       b = GD ();
755       v = b;
756       while (a --)
757 	{
758 	  v = b << 1;
759 	  v |= get_carry ();
760 	  set_carry ((b >> (obits - 1)) & 1);
761 	  b = v;
762 	}
763       PD (v);
764       break;
765 
766     case RLO_ror:
767       tprintf ("ROR:"); /* d >>= s */
768       a = GS ();
769       b = GD ();
770       v = b;
771       while (a --)
772 	{
773 	  v = b >> 1;
774 	  v |= (b & 1) << (obits - 1);
775 	  set_carry (b & 1);
776 	  b = v;
777 	}
778       PD (v);
779       break;
780 
781     case RLO_rorc:
782       tprintf ("RORC:"); /* d >>= s */
783       a = GS ();
784       b = GD ();
785       v = b;
786       while (a --)
787 	{
788 	  v = b >> 1;
789 	  v |= (get_carry () << (obits - 1));
790 	  set_carry (b & 1);
791 	  b = v;
792 	}
793       PD (v);
794       break;
795 
796     case RLO_sar:
797       tprintf ("SAR:"); /* d >>= s */
798       a = GS ();
799       b = GD ();
800       v = b;
801       while (a --)
802 	{
803 	  v = b >> 1;
804 	  v |= b & (1 << (obits - 1));
805 	  set_carry (b & 1);
806 	  b = v;
807 	}
808       PD (v);
809       break;
810 
811     case RLO_sel:
812       tprintf ("SEL:");
813       a = GS ();
814       b = get_reg (RL78_Reg_PSW);
815       b &= ~(RL78_PSW_RBS1 | RL78_PSW_RBS0);
816       if (a & 1)
817 	b |= RL78_PSW_RBS0;
818       if (a & 2)
819 	b |= RL78_PSW_RBS1;
820       set_reg (RL78_Reg_PSW, b);
821       tprintf ("\n");
822       break;
823 
824     case RLO_shl:
825       tprintf ("SHL%d:", obits); /* d <<= s */
826       a = GS ();
827       b = GD ();
828       v = b;
829       while (a --)
830 	{
831 	  v = b << 1;
832 	  tprintf ("b = 0x%x & 0x%x\n", b, 1<<(obits - 1));
833 	  set_carry (b & (1<<(obits - 1)));
834 	  b = v;
835 	}
836       PD (v);
837       break;
838 
839     case RLO_shr:
840       tprintf ("SHR:"); /* d >>= s */
841       a = GS ();
842       b = GD ();
843       v = b;
844       while (a --)
845 	{
846 	  v = b >> 1;
847 	  set_carry (b & 1);
848 	  b = v;
849 	}
850       PD (v);
851       break;
852 
853     case RLO_skip:
854       tprintf ("SKIP: ");
855       if (!condition_true (opcode.op[1].condition, GS ()))
856 	{
857 	  tprintf (" false\n");
858 	  break;
859 	}
860 
861       rl78_data.dpc = pc;
862       opcode_size = rl78_decode_opcode (pc, &opcode,
863 					rl78_get_byte, &rl78_data, isa);
864       pc += opcode_size;
865       tprintf (" skipped: %s\n", opcode.syntax);
866       break;
867 
868     case RLO_stop:
869       tprintf ("STOP.\n");
870       DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A)));
871       DO_RETURN (RL78_MAKE_HIT_BREAK ());
872 
873     case RLO_sub:
874       tprintf ("SUB: ");
875       a = GS ();
876       b = GD ();
877       v = b - a;
878       FLAGS (b, v);
879       PD (v);
880       tprintf ("%d (0x%x) - %d (0x%x) = %d (0x%x)\n", b, b, a, a, v, v);
881       if (opcode.op[0].type == RL78_Operand_Indirect)
882 	CLOCKS (2);
883       break;
884 
885     case RLO_subc:
886       tprintf ("SUBC: ");
887       a = GS ();
888       b = GD ();
889       v = b - a - get_carry ();
890       FLAGS (b, v);
891       PD (v);
892       if (opcode.op[0].type == RL78_Operand_Indirect)
893 	CLOCKS (2);
894       break;
895 
896     case RLO_xch:
897       tprintf ("XCH: ");
898       a = GS ();
899       b = GD ();
900       PD (a);
901       PS (b);
902       break;
903 
904     case RLO_xor:
905       tprintf ("XOR:");
906       a = GS ();
907       b = GD ();
908       v = a ^ b;
909       FLAGS (b, v);
910       PD (v);
911       if (opcode.op[0].type == RL78_Operand_Indirect)
912 	CLOCKS (2);
913       break;
914 
915     default:
916       tprintf ("Unknown opcode?\n");
917       DO_RETURN (RL78_MAKE_HIT_BREAK ());
918     }
919 
920   if (timer_enabled)
921     process_clock_tick ();
922 
923   return RL78_MAKE_STEPPED ();
924 }
925