xref: /netbsd-src/external/gpl3/gdb/dist/sim/rl78/rl78.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /* rl78.c --- opcode semantics for stand-alone RL78 simulator.
2 
3    Copyright (C) 2008-2014 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 
425   rl78_data.dpc = pc;
426   opcode_size = rl78_decode_opcode (pc, &opcode,
427 				    rl78_get_byte, &rl78_data);
428 
429   opcode_pc = pc;
430   pc += opcode_size;
431 
432   trace_register_words = opcode.size == RL78_Word ? 1 : 0;
433 
434   /* Used by shfit/rotate instructions */
435   obits = opcode.size == RL78_Word ? 16 : 8;
436 
437   switch (opcode.id)
438     {
439     case RLO_add:
440       tprintf ("ADD: ");
441       a = GS ();
442       b = GD ();
443       v = a + b;
444       FLAGS (b, v);
445       PD (v);
446       if (opcode.op[0].type == RL78_Operand_Indirect)
447 	CLOCKS (2);
448       break;
449 
450     case RLO_addc:
451       tprintf ("ADDC: ");
452       a = GS ();
453       b = GD ();
454       v = a + b + get_carry ();
455       FLAGS (b, v);
456       PD (v);
457       if (opcode.op[0].type == RL78_Operand_Indirect)
458 	CLOCKS (2);
459       break;
460 
461     case RLO_and:
462       tprintf ("AND: ");
463       a = GS ();
464       b = GD ();
465       v = a & b;
466       FLAGS (b, v);
467       PD (v);
468       if (opcode.op[0].type == RL78_Operand_Indirect)
469 	CLOCKS (2);
470       break;
471 
472     case RLO_branch_cond:
473     case RLO_branch_cond_clear:
474       tprintf ("BRANCH_COND: ");
475       if (!condition_true (opcode.op[1].condition, GS ()))
476 	{
477 	  tprintf (" false\n");
478 	  if (opcode.op[1].condition == RL78_Condition_T
479 	      || opcode.op[1].condition == RL78_Condition_F)
480 	    CLOCKS (3);
481 	  else
482 	    CLOCKS (2);
483 	  break;
484 	}
485       if (opcode.id == RLO_branch_cond_clear)
486 	PS (0);
487       tprintf (" ");
488       if (opcode.op[1].condition == RL78_Condition_T
489 	  || opcode.op[1].condition == RL78_Condition_F)
490 	CLOCKS (3); /* note: adds two clocks, total 5 clocks */
491       else
492 	CLOCKS (2); /* note: adds one clock, total 4 clocks */
493     case RLO_branch:
494       tprintf ("BRANCH: ");
495       v = GPC ();
496       WILD_JUMP_CHECK (v);
497       pc = v;
498       tprintf (" => 0x%05x\n", pc);
499       CLOCKS (3);
500       break;
501 
502     case RLO_break:
503       tprintf ("BRK: ");
504       CLOCKS (5);
505       if (rl78_in_gdb)
506 	DO_RETURN (RL78_MAKE_HIT_BREAK ());
507       else
508 	DO_RETURN (RL78_MAKE_EXITED (1));
509       break;
510 
511     case RLO_call:
512       tprintf ("CALL: ");
513       a = get_reg (RL78_Reg_SP);
514       set_reg (RL78_Reg_SP, a - 4);
515       mem_put_psi ((a - 4) | 0xf0000, pc);
516       v = GPC ();
517       WILD_JUMP_CHECK (v);
518       pc = v;
519 #if 0
520       /* Enable this code to dump the arguments for each call.  */
521       if (trace)
522 	{
523 	  int i;
524 	  skip_init ++;
525 	  for (i = 0; i < 8; i ++)
526 	    printf (" %02x", mem_get_qi (0xf0000 | (a + i)) & 0xff);
527 	  skip_init --;
528 	}
529 #endif
530       tprintf ("\n");
531       CLOCKS (3);
532       break;
533 
534     case RLO_cmp:
535       tprintf ("CMP: ");
536       a = GD ();
537       b = GS ();
538       v = a - b;
539       FLAGS (b, v);
540       tprintf (" (%d)\n", v);
541       break;
542 
543     case RLO_divhu:
544       a = get_reg (RL78_Reg_AX);
545       b = get_reg (RL78_Reg_DE);
546       tprintf (" %d / %d = ", a, b);
547       if (b == 0)
548 	{
549 	  tprintf ("%d rem %d\n", 0xffff, a);
550 	  set_reg (RL78_Reg_AX, 0xffff);
551 	  set_reg (RL78_Reg_DE, a);
552 	}
553       else
554 	{
555 	  v = a / b;
556 	  a = a % b;
557 	  tprintf ("%d rem %d\n", v, a);
558 	  set_reg (RL78_Reg_AX, v);
559 	  set_reg (RL78_Reg_DE, a);
560 	}
561       CLOCKS (9);
562       break;
563 
564     case RLO_divwu:
565       {
566 	unsigned long bcax, hlde, quot, rem;
567 	bcax = get_reg (RL78_Reg_AX) + 65536 * get_reg (RL78_Reg_BC);
568 	hlde = get_reg (RL78_Reg_DE) + 65536 * get_reg (RL78_Reg_HL);
569 
570 	tprintf (" %lu / %lu = ", bcax, hlde);
571 	if (hlde == 0)
572 	  {
573 	    tprintf ("%lu rem %lu\n", 0xffffLU, bcax);
574 	    set_reg (RL78_Reg_AX, 0xffffLU);
575 	    set_reg (RL78_Reg_BC, 0xffffLU);
576 	    set_reg (RL78_Reg_DE, bcax);
577 	    set_reg (RL78_Reg_HL, bcax >> 16);
578 	  }
579 	else
580 	  {
581 	    quot = bcax / hlde;
582 	    rem = bcax % hlde;
583 	    tprintf ("%lu rem %lu\n", quot, rem);
584 	    set_reg (RL78_Reg_AX, quot);
585 	    set_reg (RL78_Reg_BC, quot >> 16);
586 	    set_reg (RL78_Reg_DE, rem);
587 	    set_reg (RL78_Reg_HL, rem >> 16);
588 	  }
589       }
590       CLOCKS (17);
591       break;
592 
593     case RLO_halt:
594       tprintf ("HALT.\n");
595       DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A)));
596 
597     case RLO_mov:
598       tprintf ("MOV: ");
599       a = GS ();
600       FLAGS (a, a);
601       PD (a);
602       break;
603 
604 #define MACR 0xffff0
605     case RLO_mach:
606       tprintf ("MACH:");
607       a = sign_ext (get_reg (RL78_Reg_AX), 16);
608       b = sign_ext (get_reg (RL78_Reg_BC), 16);
609       v = sign_ext (mem_get_si (MACR), 32);
610       tprintf ("%08x %d + %d * %d = ", v, v, a, b);
611       v2 = sign_ext (v + a * b, 32);
612       tprintf ("%08x %d\n", v2, v2);
613       mem_put_si (MACR, v2);
614       a = get_reg (RL78_Reg_PSW);
615       v ^= v2;
616       if (v & (1<<31))
617 	a |= RL78_PSW_CY;
618       else
619 	a &= ~RL78_PSW_CY;
620       if (v2 & (1 << 31))
621 	a |= RL78_PSW_AC;
622       else
623 	a &= ~RL78_PSW_AC;
624       set_reg (RL78_Reg_PSW, a);
625       CLOCKS (3);
626       break;
627 
628     case RLO_machu:
629       tprintf ("MACHU:");
630       a = get_reg (RL78_Reg_AX);
631       b = get_reg (RL78_Reg_BC);
632       u = mem_get_si (MACR);
633       tprintf ("%08x %u + %u * %u = ", u, u, a, b);
634       u2 = (u + (unsigned)a * (unsigned)b) & 0xffffffffUL;
635       tprintf ("%08x %u\n", u2, u2);
636       mem_put_si (MACR, u2);
637       a = get_reg (RL78_Reg_PSW);
638       if (u2 < u)
639 	a |= RL78_PSW_CY;
640       else
641 	a &= ~RL78_PSW_CY;
642       a &= ~RL78_PSW_AC;
643       set_reg (RL78_Reg_PSW, a);
644       CLOCKS (3);
645       break;
646 
647     case RLO_mulu:
648       tprintf ("MULU:");
649       a = get_reg (RL78_Reg_A);
650       b = get_reg (RL78_Reg_X);
651       v = a * b;
652       tprintf (" %d * %d = %d\n", a, b, v);
653       set_reg (RL78_Reg_AX, v);
654       break;
655 
656     case RLO_mulh:
657       tprintf ("MUL:");
658       a = sign_ext (get_reg (RL78_Reg_AX), 16);
659       b = sign_ext (get_reg (RL78_Reg_BC), 16);
660       v = a * b;
661       tprintf (" %d * %d = %d\n", a, b, v);
662       set_reg (RL78_Reg_BC, v >> 16);
663       set_reg (RL78_Reg_AX, v);
664       CLOCKS (2);
665       break;
666 
667     case RLO_mulhu:
668       tprintf ("MULHU:");
669       a = get_reg (RL78_Reg_AX);
670       b = get_reg (RL78_Reg_BC);
671       v = a * b;
672       tprintf (" %d * %d = %d\n", a, b, v);
673       set_reg (RL78_Reg_BC, v >> 16);
674       set_reg (RL78_Reg_AX, v);
675       CLOCKS (2);
676       break;
677 
678     case RLO_nop:
679       tprintf ("NOP.\n");
680       break;
681 
682     case RLO_or:
683       tprintf ("OR:");
684       a = GS ();
685       b = GD ();
686       v = a | b;
687       FLAGS (b, v);
688       PD (v);
689       if (opcode.op[0].type == RL78_Operand_Indirect)
690 	CLOCKS (2);
691       break;
692 
693     case RLO_ret:
694       tprintf ("RET: ");
695       a = get_reg (RL78_Reg_SP);
696       v = mem_get_psi (a | 0xf0000);
697       WILD_JUMP_CHECK (v);
698       pc = v;
699       set_reg (RL78_Reg_SP, a + 4);
700 #if 0
701       /* Enable this code to dump the return values for each return.  */
702       if (trace)
703 	{
704 	  int i;
705 	  skip_init ++;
706 	  for (i = 0; i < 8; i ++)
707 	    printf (" %02x", mem_get_qi (0xffef0 + i) & 0xff);
708 	  skip_init --;
709 	}
710 #endif
711       tprintf ("\n");
712       CLOCKS (6);
713       break;
714 
715     case RLO_reti:
716       tprintf ("RETI: ");
717       a = get_reg (RL78_Reg_SP);
718       v = mem_get_psi (a | 0xf0000);
719       WILD_JUMP_CHECK (v);
720       pc = v;
721       b = mem_get_qi ((a + 3) | 0xf0000);
722       set_reg (RL78_Reg_PSW, b);
723       set_reg (RL78_Reg_SP, a + 4);
724       tprintf ("\n");
725       break;
726 
727     case RLO_rol:
728       tprintf ("ROL:"); /* d <<= s */
729       a = GS ();
730       b = GD ();
731       v = b;
732       while (a --)
733 	{
734 	  v = b << 1;
735 	  v |= (b >> (obits - 1)) & 1;
736 	  set_carry ((b >> (obits - 1)) & 1);
737 	  b = v;
738 	}
739       PD (v);
740       break;
741 
742     case RLO_rolc:
743       tprintf ("ROLC:"); /* d <<= s */
744       a = GS ();
745       b = GD ();
746       v = b;
747       while (a --)
748 	{
749 	  v = b << 1;
750 	  v |= get_carry ();
751 	  set_carry ((b >> (obits - 1)) & 1);
752 	  b = v;
753 	}
754       PD (v);
755       break;
756 
757     case RLO_ror:
758       tprintf ("ROR:"); /* d >>= s */
759       a = GS ();
760       b = GD ();
761       v = b;
762       while (a --)
763 	{
764 	  v = b >> 1;
765 	  v |= (b & 1) << (obits - 1);
766 	  set_carry (b & 1);
767 	  b = v;
768 	}
769       PD (v);
770       break;
771 
772     case RLO_rorc:
773       tprintf ("RORC:"); /* d >>= s */
774       a = GS ();
775       b = GD ();
776       v = b;
777       while (a --)
778 	{
779 	  v = b >> 1;
780 	  v |= (get_carry () << (obits - 1));
781 	  set_carry (b & 1);
782 	  b = v;
783 	}
784       PD (v);
785       break;
786 
787     case RLO_sar:
788       tprintf ("SAR:"); /* d >>= s */
789       a = GS ();
790       b = GD ();
791       v = b;
792       while (a --)
793 	{
794 	  v = b >> 1;
795 	  v |= b & (1 << (obits - 1));
796 	  set_carry (b & 1);
797 	  b = v;
798 	}
799       PD (v);
800       break;
801 
802     case RLO_sel:
803       tprintf ("SEL:");
804       a = GS ();
805       b = get_reg (RL78_Reg_PSW);
806       b &= ~(RL78_PSW_RBS1 | RL78_PSW_RBS0);
807       if (a & 1)
808 	b |= RL78_PSW_RBS0;
809       if (a & 2)
810 	b |= RL78_PSW_RBS1;
811       set_reg (RL78_Reg_PSW, b);
812       tprintf ("\n");
813       break;
814 
815     case RLO_shl:
816       tprintf ("SHL%d:", obits); /* d <<= s */
817       a = GS ();
818       b = GD ();
819       v = b;
820       while (a --)
821 	{
822 	  v = b << 1;
823 	  tprintf ("b = 0x%x & 0x%x\n", b, 1<<(obits - 1));
824 	  set_carry (b & (1<<(obits - 1)));
825 	  b = v;
826 	}
827       PD (v);
828       break;
829 
830     case RLO_shr:
831       tprintf ("SHR:"); /* d >>= s */
832       a = GS ();
833       b = GD ();
834       v = b;
835       while (a --)
836 	{
837 	  v = b >> 1;
838 	  set_carry (b & 1);
839 	  b = v;
840 	}
841       PD (v);
842       break;
843 
844     case RLO_skip:
845       tprintf ("SKIP: ");
846       if (!condition_true (opcode.op[1].condition, GS ()))
847 	{
848 	  tprintf (" false\n");
849 	  break;
850 	}
851 
852       rl78_data.dpc = pc;
853       opcode_size = rl78_decode_opcode (pc, &opcode,
854 					rl78_get_byte, &rl78_data);
855       pc += opcode_size;
856       tprintf (" skipped: %s\n", opcode.syntax);
857       break;
858 
859     case RLO_stop:
860       tprintf ("STOP.\n");
861       DO_RETURN (RL78_MAKE_EXITED (get_reg (RL78_Reg_A)));
862       DO_RETURN (RL78_MAKE_HIT_BREAK ());
863 
864     case RLO_sub:
865       tprintf ("SUB: ");
866       a = GS ();
867       b = GD ();
868       v = b - a;
869       FLAGS (b, v);
870       PD (v);
871       tprintf ("%d (0x%x) - %d (0x%x) = %d (0x%x)\n", b, b, a, a, v, v);
872       if (opcode.op[0].type == RL78_Operand_Indirect)
873 	CLOCKS (2);
874       break;
875 
876     case RLO_subc:
877       tprintf ("SUBC: ");
878       a = GS ();
879       b = GD ();
880       v = b - a - get_carry ();
881       FLAGS (b, v);
882       PD (v);
883       if (opcode.op[0].type == RL78_Operand_Indirect)
884 	CLOCKS (2);
885       break;
886 
887     case RLO_xch:
888       tprintf ("XCH: ");
889       a = GS ();
890       b = GD ();
891       PD (a);
892       PS (b);
893       break;
894 
895     case RLO_xor:
896       tprintf ("XOR:");
897       a = GS ();
898       b = GD ();
899       v = a ^ b;
900       FLAGS (b, v);
901       PD (v);
902       if (opcode.op[0].type == RL78_Operand_Indirect)
903 	CLOCKS (2);
904       break;
905 
906     default:
907       tprintf ("Unknown opcode?\n");
908       DO_RETURN (RL78_MAKE_HIT_BREAK ());
909     }
910 
911   if (timer_enabled)
912     process_clock_tick ();
913 
914   return RL78_MAKE_STEPPED ();
915 }
916