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