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
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;
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)
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;
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