PowerPC relocations for prefix insns
[external/binutils.git] / sim / rl78 / rl78.c
1 /* rl78.c --- opcode semantics for stand-alone RL78 simulator.
2
3    Copyright (C) 2008-2019 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 }