Home | History | Annotate | Line # | Download | only in h8300
compile.c revision 1.9
      1  1.1  christos /*
      2  1.1  christos  * Simulator for the Renesas (formerly Hitachi) H8/300 architecture.
      3  1.1  christos  *
      4  1.1  christos  * Written by Steve Chamberlain of Cygnus Support. sac (at) cygnus.com
      5  1.1  christos  *
      6  1.1  christos  * This file is part of H8/300 sim
      7  1.1  christos  *
      8  1.1  christos  *
      9  1.1  christos  * THIS SOFTWARE IS NOT COPYRIGHTED
     10  1.1  christos  *
     11  1.1  christos  * Cygnus offers the following for use in the public domain.  Cygnus makes no
     12  1.1  christos  * warranty with regard to the software or its performance and the user
     13  1.1  christos  * accepts the software "AS IS" with all faults.
     14  1.1  christos  *
     15  1.1  christos  * CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS
     16  1.1  christos  * SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
     17  1.1  christos  * AND FITNESS FOR A PARTICULAR PURPOSE.
     18  1.1  christos  */
     19  1.1  christos 
     20  1.7  christos /* This must come before any other includes.  */
     21  1.7  christos #include "defs.h"
     22  1.7  christos 
     23  1.1  christos #include <signal.h>
     24  1.1  christos #include <time.h>
     25  1.1  christos #include <stdlib.h>
     26  1.1  christos #ifdef HAVE_SYS_PARAM_H
     27  1.1  christos #include <sys/param.h>
     28  1.1  christos #endif
     29  1.8  christos #include <sys/stat.h>
     30  1.1  christos 
     31  1.1  christos #include "bfd.h"
     32  1.1  christos #include "sim-main.h"
     33  1.8  christos #include "sim/sim-h8300.h"
     34  1.1  christos #include "sys/types.h"
     35  1.5  christos #include "sim-options.h"
     36  1.7  christos #include "sim-signal.h"
     37  1.7  christos #include "sim/callback.h"
     38  1.1  christos 
     39  1.8  christos #include "h8300-sim.h"
     40  1.8  christos 
     41  1.1  christos #ifndef SIGTRAP
     42  1.1  christos # define SIGTRAP 5
     43  1.1  christos #endif
     44  1.1  christos 
     45  1.1  christos int debug;
     46  1.1  christos 
     47  1.8  christos /* Each entry in this array is an index into the main opcode
     48  1.8  christos    array for the first instruction starting with the given
     49  1.8  christos    4 bit nibble.  */
     50  1.8  christos static int nib_indices[16];
     51  1.8  christos 
     52  1.7  christos static int memory_size;
     53  1.1  christos 
     54  1.1  christos #define X(op, size)  (op * 4 + size)
     55  1.1  christos 
     56  1.1  christos #define SP (h8300hmode && !h8300_normal_mode ? SL : SW)
     57  1.1  christos 
     58  1.1  christos #define h8_opcodes ops
     59  1.1  christos #define DEFINE_TABLE
     60  1.1  christos #include "opcode/h8300.h"
     61  1.1  christos 
     62  1.1  christos /* CPU data object: */
     63  1.1  christos 
     64  1.1  christos static unsigned int
     65  1.7  christos h8_get_reg (sim_cpu *cpu, int regnum)
     66  1.1  christos {
     67  1.8  christos   return H8300_SIM_CPU (cpu)->regs[regnum];
     68  1.1  christos }
     69  1.1  christos 
     70  1.1  christos static void
     71  1.7  christos h8_set_reg (sim_cpu *cpu, int regnum, int val)
     72  1.1  christos {
     73  1.8  christos   H8300_SIM_CPU (cpu)->regs[regnum] = val;
     74  1.1  christos }
     75  1.1  christos 
     76  1.7  christos #define h8_get_ccr(cpu)		h8_get_reg (cpu, CCR_REGNUM)
     77  1.7  christos #define h8_set_ccr(cpu, val)	h8_set_reg (cpu, CCR_REGNUM, val)
     78  1.7  christos #define h8_get_exr(cpu)		h8_get_reg (cpu, EXR_REGNUM)
     79  1.7  christos #define h8_set_exr(cpu, val)	h8_set_reg (cpu, EXR_REGNUM, val)
     80  1.7  christos #define h8_get_sbr(cpu)		h8_get_reg (cpu, SBR_REGNUM)
     81  1.7  christos #define h8_set_sbr(cpu, val)	h8_set_reg (cpu, SBR_REGNUM, val)
     82  1.7  christos #define h8_get_vbr(cpu)		h8_get_reg (cpu, VBR_REGNUM)
     83  1.7  christos #define h8_set_vbr(cpu, val)	h8_set_reg (cpu, VBR_REGNUM, val)
     84  1.7  christos #define h8_get_cycles(cpu)	h8_get_reg (cpu, CYCLE_REGNUM)
     85  1.7  christos #define h8_set_cycles(cpu, val)	h8_set_reg (cpu, CYCLE_REGNUM, val)
     86  1.7  christos #define h8_get_insts(cpu)	h8_get_reg (cpu, INST_REGNUM)
     87  1.7  christos #define h8_set_insts(cpu, val)	h8_set_reg (cpu, INST_REGNUM, val)
     88  1.7  christos #define h8_get_ticks(cpu)	h8_get_reg (cpu, TICK_REGNUM)
     89  1.7  christos #define h8_set_ticks(cpu, val)	h8_set_reg (cpu, TICK_REGNUM, val)
     90  1.7  christos #define h8_get_mach(cpu)	h8_get_reg (cpu, MACH_REGNUM)
     91  1.7  christos #define h8_set_mach(cpu, val)	h8_set_reg (cpu, MACH_REGNUM, val)
     92  1.7  christos #define h8_get_macl(cpu)	h8_get_reg (cpu, MACL_REGNUM)
     93  1.7  christos #define h8_set_macl(cpu, val)	h8_set_reg (cpu, MACL_REGNUM, val)
     94  1.1  christos 
     95  1.1  christos static int
     96  1.7  christos h8_get_mask (sim_cpu *cpu)
     97  1.1  christos {
     98  1.8  christos   return H8300_SIM_CPU (cpu)->mask;
     99  1.1  christos }
    100  1.1  christos 
    101  1.1  christos static void
    102  1.7  christos h8_set_mask (sim_cpu *cpu, int val)
    103  1.1  christos {
    104  1.8  christos   H8300_SIM_CPU (cpu)->mask = val;
    105  1.1  christos }
    106  1.1  christos #if 0
    107  1.1  christos static int
    108  1.7  christos h8_get_exception (sim_cpu *cpu)
    109  1.1  christos {
    110  1.8  christos   return H8300_SIM_CPU (cpu)->exception;
    111  1.1  christos }
    112  1.1  christos 
    113  1.1  christos static void
    114  1.7  christos h8_set_exception (sim_cpu *cpu, int val)
    115  1.1  christos {
    116  1.8  christos   H8300_SIM_CPU (cpu)->exception = val;
    117  1.1  christos }
    118  1.1  christos 
    119  1.1  christos static enum h8300_sim_state
    120  1.1  christos h8_get_state (SIM_DESC sd)
    121  1.1  christos {
    122  1.7  christos   return H8300_SIM_STATE (sd)->state;
    123  1.1  christos }
    124  1.1  christos 
    125  1.1  christos static void
    126  1.1  christos h8_set_state (SIM_DESC sd, enum h8300_sim_state val)
    127  1.1  christos {
    128  1.7  christos   H8300_SIM_STATE (sd)->state = val;
    129  1.1  christos }
    130  1.1  christos #endif
    131  1.1  christos 
    132  1.1  christos static unsigned int *
    133  1.7  christos h8_get_reg_buf (sim_cpu *cpu)
    134  1.1  christos {
    135  1.8  christos   return &H8300_SIM_CPU (cpu)->regs[0];
    136  1.1  christos }
    137  1.1  christos 
    138  1.1  christos #ifdef ADEBUG
    139  1.1  christos static int
    140  1.1  christos h8_get_stats (SIM_DESC sd, int idx)
    141  1.1  christos {
    142  1.7  christos   return H8300_SIM_STATE (sd)->stats[idx];
    143  1.1  christos }
    144  1.1  christos 
    145  1.1  christos static void
    146  1.1  christos h8_increment_stats (SIM_DESC sd, int idx)
    147  1.1  christos {
    148  1.7  christos   H8300_SIM_STATE (sd)->stats[idx] ++;
    149  1.1  christos }
    150  1.1  christos #endif /* ADEBUG */
    151  1.1  christos 
    152  1.1  christos static unsigned char *
    153  1.7  christos h8_get_memory_buf (sim_cpu *cpu)
    154  1.1  christos {
    155  1.8  christos   return H8300_SIM_CPU (cpu)->memory;
    156  1.1  christos }
    157  1.1  christos 
    158  1.1  christos static void
    159  1.7  christos h8_set_memory_buf (sim_cpu *cpu, unsigned char *ptr)
    160  1.1  christos {
    161  1.8  christos   H8300_SIM_CPU (cpu)->memory = ptr;
    162  1.1  christos }
    163  1.1  christos 
    164  1.1  christos static unsigned char
    165  1.7  christos h8_get_memory (sim_cpu *cpu, int idx)
    166  1.1  christos {
    167  1.7  christos   ASSERT (idx < memory_size);
    168  1.8  christos   return H8300_SIM_CPU (cpu)->memory[idx];
    169  1.1  christos }
    170  1.1  christos 
    171  1.1  christos static void
    172  1.7  christos h8_set_memory (sim_cpu *cpu, int idx, unsigned int val)
    173  1.1  christos {
    174  1.7  christos   ASSERT (idx < memory_size);
    175  1.8  christos   H8300_SIM_CPU (cpu)->memory[idx] = (unsigned char) val;
    176  1.1  christos }
    177  1.1  christos 
    178  1.1  christos static unsigned int
    179  1.7  christos h8_get_delayed_branch (sim_cpu *cpu)
    180  1.1  christos {
    181  1.8  christos   return H8300_SIM_CPU (cpu)->delayed_branch;
    182  1.1  christos }
    183  1.1  christos 
    184  1.1  christos static void
    185  1.7  christos h8_set_delayed_branch (sim_cpu *cpu, unsigned int dest)
    186  1.1  christos {
    187  1.8  christos   H8300_SIM_CPU (cpu)->delayed_branch = dest;
    188  1.1  christos }
    189  1.1  christos 
    190  1.1  christos static char **
    191  1.7  christos h8_get_command_line (sim_cpu *cpu)
    192  1.1  christos {
    193  1.8  christos   return H8300_SIM_CPU (cpu)->command_line;
    194  1.1  christos }
    195  1.1  christos 
    196  1.1  christos static void
    197  1.7  christos h8_set_command_line (sim_cpu *cpu, char ** val)
    198  1.1  christos {
    199  1.8  christos   H8300_SIM_CPU (cpu)->command_line = val;
    200  1.1  christos }
    201  1.1  christos 
    202  1.1  christos static char *
    203  1.7  christos h8_get_cmdline_arg (sim_cpu *cpu, int index)
    204  1.1  christos {
    205  1.8  christos   return H8300_SIM_CPU (cpu)->command_line[index];
    206  1.1  christos }
    207  1.1  christos 
    208  1.1  christos static void
    209  1.7  christos h8_set_cmdline_arg (sim_cpu *cpu, int index, char * val)
    210  1.1  christos {
    211  1.8  christos   H8300_SIM_CPU (cpu)->command_line[index] = val;
    212  1.1  christos }
    213  1.1  christos 
    214  1.1  christos /* MAC Saturation Mode */
    215  1.1  christos static int
    216  1.7  christos h8_get_macS (sim_cpu *cpu)
    217  1.1  christos {
    218  1.8  christos   return H8300_SIM_CPU (cpu)->macS;
    219  1.1  christos }
    220  1.1  christos 
    221  1.7  christos #if 0
    222  1.1  christos static void
    223  1.7  christos h8_set_macS (sim_cpu *cpu, int val)
    224  1.1  christos {
    225  1.8  christos   H8300_SIM_CPU (cpu)->macS = (val != 0);
    226  1.1  christos }
    227  1.7  christos #endif
    228  1.1  christos 
    229  1.1  christos /* MAC Zero Flag */
    230  1.1  christos static int
    231  1.7  christos h8_get_macZ (sim_cpu *cpu)
    232  1.1  christos {
    233  1.8  christos   return H8300_SIM_CPU (cpu)->macZ;
    234  1.1  christos }
    235  1.1  christos 
    236  1.1  christos static void
    237  1.7  christos h8_set_macZ (sim_cpu *cpu, int val)
    238  1.1  christos {
    239  1.8  christos   H8300_SIM_CPU (cpu)->macZ = (val != 0);
    240  1.1  christos }
    241  1.1  christos 
    242  1.1  christos /* MAC Negative Flag */
    243  1.1  christos static int
    244  1.7  christos h8_get_macN (sim_cpu *cpu)
    245  1.1  christos {
    246  1.8  christos   return H8300_SIM_CPU (cpu)->macN;
    247  1.1  christos }
    248  1.1  christos 
    249  1.1  christos static void
    250  1.7  christos h8_set_macN (sim_cpu *cpu, int val)
    251  1.1  christos {
    252  1.8  christos   H8300_SIM_CPU (cpu)->macN = (val != 0);
    253  1.1  christos }
    254  1.1  christos 
    255  1.1  christos /* MAC Overflow Flag */
    256  1.1  christos static int
    257  1.7  christos h8_get_macV (sim_cpu *cpu)
    258  1.1  christos {
    259  1.8  christos   return H8300_SIM_CPU (cpu)->macV;
    260  1.1  christos }
    261  1.1  christos 
    262  1.1  christos static void
    263  1.7  christos h8_set_macV (sim_cpu *cpu, int val)
    264  1.1  christos {
    265  1.8  christos   H8300_SIM_CPU (cpu)->macV = (val != 0);
    266  1.1  christos }
    267  1.1  christos 
    268  1.1  christos /* End CPU data object.  */
    269  1.1  christos 
    270  1.1  christos /* The rate at which to call the host's poll_quit callback.  */
    271  1.1  christos 
    272  1.1  christos enum { POLL_QUIT_INTERVAL = 0x80000 };
    273  1.1  christos 
    274  1.1  christos #define LOW_BYTE(x) ((x) & 0xff)
    275  1.1  christos #define HIGH_BYTE(x) (((x) >> 8) & 0xff)
    276  1.1  christos #define P(X, Y) ((X << 8) | Y)
    277  1.1  christos 
    278  1.1  christos #define C (c != 0)
    279  1.1  christos #define Z (nz == 0)
    280  1.1  christos #define V (v != 0)
    281  1.1  christos #define N (n != 0)
    282  1.1  christos #define U (u != 0)
    283  1.1  christos #define H (h != 0)
    284  1.1  christos #define UI (ui != 0)
    285  1.1  christos #define I (intMaskBit != 0)
    286  1.1  christos 
    287  1.7  christos #define BUILDSR(cpu)						\
    288  1.7  christos   h8_set_ccr (cpu, (I << 7) | (UI << 6) | (H << 5) | (U << 4)	\
    289  1.1  christos 	     | (N << 3) | (Z << 2) | (V << 1) | C)
    290  1.1  christos 
    291  1.7  christos #define GETSR(cpu) \
    292  1.1  christos   /* Get Status Register (flags).  */		\
    293  1.7  christos   c = (h8_get_ccr (cpu) >> 0) & 1;		\
    294  1.7  christos   v = (h8_get_ccr (cpu) >> 1) & 1;		\
    295  1.7  christos   nz = !((h8_get_ccr (cpu) >> 2) & 1);		\
    296  1.7  christos   n = (h8_get_ccr (cpu) >> 3) & 1;		\
    297  1.7  christos   u = (h8_get_ccr (cpu) >> 4) & 1;		\
    298  1.7  christos   h = (h8_get_ccr (cpu) >> 5) & 1;		\
    299  1.7  christos   ui = ((h8_get_ccr (cpu) >> 6) & 1);		\
    300  1.7  christos   intMaskBit = (h8_get_ccr (cpu) >> 7) & 1
    301  1.1  christos 
    302  1.1  christos 
    303  1.1  christos #ifdef __CHAR_IS_SIGNED__
    304  1.1  christos #define SEXTCHAR(x) ((char) (x))
    305  1.1  christos #endif
    306  1.1  christos 
    307  1.1  christos #ifndef SEXTCHAR
    308  1.1  christos #define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff) : x & 0xff)
    309  1.1  christos #endif
    310  1.1  christos 
    311  1.1  christos #define UEXTCHAR(x) ((x) & 0xff)
    312  1.1  christos #define UEXTSHORT(x) ((x) & 0xffff)
    313  1.1  christos #define SEXTSHORT(x) ((short) (x))
    314  1.1  christos 
    315  1.1  christos int h8300hmode  = 0;
    316  1.1  christos int h8300smode  = 0;
    317  1.1  christos int h8300_normal_mode  = 0;
    318  1.1  christos int h8300sxmode = 0;
    319  1.1  christos 
    320  1.1  christos static int
    321  1.1  christos get_now (void)
    322  1.1  christos {
    323  1.1  christos   return time (0);	/* WinXX HAS UNIX like 'time', so why not use it? */
    324  1.1  christos }
    325  1.1  christos 
    326  1.1  christos static int
    327  1.1  christos now_persec (void)
    328  1.1  christos {
    329  1.1  christos   return 1;
    330  1.1  christos }
    331  1.1  christos 
    332  1.1  christos static int
    333  1.1  christos bitfrom (int x)
    334  1.1  christos {
    335  1.1  christos   switch (x & SIZE)
    336  1.1  christos     {
    337  1.1  christos     case L_8:
    338  1.1  christos       return SB;
    339  1.1  christos     case L_16:
    340  1.1  christos     case L_16U:
    341  1.1  christos       return SW;
    342  1.1  christos     case L_32:
    343  1.1  christos       return SL;
    344  1.1  christos     case L_P:
    345  1.1  christos       return (h8300hmode && !h8300_normal_mode)? SL : SW;
    346  1.1  christos     }
    347  1.1  christos   return 0;
    348  1.1  christos }
    349  1.1  christos 
    350  1.1  christos /* Simulate an indirection / dereference.
    351  1.1  christos    return 0 for success, -1 for failure.
    352  1.1  christos */
    353  1.1  christos 
    354  1.1  christos static unsigned int
    355  1.7  christos lvalue (SIM_DESC sd, sim_cpu *cpu, int x, int rn, unsigned int *val)
    356  1.1  christos {
    357  1.1  christos   if (val == NULL)	/* Paranoia.  */
    358  1.1  christos     return -1;
    359  1.1  christos 
    360  1.1  christos   switch (x / 4)
    361  1.1  christos     {
    362  1.1  christos     case OP_DISP:
    363  1.1  christos       if (rn == ZERO_REGNUM)
    364  1.1  christos 	*val = X (OP_IMM, SP);
    365  1.1  christos       else
    366  1.1  christos 	*val = X (OP_REG, SP);
    367  1.1  christos       break;
    368  1.1  christos     case OP_MEM:
    369  1.1  christos       *val = X (OP_MEM, SP);
    370  1.1  christos       break;
    371  1.1  christos     default:
    372  1.6  christos       sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
    373  1.1  christos       return -1;
    374  1.1  christos     }
    375  1.1  christos   return 0;
    376  1.1  christos }
    377  1.1  christos 
    378  1.1  christos static int
    379  1.7  christos cmdline_location(void)
    380  1.1  christos {
    381  1.1  christos   if (h8300smode && !h8300_normal_mode)
    382  1.1  christos     return 0xffff00L;
    383  1.1  christos   else if (h8300hmode && !h8300_normal_mode)
    384  1.1  christos     return 0x2ff00L;
    385  1.1  christos   else
    386  1.1  christos     return 0xff00L;
    387  1.1  christos }
    388  1.1  christos 
    389  1.1  christos static void
    390  1.7  christos decode (SIM_DESC sd, sim_cpu *cpu, int addr, unsigned char *data, decoded_inst *dst)
    391  1.1  christos {
    392  1.1  christos   int cst[3]   = {0, 0, 0};
    393  1.1  christos   int reg[3]   = {0, 0, 0};
    394  1.1  christos   int rdisp[3] = {0, 0, 0};
    395  1.1  christos   int opnum;
    396  1.8  christos   int index;
    397  1.1  christos   const struct h8_opcode *q;
    398  1.1  christos 
    399  1.1  christos   dst->dst.type = -1;
    400  1.1  christos   dst->src.type = -1;
    401  1.7  christos   dst->op3.type = -1;
    402  1.1  christos 
    403  1.8  christos   /* We speed up instruction decoding by caching an index into
    404  1.8  christos      the main opcode array for the first instruction with the
    405  1.8  christos      given 4 bit nibble.  */
    406  1.8  christos   index = nib_indices[(data[0] & 0xf0) >> 4];
    407  1.8  christos 
    408  1.8  christos   /* Find the exact opcode/arg combo, starting with the precomputed
    409  1.8  christos      index.  Note this loop is performance sensitive.  */
    410  1.8  christos   for (q = &h8_opcodes[index]; q->name; q++)
    411  1.1  christos     {
    412  1.1  christos       const op_type *nib = q->data.nib;
    413  1.1  christos       unsigned int len = 0;
    414  1.1  christos 
    415  1.1  christos       if ((q->available == AV_H8SX && !h8300sxmode) ||
    416  1.1  christos 	  (q->available == AV_H8S  && !h8300smode)  ||
    417  1.1  christos 	  (q->available == AV_H8H  && !h8300hmode))
    418  1.1  christos 	continue;
    419  1.1  christos 
    420  1.1  christos       cst[0]   = cst[1]   = cst[2]   = 0;
    421  1.1  christos       reg[0]   = reg[1]   = reg[2]   = 0;
    422  1.1  christos       rdisp[0] = rdisp[1] = rdisp[2] = 0;
    423  1.1  christos 
    424  1.1  christos       while (1)
    425  1.1  christos 	{
    426  1.1  christos 	  op_type looking_for = *nib;
    427  1.1  christos 	  int thisnib = data[len / 2];
    428  1.1  christos 
    429  1.1  christos 	  thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
    430  1.1  christos 	  opnum = ((looking_for & OP3) ? 2 :
    431  1.1  christos 		   (looking_for & DST) ? 1 : 0);
    432  1.1  christos 
    433  1.1  christos 	  if (looking_for < 16 && looking_for >= 0)
    434  1.1  christos 	    {
    435  1.1  christos 	      if (looking_for != thisnib)
    436  1.1  christos 		goto fail;
    437  1.1  christos 	    }
    438  1.1  christos 	  else
    439  1.1  christos 	    {
    440  1.1  christos 	      if (looking_for & B31)
    441  1.1  christos 		{
    442  1.1  christos 		  if (!((thisnib & 0x8) != 0))
    443  1.1  christos 		    goto fail;
    444  1.1  christos 
    445  1.1  christos 		  looking_for = (op_type) (looking_for & ~B31);
    446  1.1  christos 		  thisnib &= 0x7;
    447  1.1  christos 		}
    448  1.1  christos 	      else if (looking_for & B30)
    449  1.1  christos 		{
    450  1.1  christos 		  if (!((thisnib & 0x8) == 0))
    451  1.1  christos 		    goto fail;
    452  1.1  christos 
    453  1.1  christos 		  looking_for = (op_type) (looking_for & ~B30);
    454  1.1  christos 		}
    455  1.1  christos 
    456  1.1  christos 	      if (looking_for & B21)
    457  1.1  christos 		{
    458  1.1  christos 		  if (!((thisnib & 0x4) != 0))
    459  1.1  christos 		    goto fail;
    460  1.1  christos 
    461  1.1  christos 		  looking_for = (op_type) (looking_for & ~B21);
    462  1.1  christos 		  thisnib &= 0xb;
    463  1.1  christos 		}
    464  1.1  christos 	      else if (looking_for & B20)
    465  1.1  christos 		{
    466  1.1  christos 		  if (!((thisnib & 0x4) == 0))
    467  1.1  christos 		    goto fail;
    468  1.1  christos 
    469  1.1  christos 		  looking_for = (op_type) (looking_for & ~B20);
    470  1.1  christos 		}
    471  1.1  christos 
    472  1.1  christos 	      if (looking_for & B11)
    473  1.1  christos 		{
    474  1.1  christos 		  if (!((thisnib & 0x2) != 0))
    475  1.1  christos 		    goto fail;
    476  1.1  christos 
    477  1.1  christos 		  looking_for = (op_type) (looking_for & ~B11);
    478  1.1  christos 		  thisnib &= 0xd;
    479  1.1  christos 		}
    480  1.1  christos 	      else if (looking_for & B10)
    481  1.1  christos 		{
    482  1.1  christos 		  if (!((thisnib & 0x2) == 0))
    483  1.1  christos 		    goto fail;
    484  1.1  christos 
    485  1.1  christos 		  looking_for = (op_type) (looking_for & ~B10);
    486  1.1  christos 		}
    487  1.1  christos 
    488  1.1  christos 	      if (looking_for & B01)
    489  1.1  christos 		{
    490  1.1  christos 		  if (!((thisnib & 0x1) != 0))
    491  1.1  christos 		    goto fail;
    492  1.1  christos 
    493  1.1  christos 		  looking_for = (op_type) (looking_for & ~B01);
    494  1.1  christos 		  thisnib &= 0xe;
    495  1.1  christos 		}
    496  1.1  christos 	      else if (looking_for & B00)
    497  1.1  christos 		{
    498  1.1  christos 		  if (!((thisnib & 0x1) == 0))
    499  1.1  christos 		    goto fail;
    500  1.1  christos 
    501  1.1  christos 		  looking_for = (op_type) (looking_for & ~B00);
    502  1.1  christos 		}
    503  1.1  christos 
    504  1.1  christos 	      if (looking_for & IGNORE)
    505  1.1  christos 		{
    506  1.1  christos 		  /* Hitachi has declared that IGNORE must be zero.  */
    507  1.1  christos 		  if (thisnib != 0)
    508  1.1  christos 		    goto fail;
    509  1.1  christos 		}
    510  1.1  christos 	      else if ((looking_for & MODE) == DATA)
    511  1.1  christos 		{
    512  1.1  christos 		  ;			/* Skip embedded data.  */
    513  1.1  christos 		}
    514  1.1  christos 	      else if ((looking_for & MODE) == DBIT)
    515  1.1  christos 		{
    516  1.1  christos 		  /* Exclude adds/subs by looking at bit 0 and 2, and
    517  1.1  christos                      make sure the operand size, either w or l,
    518  1.1  christos                      matches by looking at bit 1.  */
    519  1.1  christos 		  if ((looking_for & 7) != (thisnib & 7))
    520  1.1  christos 		    goto fail;
    521  1.1  christos 
    522  1.1  christos 		  cst[opnum] = (thisnib & 0x8) ? 2 : 1;
    523  1.1  christos 		}
    524  1.1  christos 	      else if ((looking_for & MODE) == REG     ||
    525  1.1  christos 		       (looking_for & MODE) == LOWREG  ||
    526  1.1  christos 		       (looking_for & MODE) == IND     ||
    527  1.1  christos 		       (looking_for & MODE) == PREINC  ||
    528  1.1  christos 		       (looking_for & MODE) == POSTINC ||
    529  1.1  christos 		       (looking_for & MODE) == PREDEC  ||
    530  1.1  christos 		       (looking_for & MODE) == POSTDEC)
    531  1.1  christos 		{
    532  1.1  christos 		  reg[opnum] = thisnib;
    533  1.1  christos 		}
    534  1.1  christos 	      else if (looking_for & CTRL)
    535  1.1  christos 		{
    536  1.1  christos 		  thisnib &= 7;
    537  1.1  christos 		  if (((looking_for & MODE) == CCR  && (thisnib != C_CCR))  ||
    538  1.1  christos 		      ((looking_for & MODE) == EXR  && (thisnib != C_EXR))  ||
    539  1.1  christos 		      ((looking_for & MODE) == MACH && (thisnib != C_MACH)) ||
    540  1.1  christos 		      ((looking_for & MODE) == MACL && (thisnib != C_MACL)) ||
    541  1.1  christos 		      ((looking_for & MODE) == VBR  && (thisnib != C_VBR))  ||
    542  1.1  christos 		      ((looking_for & MODE) == SBR  && (thisnib != C_SBR)))
    543  1.1  christos 		    goto fail;
    544  1.1  christos 		  if (((looking_for & MODE) == CCR_EXR &&
    545  1.1  christos 		       (thisnib != C_CCR && thisnib != C_EXR)) ||
    546  1.1  christos 		      ((looking_for & MODE) == VBR_SBR &&
    547  1.1  christos 		       (thisnib != C_VBR && thisnib != C_SBR)) ||
    548  1.1  christos 		      ((looking_for & MODE) == MACREG &&
    549  1.1  christos 		       (thisnib != C_MACH && thisnib != C_MACL)))
    550  1.1  christos 		    goto fail;
    551  1.1  christos 		  if (((looking_for & MODE) == CC_EX_VB_SB &&
    552  1.1  christos 		       (thisnib != C_CCR && thisnib != C_EXR &&
    553  1.1  christos 			thisnib != C_VBR && thisnib != C_SBR)))
    554  1.1  christos 		    goto fail;
    555  1.1  christos 
    556  1.1  christos 		  reg[opnum] = thisnib;
    557  1.1  christos 		}
    558  1.1  christos 	      else if ((looking_for & MODE) == ABS)
    559  1.1  christos 		{
    560  1.1  christos 		  /* Absolute addresses are unsigned.  */
    561  1.1  christos 		  switch (looking_for & SIZE)
    562  1.1  christos 		    {
    563  1.1  christos 		    case L_8:
    564  1.1  christos 		      cst[opnum] = UEXTCHAR (data[len / 2]);
    565  1.1  christos 		      break;
    566  1.1  christos 		    case L_16:
    567  1.1  christos 		    case L_16U:
    568  1.1  christos 		      cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
    569  1.1  christos 		      break;
    570  1.1  christos 		    case L_32:
    571  1.1  christos 		      cst[opnum] =
    572  1.1  christos 			(data[len / 2 + 0] << 24) +
    573  1.1  christos 			(data[len / 2 + 1] << 16) +
    574  1.1  christos 			(data[len / 2 + 2] <<  8) +
    575  1.1  christos 			(data[len / 2 + 3]);
    576  1.1  christos 		      break;
    577  1.1  christos 		    default:
    578  1.1  christos 		      printf ("decode: bad size ABS: %d\n",
    579  1.1  christos 			      (looking_for & SIZE));
    580  1.1  christos 		      goto end;
    581  1.1  christos 		    }
    582  1.1  christos 		}
    583  1.1  christos 	      else if ((looking_for & MODE) == DISP   ||
    584  1.1  christos 		       (looking_for & MODE) == PCREL  ||
    585  1.1  christos 		       (looking_for & MODE) == INDEXB ||
    586  1.1  christos 		       (looking_for & MODE) == INDEXW ||
    587  1.1  christos 		       (looking_for & MODE) == INDEXL)
    588  1.1  christos 		{
    589  1.1  christos 		  switch (looking_for & SIZE)
    590  1.1  christos 		    {
    591  1.1  christos 		    case L_2:
    592  1.1  christos 		      cst[opnum] = thisnib & 3;
    593  1.1  christos 		      break;
    594  1.1  christos 		    case L_8:
    595  1.1  christos 		      cst[opnum] = SEXTCHAR (data[len / 2]);
    596  1.1  christos 		      break;
    597  1.1  christos 		    case L_16:
    598  1.1  christos 		      cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
    599  1.1  christos 		      cst[opnum] = (short) cst[opnum];	/* Sign extend.  */
    600  1.1  christos 		      break;
    601  1.1  christos 		    case L_16U:
    602  1.1  christos 		      cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
    603  1.1  christos 		      break;
    604  1.1  christos 		    case L_32:
    605  1.1  christos 		      cst[opnum] =
    606  1.1  christos 			(data[len / 2 + 0] << 24) +
    607  1.1  christos 			(data[len / 2 + 1] << 16) +
    608  1.1  christos 			(data[len / 2 + 2] <<  8) +
    609  1.1  christos 			(data[len / 2 + 3]);
    610  1.1  christos 		      break;
    611  1.1  christos 		    default:
    612  1.1  christos 		      printf ("decode: bad size DISP/PCREL/INDEX: %d\n",
    613  1.1  christos 			      (looking_for & SIZE));
    614  1.1  christos 		      goto end;
    615  1.1  christos 		    }
    616  1.1  christos 		}
    617  1.1  christos 	      else if ((looking_for & SIZE) == L_16 ||
    618  1.1  christos 		       (looking_for & SIZE) == L_16U)
    619  1.1  christos 		{
    620  1.1  christos 		  cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
    621  1.1  christos 		  /* Immediates are always unsigned.  */
    622  1.1  christos 		  if ((looking_for & SIZE) != L_16U &&
    623  1.1  christos 		      (looking_for & MODE) != IMM)
    624  1.1  christos 		    cst[opnum] = (short) cst[opnum];	/* Sign extend.  */
    625  1.1  christos 		}
    626  1.1  christos 	      else if (looking_for & ABSJMP)
    627  1.1  christos 		{
    628  1.1  christos 		  switch (looking_for & SIZE) {
    629  1.1  christos 		  case L_24:
    630  1.1  christos 		    cst[opnum] = (data[1] << 16) | (data[2] << 8) | (data[3]);
    631  1.1  christos 		    break;
    632  1.1  christos 		  case L_32:
    633  1.1  christos 		    cst[opnum] =
    634  1.1  christos 		      (data[len / 2 + 0] << 24) +
    635  1.1  christos 		      (data[len / 2 + 1] << 16) +
    636  1.1  christos 		      (data[len / 2 + 2] <<  8) +
    637  1.1  christos 		      (data[len / 2 + 3]);
    638  1.1  christos 		    break;
    639  1.1  christos 		  default:
    640  1.1  christos 		    printf ("decode: bad size ABSJMP: %d\n",
    641  1.1  christos 			    (looking_for & SIZE));
    642  1.1  christos 		      goto end;
    643  1.1  christos 		  }
    644  1.1  christos 		}
    645  1.1  christos 	      else if ((looking_for & MODE) == MEMIND)
    646  1.1  christos 		{
    647  1.1  christos 		  cst[opnum] = data[1];
    648  1.1  christos 		}
    649  1.1  christos 	      else if ((looking_for & MODE) == VECIND)
    650  1.1  christos 		{
    651  1.1  christos 		  if(h8300_normal_mode)
    652  1.1  christos 		    cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2;
    653  1.1  christos 		  else
    654  1.1  christos 		    cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4;
    655  1.7  christos 		  cst[opnum] += h8_get_vbr (cpu); /* Add vector base reg.  */
    656  1.1  christos 		}
    657  1.1  christos 	      else if ((looking_for & SIZE) == L_32)
    658  1.1  christos 		{
    659  1.1  christos 		  int i = len / 2;
    660  1.1  christos 
    661  1.1  christos 		  cst[opnum] =
    662  1.1  christos 		    (data[i + 0] << 24) |
    663  1.1  christos 		    (data[i + 1] << 16) |
    664  1.1  christos 		    (data[i + 2] <<  8) |
    665  1.1  christos 		    (data[i + 3]);
    666  1.1  christos 		}
    667  1.1  christos 	      else if ((looking_for & SIZE) == L_24)
    668  1.1  christos 		{
    669  1.1  christos 		  int i = len / 2;
    670  1.1  christos 
    671  1.1  christos 		  cst[opnum] =
    672  1.1  christos 		    (data[i + 0] << 16) |
    673  1.1  christos 		    (data[i + 1] << 8) |
    674  1.1  christos 		    (data[i + 2]);
    675  1.1  christos 		}
    676  1.1  christos 	      else if (looking_for & DISPREG)
    677  1.1  christos 		{
    678  1.1  christos 		  rdisp[opnum] = thisnib & 0x7;
    679  1.1  christos 		}
    680  1.1  christos 	      else if ((looking_for & MODE) == KBIT)
    681  1.1  christos 		{
    682  1.1  christos 		  switch (thisnib)
    683  1.1  christos 		    {
    684  1.1  christos 		    case 9:
    685  1.1  christos 		      cst[opnum] = 4;
    686  1.1  christos 		      break;
    687  1.1  christos 		    case 8:
    688  1.1  christos 		      cst[opnum] = 2;
    689  1.1  christos 		      break;
    690  1.1  christos 		    case 0:
    691  1.1  christos 		      cst[opnum] = 1;
    692  1.1  christos 		      break;
    693  1.1  christos 		    default:
    694  1.1  christos 		      goto fail;
    695  1.1  christos 		    }
    696  1.1  christos 		}
    697  1.1  christos 	      else if ((looking_for & SIZE) == L_8)
    698  1.1  christos 		{
    699  1.1  christos 		  if ((looking_for & MODE) == ABS)
    700  1.1  christos 		    {
    701  1.1  christos 		      /* Will be combined with contents of SBR_REGNUM
    702  1.1  christos 			 by fetch ().  For all modes except h8sx, this
    703  1.1  christos 			 will always contain the value 0xFFFFFF00.  */
    704  1.1  christos 		      cst[opnum] = data[len / 2] & 0xff;
    705  1.1  christos 		    }
    706  1.1  christos 		  else
    707  1.1  christos 		    {
    708  1.1  christos 		      cst[opnum] = data[len / 2] & 0xff;
    709  1.1  christos 		    }
    710  1.1  christos 		}
    711  1.1  christos 	      else if ((looking_for & SIZE) == L_2)
    712  1.1  christos 		{
    713  1.1  christos 		  cst[opnum] = thisnib & 3;
    714  1.1  christos 		}
    715  1.1  christos 	      else if ((looking_for & SIZE) == L_3 ||
    716  1.1  christos 		       (looking_for & SIZE) == L_3NZ)
    717  1.1  christos 		{
    718  1.1  christos 		  cst[opnum] = thisnib & 7;
    719  1.1  christos 		  if (cst[opnum] == 0 && (looking_for & SIZE) == L_3NZ)
    720  1.1  christos 		    goto fail;
    721  1.1  christos 		}
    722  1.1  christos 	      else if ((looking_for & SIZE) == L_4)
    723  1.1  christos 		{
    724  1.1  christos 		  cst[opnum] = thisnib & 15;
    725  1.1  christos 		}
    726  1.1  christos 	      else if ((looking_for & SIZE) == L_5)
    727  1.1  christos 		{
    728  1.1  christos 		  cst[opnum] = data[len / 2] & 0x1f;
    729  1.1  christos 		}
    730  1.1  christos 	      else if (looking_for == E)
    731  1.1  christos 		{
    732  1.1  christos #ifdef ADEBUG
    733  1.1  christos 		  dst->op = q;
    734  1.1  christos #endif
    735  1.1  christos 		  /* Fill in the args.  */
    736  1.1  christos 		  {
    737  1.1  christos 		    const op_type *args = q->args.nib;
    738  1.1  christos 		    int nargs;
    739  1.1  christos 
    740  1.1  christos 		    for (nargs = 0;
    741  1.1  christos 			 nargs < 3 && *args != E;
    742  1.1  christos 			 nargs++)
    743  1.1  christos 		      {
    744  1.1  christos 			int x = *args;
    745  1.1  christos 			ea_type *p;
    746  1.1  christos 
    747  1.1  christos 			opnum = ((x & OP3) ? 2 :
    748  1.1  christos 				 (x & DST) ? 1 : 0);
    749  1.1  christos 			if (x & DST)
    750  1.1  christos 			  p = &dst->dst;
    751  1.1  christos 			else if (x & OP3)
    752  1.1  christos 			  p = &dst->op3;
    753  1.1  christos 			else
    754  1.1  christos 			  p = &dst->src;
    755  1.1  christos 
    756  1.1  christos 			if ((x & MODE) == IMM  ||
    757  1.1  christos 			    (x & MODE) == KBIT ||
    758  1.1  christos 			    (x & MODE) == DBIT)
    759  1.1  christos 			  {
    760  1.1  christos 			    /* Use the instruction to determine
    761  1.1  christos 			       the operand size.  */
    762  1.1  christos 			    p->type = X (OP_IMM, OP_SIZE (q->how));
    763  1.1  christos 			    p->literal = cst[opnum];
    764  1.1  christos 			  }
    765  1.1  christos 			else if ((x & MODE) == CONST_2 ||
    766  1.1  christos 				 (x & MODE) == CONST_4 ||
    767  1.1  christos 				 (x & MODE) == CONST_8 ||
    768  1.1  christos 				 (x & MODE) == CONST_16)
    769  1.1  christos 			  {
    770  1.1  christos 			    /* Use the instruction to determine
    771  1.1  christos 			       the operand size.  */
    772  1.1  christos 			    p->type = X (OP_IMM, OP_SIZE (q->how));
    773  1.1  christos 			    switch (x & MODE) {
    774  1.1  christos 			    case CONST_2:	p->literal =  2; break;
    775  1.1  christos 			    case CONST_4:	p->literal =  4; break;
    776  1.1  christos 			    case CONST_8:	p->literal =  8; break;
    777  1.1  christos 			    case CONST_16:	p->literal = 16; break;
    778  1.1  christos 			    }
    779  1.1  christos 			  }
    780  1.1  christos 			else if ((x & MODE) == REG)
    781  1.1  christos 			  {
    782  1.1  christos 			    p->type = X (OP_REG, bitfrom (x));
    783  1.1  christos 			    p->reg = reg[opnum];
    784  1.1  christos 			  }
    785  1.1  christos 			else if ((x & MODE) == LOWREG)
    786  1.1  christos 			  {
    787  1.1  christos 			    p->type = X (OP_LOWREG, bitfrom (x));
    788  1.1  christos 			    p->reg = reg[opnum];
    789  1.1  christos 			  }
    790  1.1  christos 			else if ((x & MODE) == PREINC)
    791  1.1  christos 			  {
    792  1.1  christos 			    /* Use the instruction to determine
    793  1.1  christos 			       the operand size.  */
    794  1.1  christos 			    p->type = X (OP_PREINC, OP_SIZE (q->how));
    795  1.1  christos 			    p->reg = reg[opnum] & 0x7;
    796  1.1  christos 			  }
    797  1.1  christos 			else if ((x & MODE) == POSTINC)
    798  1.1  christos 			  {
    799  1.1  christos 			    /* Use the instruction to determine
    800  1.1  christos 			       the operand size.  */
    801  1.1  christos 			    p->type = X (OP_POSTINC, OP_SIZE (q->how));
    802  1.1  christos 			    p->reg = reg[opnum] & 0x7;
    803  1.1  christos 			  }
    804  1.1  christos 			else if ((x & MODE) == PREDEC)
    805  1.1  christos 			  {
    806  1.1  christos 			    /* Use the instruction to determine
    807  1.1  christos 			       the operand size.  */
    808  1.1  christos 			    p->type = X (OP_PREDEC, OP_SIZE (q->how));
    809  1.1  christos 			    p->reg = reg[opnum] & 0x7;
    810  1.1  christos 			  }
    811  1.1  christos 			else if ((x & MODE) == POSTDEC)
    812  1.1  christos 			  {
    813  1.1  christos 			    /* Use the instruction to determine
    814  1.1  christos 			       the operand size.  */
    815  1.1  christos 			    p->type = X (OP_POSTDEC, OP_SIZE (q->how));
    816  1.1  christos 			    p->reg = reg[opnum] & 0x7;
    817  1.1  christos 			  }
    818  1.1  christos 			else if ((x & MODE) == IND)
    819  1.1  christos 			  {
    820  1.1  christos 			    /* Note: an indirect is transformed into
    821  1.1  christos 			       a displacement of zero.
    822  1.1  christos 			    */
    823  1.1  christos 			    /* Use the instruction to determine
    824  1.1  christos 			       the operand size.  */
    825  1.1  christos 			    p->type = X (OP_DISP, OP_SIZE (q->how));
    826  1.1  christos 			    p->reg = reg[opnum] & 0x7;
    827  1.1  christos 			    p->literal = 0;
    828  1.1  christos 			    if (OP_KIND (q->how) == O_JSR ||
    829  1.1  christos 				OP_KIND (q->how) == O_JMP)
    830  1.7  christos 			      if (lvalue (sd, cpu, p->type, p->reg, (unsigned int *)&p->type))
    831  1.1  christos 				goto end;
    832  1.1  christos 			  }
    833  1.1  christos 			else if ((x & MODE) == ABS)
    834  1.1  christos 			  {
    835  1.1  christos 			    /* Note: a 16 or 32 bit ABS is transformed into a
    836  1.1  christos 			       displacement from pseudo-register ZERO_REGNUM,
    837  1.1  christos 			       which is always zero.  An 8 bit ABS becomes
    838  1.1  christos 			       a displacement from SBR_REGNUM.
    839  1.1  christos 			    */
    840  1.1  christos 			    /* Use the instruction to determine
    841  1.1  christos 			       the operand size.  */
    842  1.1  christos 			    p->type = X (OP_DISP, OP_SIZE (q->how));
    843  1.1  christos 			    p->literal = cst[opnum];
    844  1.1  christos 
    845  1.1  christos 			    /* 8-bit ABS is displacement from SBR.
    846  1.1  christos 			       16 and 32-bit ABS are displacement from ZERO.
    847  1.1  christos 			       (SBR will always be zero except for h8/sx)
    848  1.1  christos 			    */
    849  1.1  christos 			    if ((x & SIZE) == L_8)
    850  1.1  christos 			      p->reg = SBR_REGNUM;
    851  1.1  christos 			    else
    852  1.1  christos 			      p->reg = ZERO_REGNUM;;
    853  1.1  christos 			  }
    854  1.1  christos 			else if ((x & MODE) == MEMIND ||
    855  1.1  christos 				 (x & MODE) == VECIND)
    856  1.1  christos 			  {
    857  1.1  christos 			    /* Size doesn't matter.  */
    858  1.1  christos 			    p->type = X (OP_MEM, SB);
    859  1.1  christos 			    p->literal = cst[opnum];
    860  1.1  christos 			    if (OP_KIND (q->how) == O_JSR ||
    861  1.1  christos 				OP_KIND (q->how) == O_JMP)
    862  1.7  christos 			      if (lvalue (sd, cpu, p->type, p->reg, (unsigned int *)&p->type))
    863  1.1  christos 				goto end;
    864  1.1  christos 			  }
    865  1.1  christos 			else if ((x & MODE) == PCREL)
    866  1.1  christos 			  {
    867  1.1  christos 			    /* Size doesn't matter.  */
    868  1.1  christos 			    p->type = X (OP_PCREL, SB);
    869  1.1  christos 			    p->literal = cst[opnum];
    870  1.1  christos 			  }
    871  1.1  christos 			else if (x & ABSJMP)
    872  1.1  christos 			  {
    873  1.1  christos 			    p->type = X (OP_IMM, SP);
    874  1.1  christos 			    p->literal = cst[opnum];
    875  1.1  christos 			  }
    876  1.1  christos 			else if ((x & MODE) == INDEXB)
    877  1.1  christos 			  {
    878  1.1  christos 			    p->type = X (OP_INDEXB, OP_SIZE (q->how));
    879  1.1  christos 			    p->literal = cst[opnum];
    880  1.1  christos 			    p->reg     = rdisp[opnum];
    881  1.1  christos 			  }
    882  1.1  christos 			else if ((x & MODE) == INDEXW)
    883  1.1  christos 			  {
    884  1.1  christos 			    p->type = X (OP_INDEXW, OP_SIZE (q->how));
    885  1.1  christos 			    p->literal = cst[opnum];
    886  1.1  christos 			    p->reg     = rdisp[opnum];
    887  1.1  christos 			  }
    888  1.1  christos 			else if ((x & MODE) == INDEXL)
    889  1.1  christos 			  {
    890  1.1  christos 			    p->type = X (OP_INDEXL, OP_SIZE (q->how));
    891  1.1  christos 			    p->literal = cst[opnum];
    892  1.1  christos 			    p->reg     = rdisp[opnum];
    893  1.1  christos 			  }
    894  1.1  christos 			else if ((x & MODE) == DISP)
    895  1.1  christos 			  {
    896  1.1  christos 			    /* Yuck -- special for mova args.  */
    897  1.1  christos 			    if (strncmp (q->name, "mova", 4) == 0 &&
    898  1.1  christos 				(x & SIZE) == L_2)
    899  1.1  christos 			      {
    900  1.1  christos 				/* Mova can have a DISP2 dest, with an
    901  1.1  christos 				   INDEXB or INDEXW src.  The multiplier
    902  1.1  christos 				   for the displacement value is determined
    903  1.1  christos 				   by the src operand, not by the insn.  */
    904  1.1  christos 
    905  1.1  christos 				switch (OP_KIND (dst->src.type))
    906  1.1  christos 				  {
    907  1.1  christos 				  case OP_INDEXB:
    908  1.1  christos 				    p->type = X (OP_DISP, SB);
    909  1.1  christos 				    p->literal = cst[opnum];
    910  1.1  christos 				    break;
    911  1.1  christos 				  case OP_INDEXW:
    912  1.1  christos 				    p->type = X (OP_DISP, SW);
    913  1.1  christos 				    p->literal = cst[opnum] * 2;
    914  1.1  christos 				    break;
    915  1.1  christos 				  default:
    916  1.1  christos 				    goto fail;
    917  1.1  christos 				  }
    918  1.1  christos 			      }
    919  1.1  christos 			    else
    920  1.1  christos 			      {
    921  1.1  christos 				p->type = X (OP_DISP,   OP_SIZE (q->how));
    922  1.1  christos 				p->literal = cst[opnum];
    923  1.1  christos 				/* DISP2 is special.  */
    924  1.1  christos 				if ((x & SIZE) == L_2)
    925  1.1  christos 				  switch (OP_SIZE (q->how))
    926  1.1  christos 				    {
    927  1.1  christos 				    case SB:                  break;
    928  1.1  christos 				    case SW: p->literal *= 2; break;
    929  1.1  christos 				    case SL: p->literal *= 4; break;
    930  1.1  christos 				    }
    931  1.1  christos 			      }
    932  1.1  christos 			    p->reg     = rdisp[opnum];
    933  1.1  christos 			  }
    934  1.1  christos 			else if (x & CTRL)
    935  1.1  christos 			  {
    936  1.1  christos 			    switch (reg[opnum])
    937  1.1  christos 			      {
    938  1.1  christos 			      case C_CCR:
    939  1.1  christos 				p->type = X (OP_CCR, SB);
    940  1.1  christos 				break;
    941  1.1  christos 			      case C_EXR:
    942  1.1  christos 				p->type = X (OP_EXR, SB);
    943  1.1  christos 				break;
    944  1.1  christos 			      case C_MACH:
    945  1.1  christos 				p->type = X (OP_MACH, SL);
    946  1.1  christos 				break;
    947  1.1  christos 			      case C_MACL:
    948  1.1  christos 				p->type = X (OP_MACL, SL);
    949  1.1  christos 				break;
    950  1.1  christos 			      case C_VBR:
    951  1.1  christos 				p->type = X (OP_VBR, SL);
    952  1.1  christos 				break;
    953  1.1  christos 			      case C_SBR:
    954  1.1  christos 				p->type = X (OP_SBR, SL);
    955  1.1  christos 				break;
    956  1.1  christos 			      }
    957  1.1  christos 			  }
    958  1.1  christos 			else if ((x & MODE) == CCR)
    959  1.1  christos 			  {
    960  1.1  christos 			    p->type = OP_CCR;
    961  1.1  christos 			  }
    962  1.1  christos 			else if ((x & MODE) == EXR)
    963  1.1  christos 			  {
    964  1.1  christos 			    p->type = OP_EXR;
    965  1.1  christos 			  }
    966  1.1  christos 			else
    967  1.1  christos 			  printf ("Hmmmm 0x%x...\n", x);
    968  1.1  christos 
    969  1.1  christos 			args++;
    970  1.1  christos 		      }
    971  1.1  christos 		  }
    972  1.1  christos 
    973  1.1  christos 		  /* Unary operators: treat src and dst as equivalent.  */
    974  1.1  christos 		  if (dst->dst.type == -1)
    975  1.1  christos 		    dst->dst = dst->src;
    976  1.1  christos 		  if (dst->src.type == -1)
    977  1.1  christos 		    dst->src = dst->dst;
    978  1.1  christos 
    979  1.1  christos 		  dst->opcode = q->how;
    980  1.1  christos 		  dst->cycles = q->time;
    981  1.1  christos 
    982  1.1  christos 		  /* And jsr's to these locations are turned into
    983  1.1  christos 		     magic traps.  */
    984  1.1  christos 
    985  1.1  christos 		  if (OP_KIND (dst->opcode) == O_JSR)
    986  1.1  christos 		    {
    987  1.1  christos 		      switch (dst->src.literal)
    988  1.1  christos 			{
    989  1.1  christos 			case 0xc5:
    990  1.1  christos 			  dst->opcode = O (O_SYS_OPEN, SB);
    991  1.1  christos 			  break;
    992  1.1  christos 			case 0xc6:
    993  1.1  christos 			  dst->opcode = O (O_SYS_READ, SB);
    994  1.1  christos 			  break;
    995  1.1  christos 			case 0xc7:
    996  1.1  christos 			  dst->opcode = O (O_SYS_WRITE, SB);
    997  1.1  christos 			  break;
    998  1.1  christos 			case 0xc8:
    999  1.1  christos 			  dst->opcode = O (O_SYS_LSEEK, SB);
   1000  1.1  christos 			  break;
   1001  1.1  christos 			case 0xc9:
   1002  1.1  christos 			  dst->opcode = O (O_SYS_CLOSE, SB);
   1003  1.1  christos 			  break;
   1004  1.1  christos 			case 0xca:
   1005  1.1  christos 			  dst->opcode = O (O_SYS_STAT, SB);
   1006  1.1  christos 			  break;
   1007  1.1  christos 			case 0xcb:
   1008  1.1  christos 			  dst->opcode = O (O_SYS_FSTAT, SB);
   1009  1.1  christos 			  break;
   1010  1.1  christos 			case 0xcc:
   1011  1.1  christos 			  dst->opcode = O (O_SYS_CMDLINE, SB);
   1012  1.1  christos 			  break;
   1013  1.1  christos 			}
   1014  1.1  christos 		      /* End of Processing for system calls.  */
   1015  1.1  christos 		    }
   1016  1.1  christos 
   1017  1.7  christos 		  /* Use same register is specified for source
   1018  1.7  christos 		     and destination.
   1019  1.7  christos 		     The value of source will be the value after
   1020  1.7  christos 		     address calculation.  */
   1021  1.7  christos 		  if (OP_KIND (dst->opcode) != O_CMP &&
   1022  1.7  christos 		      OP_KIND (dst->src.type) == OP_REG &&
   1023  1.7  christos 		      (dst->src.reg & 7) == dst->dst.reg) {
   1024  1.7  christos 		    switch (OP_KIND (dst->dst.type))
   1025  1.7  christos 		      {
   1026  1.7  christos 		      case OP_POSTDEC:
   1027  1.7  christos 			dst->src.type = X (OP_REG_DEC,
   1028  1.7  christos 					   OP_SIZE (dst->dst.type));
   1029  1.7  christos 			break;
   1030  1.7  christos 		      case OP_POSTINC:
   1031  1.7  christos 			dst->src.type = X (OP_REG_INC,
   1032  1.7  christos 					   OP_SIZE (dst->dst.type));
   1033  1.7  christos 			break;
   1034  1.7  christos 		      case OP_PREINC:
   1035  1.7  christos 			if (OP_KIND (dst->opcode) == O_MOV)
   1036  1.7  christos 			  dst->src.type = X (OP_REG_INC,
   1037  1.7  christos 					     OP_SIZE (dst->dst.type));
   1038  1.7  christos 			break;
   1039  1.7  christos 		      case OP_PREDEC:
   1040  1.7  christos 			if (OP_KIND (dst->opcode) == O_MOV)
   1041  1.7  christos 			  dst->src.type = X (OP_REG_DEC,
   1042  1.7  christos 					     OP_SIZE (dst->dst.type));
   1043  1.7  christos 			break;
   1044  1.7  christos 		      }
   1045  1.7  christos 		  }
   1046  1.1  christos 		  dst->next_pc = addr + len / 2;
   1047  1.1  christos 		  return;
   1048  1.1  christos 		}
   1049  1.1  christos 	      else
   1050  1.1  christos 		printf ("Don't understand 0x%x \n", looking_for);
   1051  1.1  christos 	    }
   1052  1.1  christos 
   1053  1.1  christos 	  len++;
   1054  1.1  christos 	  nib++;
   1055  1.1  christos 	}
   1056  1.1  christos 
   1057  1.1  christos     fail:
   1058  1.1  christos       ;
   1059  1.1  christos     }
   1060  1.1  christos  end:
   1061  1.1  christos   /* Fell off the end.  */
   1062  1.1  christos   dst->opcode = O (O_ILL, SB);
   1063  1.1  christos }
   1064  1.1  christos 
   1065  1.1  christos static unsigned char  *breg[32];
   1066  1.1  christos static unsigned short *wreg[16];
   1067  1.1  christos 
   1068  1.1  christos #define GET_B_REG(X)     *(breg[X])
   1069  1.1  christos #define SET_B_REG(X, Y) (*(breg[X])) = (Y)
   1070  1.1  christos #define GET_W_REG(X)     *(wreg[X])
   1071  1.1  christos #define SET_W_REG(X, Y) (*(wreg[X])) = (Y)
   1072  1.7  christos #define GET_L_REG(X)     h8_get_reg (cpu, X)
   1073  1.7  christos #define SET_L_REG(X, Y)  h8_set_reg (cpu, X, Y)
   1074  1.1  christos 
   1075  1.1  christos #define GET_MEMORY_L(X) \
   1076  1.1  christos   ((X) < memory_size \
   1077  1.7  christos    ? ((h8_get_memory (cpu, (X)+0) << 24) | (h8_get_memory (cpu, (X)+1) << 16)  \
   1078  1.7  christos     | (h8_get_memory (cpu, (X)+2) <<  8) | (h8_get_memory (cpu, (X)+3) <<  0)) \
   1079  1.7  christos    : 0)
   1080  1.1  christos 
   1081  1.1  christos #define GET_MEMORY_W(X) \
   1082  1.1  christos   ((X) < memory_size \
   1083  1.7  christos    ? ((h8_get_memory (cpu, (X)+0) << 8) | (h8_get_memory (cpu, (X)+1) << 0)) \
   1084  1.7  christos    : 0)
   1085  1.1  christos 
   1086  1.1  christos #define GET_MEMORY_B(X) \
   1087  1.7  christos   ((X) < memory_size ? h8_get_memory (cpu, (X)) : 0)
   1088  1.1  christos 
   1089  1.1  christos #define SET_MEMORY_L(X, Y)  \
   1090  1.1  christos {  register unsigned char *_p; register int __y = (Y); \
   1091  1.7  christos    _p = ((X) < memory_size ? h8_get_memory_buf (cpu) + (X) : 0); \
   1092  1.1  christos    _p[0] = __y >> 24; _p[1] = __y >> 16; \
   1093  1.1  christos    _p[2] = __y >>  8; _p[3] = __y >>  0; \
   1094  1.1  christos }
   1095  1.1  christos 
   1096  1.1  christos #define SET_MEMORY_W(X, Y) \
   1097  1.1  christos {  register unsigned char *_p; register int __y = (Y); \
   1098  1.7  christos    _p = ((X) < memory_size ? h8_get_memory_buf (cpu) + (X) : 0); \
   1099  1.1  christos    _p[0] = __y >> 8; _p[1] = __y; \
   1100  1.1  christos }
   1101  1.1  christos 
   1102  1.1  christos #define SET_MEMORY_B(X, Y) \
   1103  1.7  christos   ((X) < memory_size ? h8_set_memory (cpu, (X), (Y)) : 0)
   1104  1.1  christos 
   1105  1.1  christos /* Simulate a memory fetch.
   1106  1.1  christos    Return 0 for success, -1 for failure.
   1107  1.1  christos */
   1108  1.1  christos 
   1109  1.1  christos static int
   1110  1.1  christos fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
   1111  1.1  christos {
   1112  1.6  christos   SIM_CPU *cpu = STATE_CPU (sd, 0);
   1113  1.1  christos   int rn = arg->reg;
   1114  1.1  christos   int abs = arg->literal;
   1115  1.1  christos   int r;
   1116  1.1  christos   int t;
   1117  1.1  christos 
   1118  1.1  christos   if (val == NULL)
   1119  1.1  christos     return -1;		/* Paranoia.  */
   1120  1.1  christos 
   1121  1.1  christos   switch (arg->type)
   1122  1.1  christos     {
   1123  1.1  christos       /* Indexed register plus displacement mode:
   1124  1.1  christos 
   1125  1.1  christos 	 This new family of addressing modes are similar to OP_DISP
   1126  1.1  christos 	 (register plus displacement), with two differences:
   1127  1.1  christos 	   1) INDEXB uses only the least significant byte of the register,
   1128  1.1  christos 	      INDEXW uses only the least significant word, and
   1129  1.1  christos 	      INDEXL uses the entire register (just like OP_DISP).
   1130  1.1  christos 	 and
   1131  1.1  christos 	   2) The displacement value in abs is multiplied by two
   1132  1.1  christos 	      for SW-sized operations, and by four for SL-size.
   1133  1.1  christos 
   1134  1.1  christos 	This gives nine possible variations.
   1135  1.1  christos       */
   1136  1.1  christos 
   1137  1.1  christos     case X (OP_INDEXB, SB):
   1138  1.1  christos     case X (OP_INDEXB, SW):
   1139  1.1  christos     case X (OP_INDEXB, SL):
   1140  1.1  christos     case X (OP_INDEXW, SB):
   1141  1.1  christos     case X (OP_INDEXW, SW):
   1142  1.1  christos     case X (OP_INDEXW, SL):
   1143  1.1  christos     case X (OP_INDEXL, SB):
   1144  1.1  christos     case X (OP_INDEXL, SW):
   1145  1.1  christos     case X (OP_INDEXL, SL):
   1146  1.1  christos       t = GET_L_REG (rn);
   1147  1.1  christos       switch (OP_KIND (arg->type)) {
   1148  1.1  christos       case OP_INDEXB:	t &= 0xff;	break;
   1149  1.1  christos       case OP_INDEXW:	t &= 0xffff;	break;
   1150  1.1  christos       case OP_INDEXL:
   1151  1.1  christos       default:		break;
   1152  1.1  christos       }
   1153  1.1  christos       switch (OP_SIZE (arg->type)) {
   1154  1.1  christos       case SB:
   1155  1.7  christos 	*val = GET_MEMORY_B ((t * 1 + abs) & h8_get_mask (cpu));
   1156  1.1  christos 	break;
   1157  1.1  christos       case SW:
   1158  1.7  christos 	*val = GET_MEMORY_W ((t * 2 + abs) & h8_get_mask (cpu));
   1159  1.1  christos 	break;
   1160  1.1  christos       case SL:
   1161  1.7  christos 	*val = GET_MEMORY_L ((t * 4 + abs) & h8_get_mask (cpu));
   1162  1.1  christos 	break;
   1163  1.1  christos       }
   1164  1.1  christos       break;
   1165  1.1  christos 
   1166  1.1  christos     case X (OP_LOWREG, SB):
   1167  1.1  christos       *val = GET_L_REG (rn) & 0xff;
   1168  1.1  christos       break;
   1169  1.1  christos     case X (OP_LOWREG, SW):
   1170  1.1  christos       *val = GET_L_REG (rn) & 0xffff;
   1171  1.1  christos       break;
   1172  1.1  christos 
   1173  1.1  christos     case X (OP_REG, SB):	/* Register direct, byte.  */
   1174  1.1  christos       *val = GET_B_REG (rn);
   1175  1.1  christos       break;
   1176  1.1  christos     case X (OP_REG, SW):	/* Register direct, word.  */
   1177  1.1  christos       *val = GET_W_REG (rn);
   1178  1.1  christos       break;
   1179  1.1  christos     case X (OP_REG, SL):	/* Register direct, long.  */
   1180  1.1  christos       *val = GET_L_REG (rn);
   1181  1.1  christos       break;
   1182  1.1  christos     case X (OP_IMM, SB):	/* Immediate, byte.  */
   1183  1.1  christos     case X (OP_IMM, SW):	/* Immediate, word.  */
   1184  1.1  christos     case X (OP_IMM, SL):	/* Immediate, long.  */
   1185  1.1  christos       *val = abs;
   1186  1.1  christos       break;
   1187  1.1  christos     case X (OP_POSTINC, SB):	/* Register indirect w/post-incr: byte.  */
   1188  1.1  christos       t = GET_L_REG (rn);
   1189  1.7  christos       r = GET_MEMORY_B (t & h8_get_mask (cpu));
   1190  1.1  christos       if (!twice)
   1191  1.1  christos 	t += 1;
   1192  1.1  christos       SET_L_REG (rn, t);
   1193  1.1  christos       *val = r;
   1194  1.1  christos       break;
   1195  1.1  christos     case X (OP_POSTINC, SW):	/* Register indirect w/post-incr: word.  */
   1196  1.1  christos       t = GET_L_REG (rn);
   1197  1.7  christos       r = GET_MEMORY_W (t & h8_get_mask (cpu));
   1198  1.1  christos       if (!twice)
   1199  1.1  christos 	t += 2;
   1200  1.1  christos       SET_L_REG (rn, t);
   1201  1.1  christos       *val = r;
   1202  1.1  christos       break;
   1203  1.1  christos     case X (OP_POSTINC, SL):	/* Register indirect w/post-incr: long.  */
   1204  1.1  christos       t = GET_L_REG (rn);
   1205  1.7  christos       r = GET_MEMORY_L (t & h8_get_mask (cpu));
   1206  1.1  christos       if (!twice)
   1207  1.1  christos 	t += 4;
   1208  1.1  christos       SET_L_REG (rn, t);
   1209  1.1  christos       *val = r;
   1210  1.1  christos       break;
   1211  1.1  christos 
   1212  1.1  christos     case X (OP_POSTDEC, SB):	/* Register indirect w/post-decr: byte.  */
   1213  1.1  christos       t = GET_L_REG (rn);
   1214  1.7  christos       r = GET_MEMORY_B (t & h8_get_mask (cpu));
   1215  1.1  christos       if (!twice)
   1216  1.1  christos 	t -= 1;
   1217  1.1  christos       SET_L_REG (rn, t);
   1218  1.1  christos       *val = r;
   1219  1.1  christos       break;
   1220  1.1  christos     case X (OP_POSTDEC, SW):	/* Register indirect w/post-decr: word.  */
   1221  1.1  christos       t = GET_L_REG (rn);
   1222  1.7  christos       r = GET_MEMORY_W (t & h8_get_mask (cpu));
   1223  1.1  christos       if (!twice)
   1224  1.1  christos 	t -= 2;
   1225  1.1  christos       SET_L_REG (rn, t);
   1226  1.1  christos       *val = r;
   1227  1.1  christos       break;
   1228  1.1  christos     case X (OP_POSTDEC, SL):	/* Register indirect w/post-decr: long.  */
   1229  1.1  christos       t = GET_L_REG (rn);
   1230  1.7  christos       r = GET_MEMORY_L (t & h8_get_mask (cpu));
   1231  1.1  christos       if (!twice)
   1232  1.1  christos 	t -= 4;
   1233  1.1  christos       SET_L_REG (rn, t);
   1234  1.1  christos       *val = r;
   1235  1.1  christos       break;
   1236  1.1  christos 
   1237  1.1  christos     case X (OP_PREDEC, SB):	/* Register indirect w/pre-decr: byte.  */
   1238  1.1  christos       t = GET_L_REG (rn) - 1;
   1239  1.1  christos       SET_L_REG (rn, t);
   1240  1.7  christos       t &= h8_get_mask (cpu);
   1241  1.1  christos       *val = GET_MEMORY_B (t);
   1242  1.1  christos       break;
   1243  1.1  christos 
   1244  1.1  christos     case X (OP_PREDEC, SW):	/* Register indirect w/pre-decr: word.  */
   1245  1.1  christos       t = GET_L_REG (rn) - 2;
   1246  1.1  christos       SET_L_REG (rn, t);
   1247  1.7  christos       t &= h8_get_mask (cpu);
   1248  1.1  christos       *val = GET_MEMORY_W (t);
   1249  1.1  christos       break;
   1250  1.1  christos 
   1251  1.1  christos     case X (OP_PREDEC, SL):	/* Register indirect w/pre-decr: long.  */
   1252  1.1  christos       t = GET_L_REG (rn) - 4;
   1253  1.1  christos       SET_L_REG (rn, t);
   1254  1.7  christos       t &= h8_get_mask (cpu);
   1255  1.1  christos       *val = GET_MEMORY_L (t);
   1256  1.1  christos       break;
   1257  1.1  christos 
   1258  1.1  christos     case X (OP_PREINC, SB):	/* Register indirect w/pre-incr: byte.  */
   1259  1.1  christos       t = GET_L_REG (rn) + 1;
   1260  1.1  christos       SET_L_REG (rn, t);
   1261  1.7  christos       t &= h8_get_mask (cpu);
   1262  1.1  christos       *val = GET_MEMORY_B (t);
   1263  1.1  christos       break;
   1264  1.1  christos 
   1265  1.1  christos     case X (OP_PREINC, SW):	/* Register indirect w/pre-incr: long.  */
   1266  1.1  christos       t = GET_L_REG (rn) + 2;
   1267  1.1  christos       SET_L_REG (rn, t);
   1268  1.7  christos       t &= h8_get_mask (cpu);
   1269  1.1  christos       *val = GET_MEMORY_W (t);
   1270  1.1  christos       break;
   1271  1.1  christos 
   1272  1.1  christos     case X (OP_PREINC, SL):	/* Register indirect w/pre-incr: long.  */
   1273  1.1  christos       t = GET_L_REG (rn) + 4;
   1274  1.1  christos       SET_L_REG (rn, t);
   1275  1.7  christos       t &= h8_get_mask (cpu);
   1276  1.1  christos       *val = GET_MEMORY_L (t);
   1277  1.1  christos       break;
   1278  1.1  christos 
   1279  1.1  christos     case X (OP_DISP, SB):	/* Register indirect w/displacement: byte.  */
   1280  1.1  christos       t = GET_L_REG (rn) + abs;
   1281  1.7  christos       t &= h8_get_mask (cpu);
   1282  1.1  christos       *val = GET_MEMORY_B (t);
   1283  1.1  christos       break;
   1284  1.1  christos 
   1285  1.1  christos     case X (OP_DISP, SW):	/* Register indirect w/displacement: word.  */
   1286  1.1  christos       t = GET_L_REG (rn) + abs;
   1287  1.7  christos       t &= h8_get_mask (cpu);
   1288  1.1  christos       *val = GET_MEMORY_W (t);
   1289  1.1  christos       break;
   1290  1.1  christos 
   1291  1.1  christos     case X (OP_DISP, SL):	/* Register indirect w/displacement: long.  */
   1292  1.1  christos       t = GET_L_REG (rn) + abs;
   1293  1.7  christos       t &= h8_get_mask (cpu);
   1294  1.1  christos       *val =GET_MEMORY_L (t);
   1295  1.1  christos       break;
   1296  1.1  christos 
   1297  1.1  christos     case X (OP_MEM, SL):	/* Absolute memory address, long.  */
   1298  1.1  christos       t = GET_MEMORY_L (abs);
   1299  1.7  christos       t &= h8_get_mask (cpu);
   1300  1.1  christos       *val = t;
   1301  1.1  christos       break;
   1302  1.1  christos 
   1303  1.1  christos     case X (OP_MEM, SW):	/* Absolute memory address, word.  */
   1304  1.1  christos       t = GET_MEMORY_W (abs);
   1305  1.7  christos       t &= h8_get_mask (cpu);
   1306  1.1  christos       *val = t;
   1307  1.1  christos       break;
   1308  1.1  christos 
   1309  1.1  christos     case X (OP_PCREL, SB):	/* PC relative (for jump, branch etc).  */
   1310  1.1  christos     case X (OP_PCREL, SW):
   1311  1.1  christos     case X (OP_PCREL, SL):
   1312  1.1  christos     case X (OP_PCREL, SN):
   1313  1.1  christos       *val = abs;
   1314  1.1  christos       break;
   1315  1.1  christos 
   1316  1.7  christos     case X (OP_REG_DEC, SB):	/* Register direct, affected decrement byte.  */
   1317  1.7  christos       *val = GET_B_REG (rn) - 1;
   1318  1.7  christos       break;
   1319  1.7  christos     case X (OP_REG_DEC, SW):	/* Register direct, affected decrement word.  */
   1320  1.7  christos       *val = GET_W_REG (rn) - 2;
   1321  1.7  christos       break;
   1322  1.7  christos     case X (OP_REG_DEC, SL):	/* Register direct, affected decrement long.  */
   1323  1.7  christos       *val = GET_L_REG (rn) - 4;
   1324  1.7  christos       break;
   1325  1.7  christos     case X (OP_REG_INC, SB):	/* Register direct, affected increment byte.  */
   1326  1.7  christos       *val = GET_B_REG (rn) + 1;
   1327  1.7  christos       break;
   1328  1.7  christos     case X (OP_REG_INC, SW):	/* Register direct, affected increment word.  */
   1329  1.7  christos       *val = GET_W_REG (rn) + 2;
   1330  1.7  christos       break;
   1331  1.7  christos     case X (OP_REG_INC, SL):	/* Register direct, affected increment long.  */
   1332  1.7  christos       *val = GET_L_REG (rn) + 4;
   1333  1.7  christos       break;
   1334  1.7  christos 
   1335  1.1  christos     case X (OP_MEM, SB):	/* Why isn't this implemented?  */
   1336  1.1  christos     default:
   1337  1.6  christos       sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
   1338  1.1  christos       return -1;
   1339  1.1  christos     }
   1340  1.1  christos   return 0;	/* Success.  */
   1341  1.1  christos }
   1342  1.1  christos 
   1343  1.1  christos /* Normal fetch.  */
   1344  1.1  christos 
   1345  1.1  christos static int
   1346  1.1  christos fetch (SIM_DESC sd, ea_type *arg, int *val)
   1347  1.1  christos {
   1348  1.1  christos   return fetch_1 (sd, arg, val, 0);
   1349  1.1  christos }
   1350  1.1  christos 
   1351  1.1  christos /* Fetch which will be followed by a store to the same location.
   1352  1.1  christos    The difference being that we don't want to do a post-increment
   1353  1.1  christos    or post-decrement at this time: we'll do it when we store.  */
   1354  1.1  christos 
   1355  1.1  christos static int
   1356  1.1  christos fetch2 (SIM_DESC sd, ea_type *arg, int *val)
   1357  1.1  christos {
   1358  1.1  christos   return fetch_1 (sd, arg, val, 1);
   1359  1.1  christos }
   1360  1.1  christos 
   1361  1.1  christos /* Simulate a memory store.
   1362  1.1  christos    Return 0 for success, -1 for failure.
   1363  1.1  christos */
   1364  1.1  christos 
   1365  1.1  christos static int
   1366  1.1  christos store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
   1367  1.1  christos {
   1368  1.6  christos   SIM_CPU *cpu = STATE_CPU (sd, 0);
   1369  1.1  christos   int rn = arg->reg;
   1370  1.1  christos   int abs = arg->literal;
   1371  1.1  christos   int t;
   1372  1.1  christos 
   1373  1.1  christos   switch (arg->type)
   1374  1.1  christos     {
   1375  1.1  christos       /* Indexed register plus displacement mode:
   1376  1.1  christos 
   1377  1.1  christos 	 This new family of addressing modes are similar to OP_DISP
   1378  1.1  christos 	 (register plus displacement), with two differences:
   1379  1.1  christos 	   1) INDEXB uses only the least significant byte of the register,
   1380  1.1  christos 	      INDEXW uses only the least significant word, and
   1381  1.1  christos 	      INDEXL uses the entire register (just like OP_DISP).
   1382  1.1  christos 	 and
   1383  1.1  christos 	   2) The displacement value in abs is multiplied by two
   1384  1.1  christos 	      for SW-sized operations, and by four for SL-size.
   1385  1.1  christos 
   1386  1.1  christos 	This gives nine possible variations.
   1387  1.1  christos       */
   1388  1.1  christos 
   1389  1.1  christos     case X (OP_INDEXB, SB):
   1390  1.1  christos     case X (OP_INDEXB, SW):
   1391  1.1  christos     case X (OP_INDEXB, SL):
   1392  1.1  christos     case X (OP_INDEXW, SB):
   1393  1.1  christos     case X (OP_INDEXW, SW):
   1394  1.1  christos     case X (OP_INDEXW, SL):
   1395  1.1  christos     case X (OP_INDEXL, SB):
   1396  1.1  christos     case X (OP_INDEXL, SW):
   1397  1.1  christos     case X (OP_INDEXL, SL):
   1398  1.1  christos       t = GET_L_REG (rn);
   1399  1.1  christos       switch (OP_KIND (arg->type)) {
   1400  1.1  christos       case OP_INDEXB:	t &= 0xff;	break;
   1401  1.1  christos       case OP_INDEXW:	t &= 0xffff;	break;
   1402  1.1  christos       case OP_INDEXL:
   1403  1.1  christos       default:		break;
   1404  1.1  christos       }
   1405  1.1  christos       switch (OP_SIZE (arg->type)) {
   1406  1.1  christos       case SB:
   1407  1.7  christos 	SET_MEMORY_B ((t * 1 + abs) & h8_get_mask (cpu), n);
   1408  1.1  christos 	break;
   1409  1.1  christos       case SW:
   1410  1.7  christos 	SET_MEMORY_W ((t * 2 + abs) & h8_get_mask (cpu), n);
   1411  1.1  christos 	break;
   1412  1.1  christos       case SL:
   1413  1.7  christos 	SET_MEMORY_L ((t * 4 + abs) & h8_get_mask (cpu), n);
   1414  1.1  christos 	break;
   1415  1.1  christos       }
   1416  1.1  christos       break;
   1417  1.1  christos 
   1418  1.1  christos     case X (OP_REG, SB):	/* Register direct, byte.  */
   1419  1.1  christos       SET_B_REG (rn, n);
   1420  1.1  christos       break;
   1421  1.1  christos     case X (OP_REG, SW):	/* Register direct, word.  */
   1422  1.1  christos       SET_W_REG (rn, n);
   1423  1.1  christos       break;
   1424  1.1  christos     case X (OP_REG, SL):	/* Register direct, long.  */
   1425  1.1  christos       SET_L_REG (rn, n);
   1426  1.1  christos       break;
   1427  1.1  christos 
   1428  1.1  christos     case X (OP_PREDEC, SB):	/* Register indirect w/pre-decr, byte.  */
   1429  1.1  christos       t = GET_L_REG (rn);
   1430  1.1  christos       if (!twice)
   1431  1.1  christos 	t -= 1;
   1432  1.1  christos       SET_L_REG (rn, t);
   1433  1.7  christos       t &= h8_get_mask (cpu);
   1434  1.1  christos       SET_MEMORY_B (t, n);
   1435  1.1  christos 
   1436  1.1  christos       break;
   1437  1.1  christos     case X (OP_PREDEC, SW):	/* Register indirect w/pre-decr, word.  */
   1438  1.1  christos       t = GET_L_REG (rn);
   1439  1.1  christos       if (!twice)
   1440  1.1  christos 	t -= 2;
   1441  1.1  christos       SET_L_REG (rn, t);
   1442  1.7  christos       t &= h8_get_mask (cpu);
   1443  1.1  christos       SET_MEMORY_W (t, n);
   1444  1.1  christos       break;
   1445  1.1  christos 
   1446  1.1  christos     case X (OP_PREDEC, SL):	/* Register indirect w/pre-decr, long.  */
   1447  1.1  christos       t = GET_L_REG (rn);
   1448  1.1  christos       if (!twice)
   1449  1.1  christos 	t -= 4;
   1450  1.1  christos       SET_L_REG (rn, t);
   1451  1.7  christos       t &= h8_get_mask (cpu);
   1452  1.1  christos       SET_MEMORY_L (t, n);
   1453  1.1  christos       break;
   1454  1.1  christos 
   1455  1.1  christos     case X (OP_PREINC, SB):	/* Register indirect w/pre-incr, byte.  */
   1456  1.1  christos       t = GET_L_REG (rn);
   1457  1.1  christos       if (!twice)
   1458  1.1  christos 	t += 1;
   1459  1.1  christos       SET_L_REG (rn, t);
   1460  1.7  christos       t &= h8_get_mask (cpu);
   1461  1.1  christos       SET_MEMORY_B (t, n);
   1462  1.1  christos 
   1463  1.1  christos       break;
   1464  1.1  christos     case X (OP_PREINC, SW):	/* Register indirect w/pre-incr, word.  */
   1465  1.1  christos       t = GET_L_REG (rn);
   1466  1.1  christos       if (!twice)
   1467  1.1  christos 	t += 2;
   1468  1.1  christos       SET_L_REG (rn, t);
   1469  1.7  christos       t &= h8_get_mask (cpu);
   1470  1.1  christos       SET_MEMORY_W (t, n);
   1471  1.1  christos       break;
   1472  1.1  christos 
   1473  1.1  christos     case X (OP_PREINC, SL):	/* Register indirect w/pre-incr, long.  */
   1474  1.1  christos       t = GET_L_REG (rn);
   1475  1.1  christos       if (!twice)
   1476  1.1  christos 	t += 4;
   1477  1.1  christos       SET_L_REG (rn, t);
   1478  1.7  christos       t &= h8_get_mask (cpu);
   1479  1.1  christos       SET_MEMORY_L (t, n);
   1480  1.1  christos       break;
   1481  1.1  christos 
   1482  1.1  christos     case X (OP_POSTDEC, SB):	/* Register indirect w/post-decr, byte.  */
   1483  1.1  christos       t = GET_L_REG (rn);
   1484  1.1  christos       SET_L_REG (rn, t - 1);
   1485  1.7  christos       t &= h8_get_mask (cpu);
   1486  1.1  christos       SET_MEMORY_B (t, n);
   1487  1.1  christos       break;
   1488  1.1  christos 
   1489  1.1  christos     case X (OP_POSTDEC, SW):	/* Register indirect w/post-decr, word.  */
   1490  1.1  christos       t = GET_L_REG (rn);
   1491  1.1  christos       SET_L_REG (rn, t - 2);
   1492  1.7  christos       t &= h8_get_mask (cpu);
   1493  1.1  christos       SET_MEMORY_W (t, n);
   1494  1.1  christos       break;
   1495  1.1  christos 
   1496  1.1  christos     case X (OP_POSTDEC, SL):	/* Register indirect w/post-decr, long.  */
   1497  1.1  christos       t = GET_L_REG (rn);
   1498  1.1  christos       SET_L_REG (rn, t - 4);
   1499  1.7  christos       t &= h8_get_mask (cpu);
   1500  1.1  christos       SET_MEMORY_L (t, n);
   1501  1.1  christos       break;
   1502  1.1  christos 
   1503  1.1  christos     case X (OP_POSTINC, SB):	/* Register indirect w/post-incr, byte.  */
   1504  1.1  christos       t = GET_L_REG (rn);
   1505  1.1  christos       SET_L_REG (rn, t + 1);
   1506  1.7  christos       t &= h8_get_mask (cpu);
   1507  1.1  christos       SET_MEMORY_B (t, n);
   1508  1.1  christos       break;
   1509  1.1  christos 
   1510  1.1  christos     case X (OP_POSTINC, SW):	/* Register indirect w/post-incr, word.  */
   1511  1.1  christos       t = GET_L_REG (rn);
   1512  1.1  christos       SET_L_REG (rn, t + 2);
   1513  1.7  christos       t &= h8_get_mask (cpu);
   1514  1.1  christos       SET_MEMORY_W (t, n);
   1515  1.1  christos       break;
   1516  1.1  christos 
   1517  1.1  christos     case X (OP_POSTINC, SL):	/* Register indirect w/post-incr, long.  */
   1518  1.1  christos       t = GET_L_REG (rn);
   1519  1.1  christos       SET_L_REG (rn, t + 4);
   1520  1.7  christos       t &= h8_get_mask (cpu);
   1521  1.1  christos       SET_MEMORY_L (t, n);
   1522  1.1  christos       break;
   1523  1.1  christos 
   1524  1.1  christos     case X (OP_DISP, SB):	/* Register indirect w/displacement, byte.  */
   1525  1.1  christos       t = GET_L_REG (rn) + abs;
   1526  1.7  christos       t &= h8_get_mask (cpu);
   1527  1.1  christos       SET_MEMORY_B (t, n);
   1528  1.1  christos       break;
   1529  1.1  christos 
   1530  1.1  christos     case X (OP_DISP, SW):	/* Register indirect w/displacement, word.  */
   1531  1.1  christos       t = GET_L_REG (rn) + abs;
   1532  1.7  christos       t &= h8_get_mask (cpu);
   1533  1.1  christos       SET_MEMORY_W (t, n);
   1534  1.1  christos       break;
   1535  1.1  christos 
   1536  1.1  christos     case X (OP_DISP, SL):	/* Register indirect w/displacement, long.  */
   1537  1.1  christos       t = GET_L_REG (rn) + abs;
   1538  1.7  christos       t &= h8_get_mask (cpu);
   1539  1.1  christos       SET_MEMORY_L (t, n);
   1540  1.1  christos       break;
   1541  1.1  christos 
   1542  1.1  christos 
   1543  1.1  christos     case X (OP_MEM, SB):	/* Why isn't this implemented?  */
   1544  1.1  christos     case X (OP_MEM, SW):	/* Why isn't this implemented?  */
   1545  1.1  christos     case X (OP_MEM, SL):	/* Why isn't this implemented?  */
   1546  1.1  christos     default:
   1547  1.6  christos       sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
   1548  1.1  christos       return -1;
   1549  1.1  christos     }
   1550  1.1  christos   return 0;
   1551  1.1  christos }
   1552  1.1  christos 
   1553  1.1  christos /* Normal store.  */
   1554  1.1  christos 
   1555  1.1  christos static int
   1556  1.1  christos store (SIM_DESC sd, ea_type *arg, int n)
   1557  1.1  christos {
   1558  1.1  christos   return store_1 (sd, arg, n, 0);
   1559  1.1  christos }
   1560  1.1  christos 
   1561  1.1  christos /* Store which follows a fetch from the same location.
   1562  1.1  christos    The difference being that we don't want to do a pre-increment
   1563  1.1  christos    or pre-decrement at this time: it was already done when we fetched.  */
   1564  1.1  christos 
   1565  1.1  christos static int
   1566  1.1  christos store2 (SIM_DESC sd, ea_type *arg, int n)
   1567  1.1  christos {
   1568  1.1  christos   return store_1 (sd, arg, n, 1);
   1569  1.1  christos }
   1570  1.1  christos 
   1571  1.9  christos /* Callback for qsort.  We sort first based on availability
   1572  1.8  christos    (available instructions sort lower).  When availability state
   1573  1.8  christos    is the same, then we use the first 4 bit nibble as a secondary
   1574  1.8  christos    sort key.
   1575  1.8  christos 
   1576  1.8  christos    We don't really care about 100% stability here, just that the
   1577  1.8  christos    available instructions come first and all instrutions with
   1578  1.8  christos    the same starting nibble are consecutive.
   1579  1.8  christos 
   1580  1.8  christos    We could do even better by recording frequency information into the
   1581  1.8  christos    main table and using that to sort within a nibble's group with the
   1582  1.8  christos    highest frequency instructions appearing first.  */
   1583  1.8  christos 
   1584  1.8  christos static int
   1585  1.8  christos instruction_comparator (const void *p1_, const void *p2_)
   1586  1.8  christos {
   1587  1.8  christos   struct h8_opcode *p1 = (struct h8_opcode *)p1_;
   1588  1.8  christos   struct h8_opcode *p2 = (struct h8_opcode *)p2_;
   1589  1.8  christos 
   1590  1.8  christos   /* The 1st sort key is based on whether or not the
   1591  1.8  christos      instruction is even available.  This reduces the
   1592  1.8  christos      number of entries we have to look at in the common
   1593  1.8  christos      case.  */
   1594  1.8  christos   bool p1_available = !((p1->available == AV_H8SX && !h8300sxmode)
   1595  1.8  christos 			|| (p1->available == AV_H8S  && !h8300smode)
   1596  1.8  christos 			|| (p1->available == AV_H8H  && !h8300hmode));
   1597  1.8  christos 
   1598  1.8  christos   bool p2_available = !((p2->available == AV_H8SX && !h8300sxmode)
   1599  1.8  christos 			|| (p2->available == AV_H8S  && !h8300smode)
   1600  1.8  christos 			|| (p2->available == AV_H8H  && !h8300hmode));
   1601  1.8  christos 
   1602  1.8  christos   /* Sort so that available instructions come before unavailable
   1603  1.8  christos      instructions.  */
   1604  1.8  christos   if (p1_available != p2_available)
   1605  1.8  christos     return p2_available - p1_available;
   1606  1.8  christos 
   1607  1.8  christos   /* Secondarily sort based on the first opcode nibble.  */
   1608  1.8  christos   return p1->data.nib[0] - p2->data.nib[0];
   1609  1.8  christos }
   1610  1.8  christos 
   1611  1.8  christos 
   1612  1.8  christos /* OPS is the opcode array, which is initially sorted by mnenomic.
   1613  1.8  christos 
   1614  1.8  christos    Sort the array so that the instructions for the sub-architecture
   1615  1.8  christos    are at the start and unavailable instructions are at the end.
   1616  1.8  christos 
   1617  1.8  christos    Within the set of available instructions, further sort them based
   1618  1.8  christos    on the first 4 bit nibble.
   1619  1.8  christos 
   1620  1.8  christos    Then find the first index into OPS for each of the 16 possible
   1621  1.8  christos    nibbles and record that into NIB_INDICES to speed up decoding.  */
   1622  1.8  christos 
   1623  1.8  christos static void
   1624  1.8  christos sort_opcodes_and_setup_nibble_indices (struct h8_opcode *ops)
   1625  1.8  christos {
   1626  1.8  christos   const struct h8_opcode *q;
   1627  1.8  christos   int i;
   1628  1.8  christos 
   1629  1.8  christos   /* First sort the OPS array.  */
   1630  1.8  christos   for (i = 0, q = ops; q->name; q++, i++)
   1631  1.8  christos     ;
   1632  1.8  christos   qsort (ops, i, sizeof (struct h8_opcode), instruction_comparator);
   1633  1.8  christos 
   1634  1.8  christos   /* Now walk the array caching the index of the first
   1635  1.8  christos      occurrence of each 4 bit nibble.  */
   1636  1.8  christos   memset (nib_indices, -1, sizeof (nib_indices));
   1637  1.8  christos   for (i = 0, q = ops; q->name; q++, i++)
   1638  1.8  christos     {
   1639  1.8  christos       int nib = q->data.nib[0];
   1640  1.8  christos 
   1641  1.8  christos       /* Record the location of the first entry with the right
   1642  1.8  christos 	 nibble count.  */
   1643  1.8  christos       if (nib_indices[nib] == -1)
   1644  1.8  christos 	nib_indices[nib] = i;
   1645  1.8  christos     }
   1646  1.8  christos }
   1647  1.8  christos 
   1648  1.8  christos 
   1649  1.1  christos /* Flag to be set whenever a new SIM_DESC object is created.  */
   1650  1.1  christos static int init_pointers_needed = 1;
   1651  1.1  christos 
   1652  1.1  christos static void
   1653  1.1  christos init_pointers (SIM_DESC sd)
   1654  1.1  christos {
   1655  1.7  christos   sim_cpu *cpu = STATE_CPU (sd, 0);
   1656  1.7  christos   struct h8300_sim_state *state = H8300_SIM_STATE (sd);
   1657  1.7  christos 
   1658  1.1  christos   if (init_pointers_needed)
   1659  1.1  christos     {
   1660  1.1  christos       int i;
   1661  1.1  christos 
   1662  1.1  christos       if (h8300smode && !h8300_normal_mode)
   1663  1.1  christos 	memory_size = H8300S_MSIZE;
   1664  1.1  christos       else if (h8300hmode && !h8300_normal_mode)
   1665  1.1  christos 	memory_size = H8300H_MSIZE;
   1666  1.1  christos       else
   1667  1.1  christos 	memory_size = H8300_MSIZE;
   1668  1.1  christos       /* `msize' must be a power of two.  */
   1669  1.1  christos       if ((memory_size & (memory_size - 1)) != 0)
   1670  1.1  christos 	{
   1671  1.6  christos 	  sim_io_printf
   1672  1.6  christos 	    (sd,
   1673  1.1  christos 	     "init_pointers: bad memory size %d, defaulting to %d.\n",
   1674  1.7  christos 	     memory_size, H8300S_MSIZE);
   1675  1.7  christos 	  memory_size = H8300S_MSIZE;
   1676  1.1  christos 	}
   1677  1.1  christos 
   1678  1.7  christos       if (h8_get_memory_buf (cpu))
   1679  1.7  christos 	free (h8_get_memory_buf (cpu));
   1680  1.1  christos 
   1681  1.7  christos       h8_set_memory_buf (cpu, (unsigned char *)
   1682  1.1  christos 			 calloc (sizeof (char), memory_size));
   1683  1.7  christos       state->memory_size = memory_size;
   1684  1.1  christos 
   1685  1.7  christos       h8_set_mask (cpu, memory_size - 1);
   1686  1.1  christos 
   1687  1.8  christos       memset (h8_get_reg_buf (cpu), 0, sizeof (H8300_SIM_CPU (cpu)->regs));
   1688  1.1  christos 
   1689  1.1  christos       for (i = 0; i < 8; i++)
   1690  1.1  christos 	{
   1691  1.1  christos 	  /* FIXME: rewrite using local buffer.  */
   1692  1.7  christos 	  unsigned char *p = (unsigned char *) (h8_get_reg_buf (cpu) + i);
   1693  1.7  christos 	  unsigned char *e = (unsigned char *) (h8_get_reg_buf (cpu) + i + 1);
   1694  1.7  christos 	  unsigned short *q = (unsigned short *) (h8_get_reg_buf (cpu) + i);
   1695  1.7  christos 	  unsigned short *u = (unsigned short *) (h8_get_reg_buf (cpu) + i + 1);
   1696  1.7  christos 	  h8_set_reg (cpu, i, 0x00112233);
   1697  1.1  christos 
   1698  1.1  christos 	  while (p < e)
   1699  1.1  christos 	    {
   1700  1.1  christos 	      if (*p == 0x22)
   1701  1.1  christos 		  breg[i] = p;
   1702  1.1  christos 	      if (*p == 0x33)
   1703  1.1  christos 		  breg[i + 8] = p;
   1704  1.1  christos 	      if (*p == 0x11)
   1705  1.1  christos 		breg[i + 16] = p;
   1706  1.1  christos 	      if (*p == 0x00)
   1707  1.1  christos 		breg[i + 24] = p;
   1708  1.1  christos 	      p++;
   1709  1.1  christos 	    }
   1710  1.1  christos 
   1711  1.1  christos 	  wreg[i] = wreg[i + 8] = 0;
   1712  1.1  christos 	  while (q < u)
   1713  1.1  christos 	    {
   1714  1.1  christos 	      if (*q == 0x2233)
   1715  1.1  christos 		{
   1716  1.1  christos 		  wreg[i] = q;
   1717  1.1  christos 		}
   1718  1.1  christos 	      if (*q == 0x0011)
   1719  1.1  christos 		{
   1720  1.1  christos 		  wreg[i + 8] = q;
   1721  1.1  christos 		}
   1722  1.1  christos 	      q++;
   1723  1.1  christos 	    }
   1724  1.1  christos 
   1725  1.1  christos 	  if (wreg[i] == 0 || wreg[i + 8] == 0)
   1726  1.6  christos 	    sim_io_printf (sd, "init_pointers: internal error.\n");
   1727  1.1  christos 
   1728  1.7  christos 	  h8_set_reg (cpu, i, 0);
   1729  1.1  christos 	}
   1730  1.1  christos 
   1731  1.8  christos       /* Sort the opcode table and create indices to speed up decode.  */
   1732  1.8  christos       sort_opcodes_and_setup_nibble_indices (ops);
   1733  1.8  christos 
   1734  1.1  christos       init_pointers_needed = 0;
   1735  1.1  christos     }
   1736  1.1  christos }
   1737  1.1  christos 
   1738  1.1  christos #define OBITOP(name, f, s, op) 			\
   1739  1.1  christos case O (name, SB):				\
   1740  1.1  christos {						\
   1741  1.8  christos   int m;					\
   1742  1.1  christos 	 					\
   1743  1.1  christos   if (f)					\
   1744  1.1  christos     if (fetch (sd, &code->dst, &ea))		\
   1745  1.1  christos       goto end;					\
   1746  1.1  christos   if (fetch (sd, &code->src, &tmp))		\
   1747  1.1  christos     goto end;					\
   1748  1.1  christos   m = 1 << (tmp & 7);				\
   1749  1.1  christos   op;						\
   1750  1.1  christos   if (s)					\
   1751  1.1  christos     if (store (sd, &code->dst,ea))		\
   1752  1.1  christos       goto end;					\
   1753  1.1  christos   goto next;					\
   1754  1.1  christos }
   1755  1.1  christos 
   1756  1.6  christos static void
   1757  1.6  christos step_once (SIM_DESC sd, SIM_CPU *cpu)
   1758  1.1  christos {
   1759  1.1  christos   int cycles = 0;
   1760  1.1  christos   int insts = 0;
   1761  1.1  christos   int tick_start = get_now ();
   1762  1.1  christos   int res;
   1763  1.1  christos   int tmp;
   1764  1.1  christos   int rd;
   1765  1.1  christos   int ea;
   1766  1.1  christos   int bit;
   1767  1.1  christos   int pc;
   1768  1.1  christos   int c, nz, v, n, u, h, ui, intMaskBit;
   1769  1.7  christos   int trace = 0;
   1770  1.7  christos   int intMask = 0;
   1771  1.1  christos   int oldmask;
   1772  1.6  christos   host_callback *sim_callback = STATE_CALLBACK (sd);
   1773  1.1  christos 
   1774  1.1  christos   init_pointers (sd);
   1775  1.1  christos 
   1776  1.7  christos   pc = cpu_get_pc (cpu);
   1777  1.1  christos 
   1778  1.1  christos   /* The PC should never be odd.  */
   1779  1.1  christos   if (pc & 0x1)
   1780  1.1  christos     {
   1781  1.6  christos       sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGBUS);
   1782  1.1  christos       return;
   1783  1.1  christos     }
   1784  1.1  christos 
   1785  1.1  christos   /* Get Status Register (flags).  */
   1786  1.7  christos   GETSR (cpu);
   1787  1.1  christos 
   1788  1.1  christos   if (h8300smode)	/* Get exr.  */
   1789  1.1  christos     {
   1790  1.7  christos       trace = (h8_get_exr (cpu) >> 7) & 1;
   1791  1.7  christos       intMask = h8_get_exr (cpu) & 7;
   1792  1.1  christos     }
   1793  1.1  christos 
   1794  1.7  christos   oldmask = h8_get_mask (cpu);
   1795  1.1  christos   if (!h8300hmode || h8300_normal_mode)
   1796  1.7  christos     h8_set_mask (cpu, 0xffff);
   1797  1.1  christos   do
   1798  1.1  christos     {
   1799  1.7  christos       decoded_inst _code, *code = &_code;
   1800  1.7  christos       memset (code, 0, sizeof (*code));
   1801  1.7  christos       decode (sd, cpu, pc, h8_get_memory_buf (cpu) + pc, code);
   1802  1.7  christos       code->oldpc = pc;
   1803  1.1  christos 
   1804  1.1  christos #if ADEBUG
   1805  1.1  christos       if (debug)
   1806  1.1  christos 	{
   1807  1.1  christos 	  printf ("%x %d %s\n", pc, code->opcode,
   1808  1.1  christos 		  code->op ? code->op->name : "**");
   1809  1.1  christos 	}
   1810  1.1  christos       h8_increment_stats (sd, code->opcode);
   1811  1.1  christos #endif
   1812  1.1  christos 
   1813  1.1  christos       if (code->opcode)
   1814  1.1  christos 	{
   1815  1.1  christos 	  cycles += code->cycles;
   1816  1.1  christos 	  insts++;
   1817  1.1  christos 	}
   1818  1.1  christos 
   1819  1.1  christos       switch (code->opcode)
   1820  1.1  christos 	{
   1821  1.1  christos 	case O (O_MOVAB, SL):
   1822  1.1  christos 	case O (O_MOVAW, SL):
   1823  1.1  christos 	case O (O_MOVAL, SL):
   1824  1.1  christos 	  /* 1) Evaluate 2nd argument (dst).
   1825  1.1  christos 	     2) Mask / zero extend according to whether 1st argument (src)
   1826  1.1  christos 	        is INDEXB, INDEXW, or INDEXL.
   1827  1.1  christos 	     3) Left-shift the result by 0, 1 or 2, according to size of mova
   1828  1.1  christos 	        (mova/b, mova/w, mova/l).
   1829  1.1  christos 	     4) Add literal value of 1st argument (src).
   1830  1.1  christos 	     5) Store result in 3rd argument (op3).
   1831  1.1  christos 	  */
   1832  1.1  christos 
   1833  1.1  christos 	  /* Alas, since this is the only instruction with 3 arguments,
   1834  1.1  christos 	     decode doesn't handle them very well.  Some fix-up is required.
   1835  1.1  christos 
   1836  1.1  christos 	     a) The size of dst is determined by whether src is
   1837  1.1  christos 	        INDEXB or INDEXW.  */
   1838  1.1  christos 
   1839  1.1  christos 	  if (OP_KIND (code->src.type) == OP_INDEXB)
   1840  1.1  christos 	    code->dst.type = X (OP_KIND (code->dst.type), SB);
   1841  1.1  christos 	  else if (OP_KIND (code->src.type) == OP_INDEXW)
   1842  1.1  christos 	    code->dst.type = X (OP_KIND (code->dst.type), SW);
   1843  1.1  christos 
   1844  1.1  christos 	  /* b) If op3 == null, then this is the short form of the insn.
   1845  1.1  christos 	        Dst is the dispreg of src, and op3 is the 32-bit form
   1846  1.1  christos 		of the same register.
   1847  1.1  christos 	  */
   1848  1.1  christos 
   1849  1.7  christos 	  if (code->op3.type == -1)
   1850  1.1  christos 	    {
   1851  1.1  christos 	      /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
   1852  1.1  christos 		 We get to compose dst and op3 as follows:
   1853  1.1  christos 
   1854  1.1  christos 		     op3 is a 32-bit register, ID == src.reg.
   1855  1.1  christos 		     dst is the same register, but 8 or 16 bits
   1856  1.1  christos 		     depending on whether src is INDEXB or INDEXW.
   1857  1.1  christos 	      */
   1858  1.1  christos 
   1859  1.1  christos 	      code->op3.type = X (OP_REG, SL);
   1860  1.1  christos 	      code->op3.reg  = code->src.reg;
   1861  1.1  christos 	      code->op3.literal = 0;
   1862  1.1  christos 
   1863  1.1  christos 	      if (OP_KIND (code->src.type) == OP_INDEXB)
   1864  1.1  christos 		{
   1865  1.1  christos 		  code->dst.type = X (OP_REG, SB);
   1866  1.1  christos 		  code->dst.reg = code->op3.reg + 8;
   1867  1.1  christos 		}
   1868  1.1  christos 	      else
   1869  1.1  christos 		code->dst.type = X (OP_REG, SW);
   1870  1.1  christos 	    }
   1871  1.1  christos 
   1872  1.1  christos 	  if (fetch (sd, &code->dst, &ea))
   1873  1.1  christos 	    goto end;
   1874  1.1  christos 
   1875  1.1  christos 	  switch (OP_KIND (code->src.type)) {
   1876  1.1  christos 	  case OP_INDEXB:    ea = ea & 0xff;		break;
   1877  1.1  christos 	  case OP_INDEXW:    ea = ea & 0xffff;		break;
   1878  1.1  christos 	  case OP_INDEXL:    				break;
   1879  1.1  christos 	  default:	     goto illegal;
   1880  1.1  christos 	  }
   1881  1.1  christos 
   1882  1.1  christos 	  switch (code->opcode) {
   1883  1.1  christos 	  case O (O_MOVAB, SL):	    			break;
   1884  1.1  christos 	  case O (O_MOVAW, SL):	    ea = ea << 1;	break;
   1885  1.1  christos 	  case O (O_MOVAL, SL):     ea = ea << 2;	break;
   1886  1.1  christos 	  default: 		    goto illegal;
   1887  1.1  christos 	  }
   1888  1.1  christos 
   1889  1.1  christos 	  ea = ea + code->src.literal;
   1890  1.1  christos 
   1891  1.1  christos 	  if (store (sd, &code->op3, ea))
   1892  1.1  christos 	    goto end;
   1893  1.1  christos 
   1894  1.1  christos 	  goto next;
   1895  1.1  christos 
   1896  1.1  christos 	case O (O_SUBX, SB):	/* subx, extended sub */
   1897  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   1898  1.1  christos 	    goto end;
   1899  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   1900  1.1  christos 	    goto end;
   1901  1.1  christos 	  ea = -(ea + C);
   1902  1.1  christos 	  res = rd + ea;
   1903  1.1  christos 	  goto alu8;
   1904  1.1  christos 
   1905  1.1  christos 	case O (O_SUBX, SW):	/* subx, extended sub */
   1906  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   1907  1.1  christos 	    goto end;
   1908  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   1909  1.1  christos 	    goto end;
   1910  1.1  christos 	  ea = -(ea + C);
   1911  1.1  christos 	  res = rd + ea;
   1912  1.1  christos 	  goto alu16;
   1913  1.1  christos 
   1914  1.1  christos 	case O (O_SUBX, SL):	/* subx, extended sub */
   1915  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   1916  1.1  christos 	    goto end;
   1917  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   1918  1.1  christos 	    goto end;
   1919  1.1  christos 	  ea = -(ea + C);
   1920  1.1  christos 	  res = rd + ea;
   1921  1.1  christos 	  goto alu32;
   1922  1.1  christos 
   1923  1.1  christos 	case O (O_ADDX, SB):	/* addx, extended add */
   1924  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   1925  1.1  christos 	    goto end;
   1926  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   1927  1.1  christos 	    goto end;
   1928  1.1  christos 	  ea = ea + C;
   1929  1.1  christos 	  res = rd + ea;
   1930  1.1  christos 	  goto alu8;
   1931  1.1  christos 
   1932  1.1  christos 	case O (O_ADDX, SW):	/* addx, extended add */
   1933  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   1934  1.1  christos 	    goto end;
   1935  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   1936  1.1  christos 	    goto end;
   1937  1.1  christos 	  ea = ea + C;
   1938  1.1  christos 	  res = rd + ea;
   1939  1.1  christos 	  goto alu16;
   1940  1.1  christos 
   1941  1.1  christos 	case O (O_ADDX, SL):	/* addx, extended add */
   1942  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   1943  1.1  christos 	    goto end;
   1944  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   1945  1.1  christos 	    goto end;
   1946  1.1  christos 	  ea = ea + C;
   1947  1.1  christos 	  res = rd + ea;
   1948  1.1  christos 	  goto alu32;
   1949  1.1  christos 
   1950  1.1  christos 	case O (O_SUB, SB):		/* sub.b */
   1951  1.1  christos 	  /* Fetch rd and ea.  */
   1952  1.1  christos 	  if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
   1953  1.1  christos 	    goto end;
   1954  1.1  christos 	  ea = -ea;
   1955  1.1  christos 	  res = rd + ea;
   1956  1.1  christos 	  goto alu8;
   1957  1.1  christos 
   1958  1.1  christos 	case O (O_SUB, SW):		/* sub.w */
   1959  1.1  christos 	  /* Fetch rd and ea.  */
   1960  1.1  christos 	  if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
   1961  1.1  christos 	    goto end;
   1962  1.1  christos 	  ea = -ea;
   1963  1.1  christos 	  res = rd + ea;
   1964  1.1  christos 	  goto alu16;
   1965  1.1  christos 
   1966  1.1  christos 	case O (O_SUB, SL):		/* sub.l */
   1967  1.1  christos 	  /* Fetch rd and ea.  */
   1968  1.1  christos 	  if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
   1969  1.1  christos 	    goto end;
   1970  1.1  christos 	  ea = -ea;
   1971  1.1  christos 	  res = rd + ea;
   1972  1.1  christos 	  goto alu32;
   1973  1.1  christos 
   1974  1.1  christos 	case O (O_NEG, SB):		/* neg.b */
   1975  1.1  christos 	  /* Fetch ea.  */
   1976  1.1  christos 	  if (fetch2 (sd, &code->src, &ea))
   1977  1.1  christos 	    goto end;
   1978  1.1  christos 	  ea = -ea;
   1979  1.1  christos 	  rd = 0;
   1980  1.1  christos 	  res = rd + ea;
   1981  1.1  christos 	  goto alu8;
   1982  1.1  christos 
   1983  1.1  christos 	case O (O_NEG, SW):		/* neg.w */
   1984  1.1  christos 	  /* Fetch ea.  */
   1985  1.1  christos 	  if (fetch2 (sd, &code->src, &ea))
   1986  1.1  christos 	    goto end;
   1987  1.1  christos 	  ea = -ea;
   1988  1.1  christos 	  rd = 0;
   1989  1.1  christos 	  res = rd + ea;
   1990  1.1  christos 	  goto alu16;
   1991  1.1  christos 
   1992  1.1  christos 	case O (O_NEG, SL):		/* neg.l */
   1993  1.1  christos 	  /* Fetch ea.  */
   1994  1.1  christos 	  if (fetch2 (sd, &code->src, &ea))
   1995  1.1  christos 	    goto end;
   1996  1.1  christos 	  ea = -ea;
   1997  1.1  christos 	  rd = 0;
   1998  1.1  christos 	  res = rd + ea;
   1999  1.1  christos 	  goto alu32;
   2000  1.1  christos 
   2001  1.1  christos 	case O (O_ADD, SB):		/* add.b */
   2002  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   2003  1.1  christos 	    goto end;
   2004  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   2005  1.1  christos 	    goto end;
   2006  1.1  christos 	  res = rd + ea;
   2007  1.1  christos 	  goto alu8;
   2008  1.1  christos 
   2009  1.1  christos 	case O (O_ADD, SW):		/* add.w */
   2010  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   2011  1.1  christos 	    goto end;
   2012  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   2013  1.1  christos 	    goto end;
   2014  1.1  christos 	  res = rd + ea;
   2015  1.1  christos 	  goto alu16;
   2016  1.1  christos 
   2017  1.1  christos 	case O (O_ADD, SL):		/* add.l */
   2018  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   2019  1.1  christos 	    goto end;
   2020  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   2021  1.1  christos 	    goto end;
   2022  1.1  christos 	  res = rd + ea;
   2023  1.1  christos 	  goto alu32;
   2024  1.1  christos 
   2025  1.1  christos 	case O (O_AND, SB):		/* and.b */
   2026  1.1  christos 	  /* Fetch rd and ea.  */
   2027  1.7  christos 	  if (fetch2 (sd, &code->dst, &rd) || fetch (sd, &code->src, &ea))
   2028  1.1  christos 	    goto end;
   2029  1.1  christos 	  res = rd & ea;
   2030  1.1  christos 	  goto log8;
   2031  1.1  christos 
   2032  1.1  christos 	case O (O_AND, SW):		/* and.w */
   2033  1.1  christos 	  /* Fetch rd and ea.  */
   2034  1.1  christos 	  if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
   2035  1.1  christos 	    goto end;
   2036  1.1  christos 	  res = rd & ea;
   2037  1.1  christos 	  goto log16;
   2038  1.1  christos 
   2039  1.1  christos 	case O (O_AND, SL):		/* and.l */
   2040  1.1  christos 	  /* Fetch rd and ea.  */
   2041  1.1  christos 	  if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
   2042  1.1  christos 	    goto end;
   2043  1.1  christos 	  res = rd & ea;
   2044  1.1  christos 	  goto log32;
   2045  1.1  christos 
   2046  1.1  christos 	case O (O_OR, SB):		/* or.b */
   2047  1.1  christos 	  /* Fetch rd and ea.  */
   2048  1.7  christos 	  if (fetch2 (sd, &code->dst, &rd) || fetch (sd, &code->src, &ea))
   2049  1.1  christos 	    goto end;
   2050  1.1  christos 	  res = rd | ea;
   2051  1.1  christos 	  goto log8;
   2052  1.1  christos 
   2053  1.1  christos 	case O (O_OR, SW):		/* or.w */
   2054  1.1  christos 	  /* Fetch rd and ea.  */
   2055  1.1  christos 	  if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
   2056  1.1  christos 	    goto end;
   2057  1.1  christos 	  res = rd | ea;
   2058  1.1  christos 	  goto log16;
   2059  1.1  christos 
   2060  1.1  christos 	case O (O_OR, SL):		/* or.l */
   2061  1.1  christos 	  /* Fetch rd and ea.  */
   2062  1.1  christos 	  if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
   2063  1.1  christos 	    goto end;
   2064  1.1  christos 	  res = rd | ea;
   2065  1.1  christos 	  goto log32;
   2066  1.1  christos 
   2067  1.1  christos 	case O (O_XOR, SB):		/* xor.b */
   2068  1.1  christos 	  /* Fetch rd and ea.  */
   2069  1.1  christos 	  if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
   2070  1.1  christos 	    goto end;
   2071  1.1  christos 	  res = rd ^ ea;
   2072  1.1  christos 	  goto log8;
   2073  1.1  christos 
   2074  1.1  christos 	case O (O_XOR, SW):		/* xor.w */
   2075  1.1  christos 	  /* Fetch rd and ea.  */
   2076  1.1  christos 	  if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
   2077  1.1  christos 	    goto end;
   2078  1.1  christos 	  res = rd ^ ea;
   2079  1.1  christos 	  goto log16;
   2080  1.1  christos 
   2081  1.1  christos 	case O (O_XOR, SL):		/* xor.l */
   2082  1.1  christos 	  /* Fetch rd and ea.  */
   2083  1.1  christos 	  if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
   2084  1.1  christos 	    goto end;
   2085  1.1  christos 	  res = rd ^ ea;
   2086  1.1  christos 	  goto log32;
   2087  1.1  christos 
   2088  1.1  christos 	case O (O_MOV, SB):
   2089  1.1  christos 	  if (fetch (sd, &code->src, &res))
   2090  1.1  christos 	    goto end;
   2091  1.1  christos 	  if (store (sd, &code->dst, res))
   2092  1.1  christos 	    goto end;
   2093  1.1  christos 	  goto just_flags_log8;
   2094  1.1  christos 	case O (O_MOV, SW):
   2095  1.1  christos 	  if (fetch (sd, &code->src, &res))
   2096  1.1  christos 	    goto end;
   2097  1.1  christos 	  if (store (sd, &code->dst, res))
   2098  1.1  christos 	    goto end;
   2099  1.1  christos 	  goto just_flags_log16;
   2100  1.1  christos 	case O (O_MOV, SL):
   2101  1.1  christos 	  if (fetch (sd, &code->src, &res))
   2102  1.1  christos 	    goto end;
   2103  1.1  christos 	  if (store (sd, &code->dst, res))
   2104  1.1  christos 	    goto end;
   2105  1.1  christos 	  goto just_flags_log32;
   2106  1.1  christos 
   2107  1.1  christos 	case O (O_MOVMD, SB):		/* movmd.b */
   2108  1.1  christos 	  ea = GET_W_REG (4);
   2109  1.1  christos 	  if (ea == 0)
   2110  1.1  christos 	    ea = 0x10000;
   2111  1.1  christos 
   2112  1.1  christos 	  while (ea--)
   2113  1.1  christos 	    {
   2114  1.1  christos 	      rd = GET_MEMORY_B (GET_L_REG (5));
   2115  1.1  christos 	      SET_MEMORY_B (GET_L_REG (6), rd);
   2116  1.1  christos 	      SET_L_REG (5, GET_L_REG (5) + 1);
   2117  1.1  christos 	      SET_L_REG (6, GET_L_REG (6) + 1);
   2118  1.1  christos 	      SET_W_REG (4, ea);
   2119  1.1  christos 	    }
   2120  1.1  christos 	  goto next;
   2121  1.1  christos 
   2122  1.1  christos 	case O (O_MOVMD, SW):		/* movmd.w */
   2123  1.1  christos 	  ea = GET_W_REG (4);
   2124  1.1  christos 	  if (ea == 0)
   2125  1.1  christos 	    ea = 0x10000;
   2126  1.1  christos 
   2127  1.1  christos 	  while (ea--)
   2128  1.1  christos 	    {
   2129  1.1  christos 	      rd = GET_MEMORY_W (GET_L_REG (5));
   2130  1.1  christos 	      SET_MEMORY_W (GET_L_REG (6), rd);
   2131  1.1  christos 	      SET_L_REG (5, GET_L_REG (5) + 2);
   2132  1.1  christos 	      SET_L_REG (6, GET_L_REG (6) + 2);
   2133  1.1  christos 	      SET_W_REG (4, ea);
   2134  1.1  christos 	    }
   2135  1.1  christos 	  goto next;
   2136  1.1  christos 
   2137  1.1  christos 	case O (O_MOVMD, SL):		/* movmd.l */
   2138  1.1  christos 	  ea = GET_W_REG (4);
   2139  1.1  christos 	  if (ea == 0)
   2140  1.1  christos 	    ea = 0x10000;
   2141  1.1  christos 
   2142  1.1  christos 	  while (ea--)
   2143  1.1  christos 	    {
   2144  1.1  christos 	      rd = GET_MEMORY_L (GET_L_REG (5));
   2145  1.1  christos 	      SET_MEMORY_L (GET_L_REG (6), rd);
   2146  1.1  christos 	      SET_L_REG (5, GET_L_REG (5) + 4);
   2147  1.1  christos 	      SET_L_REG (6, GET_L_REG (6) + 4);
   2148  1.1  christos 	      SET_W_REG (4, ea);
   2149  1.1  christos 	    }
   2150  1.1  christos 	  goto next;
   2151  1.1  christos 
   2152  1.1  christos 	case O (O_MOVSD, SB):		/* movsd.b */
   2153  1.1  christos 	  /* This instruction implements strncpy, with a conditional branch.
   2154  1.1  christos 	     r4 contains n, r5 contains src, and r6 contains dst.
   2155  1.1  christos 	     The 16-bit displacement operand is added to the pc
   2156  1.1  christos 	     if and only if the end of string is reached before
   2157  1.1  christos 	     n bytes are transferred.  */
   2158  1.1  christos 
   2159  1.1  christos 	  ea = GET_L_REG (4) & 0xffff;
   2160  1.1  christos 	  if (ea == 0)
   2161  1.1  christos 	    ea = 0x10000;
   2162  1.1  christos 
   2163  1.1  christos 	  while (ea--)
   2164  1.1  christos 	    {
   2165  1.1  christos 	      rd = GET_MEMORY_B (GET_L_REG (5));
   2166  1.1  christos 	      SET_MEMORY_B (GET_L_REG (6), rd);
   2167  1.1  christos 	      SET_L_REG (5, GET_L_REG (5) + 1);
   2168  1.1  christos 	      SET_L_REG (6, GET_L_REG (6) + 1);
   2169  1.1  christos 	      SET_W_REG (4, ea);
   2170  1.1  christos 	      if (rd == 0)
   2171  1.1  christos 		goto condtrue;
   2172  1.1  christos 	    }
   2173  1.1  christos 	  goto next;
   2174  1.1  christos 
   2175  1.1  christos 	case O (O_EEPMOV, SB):		/* eepmov.b */
   2176  1.1  christos 	case O (O_EEPMOV, SW):		/* eepmov.w */
   2177  1.1  christos 	  if (h8300hmode || h8300smode)
   2178  1.1  christos 	    {
   2179  1.1  christos 	      register unsigned char *_src, *_dst;
   2180  1.1  christos 	      unsigned int count = ((code->opcode == O (O_EEPMOV, SW))
   2181  1.7  christos 				    ? h8_get_reg (cpu, R4_REGNUM) & 0xffff
   2182  1.7  christos 				    : h8_get_reg (cpu, R4_REGNUM) & 0xff);
   2183  1.1  christos 
   2184  1.7  christos 	      _src = h8_get_memory_buf (cpu) + h8_get_reg (cpu, R5_REGNUM);
   2185  1.7  christos 	      if ((_src + count) >= (h8_get_memory_buf (cpu) + memory_size))
   2186  1.7  christos 		goto illegal;
   2187  1.7  christos 	      _dst = h8_get_memory_buf (cpu) + h8_get_reg (cpu, R6_REGNUM);
   2188  1.7  christos 	      if ((_dst + count) >= (h8_get_memory_buf (cpu) + memory_size))
   2189  1.7  christos 		goto illegal;
   2190  1.1  christos 	      memcpy (_dst, _src, count);
   2191  1.1  christos 
   2192  1.7  christos 	      h8_set_reg (cpu, R5_REGNUM, h8_get_reg (cpu, R5_REGNUM) + count);
   2193  1.7  christos 	      h8_set_reg (cpu, R6_REGNUM, h8_get_reg (cpu, R6_REGNUM) + count);
   2194  1.7  christos 	      h8_set_reg (cpu, R4_REGNUM, h8_get_reg (cpu, R4_REGNUM) &
   2195  1.1  christos 			  ((code->opcode == O (O_EEPMOV, SW))
   2196  1.1  christos 			  ? (~0xffff) : (~0xff)));
   2197  1.1  christos 	      cycles += 2 * count;
   2198  1.1  christos 	      goto next;
   2199  1.1  christos 	    }
   2200  1.1  christos 	  goto illegal;
   2201  1.1  christos 
   2202  1.1  christos 	case O (O_ADDS, SL):		/* adds (.l) */
   2203  1.1  christos 	  /* FIXME fetch.
   2204  1.1  christos 	   * This insn only uses register operands, but still
   2205  1.1  christos 	   * it would be cleaner to use fetch and store...  */
   2206  1.1  christos 	  SET_L_REG (code->dst.reg,
   2207  1.1  christos 		     GET_L_REG (code->dst.reg)
   2208  1.1  christos 		     + code->src.literal);
   2209  1.1  christos 
   2210  1.1  christos 	  goto next;
   2211  1.1  christos 
   2212  1.1  christos 	case O (O_SUBS, SL):		/* subs (.l) */
   2213  1.1  christos 	  /* FIXME fetch.
   2214  1.1  christos 	   * This insn only uses register operands, but still
   2215  1.1  christos 	   * it would be cleaner to use fetch and store...  */
   2216  1.1  christos 	  SET_L_REG (code->dst.reg,
   2217  1.1  christos 		     GET_L_REG (code->dst.reg)
   2218  1.1  christos 		     - code->src.literal);
   2219  1.1  christos 	  goto next;
   2220  1.1  christos 
   2221  1.1  christos 	case O (O_CMP, SB):		/* cmp.b */
   2222  1.1  christos 	  if (fetch (sd, &code->dst, &rd))
   2223  1.1  christos 	    goto end;
   2224  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   2225  1.1  christos 	    goto end;
   2226  1.1  christos 	  ea = -ea;
   2227  1.1  christos 	  res = rd + ea;
   2228  1.1  christos 	  goto just_flags_alu8;
   2229  1.1  christos 
   2230  1.1  christos 	case O (O_CMP, SW):		/* cmp.w */
   2231  1.1  christos 	  if (fetch (sd, &code->dst, &rd))
   2232  1.1  christos 	    goto end;
   2233  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   2234  1.1  christos 	    goto end;
   2235  1.1  christos 	  ea = -ea;
   2236  1.1  christos 	  res = rd + ea;
   2237  1.1  christos 	  goto just_flags_alu16;
   2238  1.1  christos 
   2239  1.1  christos 	case O (O_CMP, SL):		/* cmp.l */
   2240  1.1  christos 	  if (fetch (sd, &code->dst, &rd))
   2241  1.1  christos 	    goto end;
   2242  1.1  christos 	  if (fetch (sd, &code->src, &ea))
   2243  1.1  christos 	    goto end;
   2244  1.1  christos 	  ea = -ea;
   2245  1.1  christos 	  res = rd + ea;
   2246  1.1  christos 	  goto just_flags_alu32;
   2247  1.1  christos 
   2248  1.1  christos 	case O (O_DEC, SB):		/* dec.b */
   2249  1.1  christos 	  /* FIXME fetch.
   2250  1.1  christos 	   * This insn only uses register operands, but still
   2251  1.1  christos 	   * it would be cleaner to use fetch and store...  */
   2252  1.1  christos 	  rd = GET_B_REG (code->src.reg);
   2253  1.1  christos 	  ea = -1;
   2254  1.1  christos 	  res = rd + ea;
   2255  1.1  christos 	  SET_B_REG (code->src.reg, res);
   2256  1.1  christos 	  goto just_flags_inc8;
   2257  1.1  christos 
   2258  1.1  christos 	case O (O_DEC, SW):		/* dec.w */
   2259  1.1  christos 	  /* FIXME fetch.
   2260  1.1  christos 	   * This insn only uses register operands, but still
   2261  1.1  christos 	   * it would be cleaner to use fetch and store...  */
   2262  1.1  christos 	  rd = GET_W_REG (code->dst.reg);
   2263  1.1  christos 	  ea = -code->src.literal;
   2264  1.1  christos 	  res = rd + ea;
   2265  1.1  christos 	  SET_W_REG (code->dst.reg, res);
   2266  1.1  christos 	  goto just_flags_inc16;
   2267  1.1  christos 
   2268  1.1  christos 	case O (O_DEC, SL):		/* dec.l */
   2269  1.1  christos 	  /* FIXME fetch.
   2270  1.1  christos 	   * This insn only uses register operands, but still
   2271  1.1  christos 	   * it would be cleaner to use fetch and store...  */
   2272  1.1  christos 	  rd = GET_L_REG (code->dst.reg);
   2273  1.1  christos 	  ea = -code->src.literal;
   2274  1.1  christos 	  res = rd + ea;
   2275  1.1  christos 	  SET_L_REG (code->dst.reg, res);
   2276  1.1  christos 	  goto just_flags_inc32;
   2277  1.1  christos 
   2278  1.1  christos 	case O (O_INC, SB):		/* inc.b */
   2279  1.1  christos 	  /* FIXME fetch.
   2280  1.1  christos 	   * This insn only uses register operands, but still
   2281  1.1  christos 	   * it would be cleaner to use fetch and store...  */
   2282  1.1  christos 	  rd = GET_B_REG (code->src.reg);
   2283  1.1  christos 	  ea = 1;
   2284  1.1  christos 	  res = rd + ea;
   2285  1.1  christos 	  SET_B_REG (code->src.reg, res);
   2286  1.1  christos 	  goto just_flags_inc8;
   2287  1.1  christos 
   2288  1.1  christos 	case O (O_INC, SW):		/* inc.w */
   2289  1.1  christos 	  /* FIXME fetch.
   2290  1.1  christos 	   * This insn only uses register operands, but still
   2291  1.1  christos 	   * it would be cleaner to use fetch and store...  */
   2292  1.1  christos 	  rd = GET_W_REG (code->dst.reg);
   2293  1.1  christos 	  ea = code->src.literal;
   2294  1.1  christos 	  res = rd + ea;
   2295  1.1  christos 	  SET_W_REG (code->dst.reg, res);
   2296  1.1  christos 	  goto just_flags_inc16;
   2297  1.1  christos 
   2298  1.1  christos 	case O (O_INC, SL):		/* inc.l */
   2299  1.1  christos 	  /* FIXME fetch.
   2300  1.1  christos 	   * This insn only uses register operands, but still
   2301  1.1  christos 	   * it would be cleaner to use fetch and store...  */
   2302  1.1  christos 	  rd = GET_L_REG (code->dst.reg);
   2303  1.1  christos 	  ea = code->src.literal;
   2304  1.1  christos 	  res = rd + ea;
   2305  1.1  christos 	  SET_L_REG (code->dst.reg, res);
   2306  1.1  christos 	  goto just_flags_inc32;
   2307  1.1  christos 
   2308  1.1  christos 	case O (O_LDC, SB):		/* ldc.b */
   2309  1.1  christos 	  if (fetch (sd, &code->src, &res))
   2310  1.1  christos 	    goto end;
   2311  1.1  christos 	  goto setc;
   2312  1.1  christos 
   2313  1.1  christos 	case O (O_LDC, SW):		/* ldc.w */
   2314  1.1  christos 	  if (fetch (sd, &code->src, &res))
   2315  1.1  christos 	    goto end;
   2316  1.1  christos 
   2317  1.1  christos 	  /* Word operand, value from MSB, must be shifted.  */
   2318  1.1  christos 	  res >>= 8;
   2319  1.1  christos 	  goto setc;
   2320  1.1  christos 
   2321  1.1  christos 	case O (O_LDC, SL):		/* ldc.l */
   2322  1.1  christos 	  if (fetch (sd, &code->src, &res))
   2323  1.1  christos 	    goto end;
   2324  1.1  christos 	  switch (code->dst.type) {
   2325  1.1  christos 	  case X (OP_SBR, SL):
   2326  1.7  christos 	    h8_set_sbr (cpu, res);
   2327  1.1  christos 	    break;
   2328  1.1  christos 	  case X (OP_VBR, SL):
   2329  1.7  christos 	    h8_set_vbr (cpu, res);
   2330  1.1  christos 	    break;
   2331  1.1  christos 	  default:
   2332  1.1  christos 	    goto illegal;
   2333  1.1  christos 	  }
   2334  1.1  christos 	  goto next;
   2335  1.1  christos 
   2336  1.1  christos 	case O (O_STC, SW):		/* stc.w */
   2337  1.1  christos 	case O (O_STC, SB):		/* stc.b */
   2338  1.1  christos 	  if (code->src.type == X (OP_CCR, SB))
   2339  1.1  christos 	    {
   2340  1.7  christos 	      BUILDSR (cpu);
   2341  1.7  christos 	      res = h8_get_ccr (cpu);
   2342  1.1  christos 	    }
   2343  1.1  christos 	  else if (code->src.type == X (OP_EXR, SB) && h8300smode)
   2344  1.1  christos 	    {
   2345  1.1  christos 	      if (h8300smode)
   2346  1.7  christos 		h8_set_exr (cpu, (trace << 7) | intMask);
   2347  1.7  christos 	      res = h8_get_exr (cpu);
   2348  1.1  christos 	    }
   2349  1.1  christos 	  else
   2350  1.1  christos 	    goto illegal;
   2351  1.1  christos 
   2352  1.1  christos 	  /* Word operand, value to MSB, must be shifted.  */
   2353  1.1  christos 	  if (code->opcode == X (O_STC, SW))
   2354  1.1  christos 	    res <<= 8;
   2355  1.1  christos 	  if (store (sd, &code->dst, res))
   2356  1.1  christos 	    goto end;
   2357  1.1  christos 	  goto next;
   2358  1.1  christos 	case O (O_STC, SL):		/* stc.l */
   2359  1.1  christos 	  switch (code->src.type) {
   2360  1.1  christos 	  case X (OP_SBR, SL):
   2361  1.7  christos 	    res = h8_get_sbr (cpu);
   2362  1.1  christos 	    break;
   2363  1.1  christos 	  case X (OP_VBR, SL):
   2364  1.7  christos 	    res = h8_get_vbr (cpu);
   2365  1.1  christos 	    break;
   2366  1.1  christos 	  default:
   2367  1.1  christos 	    goto illegal;
   2368  1.1  christos 	  }
   2369  1.1  christos 	  if (store (sd, &code->dst, res))
   2370  1.1  christos 	    goto end;
   2371  1.1  christos 	  goto next;
   2372  1.1  christos 
   2373  1.1  christos 	case O (O_ANDC, SB):		/* andc.b */
   2374  1.1  christos 	  if (code->dst.type == X (OP_CCR, SB))
   2375  1.1  christos 	    {
   2376  1.7  christos 	      BUILDSR (cpu);
   2377  1.7  christos 	      rd = h8_get_ccr (cpu);
   2378  1.1  christos 	    }
   2379  1.1  christos 	  else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
   2380  1.1  christos 	    {
   2381  1.1  christos 	      if (h8300smode)
   2382  1.7  christos 		h8_set_exr (cpu, (trace << 7) | intMask);
   2383  1.7  christos 	      rd = h8_get_exr (cpu);
   2384  1.1  christos 	    }
   2385  1.1  christos 	  else
   2386  1.1  christos 	    goto illegal;
   2387  1.1  christos 	  ea = code->src.literal;
   2388  1.1  christos 	  res = rd & ea;
   2389  1.1  christos 	  goto setc;
   2390  1.1  christos 
   2391  1.1  christos 	case O (O_ORC, SB):		/* orc.b */
   2392  1.1  christos 	  if (code->dst.type == X (OP_CCR, SB))
   2393  1.1  christos 	    {
   2394  1.7  christos 	      BUILDSR (cpu);
   2395  1.7  christos 	      rd = h8_get_ccr (cpu);
   2396  1.1  christos 	    }
   2397  1.1  christos 	  else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
   2398  1.1  christos 	    {
   2399  1.1  christos 	      if (h8300smode)
   2400  1.7  christos 		h8_set_exr (cpu, (trace << 7) | intMask);
   2401  1.7  christos 	      rd = h8_get_exr (cpu);
   2402  1.1  christos 	    }
   2403  1.1  christos 	  else
   2404  1.1  christos 	    goto illegal;
   2405  1.1  christos 	  ea = code->src.literal;
   2406  1.1  christos 	  res = rd | ea;
   2407  1.1  christos 	  goto setc;
   2408  1.1  christos 
   2409  1.1  christos 	case O (O_XORC, SB):		/* xorc.b */
   2410  1.1  christos 	  if (code->dst.type == X (OP_CCR, SB))
   2411  1.1  christos 	    {
   2412  1.7  christos 	      BUILDSR (cpu);
   2413  1.7  christos 	      rd = h8_get_ccr (cpu);
   2414  1.1  christos 	    }
   2415  1.1  christos 	  else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
   2416  1.1  christos 	    {
   2417  1.1  christos 	      if (h8300smode)
   2418  1.7  christos 		h8_set_exr (cpu, (trace << 7) | intMask);
   2419  1.7  christos 	      rd = h8_get_exr (cpu);
   2420  1.1  christos 	    }
   2421  1.1  christos 	  else
   2422  1.1  christos 	    goto illegal;
   2423  1.1  christos 	  ea = code->src.literal;
   2424  1.1  christos 	  res = rd ^ ea;
   2425  1.1  christos 	  goto setc;
   2426  1.1  christos 
   2427  1.1  christos 	case O (O_BRAS, SB):		/* bra/s  */
   2428  1.1  christos 	  /* This is basically an ordinary branch, with a delay slot.  */
   2429  1.1  christos 	  if (fetch (sd, &code->src, &res))
   2430  1.1  christos 	    goto end;
   2431  1.1  christos 
   2432  1.1  christos 	  if ((res & 1) == 0)
   2433  1.1  christos 	    goto illegal;
   2434  1.1  christos 
   2435  1.1  christos 	  res -= 1;
   2436  1.1  christos 
   2437  1.1  christos 	  /* Execution continues at next instruction, but
   2438  1.1  christos 	     delayed_branch is set up for next cycle.  */
   2439  1.7  christos 	  h8_set_delayed_branch (cpu, code->next_pc + res);
   2440  1.1  christos 	  pc = code->next_pc;
   2441  1.1  christos 	  goto end;
   2442  1.1  christos 
   2443  1.1  christos 	case O (O_BRAB, SB):		/* bra rd.b */
   2444  1.1  christos 	case O (O_BRAW, SW):		/* bra rd.w */
   2445  1.1  christos 	case O (O_BRAL, SL):		/* bra erd.l */
   2446  1.1  christos 	  if (fetch (sd, &code->src, &rd))
   2447  1.1  christos 	    goto end;
   2448  1.1  christos 	  switch (OP_SIZE (code->opcode)) {
   2449  1.1  christos 	  case SB:	rd &= 0xff;		break;
   2450  1.1  christos 	  case SW:	rd &= 0xffff;		break;
   2451  1.1  christos 	  case SL:	rd &= 0xffffffff;	break;
   2452  1.1  christos 	  }
   2453  1.1  christos 	  pc = code->next_pc + rd;
   2454  1.1  christos 	  goto end;
   2455  1.1  christos 
   2456  1.1  christos 	case O (O_BRABC, SB):		/* bra/bc, branch if bit clear */
   2457  1.1  christos 	case O (O_BRABS, SB):		/* bra/bs, branch if bit set   */
   2458  1.1  christos 	case O (O_BSRBC, SB):		/* bsr/bc, call   if bit clear */
   2459  1.1  christos 	case O (O_BSRBS, SB):		/* bsr/bs, call   if bit set   */
   2460  1.1  christos 	  if (fetch (sd, &code->dst, &rd) ||
   2461  1.1  christos 	      fetch (sd, &code->src, &bit))
   2462  1.1  christos 	    goto end;
   2463  1.1  christos 
   2464  1.1  christos 	  if (code->opcode == O (O_BRABC, SB) || /* branch if clear */
   2465  1.1  christos 	      code->opcode == O (O_BSRBC, SB))	 /* call   if clear */
   2466  1.1  christos 	    {
   2467  1.1  christos 	      if ((rd & (1 << bit)))		/* no branch */
   2468  1.1  christos 		goto next;
   2469  1.1  christos 	    }
   2470  1.1  christos 	  else					/* branch/call if set */
   2471  1.1  christos 	    {
   2472  1.1  christos 	      if (!(rd & (1 << bit)))		/* no branch */
   2473  1.1  christos 		goto next;
   2474  1.1  christos 	    }
   2475  1.1  christos 
   2476  1.1  christos 	  if (fetch (sd, &code->op3, &res))	/* branch */
   2477  1.1  christos 	    goto end;
   2478  1.1  christos 	  pc = code->next_pc + res;
   2479  1.1  christos 
   2480  1.1  christos 	  if (code->opcode == O (O_BRABC, SB) ||
   2481  1.1  christos 	      code->opcode == O (O_BRABS, SB))	/* branch */
   2482  1.1  christos 	    goto end;
   2483  1.1  christos 	  else					/* call   */
   2484  1.1  christos 	    goto call;
   2485  1.1  christos 
   2486  1.1  christos 	case O (O_BRA, SN):
   2487  1.1  christos 	case O (O_BRA, SL):
   2488  1.1  christos 	case O (O_BRA, SW):
   2489  1.1  christos 	case O (O_BRA, SB):		/* bra, branch always */
   2490  1.1  christos 	  if (1)
   2491  1.1  christos 	    goto condtrue;
   2492  1.1  christos 	  goto next;
   2493  1.1  christos 
   2494  1.1  christos 	case O (O_BRN, SB):		/* brn, ;-/  branch never? */
   2495  1.1  christos 	  if (0)
   2496  1.1  christos 	    goto condtrue;
   2497  1.1  christos 	  goto next;
   2498  1.1  christos 
   2499  1.1  christos 	case O (O_BHI, SB):		/* bhi */
   2500  1.1  christos 	  if ((C || Z) == 0)
   2501  1.1  christos 	    goto condtrue;
   2502  1.1  christos 	  goto next;
   2503  1.1  christos 
   2504  1.1  christos 
   2505  1.1  christos 	case O (O_BLS, SB):		/* bls */
   2506  1.1  christos 	  if ((C || Z))
   2507  1.1  christos 	    goto condtrue;
   2508  1.1  christos 	  goto next;
   2509  1.1  christos 
   2510  1.1  christos 	case O (O_BCS, SB):		/* bcs, branch if carry set */
   2511  1.1  christos 	  if ((C == 1))
   2512  1.1  christos 	    goto condtrue;
   2513  1.1  christos 	  goto next;
   2514  1.1  christos 
   2515  1.1  christos 	case O (O_BCC, SB):		/* bcc, branch if carry clear */
   2516  1.1  christos 	  if ((C == 0))
   2517  1.1  christos 	    goto condtrue;
   2518  1.1  christos 	  goto next;
   2519  1.1  christos 
   2520  1.1  christos 	case O (O_BEQ, SB):		/* beq, branch if zero set */
   2521  1.1  christos 	  if (Z)
   2522  1.1  christos 	    goto condtrue;
   2523  1.1  christos 	  goto next;
   2524  1.1  christos 	case O (O_BGT, SB):		/* bgt */
   2525  1.1  christos 	  if (((Z || (N ^ V)) == 0))
   2526  1.1  christos 	    goto condtrue;
   2527  1.1  christos 	  goto next;
   2528  1.1  christos 
   2529  1.1  christos 	case O (O_BLE, SB):		/* ble */
   2530  1.1  christos 	  if (((Z || (N ^ V)) == 1))
   2531  1.1  christos 	    goto condtrue;
   2532  1.1  christos 	  goto next;
   2533  1.1  christos 
   2534  1.1  christos 	case O (O_BGE, SB):		/* bge */
   2535  1.1  christos 	  if ((N ^ V) == 0)
   2536  1.1  christos 	    goto condtrue;
   2537  1.1  christos 	  goto next;
   2538  1.1  christos 	case O (O_BLT, SB):		/* blt */
   2539  1.1  christos 	  if ((N ^ V))
   2540  1.1  christos 	    goto condtrue;
   2541  1.1  christos 	  goto next;
   2542  1.1  christos 	case O (O_BMI, SB):		/* bmi */
   2543  1.1  christos 	  if ((N))
   2544  1.1  christos 	    goto condtrue;
   2545  1.1  christos 	  goto next;
   2546  1.1  christos 	case O (O_BNE, SB):		/* bne, branch if zero clear */
   2547  1.1  christos 	  if ((Z == 0))
   2548  1.1  christos 	    goto condtrue;
   2549  1.1  christos 	  goto next;
   2550  1.1  christos 
   2551  1.1  christos 	case O (O_BPL, SB):		/* bpl */
   2552  1.1  christos 	  if (N == 0)
   2553  1.1  christos 	    goto condtrue;
   2554  1.1  christos 	  goto next;
   2555  1.1  christos 	case O (O_BVC, SB):		/* bvc */
   2556  1.1  christos 	  if ((V == 0))
   2557  1.1  christos 	    goto condtrue;
   2558  1.1  christos 	  goto next;
   2559  1.1  christos 	case O (O_BVS, SB):		/* bvs */
   2560  1.1  christos 	  if ((V == 1))
   2561  1.1  christos 	    goto condtrue;
   2562  1.1  christos 	  goto next;
   2563  1.1  christos 
   2564  1.1  christos 	/* Trap for Command Line setup.  */
   2565  1.1  christos 	case O (O_SYS_CMDLINE, SB):
   2566  1.1  christos 	  {
   2567  1.1  christos 	    int i = 0;		/* Loop counter.  */
   2568  1.1  christos 	    int j = 0;		/* Loop counter.  */
   2569  1.1  christos 	    int ind_arg_len = 0;	/* Length of each argument.  */
   2570  1.1  christos 	    int no_of_args = 0;	/* The no. or cmdline args.  */
   2571  1.1  christos 	    int current_location = 0;	/* Location of string.  */
   2572  1.1  christos 	    int old_sp = 0;	/* The Initial Stack Pointer.  */
   2573  1.1  christos 	    int sp_move = 0;	/* No. of locations by which the stack needs
   2574  1.1  christos 				   to grow.  */
   2575  1.1  christos 	    int new_sp = 0;	/* The final stack pointer location passed
   2576  1.1  christos 				   back.  */
   2577  1.1  christos 	    int *argv_ptrs;	/* Pointers of argv strings to be stored.  */
   2578  1.1  christos 	    int argv_ptrs_location = 0;	/* Location of pointers to cmdline
   2579  1.1  christos 					   args on the stack.  */
   2580  1.1  christos 	    int char_ptr_size = 0;	/* Size of a character pointer on
   2581  1.1  christos 					   target machine.  */
   2582  1.1  christos 	    int addr_cmdline = 0;	/* Memory location where cmdline has
   2583  1.1  christos 					   to be stored.  */
   2584  1.1  christos 	    int size_cmdline = 0;	/* Size of cmdline.  */
   2585  1.1  christos 
   2586  1.1  christos 	    /* Set the address of 256 free locations where command line is
   2587  1.1  christos 	       stored.  */
   2588  1.1  christos 	    addr_cmdline = cmdline_location();
   2589  1.7  christos 	    h8_set_reg (cpu, 0, addr_cmdline);
   2590  1.1  christos 
   2591  1.1  christos 	    /* Counting the no. of commandline arguments.  */
   2592  1.7  christos 	    for (i = 0; h8_get_cmdline_arg (cpu, i) != NULL; i++)
   2593  1.1  christos 	      continue;
   2594  1.1  christos 
   2595  1.1  christos 	    /* No. of arguments in the command line.  */
   2596  1.1  christos 	    no_of_args = i;
   2597  1.1  christos 
   2598  1.1  christos 	    /* Current location is just a temporary variable,which we are
   2599  1.1  christos 	       setting to the point to the start of our commandline string.  */
   2600  1.1  christos 	    current_location = addr_cmdline;
   2601  1.1  christos 
   2602  1.1  christos 	    /* Allocating space for storing pointers of the command line
   2603  1.1  christos 	       arguments.  */
   2604  1.1  christos 	    argv_ptrs = (int *) malloc (sizeof (int) * no_of_args);
   2605  1.1  christos 
   2606  1.1  christos 	    /* Setting char_ptr_size to the sizeof (char *) on the different
   2607  1.1  christos 	       architectures.  */
   2608  1.1  christos 	    if ((h8300hmode || h8300smode) && !h8300_normal_mode)
   2609  1.1  christos 	      {
   2610  1.1  christos 		char_ptr_size = 4;
   2611  1.1  christos 	      }
   2612  1.1  christos 	    else
   2613  1.1  christos 	      {
   2614  1.1  christos 		char_ptr_size = 2;
   2615  1.1  christos 	      }
   2616  1.1  christos 
   2617  1.1  christos 	    for (i = 0; i < no_of_args; i++)
   2618  1.1  christos 	      {
   2619  1.1  christos 		ind_arg_len = 0;
   2620  1.1  christos 
   2621  1.1  christos 		/* The size of the commandline argument.  */
   2622  1.7  christos 		ind_arg_len = strlen (h8_get_cmdline_arg (cpu, i)) + 1;
   2623  1.1  christos 
   2624  1.1  christos 		/* The total size of the command line string.  */
   2625  1.1  christos 		size_cmdline += ind_arg_len;
   2626  1.1  christos 
   2627  1.1  christos 		/* As we have only 256 bytes, we need to provide a graceful
   2628  1.1  christos 		   exit. Anyways, a program using command line arguments
   2629  1.1  christos 		   where we cannot store all the command line arguments
   2630  1.1  christos 		   given may behave unpredictably.  */
   2631  1.1  christos 		if (size_cmdline >= 256)
   2632  1.1  christos 		  {
   2633  1.7  christos 		    h8_set_reg (cpu, 0, 0);
   2634  1.1  christos 		    goto next;
   2635  1.1  christos 		  }
   2636  1.1  christos 		else
   2637  1.1  christos 		  {
   2638  1.1  christos 		    /* current_location points to the memory where the next
   2639  1.1  christos 		       commandline argument is stored.  */
   2640  1.1  christos 		    argv_ptrs[i] = current_location;
   2641  1.1  christos 		    for (j = 0; j < ind_arg_len; j++)
   2642  1.1  christos 		      {
   2643  1.1  christos 			SET_MEMORY_B ((current_location +
   2644  1.1  christos 				       (sizeof (char) * j)),
   2645  1.7  christos 				      *(h8_get_cmdline_arg (cpu, i) +
   2646  1.1  christos 				       sizeof (char) * j));
   2647  1.1  christos 		      }
   2648  1.1  christos 
   2649  1.1  christos 		    /* Setting current_location to the starting of next
   2650  1.1  christos 		       argument.  */
   2651  1.1  christos 		    current_location += ind_arg_len;
   2652  1.1  christos 		  }
   2653  1.1  christos 	      }
   2654  1.1  christos 
   2655  1.1  christos 	    /* This is the original position of the stack pointer.  */
   2656  1.7  christos 	    old_sp = h8_get_reg (cpu, SP_REGNUM);
   2657  1.1  christos 
   2658  1.1  christos 	    /* We need space from the stack to store the pointers to argvs.  */
   2659  1.1  christos 	    /* As we will infringe on the stack, we need to shift the stack
   2660  1.1  christos 	       pointer so that the data is not overwritten. We calculate how
   2661  1.1  christos 	       much space is required.  */
   2662  1.1  christos 	    sp_move = (no_of_args) * (char_ptr_size);
   2663  1.1  christos 
   2664  1.1  christos 	    /* The final position of stack pointer, we have thus taken some
   2665  1.1  christos 	       space from the stack.  */
   2666  1.1  christos 	    new_sp = old_sp - sp_move;
   2667  1.1  christos 
   2668  1.1  christos 	    /* Temporary variable holding value where the argv pointers need
   2669  1.1  christos 	       to be stored.  */
   2670  1.1  christos 	    argv_ptrs_location = new_sp;
   2671  1.1  christos 
   2672  1.1  christos 	    /* The argv pointers are stored at sequential locations. As per
   2673  1.1  christos 	       the H8300 ABI.  */
   2674  1.1  christos 	    for (i = 0; i < no_of_args; i++)
   2675  1.1  christos 	      {
   2676  1.1  christos 		/* Saving the argv pointer.  */
   2677  1.1  christos 		if ((h8300hmode || h8300smode) && !h8300_normal_mode)
   2678  1.1  christos 		  {
   2679  1.1  christos 		    SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
   2680  1.1  christos 		  }
   2681  1.1  christos 		else
   2682  1.1  christos 		  {
   2683  1.1  christos 		    SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]);
   2684  1.1  christos 		  }
   2685  1.1  christos 
   2686  1.1  christos 		/* The next location where the pointer to the next argv
   2687  1.1  christos 		   string has to be stored.  */
   2688  1.1  christos 		argv_ptrs_location += char_ptr_size;
   2689  1.1  christos 	      }
   2690  1.1  christos 
   2691  1.1  christos 	    /* Required by POSIX, Setting 0x0 at the end of the list of argv
   2692  1.1  christos 	       pointers.  */
   2693  1.1  christos 	    if ((h8300hmode || h8300smode) && !h8300_normal_mode)
   2694  1.1  christos 	      {
   2695  1.1  christos 		SET_MEMORY_L (old_sp, 0x0);
   2696  1.1  christos 	      }
   2697  1.1  christos 	    else
   2698  1.1  christos 	      {
   2699  1.1  christos 		SET_MEMORY_W (old_sp, 0x0);
   2700  1.1  christos 	      }
   2701  1.1  christos 
   2702  1.1  christos 	    /* Freeing allocated memory.  */
   2703  1.1  christos 	    free (argv_ptrs);
   2704  1.1  christos 	    for (i = 0; i <= no_of_args; i++)
   2705  1.1  christos 	      {
   2706  1.7  christos 		free (h8_get_cmdline_arg (cpu, i));
   2707  1.1  christos 	      }
   2708  1.7  christos 	    free (h8_get_command_line (cpu));
   2709  1.1  christos 
   2710  1.1  christos 	    /* The no. of argv arguments are returned in Reg 0.  */
   2711  1.7  christos 	    h8_set_reg (cpu, 0, no_of_args);
   2712  1.1  christos 	    /* The Pointer to argv in Register 1.  */
   2713  1.7  christos 	    h8_set_reg (cpu, 1, new_sp);
   2714  1.1  christos 	    /* Setting the stack pointer to the new value.  */
   2715  1.7  christos 	    h8_set_reg (cpu, SP_REGNUM, new_sp);
   2716  1.1  christos 	  }
   2717  1.1  christos 	  goto next;
   2718  1.1  christos 
   2719  1.1  christos 	  /* System call processing starts.  */
   2720  1.1  christos 	case O (O_SYS_OPEN, SB):
   2721  1.1  christos 	  {
   2722  1.1  christos 	    int len = 0;	/* Length of filename.  */
   2723  1.1  christos 	    char *filename;	/* Filename would go here.  */
   2724  1.1  christos 	    char temp_char;	/* Temporary character */
   2725  1.1  christos 	    int mode = 0;	/* Mode bits for the file.  */
   2726  1.1  christos 	    int open_return;	/* Return value of open, file descriptor.  */
   2727  1.1  christos 	    int i;		/* Loop counter */
   2728  1.1  christos 	    int filename_ptr;	/* Pointer to filename in cpu memory.  */
   2729  1.1  christos 
   2730  1.1  christos 	    /* Setting filename_ptr to first argument of open,  */
   2731  1.1  christos 	    /* and trying to get mode.  */
   2732  1.1  christos 	    if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
   2733  1.1  christos 	      {
   2734  1.1  christos 		filename_ptr = GET_L_REG (0);
   2735  1.7  christos 		mode = GET_MEMORY_L (h8_get_reg (cpu, SP_REGNUM) + 4);
   2736  1.1  christos 	      }
   2737  1.1  christos 	    else
   2738  1.1  christos 	      {
   2739  1.1  christos 		filename_ptr = GET_W_REG (0);
   2740  1.7  christos 		mode = GET_MEMORY_W (h8_get_reg (cpu, SP_REGNUM) + 2);
   2741  1.1  christos 	      }
   2742  1.1  christos 
   2743  1.1  christos 	    /* Trying to find the length of the filename.  */
   2744  1.7  christos 	    temp_char = GET_MEMORY_B (h8_get_reg (cpu, 0));
   2745  1.1  christos 
   2746  1.1  christos 	    len = 1;
   2747  1.1  christos 	    while (temp_char != '\0')
   2748  1.1  christos 	      {
   2749  1.1  christos 		temp_char = GET_MEMORY_B (filename_ptr + len);
   2750  1.1  christos 		len++;
   2751  1.1  christos 	      }
   2752  1.1  christos 
   2753  1.1  christos 	    /* Allocating space for the filename.  */
   2754  1.1  christos 	    filename = (char *) malloc (sizeof (char) * len);
   2755  1.1  christos 
   2756  1.1  christos 	    /* String copying the filename from memory.  */
   2757  1.1  christos 	    for (i = 0; i < len; i++)
   2758  1.1  christos 	      {
   2759  1.1  christos 		temp_char = GET_MEMORY_B (filename_ptr + i);
   2760  1.1  christos 		filename[i] = temp_char;
   2761  1.1  christos 	      }
   2762  1.1  christos 
   2763  1.1  christos 	    /* Callback to open and return the file descriptor.  */
   2764  1.1  christos 	    open_return = sim_callback->open (sim_callback, filename, mode);
   2765  1.1  christos 
   2766  1.1  christos 	    /* Return value in register 0.  */
   2767  1.7  christos 	    h8_set_reg (cpu, 0, open_return);
   2768  1.1  christos 
   2769  1.1  christos 	    /* Freeing memory used for filename. */
   2770  1.1  christos 	    free (filename);
   2771  1.1  christos 	  }
   2772  1.1  christos 	  goto next;
   2773  1.1  christos 
   2774  1.1  christos 	case O (O_SYS_READ, SB):
   2775  1.1  christos 	  {
   2776  1.1  christos 	    char *char_ptr;	/* Where characters read would be stored.  */
   2777  1.1  christos 	    int fd;		/* File descriptor */
   2778  1.1  christos 	    int buf_size;	/* BUF_SIZE parameter in read.  */
   2779  1.1  christos 	    int i = 0;		/* Temporary Loop counter */
   2780  1.1  christos 	    int read_return = 0;	/* Return value from callback to
   2781  1.1  christos 					   read.  */
   2782  1.1  christos 
   2783  1.1  christos 	    fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
   2784  1.1  christos 	    buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
   2785  1.1  christos 
   2786  1.1  christos 	    char_ptr = (char *) malloc (sizeof (char) * buf_size);
   2787  1.1  christos 
   2788  1.1  christos 	    /* Callback to read and return the no. of characters read.  */
   2789  1.1  christos 	    read_return =
   2790  1.1  christos 	      sim_callback->read (sim_callback, fd, char_ptr, buf_size);
   2791  1.1  christos 
   2792  1.1  christos 	    /* The characters read are stored in cpu memory.  */
   2793  1.1  christos 	    for (i = 0; i < buf_size; i++)
   2794  1.1  christos 	      {
   2795  1.7  christos 		SET_MEMORY_B ((h8_get_reg (cpu, 1) + (sizeof (char) * i)),
   2796  1.1  christos 			      *(char_ptr + (sizeof (char) * i)));
   2797  1.1  christos 	      }
   2798  1.1  christos 
   2799  1.1  christos 	    /* Return value in Register 0.  */
   2800  1.7  christos 	    h8_set_reg (cpu, 0, read_return);
   2801  1.1  christos 
   2802  1.1  christos 	    /* Freeing memory used as buffer.  */
   2803  1.1  christos 	    free (char_ptr);
   2804  1.1  christos 	  }
   2805  1.1  christos 	  goto next;
   2806  1.1  christos 
   2807  1.1  christos 	case O (O_SYS_WRITE, SB):
   2808  1.1  christos 	  {
   2809  1.1  christos 	    int fd;		/* File descriptor */
   2810  1.1  christos 	    char temp_char;	/* Temporary character */
   2811  1.1  christos 	    int len;		/* Length of write, Parameter II to write.  */
   2812  1.1  christos 	    int char_ptr;	/* Character Pointer, Parameter I of write.  */
   2813  1.1  christos 	    char *ptr;		/* Where characters to be written are stored.
   2814  1.1  christos 				 */
   2815  1.1  christos 	    int write_return;	/* Return value from callback to write.  */
   2816  1.1  christos 	    int i = 0;		/* Loop counter */
   2817  1.1  christos 
   2818  1.1  christos 	    fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
   2819  1.1  christos 	    char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
   2820  1.1  christos 	    len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
   2821  1.1  christos 
   2822  1.1  christos 	    /* Allocating space for the characters to be written.  */
   2823  1.1  christos 	    ptr = (char *) malloc (sizeof (char) * len);
   2824  1.1  christos 
   2825  1.1  christos 	    /* Fetching the characters from cpu memory.  */
   2826  1.1  christos 	    for (i = 0; i < len; i++)
   2827  1.1  christos 	      {
   2828  1.1  christos 		temp_char = GET_MEMORY_B (char_ptr + i);
   2829  1.1  christos 		ptr[i] = temp_char;
   2830  1.1  christos 	      }
   2831  1.1  christos 
   2832  1.1  christos 	    /* Callback write and return the no. of characters written.  */
   2833  1.1  christos 	    write_return = sim_callback->write (sim_callback, fd, ptr, len);
   2834  1.1  christos 
   2835  1.1  christos 	    /* Return value in Register 0.  */
   2836  1.7  christos 	    h8_set_reg (cpu, 0, write_return);
   2837  1.1  christos 
   2838  1.1  christos 	    /* Freeing memory used as buffer.  */
   2839  1.1  christos 	    free (ptr);
   2840  1.1  christos 	  }
   2841  1.1  christos 	  goto next;
   2842  1.1  christos 
   2843  1.1  christos 	case O (O_SYS_LSEEK, SB):
   2844  1.1  christos 	  {
   2845  1.1  christos 	    int fd;		/* File descriptor */
   2846  1.1  christos 	    int offset;		/* Offset */
   2847  1.1  christos 	    int origin;		/* Origin */
   2848  1.1  christos 	    int lseek_return;	/* Return value from callback to lseek.  */
   2849  1.1  christos 
   2850  1.1  christos 	    fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
   2851  1.1  christos 	    offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
   2852  1.1  christos 	    origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
   2853  1.1  christos 
   2854  1.1  christos 	    /* Callback lseek and return offset.  */
   2855  1.1  christos 	    lseek_return =
   2856  1.1  christos 	      sim_callback->lseek (sim_callback, fd, offset, origin);
   2857  1.1  christos 
   2858  1.1  christos 	    /* Return value in register 0.  */
   2859  1.7  christos 	    h8_set_reg (cpu, 0, lseek_return);
   2860  1.1  christos 	  }
   2861  1.1  christos 	  goto next;
   2862  1.1  christos 
   2863  1.1  christos 	case O (O_SYS_CLOSE, SB):
   2864  1.1  christos 	  {
   2865  1.1  christos 	    int fd;		/* File descriptor */
   2866  1.1  christos 	    int close_return;	/* Return value from callback to close.  */
   2867  1.1  christos 
   2868  1.1  christos 	    fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
   2869  1.1  christos 
   2870  1.1  christos 	    /* Callback close and return.  */
   2871  1.1  christos 	    close_return = sim_callback->close (sim_callback, fd);
   2872  1.1  christos 
   2873  1.1  christos 	    /* Return value in register 0.  */
   2874  1.7  christos 	    h8_set_reg (cpu, 0, close_return);
   2875  1.1  christos 	  }
   2876  1.1  christos 	  goto next;
   2877  1.1  christos 
   2878  1.1  christos 	case O (O_SYS_FSTAT, SB):
   2879  1.1  christos 	  {
   2880  1.1  christos 	    int fd;		/* File descriptor */
   2881  1.1  christos 	    struct stat stat_rec;	/* Stat record */
   2882  1.1  christos 	    int fstat_return;	/* Return value from callback to stat.  */
   2883  1.1  christos 	    int stat_ptr;	/* Pointer to stat record.  */
   2884  1.1  christos 
   2885  1.1  christos 	    fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
   2886  1.1  christos 
   2887  1.1  christos 	    /* Setting stat_ptr to second argument of stat.  */
   2888  1.1  christos 	    stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
   2889  1.1  christos 
   2890  1.1  christos 	    /* Callback stat and return.  */
   2891  1.3  christos 	    fstat_return = sim_callback->to_fstat (sim_callback, fd,
   2892  1.3  christos 						   &stat_rec);
   2893  1.1  christos 
   2894  1.1  christos 	    /* Setting up the stat structure returned.  */
   2895  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
   2896  1.1  christos 	    stat_ptr += 2;
   2897  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
   2898  1.1  christos 	    stat_ptr += 2;
   2899  1.1  christos 	    SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
   2900  1.1  christos 	    stat_ptr += 4;
   2901  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
   2902  1.1  christos 	    stat_ptr += 2;
   2903  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
   2904  1.1  christos 	    stat_ptr += 2;
   2905  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
   2906  1.1  christos 	    stat_ptr += 2;
   2907  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
   2908  1.1  christos 	    stat_ptr += 2;
   2909  1.1  christos 	    SET_MEMORY_L (stat_ptr, stat_rec.st_size);
   2910  1.1  christos 	    stat_ptr += 4;
   2911  1.1  christos 	    SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
   2912  1.1  christos 	    stat_ptr += 8;
   2913  1.1  christos 	    SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
   2914  1.1  christos 	    stat_ptr += 8;
   2915  1.1  christos 	    SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
   2916  1.1  christos 
   2917  1.1  christos 	    /* Return value in register 0.  */
   2918  1.7  christos 	    h8_set_reg (cpu, 0, fstat_return);
   2919  1.1  christos 	  }
   2920  1.1  christos 	  goto next;
   2921  1.1  christos 
   2922  1.1  christos 	case O (O_SYS_STAT, SB):
   2923  1.1  christos 	  {
   2924  1.1  christos 	    int len = 0;	/* Length of filename.  */
   2925  1.1  christos 	    char *filename;	/* Filename would go here.  */
   2926  1.1  christos 	    char temp_char;	/* Temporary character */
   2927  1.1  christos 	    int filename_ptr;	/* Pointer to filename in cpu memory.  */
   2928  1.1  christos 	    struct stat stat_rec;	/* Stat record */
   2929  1.1  christos 	    int stat_return;	/* Return value from callback to stat */
   2930  1.1  christos 	    int stat_ptr;	/* Pointer to stat record.  */
   2931  1.1  christos 	    int i = 0;		/* Loop Counter */
   2932  1.1  christos 
   2933  1.1  christos 	    /* Setting filename_ptr to first argument of open.  */
   2934  1.1  christos 	    filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
   2935  1.1  christos 
   2936  1.1  christos 	    /* Trying to find the length of the filename.  */
   2937  1.7  christos 	    temp_char = GET_MEMORY_B (h8_get_reg (cpu, 0));
   2938  1.1  christos 
   2939  1.1  christos 	    len = 1;
   2940  1.1  christos 	    while (temp_char != '\0')
   2941  1.1  christos 	      {
   2942  1.1  christos 		temp_char = GET_MEMORY_B (filename_ptr + len);
   2943  1.1  christos 		len++;
   2944  1.1  christos 	      }
   2945  1.1  christos 
   2946  1.1  christos 	    /* Allocating space for the filename.  */
   2947  1.1  christos 	    filename = (char *) malloc (sizeof (char) * len);
   2948  1.1  christos 
   2949  1.1  christos 	    /* String copying the filename from memory.  */
   2950  1.1  christos 	    for (i = 0; i < len; i++)
   2951  1.1  christos 	      {
   2952  1.1  christos 		temp_char = GET_MEMORY_B (filename_ptr + i);
   2953  1.1  christos 		filename[i] = temp_char;
   2954  1.1  christos 	      }
   2955  1.1  christos 
   2956  1.1  christos 	    /* Setting stat_ptr to second argument of stat.  */
   2957  1.7  christos 	    /* stat_ptr = h8_get_reg (cpu, 1); */
   2958  1.1  christos 	    stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
   2959  1.1  christos 
   2960  1.1  christos 	    /* Callback stat and return.  */
   2961  1.1  christos 	    stat_return =
   2962  1.3  christos 	      sim_callback->to_stat (sim_callback, filename, &stat_rec);
   2963  1.1  christos 
   2964  1.1  christos 	    /* Freeing memory used for filename.  */
   2965  1.1  christos 	    free (filename);
   2966  1.1  christos 
   2967  1.1  christos 	    /* Setting up the stat structure returned.  */
   2968  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
   2969  1.1  christos 	    stat_ptr += 2;
   2970  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
   2971  1.1  christos 	    stat_ptr += 2;
   2972  1.1  christos 	    SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
   2973  1.1  christos 	    stat_ptr += 4;
   2974  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
   2975  1.1  christos 	    stat_ptr += 2;
   2976  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
   2977  1.1  christos 	    stat_ptr += 2;
   2978  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
   2979  1.1  christos 	    stat_ptr += 2;
   2980  1.1  christos 	    SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
   2981  1.1  christos 	    stat_ptr += 2;
   2982  1.1  christos 	    SET_MEMORY_L (stat_ptr, stat_rec.st_size);
   2983  1.1  christos 	    stat_ptr += 4;
   2984  1.1  christos 	    SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
   2985  1.1  christos 	    stat_ptr += 8;
   2986  1.1  christos 	    SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
   2987  1.1  christos 	    stat_ptr += 8;
   2988  1.1  christos 	    SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
   2989  1.1  christos 
   2990  1.1  christos 	    /* Return value in register 0.  */
   2991  1.7  christos 	    h8_set_reg (cpu, 0, stat_return);
   2992  1.1  christos 	  }
   2993  1.1  christos 	  goto next;
   2994  1.1  christos 	  /* End of system call processing.  */
   2995  1.1  christos 
   2996  1.1  christos 	case O (O_NOT, SB):		/* not.b */
   2997  1.1  christos 	  if (fetch2 (sd, &code->src, &rd))
   2998  1.1  christos 	    goto end;
   2999  1.1  christos 	  rd = ~rd;
   3000  1.1  christos 	  v = 0;
   3001  1.1  christos 	  goto shift8;
   3002  1.1  christos 
   3003  1.1  christos 	case O (O_NOT, SW):		/* not.w */
   3004  1.1  christos 	  if (fetch2 (sd, &code->src, &rd))
   3005  1.1  christos 	    goto end;
   3006  1.1  christos 	  rd = ~rd;
   3007  1.1  christos 	  v = 0;
   3008  1.1  christos 	  goto shift16;
   3009  1.1  christos 
   3010  1.1  christos 	case O (O_NOT, SL):		/* not.l */
   3011  1.1  christos 	  if (fetch2 (sd, &code->src, &rd))
   3012  1.1  christos 	    goto end;
   3013  1.1  christos 	  rd = ~rd;
   3014  1.1  christos 	  v = 0;
   3015  1.1  christos 	  goto shift32;
   3016  1.1  christos 
   3017  1.1  christos 	case O (O_SHLL, SB):	/* shll.b */
   3018  1.1  christos 	case O (O_SHLR, SB):	/* shlr.b */
   3019  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3020  1.1  christos 	    goto end;
   3021  1.1  christos 
   3022  1.1  christos 	  if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
   3023  1.1  christos 	    ea = 1;		/* unary  op */
   3024  1.1  christos 	  else			/* binary op */
   3025  1.1  christos 	    fetch (sd, &code->src, &ea);
   3026  1.1  christos 
   3027  1.1  christos 	  if (code->opcode == O (O_SHLL, SB))
   3028  1.1  christos 	    {
   3029  1.1  christos 	      v = (ea > 8);
   3030  1.1  christos 	      c = rd & (0x80 >> (ea - 1));
   3031  1.1  christos 	      rd <<= ea;
   3032  1.1  christos 	    }
   3033  1.1  christos 	  else
   3034  1.1  christos 	    {
   3035  1.1  christos 	      v = 0;
   3036  1.1  christos 	      c = rd & (1 << (ea - 1));
   3037  1.1  christos 	      rd = (unsigned char) rd >> ea;
   3038  1.1  christos 	    }
   3039  1.1  christos 	  goto shift8;
   3040  1.1  christos 
   3041  1.1  christos 	case O (O_SHLL, SW):	/* shll.w */
   3042  1.1  christos 	case O (O_SHLR, SW):	/* shlr.w */
   3043  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3044  1.1  christos 	    goto end;
   3045  1.1  christos 
   3046  1.1  christos 	  if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
   3047  1.1  christos 	    ea = 1;		/* unary  op */
   3048  1.1  christos 	  else
   3049  1.1  christos 	    fetch (sd, &code->src, &ea);
   3050  1.1  christos 
   3051  1.1  christos 	  if (code->opcode == O (O_SHLL, SW))
   3052  1.1  christos 	    {
   3053  1.1  christos 	      v = (ea > 16);
   3054  1.1  christos 	      c = rd & (0x8000 >> (ea - 1));
   3055  1.1  christos 	      rd <<= ea;
   3056  1.1  christos 	    }
   3057  1.1  christos 	  else
   3058  1.1  christos 	    {
   3059  1.1  christos 	      v = 0;
   3060  1.1  christos 	      c = rd & (1 << (ea - 1));
   3061  1.1  christos 	      rd = (unsigned short) rd >> ea;
   3062  1.1  christos 	    }
   3063  1.1  christos 	  goto shift16;
   3064  1.1  christos 
   3065  1.1  christos 	case O (O_SHLL, SL):	/* shll.l */
   3066  1.1  christos 	case O (O_SHLR, SL):	/* shlr.l */
   3067  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3068  1.1  christos 	    goto end;
   3069  1.1  christos 
   3070  1.1  christos 	  if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
   3071  1.1  christos 	    ea = 1;		/* unary  op */
   3072  1.1  christos 	  else
   3073  1.1  christos 	    fetch (sd, &code->src, &ea);
   3074  1.1  christos 
   3075  1.1  christos 	  if (code->opcode == O (O_SHLL, SL))
   3076  1.1  christos 	    {
   3077  1.1  christos 	      v = (ea > 32);
   3078  1.1  christos 	      c = rd & (0x80000000 >> (ea - 1));
   3079  1.1  christos 	      rd <<= ea;
   3080  1.1  christos 	    }
   3081  1.1  christos 	  else
   3082  1.1  christos 	    {
   3083  1.1  christos 	      v = 0;
   3084  1.1  christos 	      c = rd & (1 << (ea - 1));
   3085  1.1  christos 	      rd = (unsigned int) rd >> ea;
   3086  1.1  christos 	    }
   3087  1.1  christos 	  goto shift32;
   3088  1.1  christos 
   3089  1.1  christos 	case O (O_SHAL, SB):
   3090  1.1  christos 	case O (O_SHAR, SB):
   3091  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3092  1.1  christos 	    goto end;
   3093  1.1  christos 
   3094  1.1  christos 	  if (code->src.type == X (OP_IMM, SB))
   3095  1.1  christos 	    fetch (sd, &code->src, &ea);
   3096  1.1  christos 	  else
   3097  1.1  christos 	    ea = 1;
   3098  1.1  christos 
   3099  1.1  christos 	  if (code->opcode == O (O_SHAL, SB))
   3100  1.1  christos 	    {
   3101  1.1  christos 	      c = rd & (0x80 >> (ea - 1));
   3102  1.1  christos 	      res = rd >> (7 - ea);
   3103  1.1  christos 	      v = ((res & 1) && !(res & 2))
   3104  1.1  christos 		|| (!(res & 1) && (res & 2));
   3105  1.1  christos 	      rd <<= ea;
   3106  1.1  christos 	    }
   3107  1.1  christos 	  else
   3108  1.1  christos 	    {
   3109  1.1  christos 	      c = rd & (1 << (ea - 1));
   3110  1.1  christos 	      v = 0;
   3111  1.1  christos 	      rd = ((signed char) rd) >> ea;
   3112  1.1  christos 	    }
   3113  1.1  christos 	  goto shift8;
   3114  1.1  christos 
   3115  1.1  christos 	case O (O_SHAL, SW):
   3116  1.1  christos 	case O (O_SHAR, SW):
   3117  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3118  1.1  christos 	    goto end;
   3119  1.1  christos 
   3120  1.1  christos 	  if (code->src.type == X (OP_IMM, SW))
   3121  1.1  christos 	    fetch (sd, &code->src, &ea);
   3122  1.1  christos 	  else
   3123  1.1  christos 	    ea = 1;
   3124  1.1  christos 
   3125  1.1  christos 	  if (code->opcode == O (O_SHAL, SW))
   3126  1.1  christos 	    {
   3127  1.1  christos 	      c = rd & (0x8000 >> (ea - 1));
   3128  1.1  christos 	      res = rd >> (15 - ea);
   3129  1.1  christos 	      v = ((res & 1) && !(res & 2))
   3130  1.1  christos 		|| (!(res & 1) && (res & 2));
   3131  1.1  christos 	      rd <<= ea;
   3132  1.1  christos 	    }
   3133  1.1  christos 	  else
   3134  1.1  christos 	    {
   3135  1.1  christos 	      c = rd & (1 << (ea - 1));
   3136  1.1  christos 	      v = 0;
   3137  1.1  christos 	      rd = ((signed short) rd) >> ea;
   3138  1.1  christos 	    }
   3139  1.1  christos 	  goto shift16;
   3140  1.1  christos 
   3141  1.1  christos 	case O (O_SHAL, SL):
   3142  1.1  christos 	case O (O_SHAR, SL):
   3143  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3144  1.1  christos 	    goto end;
   3145  1.1  christos 
   3146  1.1  christos 	  if (code->src.type == X (OP_IMM, SL))
   3147  1.1  christos 	    fetch (sd, &code->src, &ea);
   3148  1.1  christos 	  else
   3149  1.1  christos 	    ea = 1;
   3150  1.1  christos 
   3151  1.1  christos 	  if (code->opcode == O (O_SHAL, SL))
   3152  1.1  christos 	    {
   3153  1.1  christos 	      c = rd & (0x80000000 >> (ea - 1));
   3154  1.1  christos 	      res = rd >> (31 - ea);
   3155  1.1  christos 	      v = ((res & 1) && !(res & 2))
   3156  1.1  christos 		|| (!(res & 1) && (res & 2));
   3157  1.1  christos 	      rd <<= ea;
   3158  1.1  christos 	    }
   3159  1.1  christos 	  else
   3160  1.1  christos 	    {
   3161  1.1  christos 	      c = rd & (1 << (ea - 1));
   3162  1.1  christos 	      v = 0;
   3163  1.1  christos 	      rd = ((signed int) rd) >> ea;
   3164  1.1  christos 	    }
   3165  1.1  christos 	  goto shift32;
   3166  1.1  christos 
   3167  1.1  christos 	case O (O_ROTL, SB):
   3168  1.1  christos 	case O (O_ROTR, SB):
   3169  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3170  1.1  christos 	    goto end;
   3171  1.1  christos 
   3172  1.1  christos 	  if (code->src.type == X (OP_IMM, SB))
   3173  1.1  christos 	    fetch (sd, &code->src, &ea);
   3174  1.1  christos 	  else
   3175  1.1  christos 	    ea = 1;
   3176  1.1  christos 
   3177  1.1  christos 	  while (ea--)
   3178  1.1  christos 	    if (code->opcode == O (O_ROTL, SB))
   3179  1.1  christos 	      {
   3180  1.1  christos 		c = rd & 0x80;
   3181  1.1  christos 		rd <<= 1;
   3182  1.1  christos 		if (c)
   3183  1.1  christos 		  rd |= 1;
   3184  1.1  christos 	      }
   3185  1.1  christos 	    else
   3186  1.1  christos 	      {
   3187  1.1  christos 		c = rd & 1;
   3188  1.1  christos 		rd = ((unsigned char) rd) >> 1;
   3189  1.1  christos 		if (c)
   3190  1.1  christos 		  rd |= 0x80;
   3191  1.1  christos 	      }
   3192  1.1  christos 
   3193  1.1  christos 	  v = 0;
   3194  1.1  christos 	  goto shift8;
   3195  1.1  christos 
   3196  1.1  christos 	case O (O_ROTL, SW):
   3197  1.1  christos 	case O (O_ROTR, SW):
   3198  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3199  1.1  christos 	    goto end;
   3200  1.1  christos 
   3201  1.1  christos 	  if (code->src.type == X (OP_IMM, SW))
   3202  1.1  christos 	    fetch (sd, &code->src, &ea);
   3203  1.1  christos 	  else
   3204  1.1  christos 	    ea = 1;
   3205  1.1  christos 
   3206  1.1  christos 	  while (ea--)
   3207  1.1  christos 	    if (code->opcode == O (O_ROTL, SW))
   3208  1.1  christos 	      {
   3209  1.1  christos 		c = rd & 0x8000;
   3210  1.1  christos 		rd <<= 1;
   3211  1.1  christos 		if (c)
   3212  1.1  christos 		  rd |= 1;
   3213  1.1  christos 	      }
   3214  1.1  christos 	    else
   3215  1.1  christos 	      {
   3216  1.1  christos 		c = rd & 1;
   3217  1.1  christos 		rd = ((unsigned short) rd) >> 1;
   3218  1.1  christos 		if (c)
   3219  1.1  christos 		  rd |= 0x8000;
   3220  1.1  christos 	      }
   3221  1.1  christos 
   3222  1.1  christos 	  v = 0;
   3223  1.1  christos 	  goto shift16;
   3224  1.1  christos 
   3225  1.1  christos 	case O (O_ROTL, SL):
   3226  1.1  christos 	case O (O_ROTR, SL):
   3227  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3228  1.1  christos 	    goto end;
   3229  1.1  christos 
   3230  1.1  christos 	  if (code->src.type == X (OP_IMM, SL))
   3231  1.1  christos 	    fetch (sd, &code->src, &ea);
   3232  1.1  christos 	  else
   3233  1.1  christos 	    ea = 1;
   3234  1.1  christos 
   3235  1.1  christos 	  while (ea--)
   3236  1.1  christos 	    if (code->opcode == O (O_ROTL, SL))
   3237  1.1  christos 	      {
   3238  1.1  christos 		c = rd & 0x80000000;
   3239  1.1  christos 		rd <<= 1;
   3240  1.1  christos 		if (c)
   3241  1.1  christos 		  rd |= 1;
   3242  1.1  christos 	      }
   3243  1.1  christos 	    else
   3244  1.1  christos 	      {
   3245  1.1  christos 		c = rd & 1;
   3246  1.1  christos 		rd = ((unsigned int) rd) >> 1;
   3247  1.1  christos 		if (c)
   3248  1.1  christos 		  rd |= 0x80000000;
   3249  1.1  christos 	      }
   3250  1.1  christos 
   3251  1.1  christos 	  v = 0;
   3252  1.1  christos 	  goto shift32;
   3253  1.1  christos 
   3254  1.1  christos 	case O (O_ROTXL, SB):
   3255  1.1  christos 	case O (O_ROTXR, SB):
   3256  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3257  1.1  christos 	    goto end;
   3258  1.1  christos 
   3259  1.1  christos 	  if (code->src.type == X (OP_IMM, SB))
   3260  1.1  christos 	    fetch (sd, &code->src, &ea);
   3261  1.1  christos 	  else
   3262  1.1  christos 	    ea = 1;
   3263  1.1  christos 
   3264  1.1  christos 	  while (ea--)
   3265  1.1  christos 	    if (code->opcode == O (O_ROTXL, SB))
   3266  1.1  christos 	      {
   3267  1.1  christos 		res = rd & 0x80;
   3268  1.1  christos 		rd <<= 1;
   3269  1.1  christos 		if (C)
   3270  1.1  christos 		  rd |= 1;
   3271  1.1  christos 		c = res;
   3272  1.1  christos 	      }
   3273  1.1  christos 	    else
   3274  1.1  christos 	      {
   3275  1.1  christos 		res = rd & 1;
   3276  1.1  christos 		rd = ((unsigned char) rd) >> 1;
   3277  1.1  christos 		if (C)
   3278  1.1  christos 		  rd |= 0x80;
   3279  1.1  christos 		c = res;
   3280  1.1  christos 	      }
   3281  1.1  christos 
   3282  1.1  christos 	  v = 0;
   3283  1.1  christos 	  goto shift8;
   3284  1.1  christos 
   3285  1.1  christos 	case O (O_ROTXL, SW):
   3286  1.1  christos 	case O (O_ROTXR, SW):
   3287  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3288  1.1  christos 	    goto end;
   3289  1.1  christos 
   3290  1.1  christos 	  if (code->src.type == X (OP_IMM, SW))
   3291  1.1  christos 	    fetch (sd, &code->src, &ea);
   3292  1.1  christos 	  else
   3293  1.1  christos 	    ea = 1;
   3294  1.1  christos 
   3295  1.1  christos 	  while (ea--)
   3296  1.1  christos 	    if (code->opcode == O (O_ROTXL, SW))
   3297  1.1  christos 	      {
   3298  1.1  christos 		res = rd & 0x8000;
   3299  1.1  christos 		rd <<= 1;
   3300  1.1  christos 		if (C)
   3301  1.1  christos 		  rd |= 1;
   3302  1.1  christos 		c = res;
   3303  1.1  christos 	      }
   3304  1.1  christos 	    else
   3305  1.1  christos 	      {
   3306  1.1  christos 		res = rd & 1;
   3307  1.1  christos 		rd = ((unsigned short) rd) >> 1;
   3308  1.1  christos 		if (C)
   3309  1.1  christos 		  rd |= 0x8000;
   3310  1.1  christos 		c = res;
   3311  1.1  christos 	      }
   3312  1.1  christos 
   3313  1.1  christos 	  v = 0;
   3314  1.1  christos 	  goto shift16;
   3315  1.1  christos 
   3316  1.1  christos 	case O (O_ROTXL, SL):
   3317  1.1  christos 	case O (O_ROTXR, SL):
   3318  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   3319  1.1  christos 	    goto end;
   3320  1.1  christos 
   3321  1.1  christos 	  if (code->src.type == X (OP_IMM, SL))
   3322  1.1  christos 	    fetch (sd, &code->src, &ea);
   3323  1.1  christos 	  else
   3324  1.1  christos 	    ea = 1;
   3325  1.1  christos 
   3326  1.1  christos 	  while (ea--)
   3327  1.1  christos 	    if (code->opcode == O (O_ROTXL, SL))
   3328  1.1  christos 	      {
   3329  1.1  christos 		res = rd & 0x80000000;
   3330  1.1  christos 		rd <<= 1;
   3331  1.1  christos 		if (C)
   3332  1.1  christos 		  rd |= 1;
   3333  1.1  christos 		c = res;
   3334  1.1  christos 	      }
   3335  1.1  christos 	    else
   3336  1.1  christos 	      {
   3337  1.1  christos 		res = rd & 1;
   3338  1.1  christos 		rd = ((unsigned int) rd) >> 1;
   3339  1.1  christos 		if (C)
   3340  1.1  christos 		  rd |= 0x80000000;
   3341  1.1  christos 		c = res;
   3342  1.1  christos 	      }
   3343  1.1  christos 
   3344  1.1  christos 	  v = 0;
   3345  1.1  christos 	  goto shift32;
   3346  1.1  christos 
   3347  1.1  christos         case O (O_JMP, SN):
   3348  1.1  christos         case O (O_JMP, SL):
   3349  1.1  christos         case O (O_JMP, SB):		/* jmp */
   3350  1.1  christos         case O (O_JMP, SW):
   3351  1.1  christos 	  fetch (sd, &code->src, &pc);
   3352  1.1  christos 	  goto end;
   3353  1.1  christos 
   3354  1.1  christos 	case O (O_JSR, SN):
   3355  1.1  christos 	case O (O_JSR, SL):
   3356  1.1  christos 	case O (O_JSR, SB):		/* jsr, jump to subroutine */
   3357  1.1  christos 	case O (O_JSR, SW):
   3358  1.1  christos 	  if (fetch (sd, &code->src, &pc))
   3359  1.1  christos 	    goto end;
   3360  1.1  christos 	call:
   3361  1.7  christos 	  tmp = h8_get_reg (cpu, SP_REGNUM);
   3362  1.1  christos 
   3363  1.1  christos 	  if (h8300hmode && !h8300_normal_mode)
   3364  1.1  christos 	    {
   3365  1.1  christos 	      tmp -= 4;
   3366  1.1  christos 	      SET_MEMORY_L (tmp, code->next_pc);
   3367  1.1  christos 	    }
   3368  1.1  christos 	  else
   3369  1.1  christos 	    {
   3370  1.1  christos 	      tmp -= 2;
   3371  1.1  christos 	      SET_MEMORY_W (tmp, code->next_pc);
   3372  1.1  christos 	    }
   3373  1.7  christos 	  h8_set_reg (cpu, SP_REGNUM, tmp);
   3374  1.1  christos 
   3375  1.1  christos 	  goto end;
   3376  1.1  christos 
   3377  1.1  christos 	case O (O_BSR, SW):
   3378  1.1  christos 	case O (O_BSR, SL):
   3379  1.1  christos 	case O (O_BSR, SB):		/* bsr, branch to subroutine */
   3380  1.1  christos 	  if (fetch (sd, &code->src, &res))
   3381  1.1  christos 	    goto end;
   3382  1.1  christos 	  pc = code->next_pc + res;
   3383  1.1  christos 	  goto call;
   3384  1.1  christos 
   3385  1.1  christos 	case O (O_RTE, SN):		/* rte, return from exception */
   3386  1.1  christos 	rte:
   3387  1.1  christos 	  /* Pops exr and ccr before pc -- otherwise identical to rts.  */
   3388  1.7  christos 	  tmp = h8_get_reg (cpu, SP_REGNUM);
   3389  1.1  christos 
   3390  1.1  christos 	  if (h8300smode)			/* pop exr */
   3391  1.1  christos 	    {
   3392  1.7  christos 	      h8_set_exr (cpu, GET_MEMORY_L (tmp));
   3393  1.1  christos 	      tmp += 4;
   3394  1.1  christos 	    }
   3395  1.1  christos 	  if (h8300hmode && !h8300_normal_mode)
   3396  1.1  christos 	    {
   3397  1.7  christos 	      h8_set_ccr (cpu, GET_MEMORY_L (tmp));
   3398  1.1  christos 	      tmp += 4;
   3399  1.1  christos 	      pc = GET_MEMORY_L (tmp);
   3400  1.1  christos 	      tmp += 4;
   3401  1.1  christos 	    }
   3402  1.1  christos 	  else
   3403  1.1  christos 	    {
   3404  1.7  christos 	      h8_set_ccr (cpu, GET_MEMORY_W (tmp));
   3405  1.1  christos 	      tmp += 2;
   3406  1.1  christos 	      pc = GET_MEMORY_W (tmp);
   3407  1.1  christos 	      tmp += 2;
   3408  1.1  christos 	    }
   3409  1.1  christos 
   3410  1.7  christos 	  GETSR (cpu);
   3411  1.7  christos 	  h8_set_reg (cpu, SP_REGNUM, tmp);
   3412  1.1  christos 	  goto end;
   3413  1.1  christos 
   3414  1.1  christos 	case O (O_RTS, SN):		/* rts, return from subroutine */
   3415  1.1  christos 	rts:
   3416  1.7  christos 	  tmp = h8_get_reg (cpu, SP_REGNUM);
   3417  1.1  christos 
   3418  1.1  christos 	  if (h8300hmode && !h8300_normal_mode)
   3419  1.1  christos 	    {
   3420  1.1  christos 	      pc = GET_MEMORY_L (tmp);
   3421  1.1  christos 	      tmp += 4;
   3422  1.1  christos 	    }
   3423  1.1  christos 	  else
   3424  1.1  christos 	    {
   3425  1.1  christos 	      pc = GET_MEMORY_W (tmp);
   3426  1.1  christos 	      tmp += 2;
   3427  1.1  christos 	    }
   3428  1.1  christos 
   3429  1.7  christos 	  h8_set_reg (cpu, SP_REGNUM, tmp);
   3430  1.1  christos 	  goto end;
   3431  1.1  christos 
   3432  1.1  christos 	case O (O_ILL, SB):		/* illegal */
   3433  1.6  christos 	  sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
   3434  1.1  christos 	  goto end;
   3435  1.1  christos 
   3436  1.1  christos 	case O (O_SLEEP, SN):		/* sleep */
   3437  1.1  christos 	  /* Check for magic numbers in r1 and r2.  */
   3438  1.7  christos 	  if ((h8_get_reg (cpu, R1_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC1 &&
   3439  1.7  christos 	      (h8_get_reg (cpu, R2_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC2 &&
   3440  1.7  christos 	      SIM_WIFEXITED (h8_get_reg (cpu, 0)))
   3441  1.1  christos 	    {
   3442  1.1  christos 	      /* This trap comes from _exit, not from gdb.  */
   3443  1.6  christos 	      sim_engine_halt (sd, cpu, NULL, pc, sim_exited,
   3444  1.7  christos 			       SIM_WEXITSTATUS (h8_get_reg (cpu, 0)));
   3445  1.1  christos 	    }
   3446  1.1  christos #if 0
   3447  1.1  christos 	  /* Unfortunately this won't really work, because
   3448  1.1  christos 	     when we take a breakpoint trap, R0 has a "random",
   3449  1.1  christos 	     user-defined value.  Don't see any immediate solution.  */
   3450  1.7  christos 	  else if (SIM_WIFSTOPPED (h8_get_reg (cpu, 0)))
   3451  1.1  christos 	    {
   3452  1.1  christos 	      /* Pass the stop signal up to gdb.  */
   3453  1.6  christos 	      sim_engine_halt (sd, cpu, NULL, pc, sim_stopped,
   3454  1.7  christos 			       SIM_WSTOPSIG (h8_get_reg (cpu, 0)));
   3455  1.1  christos 	    }
   3456  1.1  christos #endif
   3457  1.1  christos 	  else
   3458  1.1  christos 	    {
   3459  1.1  christos 	      /* Treat it as a sigtrap.  */
   3460  1.6  christos 	      sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
   3461  1.1  christos 	    }
   3462  1.1  christos 	  goto end;
   3463  1.1  christos 
   3464  1.1  christos 	case O (O_TRAPA, SB):		/* trapa */
   3465  1.1  christos 	  if (fetch (sd, &code->src, &res))
   3466  1.1  christos    	    goto end;			/* res is vector number.  */
   3467  1.1  christos 
   3468  1.7  christos    	  tmp = h8_get_reg (cpu, SP_REGNUM);
   3469  1.1  christos    	  if(h8300_normal_mode)
   3470  1.1  christos    	    {
   3471  1.1  christos    	      tmp -= 2;
   3472  1.1  christos    	      SET_MEMORY_W (tmp, code->next_pc);
   3473  1.1  christos    	      tmp -= 2;
   3474  1.7  christos    	      SET_MEMORY_W (tmp, h8_get_ccr (cpu));
   3475  1.1  christos    	    }
   3476  1.1  christos    	  else
   3477  1.1  christos    	    {
   3478  1.1  christos    	      tmp -= 4;
   3479  1.1  christos    	      SET_MEMORY_L (tmp, code->next_pc);
   3480  1.1  christos    	      tmp -= 4;
   3481  1.7  christos    	      SET_MEMORY_L (tmp, h8_get_ccr (cpu));
   3482  1.1  christos    	    }
   3483  1.1  christos    	  intMaskBit = 1;
   3484  1.7  christos    	  BUILDSR (cpu);
   3485  1.1  christos 
   3486  1.1  christos 	  if (h8300smode)
   3487  1.1  christos 	    {
   3488  1.1  christos 	      tmp -= 4;
   3489  1.7  christos 	      SET_MEMORY_L (tmp, h8_get_exr (cpu));
   3490  1.1  christos 	    }
   3491  1.1  christos 
   3492  1.7  christos 	  h8_set_reg (cpu, SP_REGNUM, tmp);
   3493  1.1  christos 
   3494  1.1  christos 	  if(h8300_normal_mode)
   3495  1.1  christos 	    pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
   3496  1.1  christos 	  else
   3497  1.1  christos 	    pc = GET_MEMORY_L (0x20 + res * 4);
   3498  1.1  christos 	  goto end;
   3499  1.1  christos 
   3500  1.1  christos 	case O (O_BPT, SN):
   3501  1.6  christos 	  sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
   3502  1.1  christos 	  goto end;
   3503  1.1  christos 
   3504  1.1  christos 	case O (O_BSETEQ, SB):
   3505  1.1  christos 	  if (Z)
   3506  1.1  christos 	    goto bset;
   3507  1.1  christos 	  goto next;
   3508  1.1  christos 
   3509  1.1  christos 	case O (O_BSETNE, SB):
   3510  1.1  christos 	  if (!Z)
   3511  1.1  christos 	    goto bset;
   3512  1.1  christos 	  goto next;
   3513  1.1  christos 
   3514  1.1  christos 	case O (O_BCLREQ, SB):
   3515  1.1  christos 	  if (Z)
   3516  1.1  christos 	    goto bclr;
   3517  1.1  christos 	  goto next;
   3518  1.1  christos 
   3519  1.1  christos 	case O (O_BCLRNE, SB):
   3520  1.1  christos 	  if (!Z)
   3521  1.1  christos 	    goto bclr;
   3522  1.1  christos 	  goto next;
   3523  1.1  christos 
   3524  1.1  christos 	  OBITOP (O_BNOT, 1, 1, ea ^= m);		/* bnot */
   3525  1.1  christos 	  OBITOP (O_BTST, 1, 0, nz = ea & m);		/* btst */
   3526  1.1  christos 	bset:
   3527  1.1  christos 	  OBITOP (O_BSET, 1, 1, ea |= m);		/* bset */
   3528  1.1  christos 	bclr:
   3529  1.1  christos 	  OBITOP (O_BCLR, 1, 1, ea &= ~m);		/* bclr */
   3530  1.1  christos 	  OBITOP (O_BLD, 1, 0, c = ea & m);		/* bld  */
   3531  1.1  christos 	  OBITOP (O_BILD, 1, 0, c = !(ea & m));		/* bild */
   3532  1.1  christos 	  OBITOP (O_BST, 1, 1, ea &= ~m;
   3533  1.1  christos 		  if (C) ea |= m);			/* bst  */
   3534  1.1  christos 	  OBITOP (O_BIST, 1, 1, ea &= ~m;
   3535  1.1  christos 		  if (!C) ea |= m);			/* bist */
   3536  1.1  christos 	  OBITOP (O_BSTZ, 1, 1, ea &= ~m;
   3537  1.1  christos 		  if (Z) ea |= m);			/* bstz */
   3538  1.1  christos 	  OBITOP (O_BISTZ, 1, 1, ea &= ~m;
   3539  1.1  christos 		  if (!Z) ea |= m);			/* bistz */
   3540  1.1  christos 	  OBITOP (O_BAND, 1, 0, c = (ea & m) && C);	/* band */
   3541  1.1  christos 	  OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C);	/* biand */
   3542  1.1  christos 	  OBITOP (O_BOR, 1, 0, c = (ea & m) || C);	/* bor  */
   3543  1.1  christos 	  OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C);	/* bior */
   3544  1.1  christos 	  OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C);	/* bxor */
   3545  1.1  christos 	  OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C);	/* bixor */
   3546  1.1  christos 
   3547  1.1  christos 	case O (O_BFLD, SB):				/* bfld */
   3548  1.1  christos 	  /* bitfield load */
   3549  1.1  christos 	  ea = 0;
   3550  1.1  christos 	  if (fetch (sd, &code->src, &bit))
   3551  1.1  christos 	    goto end;
   3552  1.1  christos 
   3553  1.1  christos 	  if (bit != 0)
   3554  1.1  christos 	    {
   3555  1.1  christos 	      if (fetch (sd, &code->dst, &ea))
   3556  1.1  christos 		goto end;
   3557  1.1  christos 
   3558  1.1  christos 	      ea &= bit;
   3559  1.1  christos 	      while (!(bit & 1))
   3560  1.1  christos 		{
   3561  1.1  christos 		  ea  >>= 1;
   3562  1.1  christos 		  bit >>= 1;
   3563  1.1  christos 		}
   3564  1.1  christos 	    }
   3565  1.1  christos 	  if (store (sd, &code->op3, ea))
   3566  1.1  christos 	    goto end;
   3567  1.1  christos 
   3568  1.1  christos 	  goto next;
   3569  1.1  christos 
   3570  1.1  christos 	case O(O_BFST, SB):			/* bfst */
   3571  1.1  christos 	  /* bitfield store */
   3572  1.1  christos 	  /* NOTE: the imm8 value is in dst, and the ea value
   3573  1.1  christos 	     (which is actually the destination) is in op3.
   3574  1.1  christos 	     It has to be that way, to avoid breaking the assembler.  */
   3575  1.1  christos 
   3576  1.1  christos 	  if (fetch (sd, &code->dst, &bit))	/* imm8 */
   3577  1.1  christos 	    goto end;
   3578  1.1  christos 	  if (bit == 0)				/* noop -- nothing to do.  */
   3579  1.1  christos 	    goto next;
   3580  1.1  christos 
   3581  1.1  christos 	  if (fetch (sd, &code->src, &rd))	/* reg8 src */
   3582  1.1  christos 	    goto end;
   3583  1.1  christos 
   3584  1.1  christos 	  if (fetch2 (sd, &code->op3, &ea))	/* ea dst */
   3585  1.1  christos 	    goto end;
   3586  1.1  christos 
   3587  1.1  christos 	  /* Left-shift the register data into position.  */
   3588  1.1  christos 	  for (tmp = bit; !(tmp & 1); tmp >>= 1)
   3589  1.1  christos 	    rd <<= 1;
   3590  1.1  christos 
   3591  1.1  christos 	  /* Combine it with the neighboring bits.  */
   3592  1.1  christos 	  ea = (ea & ~bit) | (rd & bit);
   3593  1.1  christos 
   3594  1.1  christos 	  /* Put it back.  */
   3595  1.1  christos 	  if (store2 (sd, &code->op3, ea))
   3596  1.1  christos 	    goto end;
   3597  1.1  christos 	  goto next;
   3598  1.1  christos 
   3599  1.1  christos 	case O (O_CLRMAC, SN):		/* clrmac */
   3600  1.7  christos 	  h8_set_mach (cpu, 0);
   3601  1.7  christos 	  h8_set_macl (cpu, 0);
   3602  1.7  christos 	  h8_set_macZ (cpu, 1);
   3603  1.7  christos 	  h8_set_macV (cpu, 0);
   3604  1.7  christos 	  h8_set_macN (cpu, 0);
   3605  1.1  christos 	  goto next;
   3606  1.1  christos 
   3607  1.1  christos 	case O (O_STMAC, SL):		/* stmac, 260 */
   3608  1.1  christos 	  switch (code->src.type) {
   3609  1.1  christos 	  case X (OP_MACH, SL):
   3610  1.7  christos 	    res = h8_get_mach (cpu);
   3611  1.1  christos 	    if (res & 0x200)		/* sign extend */
   3612  1.1  christos 	      res |= 0xfffffc00;
   3613  1.1  christos 	    break;
   3614  1.1  christos 	  case X (OP_MACL, SL):
   3615  1.7  christos 	    res = h8_get_macl (cpu);
   3616  1.1  christos 	    break;
   3617  1.1  christos 	  default:	goto illegal;
   3618  1.1  christos 	  }
   3619  1.7  christos 	  nz = !h8_get_macZ (cpu);
   3620  1.7  christos 	  n = h8_get_macN (cpu);
   3621  1.7  christos 	  v = h8_get_macV (cpu);
   3622  1.1  christos 
   3623  1.1  christos 	  if (store (sd, &code->dst, res))
   3624  1.1  christos 	    goto end;
   3625  1.1  christos 
   3626  1.1  christos 	  goto next;
   3627  1.1  christos 
   3628  1.1  christos 	case O (O_LDMAC, SL):		/* ldmac, 179 */
   3629  1.1  christos 	  if (fetch (sd, &code->src, &rd))
   3630  1.1  christos 	    goto end;
   3631  1.1  christos 
   3632  1.1  christos 	  switch (code->dst.type) {
   3633  1.1  christos 	  case X (OP_MACH, SL):
   3634  1.1  christos 	    rd &= 0x3ff;		/* Truncate to 10 bits */
   3635  1.7  christos 	    h8_set_mach (cpu, rd);
   3636  1.1  christos 	    break;
   3637  1.1  christos 	  case X (OP_MACL, SL):
   3638  1.7  christos 	    h8_set_macl (cpu, rd);
   3639  1.1  christos 	    break;
   3640  1.1  christos 	  default:	goto illegal;
   3641  1.1  christos 	  }
   3642  1.7  christos 	  h8_set_macV (cpu, 0);
   3643  1.1  christos 	  goto next;
   3644  1.1  christos 
   3645  1.1  christos 	case O (O_MAC, SW):
   3646  1.1  christos 	  if (fetch (sd, &code->src, &rd) ||
   3647  1.1  christos 	      fetch (sd, &code->dst, &res))
   3648  1.1  christos 	    goto end;
   3649  1.1  christos 
   3650  1.1  christos 	  /* Ye gods, this is non-portable!
   3651  1.1  christos 	     However, the existing mul/div code is similar.  */
   3652  1.1  christos 	  res = SEXTSHORT (res) * SEXTSHORT (rd);
   3653  1.1  christos 
   3654  1.7  christos 	  if (h8_get_macS (cpu))		/* Saturating mode */
   3655  1.1  christos 	    {
   3656  1.7  christos 	      long long mac = h8_get_macl (cpu);
   3657  1.1  christos 
   3658  1.1  christos 	      if (mac & 0x80000000)		/* sign extend */
   3659  1.1  christos 		mac |= 0xffffffff00000000LL;
   3660  1.1  christos 
   3661  1.1  christos 	      mac += res;
   3662  1.1  christos 	      if (mac > 0x7fffffff || mac < 0xffffffff80000000LL)
   3663  1.7  christos 		h8_set_macV (cpu, 1);
   3664  1.7  christos 	      h8_set_macZ (cpu, (mac == 0));
   3665  1.7  christos 	      h8_set_macN (cpu, (mac  < 0));
   3666  1.7  christos 	      h8_set_macl (cpu, (int) mac);
   3667  1.1  christos 	    }
   3668  1.1  christos 	  else				/* "Less Saturating" mode */
   3669  1.1  christos 	    {
   3670  1.7  christos 	      long long mac = h8_get_mach (cpu);
   3671  1.1  christos 	      mac <<= 32;
   3672  1.7  christos 	      mac += h8_get_macl (cpu);
   3673  1.1  christos 
   3674  1.1  christos 	      if (mac & 0x20000000000LL)	/* sign extend */
   3675  1.1  christos 		mac |= 0xfffffc0000000000LL;
   3676  1.1  christos 
   3677  1.1  christos 	      mac += res;
   3678  1.1  christos 	      if (mac > 0x1ffffffffffLL ||
   3679  1.1  christos 		  mac < (long long) 0xfffffe0000000000LL)
   3680  1.7  christos 		h8_set_macV (cpu, 1);
   3681  1.7  christos 	      h8_set_macZ (cpu, (mac == 0));
   3682  1.7  christos 	      h8_set_macN (cpu, (mac  < 0));
   3683  1.7  christos 	      h8_set_macl (cpu, (int) mac);
   3684  1.1  christos 	      mac >>= 32;
   3685  1.7  christos 	      h8_set_mach (cpu, (int) (mac & 0x3ff));
   3686  1.1  christos 	    }
   3687  1.1  christos 	  goto next;
   3688  1.1  christos 
   3689  1.1  christos 	case O (O_MULS, SW):		/* muls.w */
   3690  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3691  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3692  1.1  christos 	    goto end;
   3693  1.1  christos 
   3694  1.1  christos 	  ea = SEXTSHORT (ea);
   3695  1.1  christos 	  res = SEXTSHORT (ea * SEXTSHORT (rd));
   3696  1.1  christos 
   3697  1.1  christos 	  n  = res & 0x8000;
   3698  1.1  christos 	  nz = res & 0xffff;
   3699  1.1  christos 	  if (store (sd, &code->dst, res))
   3700  1.1  christos 	    goto end;
   3701  1.1  christos 
   3702  1.1  christos 	  goto next;
   3703  1.1  christos 
   3704  1.1  christos 	case O (O_MULS, SL):		/* muls.l */
   3705  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3706  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3707  1.1  christos 	    goto end;
   3708  1.1  christos 
   3709  1.1  christos 	  res = ea * rd;
   3710  1.1  christos 
   3711  1.1  christos 	  n  = res & 0x80000000;
   3712  1.1  christos 	  nz = res & 0xffffffff;
   3713  1.1  christos 	  if (store (sd, &code->dst, res))
   3714  1.1  christos 	    goto end;
   3715  1.1  christos 	  goto next;
   3716  1.1  christos 
   3717  1.1  christos 	case O (O_MULSU, SL):		/* muls/u.l */
   3718  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3719  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3720  1.1  christos 	    goto end;
   3721  1.1  christos 
   3722  1.1  christos 	  /* Compute upper 32 bits of the 64-bit result.  */
   3723  1.1  christos 	  res = (((long long) ea) * ((long long) rd)) >> 32;
   3724  1.1  christos 
   3725  1.1  christos 	  n  = res & 0x80000000;
   3726  1.1  christos 	  nz = res & 0xffffffff;
   3727  1.1  christos 	  if (store (sd, &code->dst, res))
   3728  1.1  christos 	    goto end;
   3729  1.1  christos 	  goto next;
   3730  1.1  christos 
   3731  1.1  christos 	case O (O_MULU, SW):		/* mulu.w */
   3732  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3733  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3734  1.1  christos 	    goto end;
   3735  1.1  christos 
   3736  1.1  christos 	  res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd)));
   3737  1.1  christos 
   3738  1.1  christos 	  /* Don't set Z or N.  */
   3739  1.1  christos 	  if (store (sd, &code->dst, res))
   3740  1.1  christos 	    goto end;
   3741  1.1  christos 
   3742  1.1  christos 	  goto next;
   3743  1.1  christos 
   3744  1.1  christos 	case O (O_MULU, SL):		/* mulu.l */
   3745  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3746  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3747  1.1  christos 	    goto end;
   3748  1.1  christos 
   3749  1.1  christos 	  res = ea * rd;
   3750  1.1  christos 
   3751  1.1  christos 	  /* Don't set Z or N.  */
   3752  1.1  christos 	  if (store (sd, &code->dst, res))
   3753  1.1  christos 	    goto end;
   3754  1.1  christos 
   3755  1.1  christos 	  goto next;
   3756  1.1  christos 
   3757  1.1  christos 	case O (O_MULUU, SL):		/* mulu/u.l */
   3758  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3759  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3760  1.1  christos 	    goto end;
   3761  1.1  christos 
   3762  1.1  christos 	  /* Compute upper 32 bits of the 64-bit result.  */
   3763  1.1  christos 	  res = (((unsigned long long) (unsigned) ea) *
   3764  1.1  christos 		 ((unsigned long long) (unsigned) rd)) >> 32;
   3765  1.1  christos 
   3766  1.1  christos 	  /* Don't set Z or N.  */
   3767  1.1  christos 	  if (store (sd, &code->dst, res))
   3768  1.1  christos 	    goto end;
   3769  1.1  christos 
   3770  1.1  christos 	  goto next;
   3771  1.1  christos 
   3772  1.1  christos 	case O (O_MULXS, SB):		/* mulxs.b */
   3773  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3774  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3775  1.1  christos 	    goto end;
   3776  1.1  christos 
   3777  1.1  christos 	  ea = SEXTCHAR (ea);
   3778  1.1  christos 	  res = ea * SEXTCHAR (rd);
   3779  1.1  christos 
   3780  1.1  christos 	  n  = res & 0x8000;
   3781  1.1  christos 	  nz = res & 0xffff;
   3782  1.1  christos 	  if (store (sd, &code->dst, res))
   3783  1.1  christos 	    goto end;
   3784  1.1  christos 
   3785  1.1  christos 	  goto next;
   3786  1.1  christos 
   3787  1.1  christos 	case O (O_MULXS, SW):		/* mulxs.w */
   3788  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3789  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3790  1.1  christos 	    goto end;
   3791  1.1  christos 
   3792  1.1  christos 	  ea = SEXTSHORT (ea);
   3793  1.1  christos 	  res = ea * SEXTSHORT (rd & 0xffff);
   3794  1.1  christos 
   3795  1.1  christos 	  n  = res & 0x80000000;
   3796  1.1  christos 	  nz = res & 0xffffffff;
   3797  1.1  christos 	  if (store (sd, &code->dst, res))
   3798  1.1  christos 	    goto end;
   3799  1.1  christos 
   3800  1.1  christos 	  goto next;
   3801  1.1  christos 
   3802  1.1  christos 	case O (O_MULXU, SB):		/* mulxu.b */
   3803  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3804  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3805  1.1  christos 	    goto end;
   3806  1.1  christos 
   3807  1.1  christos 	  res = UEXTCHAR (ea) * UEXTCHAR (rd);
   3808  1.1  christos 
   3809  1.1  christos 	  if (store (sd, &code->dst, res))
   3810  1.1  christos 	    goto end;
   3811  1.1  christos 
   3812  1.1  christos 	  goto next;
   3813  1.1  christos 
   3814  1.1  christos 	case O (O_MULXU, SW):		/* mulxu.w */
   3815  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3816  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3817  1.1  christos 	    goto end;
   3818  1.1  christos 
   3819  1.1  christos 	  res = UEXTSHORT (ea) * UEXTSHORT (rd);
   3820  1.1  christos 
   3821  1.1  christos 	  if (store (sd, &code->dst, res))
   3822  1.1  christos 	    goto end;
   3823  1.1  christos 
   3824  1.1  christos 	  goto next;
   3825  1.1  christos 
   3826  1.1  christos 	case O (O_TAS, SB):		/* tas (test and set) */
   3827  1.1  christos 	  if (!h8300sxmode)		/* h8sx can use any register. */
   3828  1.1  christos 	    switch (code->src.reg)
   3829  1.1  christos 	      {
   3830  1.1  christos 	      case R0_REGNUM:
   3831  1.1  christos 	      case R1_REGNUM:
   3832  1.1  christos 	      case R4_REGNUM:
   3833  1.1  christos 	      case R5_REGNUM:
   3834  1.1  christos 		break;
   3835  1.1  christos 	      default:
   3836  1.1  christos 		goto illegal;
   3837  1.1  christos 	      }
   3838  1.1  christos 
   3839  1.1  christos 	  if (fetch (sd, &code->src, &res))
   3840  1.1  christos 	    goto end;
   3841  1.1  christos 	  if (store (sd, &code->src, res | 0x80))
   3842  1.1  christos 	    goto end;
   3843  1.1  christos 
   3844  1.1  christos 	  goto just_flags_log8;
   3845  1.1  christos 
   3846  1.1  christos 	case O (O_DIVU, SW):			/* divu.w */
   3847  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3848  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3849  1.1  christos 	    goto end;
   3850  1.1  christos 
   3851  1.1  christos 	  n  = ea & 0x8000;
   3852  1.1  christos 	  nz = ea & 0xffff;
   3853  1.1  christos 	  if (ea)
   3854  1.1  christos 	    res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea));
   3855  1.1  christos 	  else
   3856  1.1  christos 	    res = 0;
   3857  1.1  christos 
   3858  1.1  christos 	  if (store (sd, &code->dst, res))
   3859  1.1  christos 	    goto end;
   3860  1.1  christos 	  goto next;
   3861  1.1  christos 
   3862  1.1  christos 	case O (O_DIVU, SL):			/* divu.l */
   3863  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3864  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3865  1.1  christos 	    goto end;
   3866  1.1  christos 
   3867  1.1  christos 	  n  = ea & 0x80000000;
   3868  1.1  christos 	  nz = ea & 0xffffffff;
   3869  1.1  christos 	  if (ea)
   3870  1.1  christos 	    res = (unsigned) rd / ea;
   3871  1.1  christos 	  else
   3872  1.1  christos 	    res = 0;
   3873  1.1  christos 
   3874  1.1  christos 	  if (store (sd, &code->dst, res))
   3875  1.1  christos 	    goto end;
   3876  1.1  christos 	  goto next;
   3877  1.1  christos 
   3878  1.1  christos 	case O (O_DIVS, SW):			/* divs.w */
   3879  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3880  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3881  1.1  christos 	    goto end;
   3882  1.1  christos 
   3883  1.1  christos 	  if (ea)
   3884  1.1  christos 	    {
   3885  1.1  christos 	      res = SEXTSHORT (rd) / SEXTSHORT (ea);
   3886  1.1  christos 	      nz  = 1;
   3887  1.1  christos 	    }
   3888  1.1  christos 	  else
   3889  1.1  christos 	    {
   3890  1.1  christos 	      res = 0;
   3891  1.1  christos 	      nz  = 0;
   3892  1.1  christos 	    }
   3893  1.1  christos 
   3894  1.1  christos 	  n = res & 0x8000;
   3895  1.1  christos 	  if (store (sd, &code->dst, res))
   3896  1.1  christos 	    goto end;
   3897  1.1  christos 	  goto next;
   3898  1.1  christos 
   3899  1.1  christos 	case O (O_DIVS, SL):			/* divs.l */
   3900  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3901  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3902  1.1  christos 	    goto end;
   3903  1.1  christos 
   3904  1.1  christos 	  if (ea)
   3905  1.1  christos 	    {
   3906  1.1  christos 	      res = rd / ea;
   3907  1.1  christos 	      nz  = 1;
   3908  1.1  christos 	    }
   3909  1.1  christos 	  else
   3910  1.1  christos 	    {
   3911  1.1  christos 	      res = 0;
   3912  1.1  christos 	      nz  = 0;
   3913  1.1  christos 	    }
   3914  1.1  christos 
   3915  1.1  christos 	  n = res & 0x80000000;
   3916  1.1  christos 	  if (store (sd, &code->dst, res))
   3917  1.1  christos 	    goto end;
   3918  1.1  christos 	  goto next;
   3919  1.1  christos 
   3920  1.1  christos 	case O (O_DIVXU, SB):			/* divxu.b */
   3921  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3922  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3923  1.1  christos 	    goto end;
   3924  1.1  christos 
   3925  1.1  christos 	  rd = UEXTSHORT (rd);
   3926  1.1  christos 	  ea = UEXTCHAR (ea);
   3927  1.1  christos 
   3928  1.1  christos 	  n  = ea & 0x80;
   3929  1.1  christos 	  nz = ea & 0xff;
   3930  1.1  christos 	  if (ea)
   3931  1.1  christos 	    {
   3932  1.1  christos 	      tmp = (unsigned) rd % ea;
   3933  1.1  christos 	      res = (unsigned) rd / ea;
   3934  1.1  christos 	    }
   3935  1.1  christos 	  else
   3936  1.1  christos 	    {
   3937  1.1  christos 	      tmp = 0;
   3938  1.1  christos 	      res = 0;
   3939  1.1  christos 	    }
   3940  1.1  christos 
   3941  1.1  christos 	  if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
   3942  1.1  christos 	    goto end;
   3943  1.1  christos 	  goto next;
   3944  1.1  christos 
   3945  1.1  christos 	case O (O_DIVXU, SW):			/* divxu.w */
   3946  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3947  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3948  1.1  christos 	    goto end;
   3949  1.1  christos 
   3950  1.1  christos 	  ea = UEXTSHORT (ea);
   3951  1.1  christos 
   3952  1.1  christos 	  n  = ea & 0x8000;
   3953  1.1  christos 	  nz = ea & 0xffff;
   3954  1.1  christos 	  if (ea)
   3955  1.1  christos 	    {
   3956  1.1  christos 	      tmp = (unsigned) rd % ea;
   3957  1.1  christos 	      res = (unsigned) rd / ea;
   3958  1.1  christos 	    }
   3959  1.1  christos 	  else
   3960  1.1  christos 	    {
   3961  1.1  christos 	      tmp = 0;
   3962  1.1  christos 	      res = 0;
   3963  1.1  christos 	    }
   3964  1.1  christos 
   3965  1.1  christos 	  if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
   3966  1.1  christos 	    goto end;
   3967  1.1  christos 	  goto next;
   3968  1.1  christos 
   3969  1.1  christos 	case O (O_DIVXS, SB):			/* divxs.b */
   3970  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3971  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3972  1.1  christos 	    goto end;
   3973  1.1  christos 
   3974  1.1  christos 	  rd = SEXTSHORT (rd);
   3975  1.1  christos 	  ea = SEXTCHAR (ea);
   3976  1.1  christos 
   3977  1.1  christos 	  if (ea)
   3978  1.1  christos 	    {
   3979  1.1  christos 	      tmp = (int) rd % (int) ea;
   3980  1.1  christos 	      res = (int) rd / (int) ea;
   3981  1.1  christos 	      nz  = 1;
   3982  1.1  christos 	    }
   3983  1.1  christos 	  else
   3984  1.1  christos 	    {
   3985  1.1  christos 	      tmp = 0;
   3986  1.1  christos 	      res = 0;
   3987  1.1  christos 	      nz  = 0;
   3988  1.1  christos 	    }
   3989  1.1  christos 
   3990  1.1  christos 	  n = res & 0x8000;
   3991  1.1  christos 	  if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
   3992  1.1  christos 	    goto end;
   3993  1.1  christos 	  goto next;
   3994  1.1  christos 
   3995  1.1  christos 	case O (O_DIVXS, SW):			/* divxs.w */
   3996  1.1  christos 	  if (fetch (sd, &code->src, &ea) ||
   3997  1.1  christos 	      fetch (sd, &code->dst, &rd))
   3998  1.1  christos 	    goto end;
   3999  1.1  christos 
   4000  1.1  christos 	  ea = SEXTSHORT (ea);
   4001  1.1  christos 
   4002  1.1  christos 	  if (ea)
   4003  1.1  christos 	    {
   4004  1.1  christos 	      tmp = (int) rd % (int) ea;
   4005  1.1  christos 	      res = (int) rd / (int) ea;
   4006  1.1  christos 	      nz  = 1;
   4007  1.1  christos 	    }
   4008  1.1  christos 	  else
   4009  1.1  christos 	    {
   4010  1.1  christos 	      tmp = 0;
   4011  1.1  christos 	      res = 0;
   4012  1.1  christos 	      nz  = 0;
   4013  1.1  christos 	    }
   4014  1.1  christos 
   4015  1.1  christos 	  n = res & 0x80000000;
   4016  1.1  christos 	  if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
   4017  1.1  christos 	    goto end;
   4018  1.1  christos 	  goto next;
   4019  1.1  christos 
   4020  1.1  christos 	case O (O_EXTS, SW):			/* exts.w, signed extend */
   4021  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   4022  1.1  christos 	    goto end;
   4023  1.1  christos 	  ea = rd & 0x80 ? -256 : 0;
   4024  1.1  christos 	  res = (rd & 0xff) + ea;
   4025  1.1  christos 	  goto log16;
   4026  1.1  christos 
   4027  1.1  christos 	case O (O_EXTS, SL):			/* exts.l, signed extend */
   4028  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   4029  1.1  christos 	    goto end;
   4030  1.1  christos 	  if (code->src.type == X (OP_IMM, SL))
   4031  1.1  christos 	    {
   4032  1.1  christos 	      if (fetch (sd, &code->src, &ea))
   4033  1.1  christos 		goto end;
   4034  1.1  christos 
   4035  1.1  christos 	      if (ea == 2)			/* exts.l #2, nn */
   4036  1.1  christos 		{
   4037  1.1  christos 		  /* Sign-extend from 8-bit to 32-bit.  */
   4038  1.1  christos 		  ea = rd & 0x80 ? -256 : 0;
   4039  1.1  christos 		  res = (rd & 0xff) + ea;
   4040  1.1  christos 		  goto log32;
   4041  1.1  christos 		}
   4042  1.1  christos 	    }
   4043  1.1  christos 	  /* Sign-extend from 16-bit to 32-bit.  */
   4044  1.1  christos 	  ea = rd & 0x8000 ? -65536 : 0;
   4045  1.1  christos 	  res = (rd & 0xffff) + ea;
   4046  1.1  christos 	  goto log32;
   4047  1.1  christos 
   4048  1.1  christos 	case O (O_EXTU, SW):			/* extu.w, unsigned extend */
   4049  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   4050  1.1  christos 	    goto end;
   4051  1.1  christos 	  ea = 0;
   4052  1.1  christos 	  res = (rd & 0xff) + ea;
   4053  1.1  christos 	  goto log16;
   4054  1.1  christos 
   4055  1.1  christos 	case O (O_EXTU, SL):			/* extu.l, unsigned extend */
   4056  1.1  christos 	  if (fetch2 (sd, &code->dst, &rd))
   4057  1.1  christos 	    goto end;
   4058  1.1  christos 	  if (code->src.type == X (OP_IMM, SL))
   4059  1.1  christos 	    {
   4060  1.1  christos 	      if (fetch (sd, &code->src, &ea))
   4061  1.1  christos 		goto end;
   4062  1.1  christos 
   4063  1.1  christos 	      if (ea == 2)			/* extu.l #2, nn */
   4064  1.1  christos 		{
   4065  1.1  christos 		  /* Zero-extend from 8-bit to 32-bit.  */
   4066  1.1  christos 		  ea = 0;
   4067  1.1  christos 		  res = (rd & 0xff) + ea;
   4068  1.1  christos 		  goto log32;
   4069  1.1  christos 		}
   4070  1.1  christos 	    }
   4071  1.1  christos 	  /* Zero-extend from 16-bit to 32-bit.  */
   4072  1.1  christos 	  ea = 0;
   4073  1.1  christos 	  res = (rd & 0xffff) + ea;
   4074  1.1  christos 	  goto log32;
   4075  1.1  christos 
   4076  1.1  christos 	case O (O_NOP, SN):			/* nop */
   4077  1.1  christos 	  goto next;
   4078  1.1  christos 
   4079  1.1  christos 	case O (O_STM, SL):			/* stm, store to memory */
   4080  1.1  christos 	  {
   4081  1.1  christos 	    int nregs, firstreg, i;
   4082  1.1  christos 
   4083  1.1  christos 	    nregs = GET_MEMORY_B (pc + 1);
   4084  1.1  christos 	    nregs >>= 4;
   4085  1.1  christos 	    nregs &= 0xf;
   4086  1.1  christos 	    firstreg = code->src.reg;
   4087  1.1  christos 	    firstreg &= 0xf;
   4088  1.1  christos 	    for (i = firstreg; i <= firstreg + nregs; i++)
   4089  1.1  christos 	      {
   4090  1.7  christos 		h8_set_reg (cpu, SP_REGNUM, h8_get_reg (cpu, SP_REGNUM) - 4);
   4091  1.7  christos 		SET_MEMORY_L (h8_get_reg (cpu, SP_REGNUM), h8_get_reg (cpu, i));
   4092  1.1  christos 	      }
   4093  1.1  christos 	  }
   4094  1.1  christos 	  goto next;
   4095  1.1  christos 
   4096  1.1  christos 	case O (O_LDM, SL):			/* ldm,  load from memory */
   4097  1.1  christos 	case O (O_RTEL, SN):			/* rte/l, ldm plus rte */
   4098  1.1  christos 	case O (O_RTSL, SN):			/* rts/l, ldm plus rts */
   4099  1.1  christos 	  {
   4100  1.1  christos 	    int nregs, firstreg, i;
   4101  1.1  christos 
   4102  1.1  christos 	    nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
   4103  1.1  christos 	    firstreg = code->dst.reg & 0xf;
   4104  1.1  christos 	    for (i = firstreg; i >= firstreg - nregs; i--)
   4105  1.1  christos 	      {
   4106  1.7  christos 		h8_set_reg (cpu, i, GET_MEMORY_L (h8_get_reg (cpu, SP_REGNUM)));
   4107  1.7  christos 		h8_set_reg (cpu, SP_REGNUM, h8_get_reg (cpu, SP_REGNUM) + 4);
   4108  1.1  christos 	      }
   4109  1.1  christos 	  }
   4110  1.1  christos 	  switch (code->opcode) {
   4111  1.1  christos 	  case O (O_RTEL, SN):
   4112  1.1  christos 	    goto rte;
   4113  1.1  christos 	  case O (O_RTSL, SN):
   4114  1.1  christos 	    goto rts;
   4115  1.1  christos 	  case O (O_LDM, SL):
   4116  1.1  christos 	    goto next;
   4117  1.1  christos 	  default:
   4118  1.1  christos 	    goto illegal;
   4119  1.1  christos 	  }
   4120  1.1  christos 
   4121  1.1  christos 	case O (O_DAA, SB):
   4122  1.1  christos 	  /* Decimal Adjust Addition.  This is for BCD arithmetic.  */
   4123  1.1  christos 	  res = GET_B_REG (code->src.reg);	/* FIXME fetch? */
   4124  1.1  christos 	  if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) &&
   4125  1.1  christos 	      !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
   4126  1.7  christos 	    /* Nothing.  */;		/* Value added == 0.  */
   4127  1.1  christos 	  else if (!c && (0  <= (res >>  4) && (res >>  4) <=  8) &&
   4128  1.1  christos 		   !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
   4129  1.1  christos 	    res = res + 0x6;		/* Value added == 6.  */
   4130  1.1  christos 	  else if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) &&
   4131  1.1  christos 		    h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
   4132  1.1  christos 	    res = res + 0x6;		/* Value added == 6.  */
   4133  1.1  christos 	  else if (!c && (10 <= (res >>  4) && (res >>  4) <= 15) &&
   4134  1.1  christos 		   !h && (0  <= (res & 0xf) && (res & 0xf) <=  9))
   4135  1.1  christos 	    res = res + 0x60;		/* Value added == 60.  */
   4136  1.1  christos 	  else if (!c && (9  <= (res >>  4) && (res >>  4) <= 15) &&
   4137  1.1  christos 		   !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
   4138  1.1  christos 	    res = res + 0x66;		/* Value added == 66.  */
   4139  1.1  christos 	  else if (!c && (10 <= (res >>  4) && (res >>  4) <= 15) &&
   4140  1.1  christos 		    h && (0  <= (res & 0xf) && (res & 0xf) <=  3))
   4141  1.1  christos 	    res = res + 0x66;		/* Value added == 66.  */
   4142  1.1  christos 	  else if ( c && (1 <= (res >>  4) && (res >>  4) <= 2) &&
   4143  1.1  christos 		   !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
   4144  1.1  christos 	    res = res + 0x60;		/* Value added == 60.  */
   4145  1.1  christos 	  else if ( c && (1  <= (res >>  4) && (res >>  4) <=  2) &&
   4146  1.1  christos 		   !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
   4147  1.1  christos 	    res = res + 0x66;		/* Value added == 66.  */
   4148  1.1  christos 	  else if (c && (1 <= (res >>  4) && (res >>  4) <= 3) &&
   4149  1.1  christos 		   h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
   4150  1.1  christos 	    res = res + 0x66;		/* Value added == 66.  */
   4151  1.1  christos 
   4152  1.1  christos 	  goto alu8;
   4153  1.1  christos 
   4154  1.1  christos 	case O (O_DAS, SB):
   4155  1.1  christos 	  /* Decimal Adjust Subtraction.  This is for BCD arithmetic.  */
   4156  1.1  christos 	  res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
   4157  1.1  christos 	  if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) &&
   4158  1.1  christos 	      !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
   4159  1.7  christos 	    /* Nothing.  */;		/* Value added == 0.  */
   4160  1.1  christos 	  else if (!c && (0 <= (res >>  4) && (res >>  4) <=  8) &&
   4161  1.1  christos 		    h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
   4162  1.1  christos 	    res = res + 0xfa;		/* Value added == 0xfa.  */
   4163  1.1  christos 	  else if ( c && (7 <= (res >>  4) && (res >>  4) <= 15) &&
   4164  1.1  christos 		   !h && (0 <= (res & 0xf) && (res & 0xf) <=  9))
   4165  1.1  christos 	    res = res + 0xa0;		/* Value added == 0xa0.  */
   4166  1.1  christos 	  else if (c && (6 <= (res >>  4) && (res >>  4) <= 15) &&
   4167  1.1  christos 		   h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
   4168  1.1  christos 	    res = res + 0x9a;		/* Value added == 0x9a.  */
   4169  1.1  christos 
   4170  1.1  christos 	  goto alu8;
   4171  1.1  christos 
   4172  1.1  christos 	default:
   4173  1.1  christos 	illegal:
   4174  1.6  christos 	  sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
   4175  1.1  christos 	  goto end;
   4176  1.1  christos 
   4177  1.1  christos 	}
   4178  1.1  christos 
   4179  1.6  christos       sim_io_printf (sd, "sim_resume: internal error.\n");
   4180  1.6  christos       sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
   4181  1.1  christos       goto end;
   4182  1.1  christos 
   4183  1.1  christos     setc:
   4184  1.1  christos       if (code->dst.type == X (OP_CCR, SB) ||
   4185  1.1  christos 	  code->dst.type == X (OP_CCR, SW))
   4186  1.1  christos 	{
   4187  1.7  christos 	  h8_set_ccr (cpu, res);
   4188  1.7  christos 	  GETSR (cpu);
   4189  1.1  christos 	}
   4190  1.1  christos       else if (h8300smode &&
   4191  1.1  christos 	       (code->dst.type == X (OP_EXR, SB) ||
   4192  1.1  christos 		code->dst.type == X (OP_EXR, SW)))
   4193  1.1  christos 	{
   4194  1.7  christos 	  h8_set_exr (cpu, res);
   4195  1.1  christos 	  if (h8300smode)	/* Get exr.  */
   4196  1.1  christos 	    {
   4197  1.7  christos 	      trace = (h8_get_exr (cpu) >> 7) & 1;
   4198  1.7  christos 	      intMask = h8_get_exr (cpu) & 7;
   4199  1.1  christos 	    }
   4200  1.1  christos 	}
   4201  1.1  christos       else
   4202  1.1  christos 	goto illegal;
   4203  1.1  christos 
   4204  1.1  christos       goto next;
   4205  1.1  christos 
   4206  1.1  christos     condtrue:
   4207  1.1  christos       /* When a branch works */
   4208  1.1  christos       if (fetch (sd, &code->src, &res))
   4209  1.1  christos 	goto end;
   4210  1.1  christos       if (res & 1)		/* bad address */
   4211  1.1  christos 	goto illegal;
   4212  1.1  christos       pc = code->next_pc + res;
   4213  1.1  christos       goto end;
   4214  1.1  christos 
   4215  1.1  christos       /* Set the cond codes from res */
   4216  1.1  christos     bitop:
   4217  1.1  christos 
   4218  1.1  christos       /* Set the flags after an 8 bit inc/dec operation */
   4219  1.1  christos     just_flags_inc8:
   4220  1.1  christos       n = res & 0x80;
   4221  1.1  christos       nz = res & 0xff;
   4222  1.1  christos       v = (rd & 0x7f) == 0x7f;
   4223  1.1  christos       goto next;
   4224  1.1  christos 
   4225  1.1  christos       /* Set the flags after an 16 bit inc/dec operation */
   4226  1.1  christos     just_flags_inc16:
   4227  1.1  christos       n = res & 0x8000;
   4228  1.1  christos       nz = res & 0xffff;
   4229  1.1  christos       v = (rd & 0x7fff) == 0x7fff;
   4230  1.1  christos       goto next;
   4231  1.1  christos 
   4232  1.1  christos       /* Set the flags after an 32 bit inc/dec operation */
   4233  1.1  christos     just_flags_inc32:
   4234  1.1  christos       n = res & 0x80000000;
   4235  1.1  christos       nz = res & 0xffffffff;
   4236  1.1  christos       v = (rd & 0x7fffffff) == 0x7fffffff;
   4237  1.1  christos       goto next;
   4238  1.1  christos 
   4239  1.1  christos     shift8:
   4240  1.1  christos       /* Set flags after an 8 bit shift op, carry,overflow set in insn */
   4241  1.1  christos       n = (rd & 0x80);
   4242  1.1  christos       nz = rd & 0xff;
   4243  1.1  christos       if (store2 (sd, &code->dst, rd))
   4244  1.1  christos 	goto end;
   4245  1.1  christos       goto next;
   4246  1.1  christos 
   4247  1.1  christos     shift16:
   4248  1.1  christos       /* Set flags after an 16 bit shift op, carry,overflow set in insn */
   4249  1.1  christos       n = (rd & 0x8000);
   4250  1.1  christos       nz = rd & 0xffff;
   4251  1.1  christos       if (store2 (sd, &code->dst, rd))
   4252  1.1  christos 	goto end;
   4253  1.1  christos       goto next;
   4254  1.1  christos 
   4255  1.1  christos     shift32:
   4256  1.1  christos       /* Set flags after an 32 bit shift op, carry,overflow set in insn */
   4257  1.1  christos       n = (rd & 0x80000000);
   4258  1.1  christos       nz = rd & 0xffffffff;
   4259  1.1  christos       if (store2 (sd, &code->dst, rd))
   4260  1.1  christos 	goto end;
   4261  1.1  christos       goto next;
   4262  1.1  christos 
   4263  1.1  christos     log32:
   4264  1.1  christos       if (store2 (sd, &code->dst, res))
   4265  1.1  christos 	goto end;
   4266  1.1  christos 
   4267  1.1  christos     just_flags_log32:
   4268  1.1  christos       /* flags after a 32bit logical operation */
   4269  1.1  christos       n = res & 0x80000000;
   4270  1.1  christos       nz = res & 0xffffffff;
   4271  1.1  christos       v = 0;
   4272  1.1  christos       goto next;
   4273  1.1  christos 
   4274  1.1  christos     log16:
   4275  1.1  christos       if (store2 (sd, &code->dst, res))
   4276  1.1  christos 	goto end;
   4277  1.1  christos 
   4278  1.1  christos     just_flags_log16:
   4279  1.1  christos       /* flags after a 16bit logical operation */
   4280  1.1  christos       n = res & 0x8000;
   4281  1.1  christos       nz = res & 0xffff;
   4282  1.1  christos       v = 0;
   4283  1.1  christos       goto next;
   4284  1.1  christos 
   4285  1.1  christos     log8:
   4286  1.1  christos       if (store2 (sd, &code->dst, res))
   4287  1.1  christos 	goto end;
   4288  1.1  christos 
   4289  1.1  christos     just_flags_log8:
   4290  1.1  christos       n = res & 0x80;
   4291  1.1  christos       nz = res & 0xff;
   4292  1.1  christos       v = 0;
   4293  1.1  christos       goto next;
   4294  1.1  christos 
   4295  1.1  christos     alu8:
   4296  1.1  christos       if (store2 (sd, &code->dst, res))
   4297  1.1  christos 	goto end;
   4298  1.1  christos 
   4299  1.1  christos     just_flags_alu8:
   4300  1.1  christos       n = res & 0x80;
   4301  1.1  christos       nz = res & 0xff;
   4302  1.1  christos       c = (res & 0x100);
   4303  1.1  christos       switch (code->opcode / 4)
   4304  1.1  christos 	{
   4305  1.1  christos 	case O_ADD:
   4306  1.1  christos 	case O_ADDX:
   4307  1.1  christos 	  v = ((rd & 0x80) == (ea & 0x80)
   4308  1.1  christos 	       && (rd & 0x80) != (res & 0x80));
   4309  1.1  christos 	  break;
   4310  1.1  christos 	case O_SUB:
   4311  1.1  christos 	case O_SUBX:
   4312  1.1  christos 	case O_CMP:
   4313  1.1  christos 	  v = ((rd & 0x80) != (-ea & 0x80)
   4314  1.1  christos 	       && (rd & 0x80) != (res & 0x80));
   4315  1.1  christos 	  break;
   4316  1.1  christos 	case O_NEG:
   4317  1.1  christos 	  v = (rd == 0x80);
   4318  1.1  christos 	  break;
   4319  1.1  christos 	case O_DAA:
   4320  1.1  christos 	case O_DAS:
   4321  1.1  christos 	  break;	/* No effect on v flag.  */
   4322  1.1  christos 	}
   4323  1.1  christos       goto next;
   4324  1.1  christos 
   4325  1.1  christos     alu16:
   4326  1.1  christos       if (store2 (sd, &code->dst, res))
   4327  1.1  christos 	goto end;
   4328  1.1  christos 
   4329  1.1  christos     just_flags_alu16:
   4330  1.1  christos       n = res & 0x8000;
   4331  1.1  christos       nz = res & 0xffff;
   4332  1.1  christos       c = (res & 0x10000);
   4333  1.1  christos       switch (code->opcode / 4)
   4334  1.1  christos 	{
   4335  1.1  christos 	case O_ADD:
   4336  1.1  christos 	case O_ADDX:
   4337  1.1  christos 	  v = ((rd & 0x8000) == (ea & 0x8000)
   4338  1.1  christos 	       && (rd & 0x8000) != (res & 0x8000));
   4339  1.1  christos 	  break;
   4340  1.1  christos 	case O_SUB:
   4341  1.1  christos 	case O_SUBX:
   4342  1.1  christos 	case O_CMP:
   4343  1.1  christos 	  v = ((rd & 0x8000) != (-ea & 0x8000)
   4344  1.1  christos 	       && (rd & 0x8000) != (res & 0x8000));
   4345  1.1  christos 	  break;
   4346  1.1  christos 	case O_NEG:
   4347  1.1  christos 	  v = (rd == 0x8000);
   4348  1.1  christos 	  break;
   4349  1.1  christos 	}
   4350  1.1  christos       goto next;
   4351  1.1  christos 
   4352  1.1  christos     alu32:
   4353  1.1  christos       if (store2 (sd, &code->dst, res))
   4354  1.1  christos 	goto end;
   4355  1.1  christos 
   4356  1.1  christos     just_flags_alu32:
   4357  1.1  christos       n = res & 0x80000000;
   4358  1.1  christos       nz = res & 0xffffffff;
   4359  1.1  christos       switch (code->opcode / 4)
   4360  1.1  christos 	{
   4361  1.1  christos 	case O_ADD:
   4362  1.1  christos 	case O_ADDX:
   4363  1.1  christos 	  v = ((rd & 0x80000000) == (ea & 0x80000000)
   4364  1.1  christos 	       && (rd & 0x80000000) != (res & 0x80000000));
   4365  1.1  christos 	  c = ((unsigned) res < (unsigned) rd) ||
   4366  1.1  christos 	    ((unsigned) res < (unsigned) ea);
   4367  1.1  christos 	  break;
   4368  1.1  christos 	case O_SUB:
   4369  1.1  christos 	case O_SUBX:
   4370  1.1  christos 	case O_CMP:
   4371  1.1  christos 	  v = ((rd & 0x80000000) != (-ea & 0x80000000)
   4372  1.1  christos 	       && (rd & 0x80000000) != (res & 0x80000000));
   4373  1.1  christos 	  c = (unsigned) rd < (unsigned) -ea;
   4374  1.1  christos 	  break;
   4375  1.1  christos 	case O_NEG:
   4376  1.1  christos 	  v = (rd == 0x80000000);
   4377  1.1  christos 	  c = res != 0;
   4378  1.1  christos 	  break;
   4379  1.1  christos 	}
   4380  1.1  christos       goto next;
   4381  1.1  christos 
   4382  1.1  christos     next:
   4383  1.7  christos       if ((res = h8_get_delayed_branch (cpu)) != 0)
   4384  1.1  christos 	{
   4385  1.1  christos 	  pc = res;
   4386  1.7  christos 	  h8_set_delayed_branch (cpu, 0);
   4387  1.1  christos 	}
   4388  1.1  christos       else
   4389  1.1  christos 	pc = code->next_pc;
   4390  1.1  christos 
   4391  1.6  christos     } while (0);
   4392  1.1  christos 
   4393  1.6  christos  end:
   4394  1.7  christos   h8_set_ticks (cpu, h8_get_ticks (cpu) + get_now () - tick_start);
   4395  1.7  christos   h8_set_cycles (cpu, h8_get_cycles (cpu) + cycles);
   4396  1.7  christos   h8_set_insts (cpu, h8_get_insts (cpu) + insts);
   4397  1.7  christos   cpu_set_pc (cpu, pc);
   4398  1.7  christos   BUILDSR (cpu);
   4399  1.1  christos 
   4400  1.1  christos   if (h8300smode)
   4401  1.7  christos     h8_set_exr (cpu, (trace<<7) | intMask);
   4402  1.1  christos 
   4403  1.7  christos   h8_set_mask (cpu, oldmask);
   4404  1.1  christos }
   4405  1.1  christos 
   4406  1.6  christos void
   4407  1.6  christos sim_engine_run (SIM_DESC sd,
   4408  1.6  christos 		int next_cpu_nr,  /* ignore  */
   4409  1.6  christos 		int nr_cpus,      /* ignore  */
   4410  1.6  christos 		int siggnal)
   4411  1.6  christos {
   4412  1.6  christos   sim_cpu *cpu;
   4413  1.6  christos 
   4414  1.6  christos   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
   4415  1.6  christos 
   4416  1.6  christos   cpu = STATE_CPU (sd, 0);
   4417  1.6  christos 
   4418  1.6  christos   while (1)
   4419  1.6  christos     {
   4420  1.6  christos       step_once (sd, cpu);
   4421  1.6  christos       if (sim_events_tick (sd))
   4422  1.6  christos 	sim_events_process (sd);
   4423  1.6  christos     }
   4424  1.6  christos }
   4425  1.6  christos 
   4426  1.8  christos uint64_t
   4427  1.8  christos sim_write (SIM_DESC sd, uint64_t addr, const void *buffer, uint64_t size)
   4428  1.1  christos {
   4429  1.7  christos   sim_cpu *cpu = STATE_CPU (sd, 0);
   4430  1.1  christos   int i;
   4431  1.7  christos   const unsigned char *data = buffer;
   4432  1.1  christos 
   4433  1.1  christos   init_pointers (sd);
   4434  1.1  christos   if (addr < 0)
   4435  1.1  christos     return 0;
   4436  1.1  christos   for (i = 0; i < size; i++)
   4437  1.1  christos     {
   4438  1.1  christos       if (addr < memory_size)
   4439  1.1  christos 	{
   4440  1.7  christos 	  h8_set_memory (cpu, addr + i, data[i]);
   4441  1.1  christos 	}
   4442  1.1  christos       else
   4443  1.7  christos 	break;
   4444  1.1  christos     }
   4445  1.7  christos   return i;
   4446  1.1  christos }
   4447  1.1  christos 
   4448  1.8  christos uint64_t
   4449  1.8  christos sim_read (SIM_DESC sd, uint64_t addr, void *buffer, uint64_t size)
   4450  1.1  christos {
   4451  1.7  christos   sim_cpu *cpu = STATE_CPU (sd, 0);
   4452  1.7  christos 
   4453  1.1  christos   init_pointers (sd);
   4454  1.1  christos   if (addr < 0)
   4455  1.1  christos     return 0;
   4456  1.7  christos   if (addr + size < memory_size)
   4457  1.7  christos     memcpy (buffer, h8_get_memory_buf (cpu) + addr, size);
   4458  1.1  christos   else
   4459  1.7  christos     return 0;
   4460  1.1  christos   return size;
   4461  1.1  christos }
   4462  1.1  christos 
   4463  1.6  christos static int
   4464  1.7  christos h8300_reg_store (SIM_CPU *cpu, int rn, const void *buf, int length)
   4465  1.1  christos {
   4466  1.7  christos   const unsigned char *value = buf;
   4467  1.1  christos   int longval;
   4468  1.1  christos   int shortval;
   4469  1.1  christos   int intval;
   4470  1.7  christos 
   4471  1.1  christos   longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
   4472  1.1  christos   shortval = (value[0] << 8) | (value[1]);
   4473  1.1  christos   intval = h8300hmode ? longval : shortval;
   4474  1.1  christos 
   4475  1.6  christos   init_pointers (CPU_STATE (cpu));
   4476  1.1  christos   switch (rn)
   4477  1.1  christos     {
   4478  1.1  christos     case PC_REGNUM:
   4479  1.1  christos       if(h8300_normal_mode)
   4480  1.7  christos 	cpu_set_pc (cpu, shortval); /* PC for Normal mode is 2 bytes */
   4481  1.1  christos       else
   4482  1.7  christos 	cpu_set_pc (cpu, intval);
   4483  1.1  christos       break;
   4484  1.1  christos     default:
   4485  1.6  christos       return -1;
   4486  1.1  christos     case R0_REGNUM:
   4487  1.1  christos     case R1_REGNUM:
   4488  1.1  christos     case R2_REGNUM:
   4489  1.1  christos     case R3_REGNUM:
   4490  1.1  christos     case R4_REGNUM:
   4491  1.1  christos     case R5_REGNUM:
   4492  1.1  christos     case R6_REGNUM:
   4493  1.1  christos     case R7_REGNUM:
   4494  1.1  christos     case CCR_REGNUM:
   4495  1.1  christos     case EXR_REGNUM:
   4496  1.1  christos     case SBR_REGNUM:
   4497  1.1  christos     case VBR_REGNUM:
   4498  1.1  christos     case MACH_REGNUM:
   4499  1.1  christos     case MACL_REGNUM:
   4500  1.7  christos       h8_set_reg (cpu, rn, intval);
   4501  1.1  christos       break;
   4502  1.1  christos     case CYCLE_REGNUM:
   4503  1.1  christos     case INST_REGNUM:
   4504  1.1  christos     case TICK_REGNUM:
   4505  1.7  christos       h8_set_reg (cpu, rn, longval);
   4506  1.1  christos       break;
   4507  1.1  christos     }
   4508  1.1  christos   return length;
   4509  1.1  christos }
   4510  1.1  christos 
   4511  1.6  christos static int
   4512  1.7  christos h8300_reg_fetch (SIM_CPU *cpu, int rn, void *buf, int length)
   4513  1.1  christos {
   4514  1.7  christos   unsigned char *value = buf;
   4515  1.1  christos   int v;
   4516  1.1  christos   int longreg = 0;
   4517  1.1  christos 
   4518  1.6  christos   init_pointers (CPU_STATE (cpu));
   4519  1.1  christos 
   4520  1.1  christos   if (!h8300smode && rn >= EXR_REGNUM)
   4521  1.1  christos     rn++;
   4522  1.1  christos   switch (rn)
   4523  1.1  christos     {
   4524  1.1  christos     default:
   4525  1.6  christos       return -1;
   4526  1.6  christos     case PC_REGNUM:
   4527  1.7  christos       v = cpu_get_pc (cpu);
   4528  1.1  christos       break;
   4529  1.1  christos     case CCR_REGNUM:
   4530  1.1  christos     case EXR_REGNUM:
   4531  1.1  christos     case SBR_REGNUM:
   4532  1.1  christos     case VBR_REGNUM:
   4533  1.1  christos     case MACH_REGNUM:
   4534  1.1  christos     case MACL_REGNUM:
   4535  1.1  christos     case R0_REGNUM:
   4536  1.1  christos     case R1_REGNUM:
   4537  1.1  christos     case R2_REGNUM:
   4538  1.1  christos     case R3_REGNUM:
   4539  1.1  christos     case R4_REGNUM:
   4540  1.1  christos     case R5_REGNUM:
   4541  1.1  christos     case R6_REGNUM:
   4542  1.1  christos     case R7_REGNUM:
   4543  1.7  christos       v = h8_get_reg (cpu, rn);
   4544  1.1  christos       break;
   4545  1.1  christos     case CYCLE_REGNUM:
   4546  1.1  christos     case TICK_REGNUM:
   4547  1.6  christos     case INST_REGNUM:
   4548  1.7  christos       v = h8_get_reg (cpu, rn);
   4549  1.1  christos       longreg = 1;
   4550  1.1  christos       break;
   4551  1.6  christos     case ZERO_REGNUM:
   4552  1.6  christos       v = 0;
   4553  1.1  christos       break;
   4554  1.1  christos     }
   4555  1.1  christos   /* In Normal mode PC is 2 byte, but other registers are 4 byte */
   4556  1.1  christos   if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
   4557  1.1  christos     {
   4558  1.7  christos       value[0] = v >> 24;
   4559  1.7  christos       value[1] = v >> 16;
   4560  1.7  christos       value[2] = v >> 8;
   4561  1.7  christos       value[3] = v >> 0;
   4562  1.6  christos       return 4;
   4563  1.1  christos     }
   4564  1.1  christos   else
   4565  1.1  christos     {
   4566  1.7  christos       value[0] = v >> 8;
   4567  1.7  christos       value[1] = v;
   4568  1.6  christos       return 2;
   4569  1.1  christos     }
   4570  1.1  christos }
   4571  1.1  christos 
   4572  1.1  christos void
   4573  1.8  christos sim_info (SIM_DESC sd, bool verbose)
   4574  1.1  christos {
   4575  1.7  christos   sim_cpu *cpu = STATE_CPU (sd, 0);
   4576  1.7  christos   double timetaken = (double) h8_get_ticks (cpu) / (double) now_persec ();
   4577  1.7  christos   double virttime = h8_get_cycles (cpu) / 10.0e6;
   4578  1.1  christos 
   4579  1.7  christos   sim_io_printf (sd, "\n\n#instructions executed  %10d\n", h8_get_insts (cpu));
   4580  1.7  christos   sim_io_printf (sd, "#cycles (v approximate) %10d\n", h8_get_cycles (cpu));
   4581  1.6  christos   sim_io_printf (sd, "#real time taken        %10.4f\n", timetaken);
   4582  1.6  christos   sim_io_printf (sd, "#virtual time taken     %10.4f\n", virttime);
   4583  1.1  christos   if (timetaken != 0.0)
   4584  1.6  christos     sim_io_printf (sd, "#simulation ratio       %10.4f\n", virttime / timetaken);
   4585  1.1  christos 
   4586  1.1  christos #ifdef ADEBUG
   4587  1.1  christos   /* This to be conditional on `what' (aka `verbose'),
   4588  1.1  christos      however it was never passed as non-zero.  */
   4589  1.1  christos   if (1)
   4590  1.1  christos     {
   4591  1.1  christos       int i;
   4592  1.1  christos       for (i = 0; i < O_LAST; i++)
   4593  1.1  christos 	{
   4594  1.1  christos 	  if (h8_get_stats (sd, i))
   4595  1.6  christos 	    sim_io_printf (sd, "%d: %d\n", i, h8_get_stats (sd, i));
   4596  1.1  christos 	}
   4597  1.1  christos     }
   4598  1.1  christos #endif
   4599  1.1  christos }
   4600  1.1  christos 
   4601  1.1  christos /* Indicate whether the cpu is an H8/300 or H8/300H.
   4602  1.1  christos    FLAG is non-zero for the H8/300H.  */
   4603  1.1  christos 
   4604  1.7  christos static void
   4605  1.1  christos set_h8300h (unsigned long machine)
   4606  1.1  christos {
   4607  1.1  christos   /* FIXME: Much of the code in sim_load can be moved to sim_open.
   4608  1.1  christos      This function being replaced by a sim_open:ARGV configuration
   4609  1.1  christos      option.  */
   4610  1.1  christos 
   4611  1.1  christos   h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
   4612  1.1  christos 
   4613  1.1  christos   if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
   4614  1.1  christos     h8300sxmode = 1;
   4615  1.1  christos 
   4616  1.1  christos   if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
   4617  1.1  christos     h8300smode = 1;
   4618  1.1  christos 
   4619  1.1  christos   if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
   4620  1.1  christos     h8300hmode = 1;
   4621  1.1  christos 
   4622  1.1  christos   if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
   4623  1.1  christos     h8300_normal_mode = 1;
   4624  1.1  christos }
   4625  1.1  christos 
   4626  1.6  christos /* H8300-specific options.
   4627  1.6  christos    TODO: These really should be merged into the common model modules.  */
   4628  1.6  christos typedef enum {
   4629  1.6  christos   OPTION_H8300H,
   4630  1.6  christos   OPTION_H8300S,
   4631  1.6  christos   OPTION_H8300SX
   4632  1.6  christos } H8300_OPTIONS;
   4633  1.6  christos 
   4634  1.6  christos static SIM_RC
   4635  1.6  christos h8300_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
   4636  1.6  christos 		      char *arg, int is_command ATTRIBUTE_UNUSED)
   4637  1.6  christos {
   4638  1.6  christos   switch ((H8300_OPTIONS) opt)
   4639  1.6  christos     {
   4640  1.6  christos     case OPTION_H8300H:
   4641  1.6  christos       set_h8300h (bfd_mach_h8300h);
   4642  1.6  christos       break;
   4643  1.6  christos     case OPTION_H8300S:
   4644  1.6  christos       set_h8300h (bfd_mach_h8300s);
   4645  1.6  christos       break;
   4646  1.6  christos     case OPTION_H8300SX:
   4647  1.6  christos       set_h8300h (bfd_mach_h8300sx);
   4648  1.6  christos       break;
   4649  1.6  christos 
   4650  1.6  christos       default:
   4651  1.6  christos 	/* We'll actually never get here; the caller handles the error
   4652  1.6  christos 	   case.  */
   4653  1.6  christos 	sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
   4654  1.6  christos 	return SIM_RC_FAIL;
   4655  1.6  christos     }
   4656  1.6  christos 
   4657  1.6  christos   return SIM_RC_OK;
   4658  1.6  christos }
   4659  1.6  christos 
   4660  1.6  christos static const OPTION h8300_options[] =
   4661  1.6  christos {
   4662  1.6  christos   { {"h8300h", no_argument, NULL, OPTION_H8300H},
   4663  1.6  christos       'h', NULL, "Indicate the CPU is H8/300H",
   4664  1.6  christos       h8300_option_handler },
   4665  1.6  christos   { {"h8300s", no_argument, NULL, OPTION_H8300S},
   4666  1.6  christos       'S', NULL, "Indicate the CPU is H8S",
   4667  1.6  christos       h8300_option_handler },
   4668  1.6  christos   { {"h8300sx", no_argument, NULL, OPTION_H8300SX},
   4669  1.6  christos       'x', NULL, "Indicate the CPU is H8SX",
   4670  1.6  christos       h8300_option_handler },
   4671  1.6  christos   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
   4672  1.6  christos };
   4673  1.6  christos 
   4674  1.5  christos static sim_cia
   4675  1.5  christos h8300_pc_get (sim_cpu *cpu)
   4676  1.5  christos {
   4677  1.8  christos   return H8300_SIM_CPU (cpu)->pc;
   4678  1.5  christos }
   4679  1.5  christos 
   4680  1.5  christos static void
   4681  1.5  christos h8300_pc_set (sim_cpu *cpu, sim_cia pc)
   4682  1.5  christos {
   4683  1.8  christos   H8300_SIM_CPU (cpu)->pc = pc;
   4684  1.5  christos }
   4685  1.5  christos 
   4686  1.1  christos /* Cover function of sim_state_free to free the cpu buffers as well.  */
   4687  1.1  christos 
   4688  1.1  christos static void
   4689  1.1  christos free_state (SIM_DESC sd)
   4690  1.1  christos {
   4691  1.1  christos   if (STATE_MODULES (sd) != NULL)
   4692  1.1  christos     sim_module_uninstall (sd);
   4693  1.1  christos 
   4694  1.1  christos   /* Fixme: free buffers in _sim_cpu.  */
   4695  1.1  christos   sim_state_free (sd);
   4696  1.1  christos }
   4697  1.1  christos 
   4698  1.1  christos SIM_DESC
   4699  1.1  christos sim_open (SIM_OPEN_KIND kind,
   4700  1.1  christos 	  struct host_callback_struct *callback,
   4701  1.1  christos 	  struct bfd *abfd,
   4702  1.6  christos 	  char * const *argv)
   4703  1.1  christos {
   4704  1.5  christos   int i;
   4705  1.1  christos   SIM_DESC sd;
   4706  1.1  christos   sim_cpu *cpu;
   4707  1.1  christos 
   4708  1.7  christos   sd = sim_state_alloc_extra (kind, callback, sizeof (struct h8300_sim_state));
   4709  1.7  christos 
   4710  1.7  christos   /* Set default options before parsing user options.  */
   4711  1.7  christos   current_target_byte_order = BFD_ENDIAN_BIG;
   4712  1.5  christos 
   4713  1.5  christos   /* The cpu data is kept in a separately allocated chunk of memory.  */
   4714  1.8  christos   if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct h8300_sim_cpu))
   4715  1.8  christos       != SIM_RC_OK)
   4716  1.5  christos     {
   4717  1.5  christos       free_state (sd);
   4718  1.5  christos       return 0;
   4719  1.5  christos     }
   4720  1.5  christos 
   4721  1.1  christos   cpu = STATE_CPU (sd, 0);
   4722  1.1  christos   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
   4723  1.7  christos   h8_set_reg (cpu, SBR_REGNUM, 0xFFFFFF00);
   4724  1.1  christos   /* sim_cpu object is new, so some initialization is needed.  */
   4725  1.1  christos   init_pointers_needed = 1;
   4726  1.1  christos 
   4727  1.6  christos   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
   4728  1.6  christos     {
   4729  1.6  christos       free_state (sd);
   4730  1.6  christos       return 0;
   4731  1.6  christos     }
   4732  1.1  christos 
   4733  1.6  christos   if (sim_add_option_table (sd, NULL, h8300_options) != SIM_RC_OK)
   4734  1.1  christos     {
   4735  1.1  christos       free_state (sd);
   4736  1.1  christos       return 0;
   4737  1.1  christos     }
   4738  1.1  christos 
   4739  1.6  christos   /* The parser will print an error message for us, so we silently return.  */
   4740  1.1  christos   if (sim_parse_args (sd, argv) != SIM_RC_OK)
   4741  1.1  christos     {
   4742  1.1  christos       /* Uninstall the modules to avoid memory leaks,
   4743  1.1  christos          file descriptor leaks, etc.  */
   4744  1.1  christos       free_state (sd);
   4745  1.1  christos       return 0;
   4746  1.1  christos     }
   4747  1.1  christos 
   4748  1.1  christos   /* Check for/establish the a reference program image.  */
   4749  1.7  christos   if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
   4750  1.1  christos     {
   4751  1.1  christos       free_state (sd);
   4752  1.1  christos       return 0;
   4753  1.1  christos     }
   4754  1.1  christos 
   4755  1.1  christos   /* Establish any remaining configuration options.  */
   4756  1.1  christos   if (sim_config (sd) != SIM_RC_OK)
   4757  1.1  christos     {
   4758  1.1  christos       free_state (sd);
   4759  1.1  christos       return 0;
   4760  1.1  christos     }
   4761  1.1  christos 
   4762  1.1  christos   if (sim_post_argv_init (sd) != SIM_RC_OK)
   4763  1.1  christos     {
   4764  1.1  christos       /* Uninstall the modules to avoid memory leaks,
   4765  1.1  christos          file descriptor leaks, etc.  */
   4766  1.1  christos       free_state (sd);
   4767  1.1  christos       return 0;
   4768  1.1  christos     }
   4769  1.1  christos 
   4770  1.5  christos   /* CPU specific initialization.  */
   4771  1.5  christos   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
   4772  1.5  christos     {
   4773  1.8  christos       cpu = STATE_CPU (sd, i);
   4774  1.5  christos 
   4775  1.6  christos       CPU_REG_FETCH (cpu) = h8300_reg_fetch;
   4776  1.6  christos       CPU_REG_STORE (cpu) = h8300_reg_store;
   4777  1.5  christos       CPU_PC_FETCH (cpu) = h8300_pc_get;
   4778  1.5  christos       CPU_PC_STORE (cpu) = h8300_pc_set;
   4779  1.5  christos     }
   4780  1.5  christos 
   4781  1.1  christos   /*  sim_hw_configure (sd); */
   4782  1.1  christos 
   4783  1.1  christos   /* FIXME: Much of the code in sim_load can be moved here.  */
   4784  1.1  christos 
   4785  1.1  christos   return sd;
   4786  1.1  christos }
   4787  1.1  christos 
   4788  1.1  christos /* Called by gdb to load a program into memory.  */
   4789  1.1  christos 
   4790  1.1  christos SIM_RC
   4791  1.3  christos sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
   4792  1.1  christos {
   4793  1.7  christos   sim_cpu *cpu = STATE_CPU (sd, 0);
   4794  1.7  christos   struct h8300_sim_state *state = H8300_SIM_STATE (sd);
   4795  1.1  christos   bfd *prog_bfd;
   4796  1.1  christos 
   4797  1.1  christos   /* FIXME: The code below that sets a specific variant of the H8/300
   4798  1.1  christos      being simulated should be moved to sim_open().  */
   4799  1.1  christos 
   4800  1.1  christos   /* See if the file is for the H8/300 or H8/300H.  */
   4801  1.1  christos   /* ??? This may not be the most efficient way.  The z8k simulator
   4802  1.1  christos      does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO).  */
   4803  1.1  christos   if (abfd != NULL)
   4804  1.1  christos     prog_bfd = abfd;
   4805  1.1  christos   else
   4806  1.1  christos     prog_bfd = bfd_openr (prog, NULL);
   4807  1.1  christos   if (prog_bfd != NULL)
   4808  1.1  christos     {
   4809  1.1  christos       /* Set the cpu type.  We ignore failure from bfd_check_format
   4810  1.1  christos 	 and bfd_openr as sim_load_file checks too.  */
   4811  1.1  christos       if (bfd_check_format (prog_bfd, bfd_object))
   4812  1.1  christos 	{
   4813  1.1  christos 	  set_h8300h (bfd_get_mach (prog_bfd));
   4814  1.1  christos 	}
   4815  1.1  christos     }
   4816  1.1  christos 
   4817  1.1  christos   /* If we're using gdb attached to the simulator, then we have to
   4818  1.1  christos      reallocate memory for the simulator.
   4819  1.1  christos 
   4820  1.1  christos      When gdb first starts, it calls fetch_registers (among other
   4821  1.1  christos      functions), which in turn calls init_pointers, which allocates
   4822  1.1  christos      simulator memory.
   4823  1.1  christos 
   4824  1.1  christos      The problem is when we do that, we don't know whether we're
   4825  1.1  christos      debugging an H8/300 or H8/300H program.
   4826  1.1  christos 
   4827  1.1  christos      This is the first point at which we can make that determination,
   4828  1.1  christos      so we just reallocate memory now; this will also allow us to handle
   4829  1.1  christos      switching between H8/300 and H8/300H programs without exiting
   4830  1.1  christos      gdb.  */
   4831  1.1  christos 
   4832  1.1  christos   if (h8300smode && !h8300_normal_mode)
   4833  1.1  christos     memory_size = H8300S_MSIZE;
   4834  1.1  christos   else if (h8300hmode && !h8300_normal_mode)
   4835  1.1  christos     memory_size = H8300H_MSIZE;
   4836  1.1  christos   else
   4837  1.1  christos     memory_size = H8300_MSIZE;
   4838  1.1  christos 
   4839  1.7  christos   if (h8_get_memory_buf (cpu))
   4840  1.7  christos     free (h8_get_memory_buf (cpu));
   4841  1.1  christos 
   4842  1.7  christos   h8_set_memory_buf (cpu, (unsigned char *)
   4843  1.1  christos 		     calloc (sizeof (char), memory_size));
   4844  1.7  christos   state->memory_size = memory_size;
   4845  1.1  christos 
   4846  1.1  christos   /* `msize' must be a power of two.  */
   4847  1.1  christos   if ((memory_size & (memory_size - 1)) != 0)
   4848  1.1  christos     {
   4849  1.6  christos       sim_io_printf (sd, "sim_load: bad memory size.\n");
   4850  1.1  christos       return SIM_RC_FAIL;
   4851  1.1  christos     }
   4852  1.7  christos   h8_set_mask (cpu, memory_size - 1);
   4853  1.1  christos 
   4854  1.6  christos   if (sim_load_file (sd, STATE_MY_NAME (sd), STATE_CALLBACK (sd), prog,
   4855  1.6  christos 		     prog_bfd, STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG,
   4856  1.1  christos 		     0, sim_write)
   4857  1.1  christos       == NULL)
   4858  1.1  christos     {
   4859  1.1  christos       /* Close the bfd if we opened it.  */
   4860  1.1  christos       if (abfd == NULL && prog_bfd != NULL)
   4861  1.1  christos 	bfd_close (prog_bfd);
   4862  1.1  christos       return SIM_RC_FAIL;
   4863  1.1  christos     }
   4864  1.1  christos 
   4865  1.1  christos   /* Close the bfd if we opened it.  */
   4866  1.1  christos   if (abfd == NULL && prog_bfd != NULL)
   4867  1.1  christos     bfd_close (prog_bfd);
   4868  1.1  christos   return SIM_RC_OK;
   4869  1.1  christos }
   4870  1.1  christos 
   4871  1.1  christos SIM_RC
   4872  1.6  christos sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
   4873  1.6  christos 		     char * const *argv, char * const *env)
   4874  1.1  christos {
   4875  1.7  christos   SIM_CPU *cpu = STATE_CPU (sd, 0);
   4876  1.1  christos   int i = 0;
   4877  1.1  christos   int no_of_args = 0;
   4878  1.1  christos 
   4879  1.1  christos   if (abfd != NULL)
   4880  1.7  christos     cpu_set_pc (cpu, bfd_get_start_address (abfd));
   4881  1.1  christos   else
   4882  1.7  christos     cpu_set_pc (cpu, 0);
   4883  1.1  christos 
   4884  1.1  christos   /* Command Line support.  */
   4885  1.1  christos   if (argv != NULL)
   4886  1.1  christos     {
   4887  1.1  christos       /* Counting the no. of commandline arguments.  */
   4888  1.1  christos       for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
   4889  1.1  christos         continue;
   4890  1.1  christos 
   4891  1.1  christos       /* Allocating memory for the argv pointers.  */
   4892  1.7  christos       h8_set_command_line (cpu, (char **) malloc ((sizeof (char *))
   4893  1.1  christos 						 * (no_of_args + 1)));
   4894  1.1  christos 
   4895  1.1  christos       for (i = 0; i < no_of_args; i++)
   4896  1.1  christos 	{
   4897  1.1  christos 	  /* Copying the argument string.  */
   4898  1.7  christos 	  h8_set_cmdline_arg (cpu, i, (char *) strdup (argv[i]));
   4899  1.1  christos 	}
   4900  1.7  christos       h8_set_cmdline_arg (cpu, i, NULL);
   4901  1.1  christos     }
   4902  1.1  christos 
   4903  1.1  christos   return SIM_RC_OK;
   4904  1.1  christos }
   4905