OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gdb/] [gdb-6.8/] [gdb-6.8.openrisc-2.1/] [sim/] [h8300/] [compile.c] - Diff between revs 24 and 33

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 24 Rev 33
/*
/*
 * Simulator for the Renesas (formerly Hitachi) H8/300 architecture.
 * Simulator for the Renesas (formerly Hitachi) H8/300 architecture.
 *
 *
 * Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com
 * Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com
 *
 *
 * This file is part of H8/300 sim
 * This file is part of H8/300 sim
 *
 *
 *
 *
 * THIS SOFTWARE IS NOT COPYRIGHTED
 * THIS SOFTWARE IS NOT COPYRIGHTED
 *
 *
 * Cygnus offers the following for use in the public domain.  Cygnus makes no
 * Cygnus offers the following for use in the public domain.  Cygnus makes no
 * warranty with regard to the software or its performance and the user
 * warranty with regard to the software or its performance and the user
 * accepts the software "AS IS" with all faults.
 * accepts the software "AS IS" with all faults.
 *
 *
 * CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS
 * CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS
 * SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
 * SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.
 * AND FITNESS FOR A PARTICULAR PURPOSE.
 */
 */
 
 
#include <signal.h>
#include <signal.h>
#ifdef HAVE_TIME_H
#ifdef HAVE_TIME_H
#include <time.h>
#include <time.h>
#endif
#endif
#ifdef HAVE_STDLIB_H
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#include <stdlib.h>
#endif
#endif
#ifdef HAVE_SYS_PARAM_H
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#include <sys/param.h>
#endif
#endif
 
 
#include "bfd.h"
#include "bfd.h"
#include "sim-main.h"
#include "sim-main.h"
#include "gdb/sim-h8300.h"
#include "gdb/sim-h8300.h"
#include "sys/stat.h"
#include "sys/stat.h"
#include "sys/types.h"
#include "sys/types.h"
 
 
#ifndef SIGTRAP
#ifndef SIGTRAP
# define SIGTRAP 5
# define SIGTRAP 5
#endif
#endif
 
 
int debug;
int debug;
 
 
host_callback *sim_callback;
host_callback *sim_callback;
 
 
static SIM_OPEN_KIND sim_kind;
static SIM_OPEN_KIND sim_kind;
static char *myname;
static char *myname;
 
 
/* FIXME: Needs to live in header file.
/* FIXME: Needs to live in header file.
   This header should also include the things in remote-sim.h.
   This header should also include the things in remote-sim.h.
   One could move this to remote-sim.h but this function isn't needed
   One could move this to remote-sim.h but this function isn't needed
   by gdb.  */
   by gdb.  */
static void set_simcache_size (SIM_DESC, int);
static void set_simcache_size (SIM_DESC, int);
 
 
#define X(op, size)  (op * 4 + size)
#define X(op, size)  (op * 4 + size)
 
 
#define SP (h8300hmode && !h8300_normal_mode ? SL : SW)
#define SP (h8300hmode && !h8300_normal_mode ? SL : SW)
 
 
#define h8_opcodes ops
#define h8_opcodes ops
#define DEFINE_TABLE
#define DEFINE_TABLE
#include "opcode/h8300.h"
#include "opcode/h8300.h"
 
 
/* CPU data object: */
/* CPU data object: */
 
 
static int
static int
sim_state_initialize (SIM_DESC sd, sim_cpu *cpu)
sim_state_initialize (SIM_DESC sd, sim_cpu *cpu)
{
{
  /* FIXME: not really necessary, since sim_cpu_alloc calls zalloc.  */
  /* FIXME: not really necessary, since sim_cpu_alloc calls zalloc.  */
 
 
  memset (&cpu->regs, 0, sizeof(cpu->regs));
  memset (&cpu->regs, 0, sizeof(cpu->regs));
  cpu->regs[SBR_REGNUM] = 0xFFFFFF00;
  cpu->regs[SBR_REGNUM] = 0xFFFFFF00;
  cpu->pc = 0;
  cpu->pc = 0;
  cpu->delayed_branch = 0;
  cpu->delayed_branch = 0;
  cpu->memory = NULL;
  cpu->memory = NULL;
  cpu->eightbit = NULL;
  cpu->eightbit = NULL;
  cpu->mask = 0;
  cpu->mask = 0;
 
 
  /* Initialize local simulator state.  */
  /* Initialize local simulator state.  */
  sd->sim_cache = NULL;
  sd->sim_cache = NULL;
  sd->sim_cache_size = 0;
  sd->sim_cache_size = 0;
  sd->cache_idx = NULL;
  sd->cache_idx = NULL;
  sd->cache_top = 0;
  sd->cache_top = 0;
  sd->memory_size = 0;
  sd->memory_size = 0;
  sd->compiles = 0;
  sd->compiles = 0;
#ifdef ADEBUG
#ifdef ADEBUG
  memset (&cpu->stats, 0, sizeof (cpu->stats));
  memset (&cpu->stats, 0, sizeof (cpu->stats));
#endif
#endif
  return 0;
  return 0;
}
}
 
 
static unsigned int
static unsigned int
h8_get_pc (SIM_DESC sd)
h8_get_pc (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> pc;
  return (STATE_CPU (sd, 0)) -> pc;
}
}
 
 
static void
static void
h8_set_pc (SIM_DESC sd, unsigned int val)
h8_set_pc (SIM_DESC sd, unsigned int val)
{
{
  (STATE_CPU (sd, 0)) -> pc = val;
  (STATE_CPU (sd, 0)) -> pc = val;
}
}
 
 
static unsigned int
static unsigned int
h8_get_ccr (SIM_DESC sd)
h8_get_ccr (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> regs[CCR_REGNUM];
  return (STATE_CPU (sd, 0)) -> regs[CCR_REGNUM];
}
}
 
 
static void
static void
h8_set_ccr (SIM_DESC sd, unsigned int val)
h8_set_ccr (SIM_DESC sd, unsigned int val)
{
{
  (STATE_CPU (sd, 0)) -> regs[CCR_REGNUM] = val;
  (STATE_CPU (sd, 0)) -> regs[CCR_REGNUM] = val;
}
}
 
 
static unsigned int
static unsigned int
h8_get_exr (SIM_DESC sd)
h8_get_exr (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> regs[EXR_REGNUM];
  return (STATE_CPU (sd, 0)) -> regs[EXR_REGNUM];
}
}
 
 
static void
static void
h8_set_exr (SIM_DESC sd, unsigned int val)
h8_set_exr (SIM_DESC sd, unsigned int val)
{
{
  (STATE_CPU (sd, 0)) -> regs[EXR_REGNUM] = val;
  (STATE_CPU (sd, 0)) -> regs[EXR_REGNUM] = val;
}
}
 
 
static int
static int
h8_get_sbr (SIM_DESC sd)
h8_get_sbr (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> regs[SBR_REGNUM];
  return (STATE_CPU (sd, 0)) -> regs[SBR_REGNUM];
}
}
 
 
static void
static void
h8_set_sbr (SIM_DESC sd, int val)
h8_set_sbr (SIM_DESC sd, int val)
{
{
  (STATE_CPU (sd, 0)) -> regs[SBR_REGNUM] = val;
  (STATE_CPU (sd, 0)) -> regs[SBR_REGNUM] = val;
}
}
 
 
static int
static int
h8_get_vbr (SIM_DESC sd)
h8_get_vbr (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> regs[VBR_REGNUM];
  return (STATE_CPU (sd, 0)) -> regs[VBR_REGNUM];
}
}
 
 
static void
static void
h8_set_vbr (SIM_DESC sd, int val)
h8_set_vbr (SIM_DESC sd, int val)
{
{
  (STATE_CPU (sd, 0)) -> regs[VBR_REGNUM] = val;
  (STATE_CPU (sd, 0)) -> regs[VBR_REGNUM] = val;
}
}
 
 
static int
static int
h8_get_cache_top (SIM_DESC sd)
h8_get_cache_top (SIM_DESC sd)
{
{
  return sd -> cache_top;
  return sd -> cache_top;
}
}
 
 
static void
static void
h8_set_cache_top (SIM_DESC sd, int val)
h8_set_cache_top (SIM_DESC sd, int val)
{
{
  sd -> cache_top = val;
  sd -> cache_top = val;
}
}
 
 
static int
static int
h8_get_mask (SIM_DESC sd)
h8_get_mask (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> mask;
  return (STATE_CPU (sd, 0)) -> mask;
}
}
 
 
static void
static void
h8_set_mask (SIM_DESC sd, int val)
h8_set_mask (SIM_DESC sd, int val)
{
{
  (STATE_CPU (sd, 0)) -> mask = val;
  (STATE_CPU (sd, 0)) -> mask = val;
}
}
#if 0
#if 0
static int
static int
h8_get_exception (SIM_DESC sd)
h8_get_exception (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> exception;
  return (STATE_CPU (sd, 0)) -> exception;
}
}
 
 
static void
static void
h8_set_exception (SIM_DESC sd, int val)
h8_set_exception (SIM_DESC sd, int val)
{
{
  (STATE_CPU (sd, 0)) -> exception = val;
  (STATE_CPU (sd, 0)) -> exception = val;
}
}
 
 
static enum h8300_sim_state
static enum h8300_sim_state
h8_get_state (SIM_DESC sd)
h8_get_state (SIM_DESC sd)
{
{
  return sd -> state;
  return sd -> state;
}
}
 
 
static void
static void
h8_set_state (SIM_DESC sd, enum h8300_sim_state val)
h8_set_state (SIM_DESC sd, enum h8300_sim_state val)
{
{
  sd -> state = val;
  sd -> state = val;
}
}
#endif
#endif
static unsigned int
static unsigned int
h8_get_cycles (SIM_DESC sd)
h8_get_cycles (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> regs[CYCLE_REGNUM];
  return (STATE_CPU (sd, 0)) -> regs[CYCLE_REGNUM];
}
}
 
 
static void
static void
h8_set_cycles (SIM_DESC sd, unsigned int val)
h8_set_cycles (SIM_DESC sd, unsigned int val)
{
{
  (STATE_CPU (sd, 0)) -> regs[CYCLE_REGNUM] = val;
  (STATE_CPU (sd, 0)) -> regs[CYCLE_REGNUM] = val;
}
}
 
 
static unsigned int
static unsigned int
h8_get_insts (SIM_DESC sd)
h8_get_insts (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> regs[INST_REGNUM];
  return (STATE_CPU (sd, 0)) -> regs[INST_REGNUM];
}
}
 
 
static void
static void
h8_set_insts (SIM_DESC sd, unsigned int val)
h8_set_insts (SIM_DESC sd, unsigned int val)
{
{
  (STATE_CPU (sd, 0)) -> regs[INST_REGNUM] = val;
  (STATE_CPU (sd, 0)) -> regs[INST_REGNUM] = val;
}
}
 
 
static unsigned int
static unsigned int
h8_get_ticks (SIM_DESC sd)
h8_get_ticks (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> regs[TICK_REGNUM];
  return (STATE_CPU (sd, 0)) -> regs[TICK_REGNUM];
}
}
 
 
static void
static void
h8_set_ticks (SIM_DESC sd, unsigned int val)
h8_set_ticks (SIM_DESC sd, unsigned int val)
{
{
  (STATE_CPU (sd, 0)) -> regs[TICK_REGNUM] = val;
  (STATE_CPU (sd, 0)) -> regs[TICK_REGNUM] = val;
}
}
 
 
static unsigned int
static unsigned int
h8_get_mach (SIM_DESC sd)
h8_get_mach (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> regs[MACH_REGNUM];
  return (STATE_CPU (sd, 0)) -> regs[MACH_REGNUM];
}
}
 
 
static void
static void
h8_set_mach (SIM_DESC sd, unsigned int val)
h8_set_mach (SIM_DESC sd, unsigned int val)
{
{
  (STATE_CPU (sd, 0)) -> regs[MACH_REGNUM] = val;
  (STATE_CPU (sd, 0)) -> regs[MACH_REGNUM] = val;
}
}
 
 
static unsigned int
static unsigned int
h8_get_macl (SIM_DESC sd)
h8_get_macl (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> regs[MACL_REGNUM];
  return (STATE_CPU (sd, 0)) -> regs[MACL_REGNUM];
}
}
 
 
static void
static void
h8_set_macl (SIM_DESC sd, unsigned int val)
h8_set_macl (SIM_DESC sd, unsigned int val)
{
{
  (STATE_CPU (sd, 0)) -> regs[MACL_REGNUM] = val;
  (STATE_CPU (sd, 0)) -> regs[MACL_REGNUM] = val;
}
}
 
 
static int
static int
h8_get_compiles (SIM_DESC sd)
h8_get_compiles (SIM_DESC sd)
{
{
  return sd -> compiles;
  return sd -> compiles;
}
}
 
 
static void
static void
h8_increment_compiles (SIM_DESC sd)
h8_increment_compiles (SIM_DESC sd)
{
{
  sd -> compiles ++;
  sd -> compiles ++;
}
}
 
 
static unsigned int *
static unsigned int *
h8_get_reg_buf (SIM_DESC sd)
h8_get_reg_buf (SIM_DESC sd)
{
{
  return &(((STATE_CPU (sd, 0)) -> regs)[0]);
  return &(((STATE_CPU (sd, 0)) -> regs)[0]);
}
}
 
 
static unsigned int
static unsigned int
h8_get_reg (SIM_DESC sd, int regnum)
h8_get_reg (SIM_DESC sd, int regnum)
{
{
  return (STATE_CPU (sd, 0)) -> regs[regnum];
  return (STATE_CPU (sd, 0)) -> regs[regnum];
}
}
 
 
static void
static void
h8_set_reg (SIM_DESC sd, int regnum, int val)
h8_set_reg (SIM_DESC sd, int regnum, int val)
{
{
  (STATE_CPU (sd, 0)) -> regs[regnum] = val;
  (STATE_CPU (sd, 0)) -> regs[regnum] = val;
}
}
 
 
#ifdef ADEBUG
#ifdef ADEBUG
static int
static int
h8_get_stats (SIM_DESC sd, int idx)
h8_get_stats (SIM_DESC sd, int idx)
{
{
  return sd -> stats[idx];
  return sd -> stats[idx];
}
}
 
 
static void
static void
h8_increment_stats (SIM_DESC sd, int idx)
h8_increment_stats (SIM_DESC sd, int idx)
{
{
  sd -> stats[idx] ++;
  sd -> stats[idx] ++;
}
}
#endif /* ADEBUG */
#endif /* ADEBUG */
 
 
static unsigned short *
static unsigned short *
h8_get_cache_idx_buf (SIM_DESC sd)
h8_get_cache_idx_buf (SIM_DESC sd)
{
{
  return sd -> cache_idx;
  return sd -> cache_idx;
}
}
 
 
static void
static void
h8_set_cache_idx_buf (SIM_DESC sd, unsigned short *ptr)
h8_set_cache_idx_buf (SIM_DESC sd, unsigned short *ptr)
{
{
  sd -> cache_idx = ptr;
  sd -> cache_idx = ptr;
}
}
 
 
static unsigned short
static unsigned short
h8_get_cache_idx (SIM_DESC sd, unsigned int idx)
h8_get_cache_idx (SIM_DESC sd, unsigned int idx)
{
{
  if (idx > sd->memory_size)
  if (idx > sd->memory_size)
    return (unsigned short) -1;
    return (unsigned short) -1;
  return sd -> cache_idx[idx];
  return sd -> cache_idx[idx];
}
}
 
 
static void
static void
h8_set_cache_idx (SIM_DESC sd, int idx, unsigned int val)
h8_set_cache_idx (SIM_DESC sd, int idx, unsigned int val)
{
{
  sd -> cache_idx[idx] = (unsigned short) val;
  sd -> cache_idx[idx] = (unsigned short) val;
}
}
 
 
static unsigned char *
static unsigned char *
h8_get_memory_buf (SIM_DESC sd)
h8_get_memory_buf (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> memory;
  return (STATE_CPU (sd, 0)) -> memory;
}
}
 
 
static void
static void
h8_set_memory_buf (SIM_DESC sd, unsigned char *ptr)
h8_set_memory_buf (SIM_DESC sd, unsigned char *ptr)
{
{
  (STATE_CPU (sd, 0)) -> memory = ptr;
  (STATE_CPU (sd, 0)) -> memory = ptr;
}
}
 
 
static unsigned char
static unsigned char
h8_get_memory (SIM_DESC sd, int idx)
h8_get_memory (SIM_DESC sd, int idx)
{
{
  return (STATE_CPU (sd, 0)) -> memory[idx];
  return (STATE_CPU (sd, 0)) -> memory[idx];
}
}
 
 
static void
static void
h8_set_memory (SIM_DESC sd, int idx, unsigned int val)
h8_set_memory (SIM_DESC sd, int idx, unsigned int val)
{
{
  (STATE_CPU (sd, 0)) -> memory[idx] = (unsigned char) val;
  (STATE_CPU (sd, 0)) -> memory[idx] = (unsigned char) val;
}
}
 
 
static unsigned char *
static unsigned char *
h8_get_eightbit_buf (SIM_DESC sd)
h8_get_eightbit_buf (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> eightbit;
  return (STATE_CPU (sd, 0)) -> eightbit;
}
}
 
 
static void
static void
h8_set_eightbit_buf (SIM_DESC sd, unsigned char *ptr)
h8_set_eightbit_buf (SIM_DESC sd, unsigned char *ptr)
{
{
  (STATE_CPU (sd, 0)) -> eightbit = ptr;
  (STATE_CPU (sd, 0)) -> eightbit = ptr;
}
}
 
 
static unsigned char
static unsigned char
h8_get_eightbit (SIM_DESC sd, int idx)
h8_get_eightbit (SIM_DESC sd, int idx)
{
{
  return (STATE_CPU (sd, 0)) -> eightbit[idx];
  return (STATE_CPU (sd, 0)) -> eightbit[idx];
}
}
 
 
static void
static void
h8_set_eightbit (SIM_DESC sd, int idx, unsigned int val)
h8_set_eightbit (SIM_DESC sd, int idx, unsigned int val)
{
{
  (STATE_CPU (sd, 0)) -> eightbit[idx] = (unsigned char) val;
  (STATE_CPU (sd, 0)) -> eightbit[idx] = (unsigned char) val;
}
}
 
 
static unsigned int
static unsigned int
h8_get_delayed_branch (SIM_DESC sd)
h8_get_delayed_branch (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> delayed_branch;
  return (STATE_CPU (sd, 0)) -> delayed_branch;
}
}
 
 
static void
static void
h8_set_delayed_branch (SIM_DESC sd, unsigned int dest)
h8_set_delayed_branch (SIM_DESC sd, unsigned int dest)
{
{
  (STATE_CPU (sd, 0)) -> delayed_branch = dest;
  (STATE_CPU (sd, 0)) -> delayed_branch = dest;
}
}
 
 
static char **
static char **
h8_get_command_line (SIM_DESC sd)
h8_get_command_line (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> command_line;
  return (STATE_CPU (sd, 0)) -> command_line;
}
}
 
 
static void
static void
h8_set_command_line (SIM_DESC sd, char ** val)
h8_set_command_line (SIM_DESC sd, char ** val)
{
{
  (STATE_CPU (sd, 0)) -> command_line = val;
  (STATE_CPU (sd, 0)) -> command_line = val;
}
}
 
 
static char *
static char *
h8_get_cmdline_arg (SIM_DESC sd, int index)
h8_get_cmdline_arg (SIM_DESC sd, int index)
{
{
  return (STATE_CPU (sd, 0)) -> command_line[index];
  return (STATE_CPU (sd, 0)) -> command_line[index];
}
}
 
 
static void
static void
h8_set_cmdline_arg (SIM_DESC sd, int index, char * val)
h8_set_cmdline_arg (SIM_DESC sd, int index, char * val)
{
{
  (STATE_CPU (sd, 0)) -> command_line[index] = val;
  (STATE_CPU (sd, 0)) -> command_line[index] = val;
}
}
 
 
/* MAC Saturation Mode */
/* MAC Saturation Mode */
static int
static int
h8_get_macS (SIM_DESC sd)
h8_get_macS (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> macS;
  return (STATE_CPU (sd, 0)) -> macS;
}
}
 
 
static void
static void
h8_set_macS (SIM_DESC sd, int val)
h8_set_macS (SIM_DESC sd, int val)
{
{
  (STATE_CPU (sd, 0)) -> macS = (val != 0);
  (STATE_CPU (sd, 0)) -> macS = (val != 0);
}
}
 
 
/* MAC Zero Flag */
/* MAC Zero Flag */
static int
static int
h8_get_macZ (SIM_DESC sd)
h8_get_macZ (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> macZ;
  return (STATE_CPU (sd, 0)) -> macZ;
}
}
 
 
static void
static void
h8_set_macZ (SIM_DESC sd, int val)
h8_set_macZ (SIM_DESC sd, int val)
{
{
  (STATE_CPU (sd, 0)) -> macZ = (val != 0);
  (STATE_CPU (sd, 0)) -> macZ = (val != 0);
}
}
 
 
/* MAC Negative Flag */
/* MAC Negative Flag */
static int
static int
h8_get_macN (SIM_DESC sd)
h8_get_macN (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> macN;
  return (STATE_CPU (sd, 0)) -> macN;
}
}
 
 
static void
static void
h8_set_macN (SIM_DESC sd, int val)
h8_set_macN (SIM_DESC sd, int val)
{
{
  (STATE_CPU (sd, 0)) -> macN = (val != 0);
  (STATE_CPU (sd, 0)) -> macN = (val != 0);
}
}
 
 
/* MAC Overflow Flag */
/* MAC Overflow Flag */
static int
static int
h8_get_macV (SIM_DESC sd)
h8_get_macV (SIM_DESC sd)
{
{
  return (STATE_CPU (sd, 0)) -> macV;
  return (STATE_CPU (sd, 0)) -> macV;
}
}
 
 
static void
static void
h8_set_macV (SIM_DESC sd, int val)
h8_set_macV (SIM_DESC sd, int val)
{
{
  (STATE_CPU (sd, 0)) -> macV = (val != 0);
  (STATE_CPU (sd, 0)) -> macV = (val != 0);
}
}
 
 
/* End CPU data object.  */
/* End CPU data object.  */
 
 
/* The rate at which to call the host's poll_quit callback.  */
/* The rate at which to call the host's poll_quit callback.  */
 
 
enum { POLL_QUIT_INTERVAL = 0x80000 };
enum { POLL_QUIT_INTERVAL = 0x80000 };
 
 
#define LOW_BYTE(x) ((x) & 0xff)
#define LOW_BYTE(x) ((x) & 0xff)
#define HIGH_BYTE(x) (((x) >> 8) & 0xff)
#define HIGH_BYTE(x) (((x) >> 8) & 0xff)
#define P(X, Y) ((X << 8) | Y)
#define P(X, Y) ((X << 8) | Y)
 
 
#define C (c != 0)
#define C (c != 0)
#define Z (nz == 0)
#define Z (nz == 0)
#define V (v != 0)
#define V (v != 0)
#define N (n != 0)
#define N (n != 0)
#define U (u != 0)
#define U (u != 0)
#define H (h != 0)
#define H (h != 0)
#define UI (ui != 0)
#define UI (ui != 0)
#define I (intMaskBit != 0)
#define I (intMaskBit != 0)
 
 
#define BUILDSR(SD)                                             \
#define BUILDSR(SD)                                             \
  h8_set_ccr (SD, (I << 7) | (UI << 6) | (H << 5) | (U << 4)    \
  h8_set_ccr (SD, (I << 7) | (UI << 6) | (H << 5) | (U << 4)    \
             | (N << 3) | (Z << 2) | (V << 1) | C)
             | (N << 3) | (Z << 2) | (V << 1) | C)
 
 
#define GETSR(SD) \
#define GETSR(SD) \
  /* Get Status Register (flags).  */           \
  /* Get Status Register (flags).  */           \
  c = (h8_get_ccr (sd) >> 0) & 1;                \
  c = (h8_get_ccr (sd) >> 0) & 1;                \
  v = (h8_get_ccr (sd) >> 1) & 1;               \
  v = (h8_get_ccr (sd) >> 1) & 1;               \
  nz = !((h8_get_ccr (sd) >> 2) & 1);           \
  nz = !((h8_get_ccr (sd) >> 2) & 1);           \
  n = (h8_get_ccr (sd) >> 3) & 1;               \
  n = (h8_get_ccr (sd) >> 3) & 1;               \
  u = (h8_get_ccr (sd) >> 4) & 1;               \
  u = (h8_get_ccr (sd) >> 4) & 1;               \
  h = (h8_get_ccr (sd) >> 5) & 1;               \
  h = (h8_get_ccr (sd) >> 5) & 1;               \
  ui = ((h8_get_ccr (sd) >> 6) & 1);            \
  ui = ((h8_get_ccr (sd) >> 6) & 1);            \
  intMaskBit = (h8_get_ccr (sd) >> 7) & 1
  intMaskBit = (h8_get_ccr (sd) >> 7) & 1
 
 
 
 
#ifdef __CHAR_IS_SIGNED__
#ifdef __CHAR_IS_SIGNED__
#define SEXTCHAR(x) ((char) (x))
#define SEXTCHAR(x) ((char) (x))
#endif
#endif
 
 
#ifndef SEXTCHAR
#ifndef SEXTCHAR
#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff) : x & 0xff)
#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff) : x & 0xff)
#endif
#endif
 
 
#define UEXTCHAR(x) ((x) & 0xff)
#define UEXTCHAR(x) ((x) & 0xff)
#define UEXTSHORT(x) ((x) & 0xffff)
#define UEXTSHORT(x) ((x) & 0xffff)
#define SEXTSHORT(x) ((short) (x))
#define SEXTSHORT(x) ((short) (x))
 
 
int h8300hmode  = 0;
int h8300hmode  = 0;
int h8300smode  = 0;
int h8300smode  = 0;
int h8300_normal_mode  = 0;
int h8300_normal_mode  = 0;
int h8300sxmode = 0;
int h8300sxmode = 0;
 
 
static int memory_size;
static int memory_size;
 
 
static int
static int
get_now (void)
get_now (void)
{
{
  return time (0);       /* WinXX HAS UNIX like 'time', so why not use it? */
  return time (0);       /* WinXX HAS UNIX like 'time', so why not use it? */
}
}
 
 
static int
static int
now_persec (void)
now_persec (void)
{
{
  return 1;
  return 1;
}
}
 
 
static int
static int
bitfrom (int x)
bitfrom (int x)
{
{
  switch (x & SIZE)
  switch (x & SIZE)
    {
    {
    case L_8:
    case L_8:
      return SB;
      return SB;
    case L_16:
    case L_16:
    case L_16U:
    case L_16U:
      return SW;
      return SW;
    case L_32:
    case L_32:
      return SL;
      return SL;
    case L_P:
    case L_P:
      return (h8300hmode && !h8300_normal_mode)? SL : SW;
      return (h8300hmode && !h8300_normal_mode)? SL : SW;
    }
    }
  return 0;
  return 0;
}
}
 
 
/* Simulate an indirection / dereference.
/* Simulate an indirection / dereference.
   return 0 for success, -1 for failure.
   return 0 for success, -1 for failure.
*/
*/
 
 
static unsigned int
static unsigned int
lvalue (SIM_DESC sd, int x, int rn, unsigned int *val)
lvalue (SIM_DESC sd, int x, int rn, unsigned int *val)
{
{
  if (val == NULL)      /* Paranoia.  */
  if (val == NULL)      /* Paranoia.  */
    return -1;
    return -1;
 
 
  switch (x / 4)
  switch (x / 4)
    {
    {
    case OP_DISP:
    case OP_DISP:
      if (rn == ZERO_REGNUM)
      if (rn == ZERO_REGNUM)
        *val = X (OP_IMM, SP);
        *val = X (OP_IMM, SP);
      else
      else
        *val = X (OP_REG, SP);
        *val = X (OP_REG, SP);
      break;
      break;
    case OP_MEM:
    case OP_MEM:
      *val = X (OP_MEM, SP);
      *val = X (OP_MEM, SP);
      break;
      break;
    default:
    default:
      sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
      sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
      return -1;
      return -1;
    }
    }
  return 0;
  return 0;
}
}
 
 
static int
static int
cmdline_location()
cmdline_location()
{
{
  if (h8300smode && !h8300_normal_mode)
  if (h8300smode && !h8300_normal_mode)
    return 0xffff00L;
    return 0xffff00L;
  else if (h8300hmode && !h8300_normal_mode)
  else if (h8300hmode && !h8300_normal_mode)
    return 0x2ff00L;
    return 0x2ff00L;
  else
  else
    return 0xff00L;
    return 0xff00L;
}
}
 
 
static void
static void
decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
{
{
  int cst[3]   = {0, 0, 0};
  int cst[3]   = {0, 0, 0};
  int reg[3]   = {0, 0, 0};
  int reg[3]   = {0, 0, 0};
  int rdisp[3] = {0, 0, 0};
  int rdisp[3] = {0, 0, 0};
  int opnum;
  int opnum;
  const struct h8_opcode *q;
  const struct h8_opcode *q;
 
 
  dst->dst.type = -1;
  dst->dst.type = -1;
  dst->src.type = -1;
  dst->src.type = -1;
 
 
  /* Find the exact opcode/arg combo.  */
  /* Find the exact opcode/arg combo.  */
  for (q = h8_opcodes; q->name; q++)
  for (q = h8_opcodes; q->name; q++)
    {
    {
      op_type *nib = q->data.nib;
      op_type *nib = q->data.nib;
      unsigned int len = 0;
      unsigned int len = 0;
 
 
      if ((q->available == AV_H8SX && !h8300sxmode) ||
      if ((q->available == AV_H8SX && !h8300sxmode) ||
          (q->available == AV_H8S  && !h8300smode)  ||
          (q->available == AV_H8S  && !h8300smode)  ||
          (q->available == AV_H8H  && !h8300hmode))
          (q->available == AV_H8H  && !h8300hmode))
        continue;
        continue;
 
 
      cst[0]   = cst[1]   = cst[2]   = 0;
      cst[0]   = cst[1]   = cst[2]   = 0;
      reg[0]   = reg[1]   = reg[2]   = 0;
      reg[0]   = reg[1]   = reg[2]   = 0;
      rdisp[0] = rdisp[1] = rdisp[2] = 0;
      rdisp[0] = rdisp[1] = rdisp[2] = 0;
 
 
      while (1)
      while (1)
        {
        {
          op_type looking_for = *nib;
          op_type looking_for = *nib;
          int thisnib = data[len / 2];
          int thisnib = data[len / 2];
 
 
          thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
          thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
          opnum = ((looking_for & OP3) ? 2 :
          opnum = ((looking_for & OP3) ? 2 :
                   (looking_for & DST) ? 1 : 0);
                   (looking_for & DST) ? 1 : 0);
 
 
          if (looking_for < 16 && looking_for >= 0)
          if (looking_for < 16 && looking_for >= 0)
            {
            {
              if (looking_for != thisnib)
              if (looking_for != thisnib)
                goto fail;
                goto fail;
            }
            }
          else
          else
            {
            {
              if (looking_for & B31)
              if (looking_for & B31)
                {
                {
                  if (!((thisnib & 0x8) != 0))
                  if (!((thisnib & 0x8) != 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) (looking_for & ~B31);
                  looking_for = (op_type) (looking_for & ~B31);
                  thisnib &= 0x7;
                  thisnib &= 0x7;
                }
                }
              else if (looking_for & B30)
              else if (looking_for & B30)
                {
                {
                  if (!((thisnib & 0x8) == 0))
                  if (!((thisnib & 0x8) == 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) (looking_for & ~B30);
                  looking_for = (op_type) (looking_for & ~B30);
                }
                }
 
 
              if (looking_for & B21)
              if (looking_for & B21)
                {
                {
                  if (!((thisnib & 0x4) != 0))
                  if (!((thisnib & 0x4) != 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) (looking_for & ~B21);
                  looking_for = (op_type) (looking_for & ~B21);
                  thisnib &= 0xb;
                  thisnib &= 0xb;
                }
                }
              else if (looking_for & B20)
              else if (looking_for & B20)
                {
                {
                  if (!((thisnib & 0x4) == 0))
                  if (!((thisnib & 0x4) == 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) (looking_for & ~B20);
                  looking_for = (op_type) (looking_for & ~B20);
                }
                }
 
 
              if (looking_for & B11)
              if (looking_for & B11)
                {
                {
                  if (!((thisnib & 0x2) != 0))
                  if (!((thisnib & 0x2) != 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) (looking_for & ~B11);
                  looking_for = (op_type) (looking_for & ~B11);
                  thisnib &= 0xd;
                  thisnib &= 0xd;
                }
                }
              else if (looking_for & B10)
              else if (looking_for & B10)
                {
                {
                  if (!((thisnib & 0x2) == 0))
                  if (!((thisnib & 0x2) == 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) (looking_for & ~B10);
                  looking_for = (op_type) (looking_for & ~B10);
                }
                }
 
 
              if (looking_for & B01)
              if (looking_for & B01)
                {
                {
                  if (!((thisnib & 0x1) != 0))
                  if (!((thisnib & 0x1) != 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) (looking_for & ~B01);
                  looking_for = (op_type) (looking_for & ~B01);
                  thisnib &= 0xe;
                  thisnib &= 0xe;
                }
                }
              else if (looking_for & B00)
              else if (looking_for & B00)
                {
                {
                  if (!((thisnib & 0x1) == 0))
                  if (!((thisnib & 0x1) == 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) (looking_for & ~B00);
                  looking_for = (op_type) (looking_for & ~B00);
                }
                }
 
 
              if (looking_for & IGNORE)
              if (looking_for & IGNORE)
                {
                {
                  /* Hitachi has declared that IGNORE must be zero.  */
                  /* Hitachi has declared that IGNORE must be zero.  */
                  if (thisnib != 0)
                  if (thisnib != 0)
                    goto fail;
                    goto fail;
                }
                }
              else if ((looking_for & MODE) == DATA)
              else if ((looking_for & MODE) == DATA)
                {
                {
                  ;                     /* Skip embedded data.  */
                  ;                     /* Skip embedded data.  */
                }
                }
              else if ((looking_for & MODE) == DBIT)
              else if ((looking_for & MODE) == DBIT)
                {
                {
                  /* Exclude adds/subs by looking at bit 0 and 2, and
                  /* Exclude adds/subs by looking at bit 0 and 2, and
                     make sure the operand size, either w or l,
                     make sure the operand size, either w or l,
                     matches by looking at bit 1.  */
                     matches by looking at bit 1.  */
                  if ((looking_for & 7) != (thisnib & 7))
                  if ((looking_for & 7) != (thisnib & 7))
                    goto fail;
                    goto fail;
 
 
                  cst[opnum] = (thisnib & 0x8) ? 2 : 1;
                  cst[opnum] = (thisnib & 0x8) ? 2 : 1;
                }
                }
              else if ((looking_for & MODE) == REG     ||
              else if ((looking_for & MODE) == REG     ||
                       (looking_for & MODE) == LOWREG  ||
                       (looking_for & MODE) == LOWREG  ||
                       (looking_for & MODE) == IND     ||
                       (looking_for & MODE) == IND     ||
                       (looking_for & MODE) == PREINC  ||
                       (looking_for & MODE) == PREINC  ||
                       (looking_for & MODE) == POSTINC ||
                       (looking_for & MODE) == POSTINC ||
                       (looking_for & MODE) == PREDEC  ||
                       (looking_for & MODE) == PREDEC  ||
                       (looking_for & MODE) == POSTDEC)
                       (looking_for & MODE) == POSTDEC)
                {
                {
                  reg[opnum] = thisnib;
                  reg[opnum] = thisnib;
                }
                }
              else if (looking_for & CTRL)
              else if (looking_for & CTRL)
                {
                {
                  thisnib &= 7;
                  thisnib &= 7;
                  if (((looking_for & MODE) == CCR  && (thisnib != C_CCR))  ||
                  if (((looking_for & MODE) == CCR  && (thisnib != C_CCR))  ||
                      ((looking_for & MODE) == EXR  && (thisnib != C_EXR))  ||
                      ((looking_for & MODE) == EXR  && (thisnib != C_EXR))  ||
                      ((looking_for & MODE) == MACH && (thisnib != C_MACH)) ||
                      ((looking_for & MODE) == MACH && (thisnib != C_MACH)) ||
                      ((looking_for & MODE) == MACL && (thisnib != C_MACL)) ||
                      ((looking_for & MODE) == MACL && (thisnib != C_MACL)) ||
                      ((looking_for & MODE) == VBR  && (thisnib != C_VBR))  ||
                      ((looking_for & MODE) == VBR  && (thisnib != C_VBR))  ||
                      ((looking_for & MODE) == SBR  && (thisnib != C_SBR)))
                      ((looking_for & MODE) == SBR  && (thisnib != C_SBR)))
                    goto fail;
                    goto fail;
                  if (((looking_for & MODE) == CCR_EXR &&
                  if (((looking_for & MODE) == CCR_EXR &&
                       (thisnib != C_CCR && thisnib != C_EXR)) ||
                       (thisnib != C_CCR && thisnib != C_EXR)) ||
                      ((looking_for & MODE) == VBR_SBR &&
                      ((looking_for & MODE) == VBR_SBR &&
                       (thisnib != C_VBR && thisnib != C_SBR)) ||
                       (thisnib != C_VBR && thisnib != C_SBR)) ||
                      ((looking_for & MODE) == MACREG &&
                      ((looking_for & MODE) == MACREG &&
                       (thisnib != C_MACH && thisnib != C_MACL)))
                       (thisnib != C_MACH && thisnib != C_MACL)))
                    goto fail;
                    goto fail;
                  if (((looking_for & MODE) == CC_EX_VB_SB &&
                  if (((looking_for & MODE) == CC_EX_VB_SB &&
                       (thisnib != C_CCR && thisnib != C_EXR &&
                       (thisnib != C_CCR && thisnib != C_EXR &&
                        thisnib != C_VBR && thisnib != C_SBR)))
                        thisnib != C_VBR && thisnib != C_SBR)))
                    goto fail;
                    goto fail;
 
 
                  reg[opnum] = thisnib;
                  reg[opnum] = thisnib;
                }
                }
              else if ((looking_for & MODE) == ABS)
              else if ((looking_for & MODE) == ABS)
                {
                {
                  /* Absolute addresses are unsigned.  */
                  /* Absolute addresses are unsigned.  */
                  switch (looking_for & SIZE)
                  switch (looking_for & SIZE)
                    {
                    {
                    case L_8:
                    case L_8:
                      cst[opnum] = UEXTCHAR (data[len / 2]);
                      cst[opnum] = UEXTCHAR (data[len / 2]);
                      break;
                      break;
                    case L_16:
                    case L_16:
                    case L_16U:
                    case L_16U:
                      cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
                      cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
                      break;
                      break;
                    case L_32:
                    case L_32:
                      cst[opnum] =
                      cst[opnum] =
                        (data[len / 2 + 0] << 24) +
                        (data[len / 2 + 0] << 24) +
                        (data[len / 2 + 1] << 16) +
                        (data[len / 2 + 1] << 16) +
                        (data[len / 2 + 2] <<  8) +
                        (data[len / 2 + 2] <<  8) +
                        (data[len / 2 + 3]);
                        (data[len / 2 + 3]);
                      break;
                      break;
                    default:
                    default:
                      printf ("decode: bad size ABS: %d\n",
                      printf ("decode: bad size ABS: %d\n",
                              (looking_for & SIZE));
                              (looking_for & SIZE));
                      goto end;
                      goto end;
                    }
                    }
                }
                }
              else if ((looking_for & MODE) == DISP   ||
              else if ((looking_for & MODE) == DISP   ||
                       (looking_for & MODE) == PCREL  ||
                       (looking_for & MODE) == PCREL  ||
                       (looking_for & MODE) == INDEXB ||
                       (looking_for & MODE) == INDEXB ||
                       (looking_for & MODE) == INDEXW ||
                       (looking_for & MODE) == INDEXW ||
                       (looking_for & MODE) == INDEXL)
                       (looking_for & MODE) == INDEXL)
                {
                {
                  switch (looking_for & SIZE)
                  switch (looking_for & SIZE)
                    {
                    {
                    case L_2:
                    case L_2:
                      cst[opnum] = thisnib & 3;
                      cst[opnum] = thisnib & 3;
                      break;
                      break;
                    case L_8:
                    case L_8:
                      cst[opnum] = SEXTCHAR (data[len / 2]);
                      cst[opnum] = SEXTCHAR (data[len / 2]);
                      break;
                      break;
                    case L_16:
                    case L_16:
                      cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
                      cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
                      cst[opnum] = (short) cst[opnum];  /* Sign extend.  */
                      cst[opnum] = (short) cst[opnum];  /* Sign extend.  */
                      break;
                      break;
                    case L_16U:
                    case L_16U:
                      cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
                      cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
                      break;
                      break;
                    case L_32:
                    case L_32:
                      cst[opnum] =
                      cst[opnum] =
                        (data[len / 2 + 0] << 24) +
                        (data[len / 2 + 0] << 24) +
                        (data[len / 2 + 1] << 16) +
                        (data[len / 2 + 1] << 16) +
                        (data[len / 2 + 2] <<  8) +
                        (data[len / 2 + 2] <<  8) +
                        (data[len / 2 + 3]);
                        (data[len / 2 + 3]);
                      break;
                      break;
                    default:
                    default:
                      printf ("decode: bad size DISP/PCREL/INDEX: %d\n",
                      printf ("decode: bad size DISP/PCREL/INDEX: %d\n",
                              (looking_for & SIZE));
                              (looking_for & SIZE));
                      goto end;
                      goto end;
                    }
                    }
                }
                }
              else if ((looking_for & SIZE) == L_16 ||
              else if ((looking_for & SIZE) == L_16 ||
                       (looking_for & SIZE) == L_16U)
                       (looking_for & SIZE) == L_16U)
                {
                {
                  cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
                  cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
                  /* Immediates are always unsigned.  */
                  /* Immediates are always unsigned.  */
                  if ((looking_for & SIZE) != L_16U &&
                  if ((looking_for & SIZE) != L_16U &&
                      (looking_for & MODE) != IMM)
                      (looking_for & MODE) != IMM)
                    cst[opnum] = (short) cst[opnum];    /* Sign extend.  */
                    cst[opnum] = (short) cst[opnum];    /* Sign extend.  */
                }
                }
              else if (looking_for & ABSJMP)
              else if (looking_for & ABSJMP)
                {
                {
                  switch (looking_for & SIZE) {
                  switch (looking_for & SIZE) {
                  case L_24:
                  case L_24:
                    cst[opnum] = (data[1] << 16) | (data[2] << 8) | (data[3]);
                    cst[opnum] = (data[1] << 16) | (data[2] << 8) | (data[3]);
                    break;
                    break;
                  case L_32:
                  case L_32:
                    cst[opnum] =
                    cst[opnum] =
                      (data[len / 2 + 0] << 24) +
                      (data[len / 2 + 0] << 24) +
                      (data[len / 2 + 1] << 16) +
                      (data[len / 2 + 1] << 16) +
                      (data[len / 2 + 2] <<  8) +
                      (data[len / 2 + 2] <<  8) +
                      (data[len / 2 + 3]);
                      (data[len / 2 + 3]);
                    break;
                    break;
                  default:
                  default:
                    printf ("decode: bad size ABSJMP: %d\n",
                    printf ("decode: bad size ABSJMP: %d\n",
                            (looking_for & SIZE));
                            (looking_for & SIZE));
                      goto end;
                      goto end;
                  }
                  }
                }
                }
              else if ((looking_for & MODE) == MEMIND)
              else if ((looking_for & MODE) == MEMIND)
                {
                {
                  cst[opnum] = data[1];
                  cst[opnum] = data[1];
                }
                }
              else if ((looking_for & MODE) == VECIND)
              else if ((looking_for & MODE) == VECIND)
                {
                {
                  if(h8300_normal_mode)
                  if(h8300_normal_mode)
                    cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2;
                    cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2;
                  else
                  else
                    cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4;
                    cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4;
                  cst[opnum] += h8_get_vbr (sd); /* Add vector base reg.  */
                  cst[opnum] += h8_get_vbr (sd); /* Add vector base reg.  */
                }
                }
              else if ((looking_for & SIZE) == L_32)
              else if ((looking_for & SIZE) == L_32)
                {
                {
                  int i = len / 2;
                  int i = len / 2;
 
 
                  cst[opnum] =
                  cst[opnum] =
                    (data[i + 0] << 24) |
                    (data[i + 0] << 24) |
                    (data[i + 1] << 16) |
                    (data[i + 1] << 16) |
                    (data[i + 2] <<  8) |
                    (data[i + 2] <<  8) |
                    (data[i + 3]);
                    (data[i + 3]);
                }
                }
              else if ((looking_for & SIZE) == L_24)
              else if ((looking_for & SIZE) == L_24)
                {
                {
                  int i = len / 2;
                  int i = len / 2;
 
 
                  cst[opnum] =
                  cst[opnum] =
                    (data[i + 0] << 16) |
                    (data[i + 0] << 16) |
                    (data[i + 1] << 8) |
                    (data[i + 1] << 8) |
                    (data[i + 2]);
                    (data[i + 2]);
                }
                }
              else if (looking_for & DISPREG)
              else if (looking_for & DISPREG)
                {
                {
                  rdisp[opnum] = thisnib & 0x7;
                  rdisp[opnum] = thisnib & 0x7;
                }
                }
              else if ((looking_for & MODE) == KBIT)
              else if ((looking_for & MODE) == KBIT)
                {
                {
                  switch (thisnib)
                  switch (thisnib)
                    {
                    {
                    case 9:
                    case 9:
                      cst[opnum] = 4;
                      cst[opnum] = 4;
                      break;
                      break;
                    case 8:
                    case 8:
                      cst[opnum] = 2;
                      cst[opnum] = 2;
                      break;
                      break;
                    case 0:
                    case 0:
                      cst[opnum] = 1;
                      cst[opnum] = 1;
                      break;
                      break;
                    default:
                    default:
                      goto fail;
                      goto fail;
                    }
                    }
                }
                }
              else if ((looking_for & SIZE) == L_8)
              else if ((looking_for & SIZE) == L_8)
                {
                {
                  if ((looking_for & MODE) == ABS)
                  if ((looking_for & MODE) == ABS)
                    {
                    {
                      /* Will be combined with contents of SBR_REGNUM
                      /* Will be combined with contents of SBR_REGNUM
                         by fetch ().  For all modes except h8sx, this
                         by fetch ().  For all modes except h8sx, this
                         will always contain the value 0xFFFFFF00.  */
                         will always contain the value 0xFFFFFF00.  */
                      cst[opnum] = data[len / 2] & 0xff;
                      cst[opnum] = data[len / 2] & 0xff;
                    }
                    }
                  else
                  else
                    {
                    {
                      cst[opnum] = data[len / 2] & 0xff;
                      cst[opnum] = data[len / 2] & 0xff;
                    }
                    }
                }
                }
              else if ((looking_for & SIZE) == L_2)
              else if ((looking_for & SIZE) == L_2)
                {
                {
                  cst[opnum] = thisnib & 3;
                  cst[opnum] = thisnib & 3;
                }
                }
              else if ((looking_for & SIZE) == L_3 ||
              else if ((looking_for & SIZE) == L_3 ||
                       (looking_for & SIZE) == L_3NZ)
                       (looking_for & SIZE) == L_3NZ)
                {
                {
                  cst[opnum] = thisnib & 7;
                  cst[opnum] = thisnib & 7;
                  if (cst[opnum] == 0 && (looking_for & SIZE) == L_3NZ)
                  if (cst[opnum] == 0 && (looking_for & SIZE) == L_3NZ)
                    goto fail;
                    goto fail;
                }
                }
              else if ((looking_for & SIZE) == L_4)
              else if ((looking_for & SIZE) == L_4)
                {
                {
                  cst[opnum] = thisnib & 15;
                  cst[opnum] = thisnib & 15;
                }
                }
              else if ((looking_for & SIZE) == L_5)
              else if ((looking_for & SIZE) == L_5)
                {
                {
                  cst[opnum] = data[len / 2] & 0x1f;
                  cst[opnum] = data[len / 2] & 0x1f;
                }
                }
              else if (looking_for == E)
              else if (looking_for == E)
                {
                {
#ifdef ADEBUG
#ifdef ADEBUG
                  dst->op = q;
                  dst->op = q;
#endif
#endif
                  /* Fill in the args.  */
                  /* Fill in the args.  */
                  {
                  {
                    op_type *args = q->args.nib;
                    op_type *args = q->args.nib;
                    int hadone = 0;
                    int hadone = 0;
                    int nargs;
                    int nargs;
 
 
                    for (nargs = 0;
                    for (nargs = 0;
                         nargs < 3 && *args != E;
                         nargs < 3 && *args != E;
                         nargs++)
                         nargs++)
                      {
                      {
                        int x = *args;
                        int x = *args;
                        ea_type *p;
                        ea_type *p;
 
 
                        opnum = ((x & OP3) ? 2 :
                        opnum = ((x & OP3) ? 2 :
                                 (x & DST) ? 1 : 0);
                                 (x & DST) ? 1 : 0);
                        if (x & DST)
                        if (x & DST)
                          p = &dst->dst;
                          p = &dst->dst;
                        else if (x & OP3)
                        else if (x & OP3)
                          p = &dst->op3;
                          p = &dst->op3;
                        else
                        else
                          p = &dst->src;
                          p = &dst->src;
 
 
                        if ((x & MODE) == IMM  ||
                        if ((x & MODE) == IMM  ||
                            (x & MODE) == KBIT ||
                            (x & MODE) == KBIT ||
                            (x & MODE) == DBIT)
                            (x & MODE) == DBIT)
                          {
                          {
                            /* Use the instruction to determine
                            /* Use the instruction to determine
                               the operand size.  */
                               the operand size.  */
                            p->type = X (OP_IMM, OP_SIZE (q->how));
                            p->type = X (OP_IMM, OP_SIZE (q->how));
                            p->literal = cst[opnum];
                            p->literal = cst[opnum];
                          }
                          }
                        else if ((x & MODE) == CONST_2 ||
                        else if ((x & MODE) == CONST_2 ||
                                 (x & MODE) == CONST_4 ||
                                 (x & MODE) == CONST_4 ||
                                 (x & MODE) == CONST_8 ||
                                 (x & MODE) == CONST_8 ||
                                 (x & MODE) == CONST_16)
                                 (x & MODE) == CONST_16)
                          {
                          {
                            /* Use the instruction to determine
                            /* Use the instruction to determine
                               the operand size.  */
                               the operand size.  */
                            p->type = X (OP_IMM, OP_SIZE (q->how));
                            p->type = X (OP_IMM, OP_SIZE (q->how));
                            switch (x & MODE) {
                            switch (x & MODE) {
                            case CONST_2:       p->literal =  2; break;
                            case CONST_2:       p->literal =  2; break;
                            case CONST_4:       p->literal =  4; break;
                            case CONST_4:       p->literal =  4; break;
                            case CONST_8:       p->literal =  8; break;
                            case CONST_8:       p->literal =  8; break;
                            case CONST_16:      p->literal = 16; break;
                            case CONST_16:      p->literal = 16; break;
                            }
                            }
                          }
                          }
                        else if ((x & MODE) == REG)
                        else if ((x & MODE) == REG)
                          {
                          {
                            p->type = X (OP_REG, bitfrom (x));
                            p->type = X (OP_REG, bitfrom (x));
                            p->reg = reg[opnum];
                            p->reg = reg[opnum];
                          }
                          }
                        else if ((x & MODE) == LOWREG)
                        else if ((x & MODE) == LOWREG)
                          {
                          {
                            p->type = X (OP_LOWREG, bitfrom (x));
                            p->type = X (OP_LOWREG, bitfrom (x));
                            p->reg = reg[opnum];
                            p->reg = reg[opnum];
                          }
                          }
                        else if ((x & MODE) == PREINC)
                        else if ((x & MODE) == PREINC)
                          {
                          {
                            /* Use the instruction to determine
                            /* Use the instruction to determine
                               the operand size.  */
                               the operand size.  */
                            p->type = X (OP_PREINC, OP_SIZE (q->how));
                            p->type = X (OP_PREINC, OP_SIZE (q->how));
                            p->reg = reg[opnum] & 0x7;
                            p->reg = reg[opnum] & 0x7;
                          }
                          }
                        else if ((x & MODE) == POSTINC)
                        else if ((x & MODE) == POSTINC)
                          {
                          {
                            /* Use the instruction to determine
                            /* Use the instruction to determine
                               the operand size.  */
                               the operand size.  */
                            p->type = X (OP_POSTINC, OP_SIZE (q->how));
                            p->type = X (OP_POSTINC, OP_SIZE (q->how));
                            p->reg = reg[opnum] & 0x7;
                            p->reg = reg[opnum] & 0x7;
                          }
                          }
                        else if ((x & MODE) == PREDEC)
                        else if ((x & MODE) == PREDEC)
                          {
                          {
                            /* Use the instruction to determine
                            /* Use the instruction to determine
                               the operand size.  */
                               the operand size.  */
                            p->type = X (OP_PREDEC, OP_SIZE (q->how));
                            p->type = X (OP_PREDEC, OP_SIZE (q->how));
                            p->reg = reg[opnum] & 0x7;
                            p->reg = reg[opnum] & 0x7;
                          }
                          }
                        else if ((x & MODE) == POSTDEC)
                        else if ((x & MODE) == POSTDEC)
                          {
                          {
                            /* Use the instruction to determine
                            /* Use the instruction to determine
                               the operand size.  */
                               the operand size.  */
                            p->type = X (OP_POSTDEC, OP_SIZE (q->how));
                            p->type = X (OP_POSTDEC, OP_SIZE (q->how));
                            p->reg = reg[opnum] & 0x7;
                            p->reg = reg[opnum] & 0x7;
                          }
                          }
                        else if ((x & MODE) == IND)
                        else if ((x & MODE) == IND)
                          {
                          {
                            /* Note: an indirect is transformed into
                            /* Note: an indirect is transformed into
                               a displacement of zero.
                               a displacement of zero.
                            */
                            */
                            /* Use the instruction to determine
                            /* Use the instruction to determine
                               the operand size.  */
                               the operand size.  */
                            p->type = X (OP_DISP, OP_SIZE (q->how));
                            p->type = X (OP_DISP, OP_SIZE (q->how));
                            p->reg = reg[opnum] & 0x7;
                            p->reg = reg[opnum] & 0x7;
                            p->literal = 0;
                            p->literal = 0;
                            if (OP_KIND (q->how) == O_JSR ||
                            if (OP_KIND (q->how) == O_JSR ||
                                OP_KIND (q->how) == O_JMP)
                                OP_KIND (q->how) == O_JMP)
                              if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
                              if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
                                goto end;
                                goto end;
                          }
                          }
                        else if ((x & MODE) == ABS)
                        else if ((x & MODE) == ABS)
                          {
                          {
                            /* Note: a 16 or 32 bit ABS is transformed into a
                            /* Note: a 16 or 32 bit ABS is transformed into a
                               displacement from pseudo-register ZERO_REGNUM,
                               displacement from pseudo-register ZERO_REGNUM,
                               which is always zero.  An 8 bit ABS becomes
                               which is always zero.  An 8 bit ABS becomes
                               a displacement from SBR_REGNUM.
                               a displacement from SBR_REGNUM.
                            */
                            */
                            /* Use the instruction to determine
                            /* Use the instruction to determine
                               the operand size.  */
                               the operand size.  */
                            p->type = X (OP_DISP, OP_SIZE (q->how));
                            p->type = X (OP_DISP, OP_SIZE (q->how));
                            p->literal = cst[opnum];
                            p->literal = cst[opnum];
 
 
                            /* 8-bit ABS is displacement from SBR.
                            /* 8-bit ABS is displacement from SBR.
                               16 and 32-bit ABS are displacement from ZERO.
                               16 and 32-bit ABS are displacement from ZERO.
                               (SBR will always be zero except for h8/sx)
                               (SBR will always be zero except for h8/sx)
                            */
                            */
                            if ((x & SIZE) == L_8)
                            if ((x & SIZE) == L_8)
                              p->reg = SBR_REGNUM;
                              p->reg = SBR_REGNUM;
                            else
                            else
                              p->reg = ZERO_REGNUM;;
                              p->reg = ZERO_REGNUM;;
                          }
                          }
                        else if ((x & MODE) == MEMIND ||
                        else if ((x & MODE) == MEMIND ||
                                 (x & MODE) == VECIND)
                                 (x & MODE) == VECIND)
                          {
                          {
                            /* Size doesn't matter.  */
                            /* Size doesn't matter.  */
                            p->type = X (OP_MEM, SB);
                            p->type = X (OP_MEM, SB);
                            p->literal = cst[opnum];
                            p->literal = cst[opnum];
                            if (OP_KIND (q->how) == O_JSR ||
                            if (OP_KIND (q->how) == O_JSR ||
                                OP_KIND (q->how) == O_JMP)
                                OP_KIND (q->how) == O_JMP)
                              if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
                              if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
                                goto end;
                                goto end;
                          }
                          }
                        else if ((x & MODE) == PCREL)
                        else if ((x & MODE) == PCREL)
                          {
                          {
                            /* Size doesn't matter.  */
                            /* Size doesn't matter.  */
                            p->type = X (OP_PCREL, SB);
                            p->type = X (OP_PCREL, SB);
                            p->literal = cst[opnum];
                            p->literal = cst[opnum];
                          }
                          }
                        else if (x & ABSJMP)
                        else if (x & ABSJMP)
                          {
                          {
                            p->type = X (OP_IMM, SP);
                            p->type = X (OP_IMM, SP);
                            p->literal = cst[opnum];
                            p->literal = cst[opnum];
                          }
                          }
                        else if ((x & MODE) == INDEXB)
                        else if ((x & MODE) == INDEXB)
                          {
                          {
                            p->type = X (OP_INDEXB, OP_SIZE (q->how));
                            p->type = X (OP_INDEXB, OP_SIZE (q->how));
                            p->literal = cst[opnum];
                            p->literal = cst[opnum];
                            p->reg     = rdisp[opnum];
                            p->reg     = rdisp[opnum];
                          }
                          }
                        else if ((x & MODE) == INDEXW)
                        else if ((x & MODE) == INDEXW)
                          {
                          {
                            p->type = X (OP_INDEXW, OP_SIZE (q->how));
                            p->type = X (OP_INDEXW, OP_SIZE (q->how));
                            p->literal = cst[opnum];
                            p->literal = cst[opnum];
                            p->reg     = rdisp[opnum];
                            p->reg     = rdisp[opnum];
                          }
                          }
                        else if ((x & MODE) == INDEXL)
                        else if ((x & MODE) == INDEXL)
                          {
                          {
                            p->type = X (OP_INDEXL, OP_SIZE (q->how));
                            p->type = X (OP_INDEXL, OP_SIZE (q->how));
                            p->literal = cst[opnum];
                            p->literal = cst[opnum];
                            p->reg     = rdisp[opnum];
                            p->reg     = rdisp[opnum];
                          }
                          }
                        else if ((x & MODE) == DISP)
                        else if ((x & MODE) == DISP)
                          {
                          {
                            /* Yuck -- special for mova args.  */
                            /* Yuck -- special for mova args.  */
                            if (strncmp (q->name, "mova", 4) == 0 &&
                            if (strncmp (q->name, "mova", 4) == 0 &&
                                (x & SIZE) == L_2)
                                (x & SIZE) == L_2)
                              {
                              {
                                /* Mova can have a DISP2 dest, with an
                                /* Mova can have a DISP2 dest, with an
                                   INDEXB or INDEXW src.  The multiplier
                                   INDEXB or INDEXW src.  The multiplier
                                   for the displacement value is determined
                                   for the displacement value is determined
                                   by the src operand, not by the insn.  */
                                   by the src operand, not by the insn.  */
 
 
                                switch (OP_KIND (dst->src.type))
                                switch (OP_KIND (dst->src.type))
                                  {
                                  {
                                  case OP_INDEXB:
                                  case OP_INDEXB:
                                    p->type = X (OP_DISP, SB);
                                    p->type = X (OP_DISP, SB);
                                    p->literal = cst[opnum];
                                    p->literal = cst[opnum];
                                    break;
                                    break;
                                  case OP_INDEXW:
                                  case OP_INDEXW:
                                    p->type = X (OP_DISP, SW);
                                    p->type = X (OP_DISP, SW);
                                    p->literal = cst[opnum] * 2;
                                    p->literal = cst[opnum] * 2;
                                    break;
                                    break;
                                  default:
                                  default:
                                    goto fail;
                                    goto fail;
                                  }
                                  }
                              }
                              }
                            else
                            else
                              {
                              {
                                p->type = X (OP_DISP,   OP_SIZE (q->how));
                                p->type = X (OP_DISP,   OP_SIZE (q->how));
                                p->literal = cst[opnum];
                                p->literal = cst[opnum];
                                /* DISP2 is special.  */
                                /* DISP2 is special.  */
                                if ((x & SIZE) == L_2)
                                if ((x & SIZE) == L_2)
                                  switch (OP_SIZE (q->how))
                                  switch (OP_SIZE (q->how))
                                    {
                                    {
                                    case SB:                  break;
                                    case SB:                  break;
                                    case SW: p->literal *= 2; break;
                                    case SW: p->literal *= 2; break;
                                    case SL: p->literal *= 4; break;
                                    case SL: p->literal *= 4; break;
                                    }
                                    }
                              }
                              }
                            p->reg     = rdisp[opnum];
                            p->reg     = rdisp[opnum];
                          }
                          }
                        else if (x & CTRL)
                        else if (x & CTRL)
                          {
                          {
                            switch (reg[opnum])
                            switch (reg[opnum])
                              {
                              {
                              case C_CCR:
                              case C_CCR:
                                p->type = X (OP_CCR, SB);
                                p->type = X (OP_CCR, SB);
                                break;
                                break;
                              case C_EXR:
                              case C_EXR:
                                p->type = X (OP_EXR, SB);
                                p->type = X (OP_EXR, SB);
                                break;
                                break;
                              case C_MACH:
                              case C_MACH:
                                p->type = X (OP_MACH, SL);
                                p->type = X (OP_MACH, SL);
                                break;
                                break;
                              case C_MACL:
                              case C_MACL:
                                p->type = X (OP_MACL, SL);
                                p->type = X (OP_MACL, SL);
                                break;
                                break;
                              case C_VBR:
                              case C_VBR:
                                p->type = X (OP_VBR, SL);
                                p->type = X (OP_VBR, SL);
                                break;
                                break;
                              case C_SBR:
                              case C_SBR:
                                p->type = X (OP_SBR, SL);
                                p->type = X (OP_SBR, SL);
                                break;
                                break;
                              }
                              }
                          }
                          }
                        else if ((x & MODE) == CCR)
                        else if ((x & MODE) == CCR)
                          {
                          {
                            p->type = OP_CCR;
                            p->type = OP_CCR;
                          }
                          }
                        else if ((x & MODE) == EXR)
                        else if ((x & MODE) == EXR)
                          {
                          {
                            p->type = OP_EXR;
                            p->type = OP_EXR;
                          }
                          }
                        else
                        else
                          printf ("Hmmmm 0x%x...\n", x);
                          printf ("Hmmmm 0x%x...\n", x);
 
 
                        args++;
                        args++;
                      }
                      }
                  }
                  }
 
 
                  /* Unary operators: treat src and dst as equivalent.  */
                  /* Unary operators: treat src and dst as equivalent.  */
                  if (dst->dst.type == -1)
                  if (dst->dst.type == -1)
                    dst->dst = dst->src;
                    dst->dst = dst->src;
                  if (dst->src.type == -1)
                  if (dst->src.type == -1)
                    dst->src = dst->dst;
                    dst->src = dst->dst;
 
 
                  dst->opcode = q->how;
                  dst->opcode = q->how;
                  dst->cycles = q->time;
                  dst->cycles = q->time;
 
 
                  /* And jsr's to these locations are turned into
                  /* And jsr's to these locations are turned into
                     magic traps.  */
                     magic traps.  */
 
 
                  if (OP_KIND (dst->opcode) == O_JSR)
                  if (OP_KIND (dst->opcode) == O_JSR)
                    {
                    {
                      switch (dst->src.literal)
                      switch (dst->src.literal)
                        {
                        {
                        case 0xc5:
                        case 0xc5:
                          dst->opcode = O (O_SYS_OPEN, SB);
                          dst->opcode = O (O_SYS_OPEN, SB);
                          break;
                          break;
                        case 0xc6:
                        case 0xc6:
                          dst->opcode = O (O_SYS_READ, SB);
                          dst->opcode = O (O_SYS_READ, SB);
                          break;
                          break;
                        case 0xc7:
                        case 0xc7:
                          dst->opcode = O (O_SYS_WRITE, SB);
                          dst->opcode = O (O_SYS_WRITE, SB);
                          break;
                          break;
                        case 0xc8:
                        case 0xc8:
                          dst->opcode = O (O_SYS_LSEEK, SB);
                          dst->opcode = O (O_SYS_LSEEK, SB);
                          break;
                          break;
                        case 0xc9:
                        case 0xc9:
                          dst->opcode = O (O_SYS_CLOSE, SB);
                          dst->opcode = O (O_SYS_CLOSE, SB);
                          break;
                          break;
                        case 0xca:
                        case 0xca:
                          dst->opcode = O (O_SYS_STAT, SB);
                          dst->opcode = O (O_SYS_STAT, SB);
                          break;
                          break;
                        case 0xcb:
                        case 0xcb:
                          dst->opcode = O (O_SYS_FSTAT, SB);
                          dst->opcode = O (O_SYS_FSTAT, SB);
                          break;
                          break;
                        case 0xcc:
                        case 0xcc:
                          dst->opcode = O (O_SYS_CMDLINE, SB);
                          dst->opcode = O (O_SYS_CMDLINE, SB);
                          break;
                          break;
                        }
                        }
                      /* End of Processing for system calls.  */
                      /* End of Processing for system calls.  */
                    }
                    }
 
 
                  dst->next_pc = addr + len / 2;
                  dst->next_pc = addr + len / 2;
                  return;
                  return;
                }
                }
              else
              else
                printf ("Don't understand 0x%x \n", looking_for);
                printf ("Don't understand 0x%x \n", looking_for);
            }
            }
 
 
          len++;
          len++;
          nib++;
          nib++;
        }
        }
 
 
    fail:
    fail:
      ;
      ;
    }
    }
 end:
 end:
  /* Fell off the end.  */
  /* Fell off the end.  */
  dst->opcode = O (O_ILL, SB);
  dst->opcode = O (O_ILL, SB);
}
}
 
 
static void
static void
compile (SIM_DESC sd, int pc)
compile (SIM_DESC sd, int pc)
{
{
  int idx;
  int idx;
 
 
  /* Find the next cache entry to use.  */
  /* Find the next cache entry to use.  */
  idx = h8_get_cache_top (sd) + 1;
  idx = h8_get_cache_top (sd) + 1;
  h8_increment_compiles (sd);
  h8_increment_compiles (sd);
  if (idx >= sd->sim_cache_size)
  if (idx >= sd->sim_cache_size)
    {
    {
      idx = 1;
      idx = 1;
    }
    }
  h8_set_cache_top (sd, idx);
  h8_set_cache_top (sd, idx);
 
 
  /* Throw away its old meaning.  */
  /* Throw away its old meaning.  */
  h8_set_cache_idx (sd, sd->sim_cache[idx].oldpc, 0);
  h8_set_cache_idx (sd, sd->sim_cache[idx].oldpc, 0);
 
 
  /* Set to new address.  */
  /* Set to new address.  */
  sd->sim_cache[idx].oldpc = pc;
  sd->sim_cache[idx].oldpc = pc;
 
 
  /* Fill in instruction info.  */
  /* Fill in instruction info.  */
  decode (sd, pc, h8_get_memory_buf (sd) + pc, sd->sim_cache + idx);
  decode (sd, pc, h8_get_memory_buf (sd) + pc, sd->sim_cache + idx);
 
 
  /* Point to new cache entry.  */
  /* Point to new cache entry.  */
  h8_set_cache_idx (sd, pc, idx);
  h8_set_cache_idx (sd, pc, idx);
}
}
 
 
 
 
static unsigned char  *breg[32];
static unsigned char  *breg[32];
static unsigned short *wreg[16];
static unsigned short *wreg[16];
static unsigned int   *lreg[18];
static unsigned int   *lreg[18];
 
 
#define GET_B_REG(X)     *(breg[X])
#define GET_B_REG(X)     *(breg[X])
#define SET_B_REG(X, Y) (*(breg[X])) = (Y)
#define SET_B_REG(X, Y) (*(breg[X])) = (Y)
#define GET_W_REG(X)     *(wreg[X])
#define GET_W_REG(X)     *(wreg[X])
#define SET_W_REG(X, Y) (*(wreg[X])) = (Y)
#define SET_W_REG(X, Y) (*(wreg[X])) = (Y)
#define GET_L_REG(X)     h8_get_reg (sd, X)
#define GET_L_REG(X)     h8_get_reg (sd, X)
#define SET_L_REG(X, Y)  h8_set_reg (sd, X, Y)
#define SET_L_REG(X, Y)  h8_set_reg (sd, X, Y)
 
 
#define GET_MEMORY_L(X) \
#define GET_MEMORY_L(X) \
  ((X) < memory_size \
  ((X) < memory_size \
   ? ((h8_get_memory (sd, (X)+0) << 24) | (h8_get_memory (sd, (X)+1) << 16)  \
   ? ((h8_get_memory (sd, (X)+0) << 24) | (h8_get_memory (sd, (X)+1) << 16)  \
    | (h8_get_memory (sd, (X)+2) <<  8) | (h8_get_memory (sd, (X)+3) <<  0)) \
    | (h8_get_memory (sd, (X)+2) <<  8) | (h8_get_memory (sd, (X)+3) <<  0)) \
   : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 24) \
   : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 24) \
    | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 16) \
    | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 16) \
    | (h8_get_eightbit (sd, ((X)+2) & 0xff) <<  8) \
    | (h8_get_eightbit (sd, ((X)+2) & 0xff) <<  8) \
    | (h8_get_eightbit (sd, ((X)+3) & 0xff) <<  0)))
    | (h8_get_eightbit (sd, ((X)+3) & 0xff) <<  0)))
 
 
#define GET_MEMORY_W(X) \
#define GET_MEMORY_W(X) \
  ((X) < memory_size \
  ((X) < memory_size \
   ? ((h8_get_memory   (sd, (X)+0) << 8) \
   ? ((h8_get_memory   (sd, (X)+0) << 8) \
    | (h8_get_memory   (sd, (X)+1) << 0)) \
    | (h8_get_memory   (sd, (X)+1) << 0)) \
   : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 8) \
   : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 8) \
    | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 0)))
    | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 0)))
 
 
 
 
#define GET_MEMORY_B(X) \
#define GET_MEMORY_B(X) \
  ((X) < memory_size ? (h8_get_memory   (sd, (X))) \
  ((X) < memory_size ? (h8_get_memory   (sd, (X))) \
                     : (h8_get_eightbit (sd, (X) & 0xff)))
                     : (h8_get_eightbit (sd, (X) & 0xff)))
 
 
#define SET_MEMORY_L(X, Y)  \
#define SET_MEMORY_L(X, Y)  \
{  register unsigned char *_p; register int __y = (Y); \
{  register unsigned char *_p; register int __y = (Y); \
   _p = ((X) < memory_size ? h8_get_memory_buf   (sd) +  (X) : \
   _p = ((X) < memory_size ? h8_get_memory_buf   (sd) +  (X) : \
                             h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
                             h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
   _p[0] = __y >> 24; _p[1] = __y >> 16; \
   _p[0] = __y >> 24; _p[1] = __y >> 16; \
   _p[2] = __y >>  8; _p[3] = __y >>  0; \
   _p[2] = __y >>  8; _p[3] = __y >>  0; \
}
}
 
 
#define SET_MEMORY_W(X, Y) \
#define SET_MEMORY_W(X, Y) \
{  register unsigned char *_p; register int __y = (Y); \
{  register unsigned char *_p; register int __y = (Y); \
   _p = ((X) < memory_size ? h8_get_memory_buf   (sd) +  (X) : \
   _p = ((X) < memory_size ? h8_get_memory_buf   (sd) +  (X) : \
                             h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
                             h8_get_eightbit_buf (sd) + ((X) & 0xff)); \
   _p[0] = __y >> 8; _p[1] = __y; \
   _p[0] = __y >> 8; _p[1] = __y; \
}
}
 
 
#define SET_MEMORY_B(X, Y) \
#define SET_MEMORY_B(X, Y) \
  ((X) < memory_size ? (h8_set_memory   (sd, (X), (Y))) \
  ((X) < memory_size ? (h8_set_memory   (sd, (X), (Y))) \
                     : (h8_set_eightbit (sd, (X) & 0xff, (Y))))
                     : (h8_set_eightbit (sd, (X) & 0xff, (Y))))
 
 
/* Simulate a memory fetch.
/* Simulate a memory fetch.
   Return 0 for success, -1 for failure.
   Return 0 for success, -1 for failure.
*/
*/
 
 
static int
static int
fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
{
{
  int rn = arg->reg;
  int rn = arg->reg;
  int abs = arg->literal;
  int abs = arg->literal;
  int r;
  int r;
  int t;
  int t;
 
 
  if (val == NULL)
  if (val == NULL)
    return -1;          /* Paranoia.  */
    return -1;          /* Paranoia.  */
 
 
  switch (arg->type)
  switch (arg->type)
    {
    {
      /* Indexed register plus displacement mode:
      /* Indexed register plus displacement mode:
 
 
         This new family of addressing modes are similar to OP_DISP
         This new family of addressing modes are similar to OP_DISP
         (register plus displacement), with two differences:
         (register plus displacement), with two differences:
           1) INDEXB uses only the least significant byte of the register,
           1) INDEXB uses only the least significant byte of the register,
              INDEXW uses only the least significant word, and
              INDEXW uses only the least significant word, and
              INDEXL uses the entire register (just like OP_DISP).
              INDEXL uses the entire register (just like OP_DISP).
         and
         and
           2) The displacement value in abs is multiplied by two
           2) The displacement value in abs is multiplied by two
              for SW-sized operations, and by four for SL-size.
              for SW-sized operations, and by four for SL-size.
 
 
        This gives nine possible variations.
        This gives nine possible variations.
      */
      */
 
 
    case X (OP_INDEXB, SB):
    case X (OP_INDEXB, SB):
    case X (OP_INDEXB, SW):
    case X (OP_INDEXB, SW):
    case X (OP_INDEXB, SL):
    case X (OP_INDEXB, SL):
    case X (OP_INDEXW, SB):
    case X (OP_INDEXW, SB):
    case X (OP_INDEXW, SW):
    case X (OP_INDEXW, SW):
    case X (OP_INDEXW, SL):
    case X (OP_INDEXW, SL):
    case X (OP_INDEXL, SB):
    case X (OP_INDEXL, SB):
    case X (OP_INDEXL, SW):
    case X (OP_INDEXL, SW):
    case X (OP_INDEXL, SL):
    case X (OP_INDEXL, SL):
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      switch (OP_KIND (arg->type)) {
      switch (OP_KIND (arg->type)) {
      case OP_INDEXB:   t &= 0xff;      break;
      case OP_INDEXB:   t &= 0xff;      break;
      case OP_INDEXW:   t &= 0xffff;    break;
      case OP_INDEXW:   t &= 0xffff;    break;
      case OP_INDEXL:
      case OP_INDEXL:
      default:          break;
      default:          break;
      }
      }
      switch (OP_SIZE (arg->type)) {
      switch (OP_SIZE (arg->type)) {
      case SB:
      case SB:
        *val = GET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd));
        *val = GET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd));
        break;
        break;
      case SW:
      case SW:
        *val = GET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd));
        *val = GET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd));
        break;
        break;
      case SL:
      case SL:
        *val = GET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd));
        *val = GET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd));
        break;
        break;
      }
      }
      break;
      break;
 
 
    case X (OP_LOWREG, SB):
    case X (OP_LOWREG, SB):
      *val = GET_L_REG (rn) & 0xff;
      *val = GET_L_REG (rn) & 0xff;
      break;
      break;
    case X (OP_LOWREG, SW):
    case X (OP_LOWREG, SW):
      *val = GET_L_REG (rn) & 0xffff;
      *val = GET_L_REG (rn) & 0xffff;
      break;
      break;
 
 
    case X (OP_REG, SB):        /* Register direct, byte.  */
    case X (OP_REG, SB):        /* Register direct, byte.  */
      *val = GET_B_REG (rn);
      *val = GET_B_REG (rn);
      break;
      break;
    case X (OP_REG, SW):        /* Register direct, word.  */
    case X (OP_REG, SW):        /* Register direct, word.  */
      *val = GET_W_REG (rn);
      *val = GET_W_REG (rn);
      break;
      break;
    case X (OP_REG, SL):        /* Register direct, long.  */
    case X (OP_REG, SL):        /* Register direct, long.  */
      *val = GET_L_REG (rn);
      *val = GET_L_REG (rn);
      break;
      break;
    case X (OP_IMM, SB):        /* Immediate, byte.  */
    case X (OP_IMM, SB):        /* Immediate, byte.  */
    case X (OP_IMM, SW):        /* Immediate, word.  */
    case X (OP_IMM, SW):        /* Immediate, word.  */
    case X (OP_IMM, SL):        /* Immediate, long.  */
    case X (OP_IMM, SL):        /* Immediate, long.  */
      *val = abs;
      *val = abs;
      break;
      break;
    case X (OP_POSTINC, SB):    /* Register indirect w/post-incr: byte.  */
    case X (OP_POSTINC, SB):    /* Register indirect w/post-incr: byte.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      r = GET_MEMORY_B (t);
      r = GET_MEMORY_B (t);
      if (!twice)
      if (!twice)
        t += 1;
        t += 1;
      t = t & h8_get_mask (sd);
      t = t & h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = r;
      *val = r;
      break;
      break;
    case X (OP_POSTINC, SW):    /* Register indirect w/post-incr: word.  */
    case X (OP_POSTINC, SW):    /* Register indirect w/post-incr: word.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      r = GET_MEMORY_W (t);
      r = GET_MEMORY_W (t);
      if (!twice)
      if (!twice)
        t += 2;
        t += 2;
      t = t & h8_get_mask (sd);
      t = t & h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = r;
      *val = r;
      break;
      break;
    case X (OP_POSTINC, SL):    /* Register indirect w/post-incr: long.  */
    case X (OP_POSTINC, SL):    /* Register indirect w/post-incr: long.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      r = GET_MEMORY_L (t);
      r = GET_MEMORY_L (t);
      if (!twice)
      if (!twice)
        t += 4;
        t += 4;
      t = t & h8_get_mask (sd);
      t = t & h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = r;
      *val = r;
      break;
      break;
 
 
    case X (OP_POSTDEC, SB):    /* Register indirect w/post-decr: byte.  */
    case X (OP_POSTDEC, SB):    /* Register indirect w/post-decr: byte.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      r = GET_MEMORY_B (t);
      r = GET_MEMORY_B (t);
      if (!twice)
      if (!twice)
        t -= 1;
        t -= 1;
      t = t & h8_get_mask (sd);
      t = t & h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = r;
      *val = r;
      break;
      break;
    case X (OP_POSTDEC, SW):    /* Register indirect w/post-decr: word.  */
    case X (OP_POSTDEC, SW):    /* Register indirect w/post-decr: word.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      r = GET_MEMORY_W (t);
      r = GET_MEMORY_W (t);
      if (!twice)
      if (!twice)
        t -= 2;
        t -= 2;
      t = t & h8_get_mask (sd);
      t = t & h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = r;
      *val = r;
      break;
      break;
    case X (OP_POSTDEC, SL):    /* Register indirect w/post-decr: long.  */
    case X (OP_POSTDEC, SL):    /* Register indirect w/post-decr: long.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      r = GET_MEMORY_L (t);
      r = GET_MEMORY_L (t);
      if (!twice)
      if (!twice)
        t -= 4;
        t -= 4;
      t = t & h8_get_mask (sd);
      t = t & h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = r;
      *val = r;
      break;
      break;
 
 
    case X (OP_PREDEC, SB):     /* Register indirect w/pre-decr: byte.  */
    case X (OP_PREDEC, SB):     /* Register indirect w/pre-decr: byte.  */
      t = GET_L_REG (rn) - 1;
      t = GET_L_REG (rn) - 1;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = GET_MEMORY_B (t);
      *val = GET_MEMORY_B (t);
      break;
      break;
 
 
    case X (OP_PREDEC, SW):     /* Register indirect w/pre-decr: word.  */
    case X (OP_PREDEC, SW):     /* Register indirect w/pre-decr: word.  */
      t = GET_L_REG (rn) - 2;
      t = GET_L_REG (rn) - 2;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = GET_MEMORY_W (t);
      *val = GET_MEMORY_W (t);
      break;
      break;
 
 
    case X (OP_PREDEC, SL):     /* Register indirect w/pre-decr: long.  */
    case X (OP_PREDEC, SL):     /* Register indirect w/pre-decr: long.  */
      t = GET_L_REG (rn) - 4;
      t = GET_L_REG (rn) - 4;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = GET_MEMORY_L (t);
      *val = GET_MEMORY_L (t);
      break;
      break;
 
 
    case X (OP_PREINC, SB):     /* Register indirect w/pre-incr: byte.  */
    case X (OP_PREINC, SB):     /* Register indirect w/pre-incr: byte.  */
      t = GET_L_REG (rn) + 1;
      t = GET_L_REG (rn) + 1;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = GET_MEMORY_B (t);
      *val = GET_MEMORY_B (t);
      break;
      break;
 
 
    case X (OP_PREINC, SW):     /* Register indirect w/pre-incr: long.  */
    case X (OP_PREINC, SW):     /* Register indirect w/pre-incr: long.  */
      t = GET_L_REG (rn) + 2;
      t = GET_L_REG (rn) + 2;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = GET_MEMORY_W (t);
      *val = GET_MEMORY_W (t);
      break;
      break;
 
 
    case X (OP_PREINC, SL):     /* Register indirect w/pre-incr: long.  */
    case X (OP_PREINC, SL):     /* Register indirect w/pre-incr: long.  */
      t = GET_L_REG (rn) + 4;
      t = GET_L_REG (rn) + 4;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      *val = GET_MEMORY_L (t);
      *val = GET_MEMORY_L (t);
      break;
      break;
 
 
    case X (OP_DISP, SB):       /* Register indirect w/displacement: byte.  */
    case X (OP_DISP, SB):       /* Register indirect w/displacement: byte.  */
      t = GET_L_REG (rn) + abs;
      t = GET_L_REG (rn) + abs;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      *val = GET_MEMORY_B (t);
      *val = GET_MEMORY_B (t);
      break;
      break;
 
 
    case X (OP_DISP, SW):       /* Register indirect w/displacement: word.  */
    case X (OP_DISP, SW):       /* Register indirect w/displacement: word.  */
      t = GET_L_REG (rn) + abs;
      t = GET_L_REG (rn) + abs;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      *val = GET_MEMORY_W (t);
      *val = GET_MEMORY_W (t);
      break;
      break;
 
 
    case X (OP_DISP, SL):       /* Register indirect w/displacement: long.  */
    case X (OP_DISP, SL):       /* Register indirect w/displacement: long.  */
      t = GET_L_REG (rn) + abs;
      t = GET_L_REG (rn) + abs;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      *val =GET_MEMORY_L (t);
      *val =GET_MEMORY_L (t);
      break;
      break;
 
 
    case X (OP_MEM, SL):        /* Absolute memory address, long.  */
    case X (OP_MEM, SL):        /* Absolute memory address, long.  */
      t = GET_MEMORY_L (abs);
      t = GET_MEMORY_L (abs);
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      *val = t;
      *val = t;
      break;
      break;
 
 
    case X (OP_MEM, SW):        /* Absolute memory address, word.  */
    case X (OP_MEM, SW):        /* Absolute memory address, word.  */
      t = GET_MEMORY_W (abs);
      t = GET_MEMORY_W (abs);
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      *val = t;
      *val = t;
      break;
      break;
 
 
    case X (OP_PCREL, SB):      /* PC relative (for jump, branch etc).  */
    case X (OP_PCREL, SB):      /* PC relative (for jump, branch etc).  */
    case X (OP_PCREL, SW):
    case X (OP_PCREL, SW):
    case X (OP_PCREL, SL):
    case X (OP_PCREL, SL):
    case X (OP_PCREL, SN):
    case X (OP_PCREL, SN):
      *val = abs;
      *val = abs;
      break;
      break;
 
 
    case X (OP_MEM, SB):        /* Why isn't this implemented?  */
    case X (OP_MEM, SB):        /* Why isn't this implemented?  */
    default:
    default:
      sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
      sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
      return -1;
      return -1;
    }
    }
  return 0;      /* Success.  */
  return 0;      /* Success.  */
}
}
 
 
/* Normal fetch.  */
/* Normal fetch.  */
 
 
static int
static int
fetch (SIM_DESC sd, ea_type *arg, int *val)
fetch (SIM_DESC sd, ea_type *arg, int *val)
{
{
  return fetch_1 (sd, arg, val, 0);
  return fetch_1 (sd, arg, val, 0);
}
}
 
 
/* Fetch which will be followed by a store to the same location.
/* Fetch which will be followed by a store to the same location.
   The difference being that we don't want to do a post-increment
   The difference being that we don't want to do a post-increment
   or post-decrement at this time: we'll do it when we store.  */
   or post-decrement at this time: we'll do it when we store.  */
 
 
static int
static int
fetch2 (SIM_DESC sd, ea_type *arg, int *val)
fetch2 (SIM_DESC sd, ea_type *arg, int *val)
{
{
  return fetch_1 (sd, arg, val, 1);
  return fetch_1 (sd, arg, val, 1);
}
}
 
 
/* Simulate a memory store.
/* Simulate a memory store.
   Return 0 for success, -1 for failure.
   Return 0 for success, -1 for failure.
*/
*/
 
 
static int
static int
store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
{
{
  int rn = arg->reg;
  int rn = arg->reg;
  int abs = arg->literal;
  int abs = arg->literal;
  int t;
  int t;
 
 
  switch (arg->type)
  switch (arg->type)
    {
    {
      /* Indexed register plus displacement mode:
      /* Indexed register plus displacement mode:
 
 
         This new family of addressing modes are similar to OP_DISP
         This new family of addressing modes are similar to OP_DISP
         (register plus displacement), with two differences:
         (register plus displacement), with two differences:
           1) INDEXB uses only the least significant byte of the register,
           1) INDEXB uses only the least significant byte of the register,
              INDEXW uses only the least significant word, and
              INDEXW uses only the least significant word, and
              INDEXL uses the entire register (just like OP_DISP).
              INDEXL uses the entire register (just like OP_DISP).
         and
         and
           2) The displacement value in abs is multiplied by two
           2) The displacement value in abs is multiplied by two
              for SW-sized operations, and by four for SL-size.
              for SW-sized operations, and by four for SL-size.
 
 
        This gives nine possible variations.
        This gives nine possible variations.
      */
      */
 
 
    case X (OP_INDEXB, SB):
    case X (OP_INDEXB, SB):
    case X (OP_INDEXB, SW):
    case X (OP_INDEXB, SW):
    case X (OP_INDEXB, SL):
    case X (OP_INDEXB, SL):
    case X (OP_INDEXW, SB):
    case X (OP_INDEXW, SB):
    case X (OP_INDEXW, SW):
    case X (OP_INDEXW, SW):
    case X (OP_INDEXW, SL):
    case X (OP_INDEXW, SL):
    case X (OP_INDEXL, SB):
    case X (OP_INDEXL, SB):
    case X (OP_INDEXL, SW):
    case X (OP_INDEXL, SW):
    case X (OP_INDEXL, SL):
    case X (OP_INDEXL, SL):
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      switch (OP_KIND (arg->type)) {
      switch (OP_KIND (arg->type)) {
      case OP_INDEXB:   t &= 0xff;      break;
      case OP_INDEXB:   t &= 0xff;      break;
      case OP_INDEXW:   t &= 0xffff;    break;
      case OP_INDEXW:   t &= 0xffff;    break;
      case OP_INDEXL:
      case OP_INDEXL:
      default:          break;
      default:          break;
      }
      }
      switch (OP_SIZE (arg->type)) {
      switch (OP_SIZE (arg->type)) {
      case SB:
      case SB:
        SET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd), n);
        SET_MEMORY_B ((t * 1 + abs) & h8_get_mask (sd), n);
        break;
        break;
      case SW:
      case SW:
        SET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd), n);
        SET_MEMORY_W ((t * 2 + abs) & h8_get_mask (sd), n);
        break;
        break;
      case SL:
      case SL:
        SET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd), n);
        SET_MEMORY_L ((t * 4 + abs) & h8_get_mask (sd), n);
        break;
        break;
      }
      }
      break;
      break;
 
 
    case X (OP_REG, SB):        /* Register direct, byte.  */
    case X (OP_REG, SB):        /* Register direct, byte.  */
      SET_B_REG (rn, n);
      SET_B_REG (rn, n);
      break;
      break;
    case X (OP_REG, SW):        /* Register direct, word.  */
    case X (OP_REG, SW):        /* Register direct, word.  */
      SET_W_REG (rn, n);
      SET_W_REG (rn, n);
      break;
      break;
    case X (OP_REG, SL):        /* Register direct, long.  */
    case X (OP_REG, SL):        /* Register direct, long.  */
      SET_L_REG (rn, n);
      SET_L_REG (rn, n);
      break;
      break;
 
 
    case X (OP_PREDEC, SB):     /* Register indirect w/pre-decr, byte.  */
    case X (OP_PREDEC, SB):     /* Register indirect w/pre-decr, byte.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      if (!twice)
      if (!twice)
        t -= 1;
        t -= 1;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      SET_MEMORY_B (t, n);
      SET_MEMORY_B (t, n);
 
 
      break;
      break;
    case X (OP_PREDEC, SW):     /* Register indirect w/pre-decr, word.  */
    case X (OP_PREDEC, SW):     /* Register indirect w/pre-decr, word.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      if (!twice)
      if (!twice)
        t -= 2;
        t -= 2;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      SET_MEMORY_W (t, n);
      SET_MEMORY_W (t, n);
      break;
      break;
 
 
    case X (OP_PREDEC, SL):     /* Register indirect w/pre-decr, long.  */
    case X (OP_PREDEC, SL):     /* Register indirect w/pre-decr, long.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      if (!twice)
      if (!twice)
        t -= 4;
        t -= 4;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      SET_MEMORY_L (t, n);
      SET_MEMORY_L (t, n);
      break;
      break;
 
 
    case X (OP_PREINC, SB):     /* Register indirect w/pre-incr, byte.  */
    case X (OP_PREINC, SB):     /* Register indirect w/pre-incr, byte.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      if (!twice)
      if (!twice)
        t += 1;
        t += 1;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      SET_MEMORY_B (t, n);
      SET_MEMORY_B (t, n);
 
 
      break;
      break;
    case X (OP_PREINC, SW):     /* Register indirect w/pre-incr, word.  */
    case X (OP_PREINC, SW):     /* Register indirect w/pre-incr, word.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      if (!twice)
      if (!twice)
        t += 2;
        t += 2;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      SET_MEMORY_W (t, n);
      SET_MEMORY_W (t, n);
      break;
      break;
 
 
    case X (OP_PREINC, SL):     /* Register indirect w/pre-incr, long.  */
    case X (OP_PREINC, SL):     /* Register indirect w/pre-incr, long.  */
      t = GET_L_REG (rn);
      t = GET_L_REG (rn);
      if (!twice)
      if (!twice)
        t += 4;
        t += 4;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_L_REG (rn, t);
      SET_L_REG (rn, t);
      SET_MEMORY_L (t, n);
      SET_MEMORY_L (t, n);
      break;
      break;
 
 
    case X (OP_POSTDEC, SB):    /* Register indirect w/post-decr, byte.  */
    case X (OP_POSTDEC, SB):    /* Register indirect w/post-decr, byte.  */
      t = GET_L_REG (rn) & h8_get_mask (sd);
      t = GET_L_REG (rn) & h8_get_mask (sd);
      SET_MEMORY_B (t, n);
      SET_MEMORY_B (t, n);
      SET_L_REG (rn, t - 1);
      SET_L_REG (rn, t - 1);
      break;
      break;
 
 
    case X (OP_POSTDEC, SW):    /* Register indirect w/post-decr, word.  */
    case X (OP_POSTDEC, SW):    /* Register indirect w/post-decr, word.  */
      t = GET_L_REG (rn) & h8_get_mask (sd);
      t = GET_L_REG (rn) & h8_get_mask (sd);
      SET_MEMORY_W (t, n);
      SET_MEMORY_W (t, n);
      SET_L_REG (rn, t - 2);
      SET_L_REG (rn, t - 2);
      break;
      break;
 
 
    case X (OP_POSTDEC, SL):    /* Register indirect w/post-decr, long.  */
    case X (OP_POSTDEC, SL):    /* Register indirect w/post-decr, long.  */
      t = GET_L_REG (rn) & h8_get_mask (sd);
      t = GET_L_REG (rn) & h8_get_mask (sd);
      SET_MEMORY_L (t, n);
      SET_MEMORY_L (t, n);
      SET_L_REG (rn, t - 4);
      SET_L_REG (rn, t - 4);
      break;
      break;
 
 
    case X (OP_POSTINC, SB):    /* Register indirect w/post-incr, byte.  */
    case X (OP_POSTINC, SB):    /* Register indirect w/post-incr, byte.  */
      t = GET_L_REG (rn) & h8_get_mask (sd);
      t = GET_L_REG (rn) & h8_get_mask (sd);
      SET_MEMORY_B (t, n);
      SET_MEMORY_B (t, n);
      SET_L_REG (rn, t + 1);
      SET_L_REG (rn, t + 1);
      break;
      break;
 
 
    case X (OP_POSTINC, SW):    /* Register indirect w/post-incr, word.  */
    case X (OP_POSTINC, SW):    /* Register indirect w/post-incr, word.  */
      t = GET_L_REG (rn) & h8_get_mask (sd);
      t = GET_L_REG (rn) & h8_get_mask (sd);
      SET_MEMORY_W (t, n);
      SET_MEMORY_W (t, n);
      SET_L_REG (rn, t + 2);
      SET_L_REG (rn, t + 2);
      break;
      break;
 
 
    case X (OP_POSTINC, SL):    /* Register indirect w/post-incr, long.  */
    case X (OP_POSTINC, SL):    /* Register indirect w/post-incr, long.  */
      t = GET_L_REG (rn) & h8_get_mask (sd);
      t = GET_L_REG (rn) & h8_get_mask (sd);
      SET_MEMORY_L (t, n);
      SET_MEMORY_L (t, n);
      SET_L_REG (rn, t + 4);
      SET_L_REG (rn, t + 4);
      break;
      break;
 
 
    case X (OP_DISP, SB):       /* Register indirect w/displacement, byte.  */
    case X (OP_DISP, SB):       /* Register indirect w/displacement, byte.  */
      t = GET_L_REG (rn) + abs;
      t = GET_L_REG (rn) + abs;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_MEMORY_B (t, n);
      SET_MEMORY_B (t, n);
      break;
      break;
 
 
    case X (OP_DISP, SW):       /* Register indirect w/displacement, word.  */
    case X (OP_DISP, SW):       /* Register indirect w/displacement, word.  */
      t = GET_L_REG (rn) + abs;
      t = GET_L_REG (rn) + abs;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_MEMORY_W (t, n);
      SET_MEMORY_W (t, n);
      break;
      break;
 
 
    case X (OP_DISP, SL):       /* Register indirect w/displacement, long.  */
    case X (OP_DISP, SL):       /* Register indirect w/displacement, long.  */
      t = GET_L_REG (rn) + abs;
      t = GET_L_REG (rn) + abs;
      t &= h8_get_mask (sd);
      t &= h8_get_mask (sd);
      SET_MEMORY_L (t, n);
      SET_MEMORY_L (t, n);
      break;
      break;
 
 
 
 
    case X (OP_MEM, SB):        /* Why isn't this implemented?  */
    case X (OP_MEM, SB):        /* Why isn't this implemented?  */
    case X (OP_MEM, SW):        /* Why isn't this implemented?  */
    case X (OP_MEM, SW):        /* Why isn't this implemented?  */
    case X (OP_MEM, SL):        /* Why isn't this implemented?  */
    case X (OP_MEM, SL):        /* Why isn't this implemented?  */
    default:
    default:
      sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
      sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
      return -1;
      return -1;
    }
    }
  return 0;
  return 0;
}
}
 
 
/* Normal store.  */
/* Normal store.  */
 
 
static int
static int
store (SIM_DESC sd, ea_type *arg, int n)
store (SIM_DESC sd, ea_type *arg, int n)
{
{
  return store_1 (sd, arg, n, 0);
  return store_1 (sd, arg, n, 0);
}
}
 
 
/* Store which follows a fetch from the same location.
/* Store which follows a fetch from the same location.
   The difference being that we don't want to do a pre-increment
   The difference being that we don't want to do a pre-increment
   or pre-decrement at this time: it was already done when we fetched.  */
   or pre-decrement at this time: it was already done when we fetched.  */
 
 
static int
static int
store2 (SIM_DESC sd, ea_type *arg, int n)
store2 (SIM_DESC sd, ea_type *arg, int n)
{
{
  return store_1 (sd, arg, n, 1);
  return store_1 (sd, arg, n, 1);
}
}
 
 
static union
static union
{
{
  short int i;
  short int i;
  struct
  struct
    {
    {
      char low;
      char low;
      char high;
      char high;
    }
    }
  u;
  u;
} littleendian;
} littleendian;
 
 
/* Flag to be set whenever a new SIM_DESC object is created.  */
/* Flag to be set whenever a new SIM_DESC object is created.  */
static int init_pointers_needed = 1;
static int init_pointers_needed = 1;
 
 
static void
static void
init_pointers (SIM_DESC sd)
init_pointers (SIM_DESC sd)
{
{
  if (init_pointers_needed)
  if (init_pointers_needed)
    {
    {
      int i;
      int i;
 
 
      littleendian.i = 1;
      littleendian.i = 1;
 
 
      if (h8300smode && !h8300_normal_mode)
      if (h8300smode && !h8300_normal_mode)
        memory_size = H8300S_MSIZE;
        memory_size = H8300S_MSIZE;
      else if (h8300hmode && !h8300_normal_mode)
      else if (h8300hmode && !h8300_normal_mode)
        memory_size = H8300H_MSIZE;
        memory_size = H8300H_MSIZE;
      else
      else
        memory_size = H8300_MSIZE;
        memory_size = H8300_MSIZE;
      /* `msize' must be a power of two.  */
      /* `msize' must be a power of two.  */
      if ((memory_size & (memory_size - 1)) != 0)
      if ((memory_size & (memory_size - 1)) != 0)
        {
        {
          (*sim_callback->printf_filtered)
          (*sim_callback->printf_filtered)
            (sim_callback,
            (sim_callback,
             "init_pointers: bad memory size %d, defaulting to %d.\n",
             "init_pointers: bad memory size %d, defaulting to %d.\n",
             memory_size, memory_size = H8300S_MSIZE);
             memory_size, memory_size = H8300S_MSIZE);
        }
        }
 
 
      if (h8_get_memory_buf (sd))
      if (h8_get_memory_buf (sd))
        free (h8_get_memory_buf (sd));
        free (h8_get_memory_buf (sd));
      if (h8_get_cache_idx_buf (sd))
      if (h8_get_cache_idx_buf (sd))
        free (h8_get_cache_idx_buf (sd));
        free (h8_get_cache_idx_buf (sd));
      if (h8_get_eightbit_buf (sd))
      if (h8_get_eightbit_buf (sd))
        free (h8_get_eightbit_buf (sd));
        free (h8_get_eightbit_buf (sd));
 
 
      h8_set_memory_buf (sd, (unsigned char *)
      h8_set_memory_buf (sd, (unsigned char *)
                         calloc (sizeof (char), memory_size));
                         calloc (sizeof (char), memory_size));
      h8_set_cache_idx_buf (sd, (unsigned short *)
      h8_set_cache_idx_buf (sd, (unsigned short *)
                            calloc (sizeof (short), memory_size));
                            calloc (sizeof (short), memory_size));
      sd->memory_size = memory_size;
      sd->memory_size = memory_size;
      h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
      h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
 
 
      h8_set_mask (sd, memory_size - 1);
      h8_set_mask (sd, memory_size - 1);
 
 
      memset (h8_get_reg_buf (sd), 0, sizeof (((STATE_CPU (sd, 0))->regs)));
      memset (h8_get_reg_buf (sd), 0, sizeof (((STATE_CPU (sd, 0))->regs)));
 
 
      for (i = 0; i < 8; i++)
      for (i = 0; i < 8; i++)
        {
        {
          /* FIXME: rewrite using local buffer.  */
          /* FIXME: rewrite using local buffer.  */
          unsigned char *p = (unsigned char *) (h8_get_reg_buf (sd) + i);
          unsigned char *p = (unsigned char *) (h8_get_reg_buf (sd) + i);
          unsigned char *e = (unsigned char *) (h8_get_reg_buf (sd) + i + 1);
          unsigned char *e = (unsigned char *) (h8_get_reg_buf (sd) + i + 1);
          unsigned short *q = (unsigned short *) (h8_get_reg_buf (sd) + i);
          unsigned short *q = (unsigned short *) (h8_get_reg_buf (sd) + i);
          unsigned short *u = (unsigned short *) (h8_get_reg_buf (sd) + i + 1);
          unsigned short *u = (unsigned short *) (h8_get_reg_buf (sd) + i + 1);
          h8_set_reg (sd, i, 0x00112233);
          h8_set_reg (sd, i, 0x00112233);
 
 
          while (p < e)
          while (p < e)
            {
            {
              if (*p == 0x22)
              if (*p == 0x22)
                  breg[i] = p;
                  breg[i] = p;
              if (*p == 0x33)
              if (*p == 0x33)
                  breg[i + 8] = p;
                  breg[i + 8] = p;
              if (*p == 0x11)
              if (*p == 0x11)
                breg[i + 16] = p;
                breg[i + 16] = p;
              if (*p == 0x00)
              if (*p == 0x00)
                breg[i + 24] = p;
                breg[i + 24] = p;
              p++;
              p++;
            }
            }
 
 
          wreg[i] = wreg[i + 8] = 0;
          wreg[i] = wreg[i + 8] = 0;
          while (q < u)
          while (q < u)
            {
            {
              if (*q == 0x2233)
              if (*q == 0x2233)
                {
                {
                  wreg[i] = q;
                  wreg[i] = q;
                }
                }
              if (*q == 0x0011)
              if (*q == 0x0011)
                {
                {
                  wreg[i + 8] = q;
                  wreg[i + 8] = q;
                }
                }
              q++;
              q++;
            }
            }
 
 
          if (wreg[i] == 0 || wreg[i + 8] == 0)
          if (wreg[i] == 0 || wreg[i + 8] == 0)
            (*sim_callback->printf_filtered) (sim_callback,
            (*sim_callback->printf_filtered) (sim_callback,
                                              "init_pointers: internal error.\n");
                                              "init_pointers: internal error.\n");
 
 
          h8_set_reg (sd, i, 0);
          h8_set_reg (sd, i, 0);
          lreg[i] = h8_get_reg_buf (sd) + i;
          lreg[i] = h8_get_reg_buf (sd) + i;
        }
        }
 
 
      /* Note: sim uses pseudo-register ZERO as a zero register.  */
      /* Note: sim uses pseudo-register ZERO as a zero register.  */
      lreg[ZERO_REGNUM] = h8_get_reg_buf (sd) + ZERO_REGNUM;
      lreg[ZERO_REGNUM] = h8_get_reg_buf (sd) + ZERO_REGNUM;
      init_pointers_needed = 0;
      init_pointers_needed = 0;
 
 
      /* Initialize the seg registers.  */
      /* Initialize the seg registers.  */
      if (!sd->sim_cache)
      if (!sd->sim_cache)
        set_simcache_size (sd, CSIZE);
        set_simcache_size (sd, CSIZE);
    }
    }
}
}
 
 
/* Grotty global variable for use by control_c signal handler.  */
/* Grotty global variable for use by control_c signal handler.  */
static SIM_DESC control_c_sim_desc;
static SIM_DESC control_c_sim_desc;
 
 
static void
static void
control_c (int sig)
control_c (int sig)
{
{
  sim_engine_set_run_state (control_c_sim_desc, sim_stopped, SIGINT);
  sim_engine_set_run_state (control_c_sim_desc, sim_stopped, SIGINT);
}
}
 
 
int
int
sim_stop (SIM_DESC sd)
sim_stop (SIM_DESC sd)
{
{
  /* FIXME: use a real signal value.  */
  /* FIXME: use a real signal value.  */
  sim_engine_set_run_state (sd, sim_stopped, SIGINT);
  sim_engine_set_run_state (sd, sim_stopped, SIGINT);
  return 1;
  return 1;
}
}
 
 
#define OBITOP(name, f, s, op)                  \
#define OBITOP(name, f, s, op)                  \
case O (name, SB):                              \
case O (name, SB):                              \
{                                               \
{                                               \
  int m, tmp;                                   \
  int m, tmp;                                   \
                                                \
                                                \
  if (f)                                        \
  if (f)                                        \
    if (fetch (sd, &code->dst, &ea))            \
    if (fetch (sd, &code->dst, &ea))            \
      goto end;                                 \
      goto end;                                 \
  if (fetch (sd, &code->src, &tmp))             \
  if (fetch (sd, &code->src, &tmp))             \
    goto end;                                   \
    goto end;                                   \
  m = 1 << (tmp & 7);                           \
  m = 1 << (tmp & 7);                           \
  op;                                           \
  op;                                           \
  if (s)                                        \
  if (s)                                        \
    if (store (sd, &code->dst,ea))              \
    if (store (sd, &code->dst,ea))              \
      goto end;                                 \
      goto end;                                 \
  goto next;                                    \
  goto next;                                    \
}
}
 
 
void
void
sim_resume (SIM_DESC sd, int step, int siggnal)
sim_resume (SIM_DESC sd, int step, int siggnal)
{
{
  static int init1;
  static int init1;
  int cycles = 0;
  int cycles = 0;
  int insts = 0;
  int insts = 0;
  int tick_start = get_now ();
  int tick_start = get_now ();
  void (*prev) ();
  void (*prev) ();
  int poll_count = 0;
  int poll_count = 0;
  int res;
  int res;
  int tmp;
  int tmp;
  int rd;
  int rd;
  int ea;
  int ea;
  int bit;
  int bit;
  int pc;
  int pc;
  int c, nz, v, n, u, h, ui, intMaskBit;
  int c, nz, v, n, u, h, ui, intMaskBit;
  int trace, intMask;
  int trace, intMask;
  int oldmask;
  int oldmask;
  enum sim_stop reason;
  enum sim_stop reason;
  int sigrc;
  int sigrc;
 
 
  init_pointers (sd);
  init_pointers (sd);
 
 
  control_c_sim_desc = sd;
  control_c_sim_desc = sd;
  prev = signal (SIGINT, control_c);
  prev = signal (SIGINT, control_c);
 
 
  if (step)
  if (step)
    {
    {
      sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
      sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
    }
    }
  else
  else
    {
    {
      sim_engine_set_run_state (sd, sim_running, 0);
      sim_engine_set_run_state (sd, sim_running, 0);
    }
    }
 
 
  pc = h8_get_pc (sd);
  pc = h8_get_pc (sd);
 
 
  /* The PC should never be odd.  */
  /* The PC should never be odd.  */
  if (pc & 0x1)
  if (pc & 0x1)
    {
    {
      sim_engine_set_run_state (sd, sim_stopped, SIGBUS);
      sim_engine_set_run_state (sd, sim_stopped, SIGBUS);
      return;
      return;
    }
    }
 
 
  /* Get Status Register (flags).  */
  /* Get Status Register (flags).  */
  GETSR (sd);
  GETSR (sd);
 
 
  if (h8300smode)       /* Get exr.  */
  if (h8300smode)       /* Get exr.  */
    {
    {
      trace = (h8_get_exr (sd) >> 7) & 1;
      trace = (h8_get_exr (sd) >> 7) & 1;
      intMask = h8_get_exr (sd) & 7;
      intMask = h8_get_exr (sd) & 7;
    }
    }
 
 
  oldmask = h8_get_mask (sd);
  oldmask = h8_get_mask (sd);
  if (!h8300hmode || h8300_normal_mode)
  if (!h8300hmode || h8300_normal_mode)
    h8_set_mask (sd, 0xffff);
    h8_set_mask (sd, 0xffff);
  do
  do
    {
    {
      unsigned short cidx;
      unsigned short cidx;
      decoded_inst *code;
      decoded_inst *code;
 
 
    top:
    top:
      cidx = h8_get_cache_idx (sd, pc);
      cidx = h8_get_cache_idx (sd, pc);
      if (cidx == (unsigned short) -1 ||
      if (cidx == (unsigned short) -1 ||
          cidx >= sd->sim_cache_size)
          cidx >= sd->sim_cache_size)
        goto illegal;
        goto illegal;
 
 
      code = sd->sim_cache + cidx;
      code = sd->sim_cache + cidx;
 
 
#if ADEBUG
#if ADEBUG
      if (debug)
      if (debug)
        {
        {
          printf ("%x %d %s\n", pc, code->opcode,
          printf ("%x %d %s\n", pc, code->opcode,
                  code->op ? code->op->name : "**");
                  code->op ? code->op->name : "**");
        }
        }
      h8_increment_stats (sd, code->opcode);
      h8_increment_stats (sd, code->opcode);
#endif
#endif
 
 
      if (code->opcode)
      if (code->opcode)
        {
        {
          cycles += code->cycles;
          cycles += code->cycles;
          insts++;
          insts++;
        }
        }
 
 
      switch (code->opcode)
      switch (code->opcode)
        {
        {
        case 0:
        case 0:
          /*
          /*
           * This opcode is a fake for when we get to an
           * This opcode is a fake for when we get to an
           * instruction which hasnt been compiled
           * instruction which hasnt been compiled
           */
           */
          compile (sd, pc);
          compile (sd, pc);
          goto top;
          goto top;
          break;
          break;
 
 
        case O (O_MOVAB, SL):
        case O (O_MOVAB, SL):
        case O (O_MOVAW, SL):
        case O (O_MOVAW, SL):
        case O (O_MOVAL, SL):
        case O (O_MOVAL, SL):
          /* 1) Evaluate 2nd argument (dst).
          /* 1) Evaluate 2nd argument (dst).
             2) Mask / zero extend according to whether 1st argument (src)
             2) Mask / zero extend according to whether 1st argument (src)
                is INDEXB, INDEXW, or INDEXL.
                is INDEXB, INDEXW, or INDEXL.
             3) Left-shift the result by 0, 1 or 2, according to size of mova
             3) Left-shift the result by 0, 1 or 2, according to size of mova
                (mova/b, mova/w, mova/l).
                (mova/b, mova/w, mova/l).
             4) Add literal value of 1st argument (src).
             4) Add literal value of 1st argument (src).
             5) Store result in 3rd argument (op3).
             5) Store result in 3rd argument (op3).
          */
          */
 
 
          /* Alas, since this is the only instruction with 3 arguments,
          /* Alas, since this is the only instruction with 3 arguments,
             decode doesn't handle them very well.  Some fix-up is required.
             decode doesn't handle them very well.  Some fix-up is required.
 
 
             a) The size of dst is determined by whether src is
             a) The size of dst is determined by whether src is
                INDEXB or INDEXW.  */
                INDEXB or INDEXW.  */
 
 
          if (OP_KIND (code->src.type) == OP_INDEXB)
          if (OP_KIND (code->src.type) == OP_INDEXB)
            code->dst.type = X (OP_KIND (code->dst.type), SB);
            code->dst.type = X (OP_KIND (code->dst.type), SB);
          else if (OP_KIND (code->src.type) == OP_INDEXW)
          else if (OP_KIND (code->src.type) == OP_INDEXW)
            code->dst.type = X (OP_KIND (code->dst.type), SW);
            code->dst.type = X (OP_KIND (code->dst.type), SW);
 
 
          /* b) If op3 == null, then this is the short form of the insn.
          /* b) If op3 == null, then this is the short form of the insn.
                Dst is the dispreg of src, and op3 is the 32-bit form
                Dst is the dispreg of src, and op3 is the 32-bit form
                of the same register.
                of the same register.
          */
          */
 
 
          if (code->op3.type == 0)
          if (code->op3.type == 0)
            {
            {
              /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
              /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
                 We get to compose dst and op3 as follows:
                 We get to compose dst and op3 as follows:
 
 
                     op3 is a 32-bit register, ID == src.reg.
                     op3 is a 32-bit register, ID == src.reg.
                     dst is the same register, but 8 or 16 bits
                     dst is the same register, but 8 or 16 bits
                     depending on whether src is INDEXB or INDEXW.
                     depending on whether src is INDEXB or INDEXW.
              */
              */
 
 
              code->op3.type = X (OP_REG, SL);
              code->op3.type = X (OP_REG, SL);
              code->op3.reg  = code->src.reg;
              code->op3.reg  = code->src.reg;
              code->op3.literal = 0;
              code->op3.literal = 0;
 
 
              if (OP_KIND (code->src.type) == OP_INDEXB)
              if (OP_KIND (code->src.type) == OP_INDEXB)
                {
                {
                  code->dst.type = X (OP_REG, SB);
                  code->dst.type = X (OP_REG, SB);
                  code->dst.reg = code->op3.reg + 8;
                  code->dst.reg = code->op3.reg + 8;
                }
                }
              else
              else
                code->dst.type = X (OP_REG, SW);
                code->dst.type = X (OP_REG, SW);
            }
            }
 
 
          if (fetch (sd, &code->dst, &ea))
          if (fetch (sd, &code->dst, &ea))
            goto end;
            goto end;
 
 
          switch (OP_KIND (code->src.type)) {
          switch (OP_KIND (code->src.type)) {
          case OP_INDEXB:    ea = ea & 0xff;            break;
          case OP_INDEXB:    ea = ea & 0xff;            break;
          case OP_INDEXW:    ea = ea & 0xffff;          break;
          case OP_INDEXW:    ea = ea & 0xffff;          break;
          case OP_INDEXL:                               break;
          case OP_INDEXL:                               break;
          default:           goto illegal;
          default:           goto illegal;
          }
          }
 
 
          switch (code->opcode) {
          switch (code->opcode) {
          case O (O_MOVAB, SL):                         break;
          case O (O_MOVAB, SL):                         break;
          case O (O_MOVAW, SL):     ea = ea << 1;       break;
          case O (O_MOVAW, SL):     ea = ea << 1;       break;
          case O (O_MOVAL, SL):     ea = ea << 2;       break;
          case O (O_MOVAL, SL):     ea = ea << 2;       break;
          default:                  goto illegal;
          default:                  goto illegal;
          }
          }
 
 
          ea = ea + code->src.literal;
          ea = ea + code->src.literal;
 
 
          if (store (sd, &code->op3, ea))
          if (store (sd, &code->op3, ea))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O (O_SUBX, SB):    /* subx, extended sub */
        case O (O_SUBX, SB):    /* subx, extended sub */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = -(ea + C);
          ea = -(ea + C);
          res = rd + ea;
          res = rd + ea;
          goto alu8;
          goto alu8;
 
 
        case O (O_SUBX, SW):    /* subx, extended sub */
        case O (O_SUBX, SW):    /* subx, extended sub */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = -(ea + C);
          ea = -(ea + C);
          res = rd + ea;
          res = rd + ea;
          goto alu16;
          goto alu16;
 
 
        case O (O_SUBX, SL):    /* subx, extended sub */
        case O (O_SUBX, SL):    /* subx, extended sub */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = -(ea + C);
          ea = -(ea + C);
          res = rd + ea;
          res = rd + ea;
          goto alu32;
          goto alu32;
 
 
        case O (O_ADDX, SB):    /* addx, extended add */
        case O (O_ADDX, SB):    /* addx, extended add */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = ea + C;
          ea = ea + C;
          res = rd + ea;
          res = rd + ea;
          goto alu8;
          goto alu8;
 
 
        case O (O_ADDX, SW):    /* addx, extended add */
        case O (O_ADDX, SW):    /* addx, extended add */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = ea + C;
          ea = ea + C;
          res = rd + ea;
          res = rd + ea;
          goto alu16;
          goto alu16;
 
 
        case O (O_ADDX, SL):    /* addx, extended add */
        case O (O_ADDX, SL):    /* addx, extended add */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = ea + C;
          ea = ea + C;
          res = rd + ea;
          res = rd + ea;
          goto alu32;
          goto alu32;
 
 
        case O (O_SUB, SB):             /* sub.b */
        case O (O_SUB, SB):             /* sub.b */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          ea = -ea;
          ea = -ea;
          res = rd + ea;
          res = rd + ea;
          goto alu8;
          goto alu8;
 
 
        case O (O_SUB, SW):             /* sub.w */
        case O (O_SUB, SW):             /* sub.w */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          ea = -ea;
          ea = -ea;
          res = rd + ea;
          res = rd + ea;
          goto alu16;
          goto alu16;
 
 
        case O (O_SUB, SL):             /* sub.l */
        case O (O_SUB, SL):             /* sub.l */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          ea = -ea;
          ea = -ea;
          res = rd + ea;
          res = rd + ea;
          goto alu32;
          goto alu32;
 
 
        case O (O_NEG, SB):             /* neg.b */
        case O (O_NEG, SB):             /* neg.b */
          /* Fetch ea.  */
          /* Fetch ea.  */
          if (fetch2 (sd, &code->src, &ea))
          if (fetch2 (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = -ea;
          ea = -ea;
          rd = 0;
          rd = 0;
          res = rd + ea;
          res = rd + ea;
          goto alu8;
          goto alu8;
 
 
        case O (O_NEG, SW):             /* neg.w */
        case O (O_NEG, SW):             /* neg.w */
          /* Fetch ea.  */
          /* Fetch ea.  */
          if (fetch2 (sd, &code->src, &ea))
          if (fetch2 (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = -ea;
          ea = -ea;
          rd = 0;
          rd = 0;
          res = rd + ea;
          res = rd + ea;
          goto alu16;
          goto alu16;
 
 
        case O (O_NEG, SL):             /* neg.l */
        case O (O_NEG, SL):             /* neg.l */
          /* Fetch ea.  */
          /* Fetch ea.  */
          if (fetch2 (sd, &code->src, &ea))
          if (fetch2 (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = -ea;
          ea = -ea;
          rd = 0;
          rd = 0;
          res = rd + ea;
          res = rd + ea;
          goto alu32;
          goto alu32;
 
 
        case O (O_ADD, SB):             /* add.b */
        case O (O_ADD, SB):             /* add.b */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          res = rd + ea;
          res = rd + ea;
          goto alu8;
          goto alu8;
 
 
        case O (O_ADD, SW):             /* add.w */
        case O (O_ADD, SW):             /* add.w */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          res = rd + ea;
          res = rd + ea;
          goto alu16;
          goto alu16;
 
 
        case O (O_ADD, SL):             /* add.l */
        case O (O_ADD, SL):             /* add.l */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          res = rd + ea;
          res = rd + ea;
          goto alu32;
          goto alu32;
 
 
        case O (O_AND, SB):             /* and.b */
        case O (O_AND, SB):             /* and.b */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          res = rd & ea;
          res = rd & ea;
          goto log8;
          goto log8;
 
 
        case O (O_AND, SW):             /* and.w */
        case O (O_AND, SW):             /* and.w */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          res = rd & ea;
          res = rd & ea;
          goto log16;
          goto log16;
 
 
        case O (O_AND, SL):             /* and.l */
        case O (O_AND, SL):             /* and.l */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          res = rd & ea;
          res = rd & ea;
          goto log32;
          goto log32;
 
 
        case O (O_OR, SB):              /* or.b */
        case O (O_OR, SB):              /* or.b */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          res = rd | ea;
          res = rd | ea;
          goto log8;
          goto log8;
 
 
        case O (O_OR, SW):              /* or.w */
        case O (O_OR, SW):              /* or.w */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          res = rd | ea;
          res = rd | ea;
          goto log16;
          goto log16;
 
 
        case O (O_OR, SL):              /* or.l */
        case O (O_OR, SL):              /* or.l */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          res = rd | ea;
          res = rd | ea;
          goto log32;
          goto log32;
 
 
        case O (O_XOR, SB):             /* xor.b */
        case O (O_XOR, SB):             /* xor.b */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          res = rd ^ ea;
          res = rd ^ ea;
          goto log8;
          goto log8;
 
 
        case O (O_XOR, SW):             /* xor.w */
        case O (O_XOR, SW):             /* xor.w */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          res = rd ^ ea;
          res = rd ^ ea;
          goto log16;
          goto log16;
 
 
        case O (O_XOR, SL):             /* xor.l */
        case O (O_XOR, SL):             /* xor.l */
          /* Fetch rd and ea.  */
          /* Fetch rd and ea.  */
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
          if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          res = rd ^ ea;
          res = rd ^ ea;
          goto log32;
          goto log32;
 
 
        case O (O_MOV, SB):
        case O (O_MOV, SB):
          if (fetch (sd, &code->src, &res))
          if (fetch (sd, &code->src, &res))
            goto end;
            goto end;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto just_flags_log8;
          goto just_flags_log8;
        case O (O_MOV, SW):
        case O (O_MOV, SW):
          if (fetch (sd, &code->src, &res))
          if (fetch (sd, &code->src, &res))
            goto end;
            goto end;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto just_flags_log16;
          goto just_flags_log16;
        case O (O_MOV, SL):
        case O (O_MOV, SL):
          if (fetch (sd, &code->src, &res))
          if (fetch (sd, &code->src, &res))
            goto end;
            goto end;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto just_flags_log32;
          goto just_flags_log32;
 
 
        case O (O_MOVMD, SB):           /* movmd.b */
        case O (O_MOVMD, SB):           /* movmd.b */
          ea = GET_W_REG (4);
          ea = GET_W_REG (4);
          if (ea == 0)
          if (ea == 0)
            ea = 0x10000;
            ea = 0x10000;
 
 
          while (ea--)
          while (ea--)
            {
            {
              rd = GET_MEMORY_B (GET_L_REG (5));
              rd = GET_MEMORY_B (GET_L_REG (5));
              SET_MEMORY_B (GET_L_REG (6), rd);
              SET_MEMORY_B (GET_L_REG (6), rd);
              SET_L_REG (5, GET_L_REG (5) + 1);
              SET_L_REG (5, GET_L_REG (5) + 1);
              SET_L_REG (6, GET_L_REG (6) + 1);
              SET_L_REG (6, GET_L_REG (6) + 1);
              SET_W_REG (4, ea);
              SET_W_REG (4, ea);
            }
            }
          goto next;
          goto next;
 
 
        case O (O_MOVMD, SW):           /* movmd.w */
        case O (O_MOVMD, SW):           /* movmd.w */
          ea = GET_W_REG (4);
          ea = GET_W_REG (4);
          if (ea == 0)
          if (ea == 0)
            ea = 0x10000;
            ea = 0x10000;
 
 
          while (ea--)
          while (ea--)
            {
            {
              rd = GET_MEMORY_W (GET_L_REG (5));
              rd = GET_MEMORY_W (GET_L_REG (5));
              SET_MEMORY_W (GET_L_REG (6), rd);
              SET_MEMORY_W (GET_L_REG (6), rd);
              SET_L_REG (5, GET_L_REG (5) + 2);
              SET_L_REG (5, GET_L_REG (5) + 2);
              SET_L_REG (6, GET_L_REG (6) + 2);
              SET_L_REG (6, GET_L_REG (6) + 2);
              SET_W_REG (4, ea);
              SET_W_REG (4, ea);
            }
            }
          goto next;
          goto next;
 
 
        case O (O_MOVMD, SL):           /* movmd.l */
        case O (O_MOVMD, SL):           /* movmd.l */
          ea = GET_W_REG (4);
          ea = GET_W_REG (4);
          if (ea == 0)
          if (ea == 0)
            ea = 0x10000;
            ea = 0x10000;
 
 
          while (ea--)
          while (ea--)
            {
            {
              rd = GET_MEMORY_L (GET_L_REG (5));
              rd = GET_MEMORY_L (GET_L_REG (5));
              SET_MEMORY_L (GET_L_REG (6), rd);
              SET_MEMORY_L (GET_L_REG (6), rd);
              SET_L_REG (5, GET_L_REG (5) + 4);
              SET_L_REG (5, GET_L_REG (5) + 4);
              SET_L_REG (6, GET_L_REG (6) + 4);
              SET_L_REG (6, GET_L_REG (6) + 4);
              SET_W_REG (4, ea);
              SET_W_REG (4, ea);
            }
            }
          goto next;
          goto next;
 
 
        case O (O_MOVSD, SB):           /* movsd.b */
        case O (O_MOVSD, SB):           /* movsd.b */
          /* This instruction implements strncpy, with a conditional branch.
          /* This instruction implements strncpy, with a conditional branch.
             r4 contains n, r5 contains src, and r6 contains dst.
             r4 contains n, r5 contains src, and r6 contains dst.
             The 16-bit displacement operand is added to the pc
             The 16-bit displacement operand is added to the pc
             if and only if the end of string is reached before
             if and only if the end of string is reached before
             n bytes are transferred.  */
             n bytes are transferred.  */
 
 
          ea = GET_L_REG (4) & 0xffff;
          ea = GET_L_REG (4) & 0xffff;
          if (ea == 0)
          if (ea == 0)
            ea = 0x10000;
            ea = 0x10000;
 
 
          while (ea--)
          while (ea--)
            {
            {
              rd = GET_MEMORY_B (GET_L_REG (5));
              rd = GET_MEMORY_B (GET_L_REG (5));
              SET_MEMORY_B (GET_L_REG (6), rd);
              SET_MEMORY_B (GET_L_REG (6), rd);
              SET_L_REG (5, GET_L_REG (5) + 1);
              SET_L_REG (5, GET_L_REG (5) + 1);
              SET_L_REG (6, GET_L_REG (6) + 1);
              SET_L_REG (6, GET_L_REG (6) + 1);
              SET_W_REG (4, ea);
              SET_W_REG (4, ea);
              if (rd == 0)
              if (rd == 0)
                goto condtrue;
                goto condtrue;
            }
            }
          goto next;
          goto next;
 
 
        case O (O_EEPMOV, SB):          /* eepmov.b */
        case O (O_EEPMOV, SB):          /* eepmov.b */
        case O (O_EEPMOV, SW):          /* eepmov.w */
        case O (O_EEPMOV, SW):          /* eepmov.w */
          if (h8300hmode || h8300smode)
          if (h8300hmode || h8300smode)
            {
            {
              register unsigned char *_src, *_dst;
              register unsigned char *_src, *_dst;
              unsigned int count = ((code->opcode == O (O_EEPMOV, SW))
              unsigned int count = ((code->opcode == O (O_EEPMOV, SW))
                                    ? h8_get_reg (sd, R4_REGNUM) & 0xffff
                                    ? h8_get_reg (sd, R4_REGNUM) & 0xffff
                                    : h8_get_reg (sd, R4_REGNUM) & 0xff);
                                    : h8_get_reg (sd, R4_REGNUM) & 0xff);
 
 
              _src = (h8_get_reg (sd, R5_REGNUM) < memory_size
              _src = (h8_get_reg (sd, R5_REGNUM) < memory_size
                      ? h8_get_memory_buf   (sd) + h8_get_reg (sd, R5_REGNUM)
                      ? h8_get_memory_buf   (sd) + h8_get_reg (sd, R5_REGNUM)
                      : h8_get_eightbit_buf (sd) +
                      : h8_get_eightbit_buf (sd) +
                       (h8_get_reg (sd, R5_REGNUM) & 0xff));
                       (h8_get_reg (sd, R5_REGNUM) & 0xff));
              if ((_src + count) >= (h8_get_memory_buf (sd) + memory_size))
              if ((_src + count) >= (h8_get_memory_buf (sd) + memory_size))
                {
                {
                  if ((_src + count) >= (h8_get_eightbit_buf (sd) + 0x100))
                  if ((_src + count) >= (h8_get_eightbit_buf (sd) + 0x100))
                    goto illegal;
                    goto illegal;
                }
                }
              _dst = (h8_get_reg (sd, R6_REGNUM) < memory_size
              _dst = (h8_get_reg (sd, R6_REGNUM) < memory_size
                      ? h8_get_memory_buf   (sd) + h8_get_reg (sd, R6_REGNUM)
                      ? h8_get_memory_buf   (sd) + h8_get_reg (sd, R6_REGNUM)
                      : h8_get_eightbit_buf (sd) +
                      : h8_get_eightbit_buf (sd) +
                       (h8_get_reg (sd, R6_REGNUM) & 0xff));
                       (h8_get_reg (sd, R6_REGNUM) & 0xff));
 
 
              if ((_dst + count) >= (h8_get_memory_buf (sd) + memory_size))
              if ((_dst + count) >= (h8_get_memory_buf (sd) + memory_size))
                {
                {
                  if ((_dst + count) >= (h8_get_eightbit_buf (sd) + 0x100))
                  if ((_dst + count) >= (h8_get_eightbit_buf (sd) + 0x100))
                    goto illegal;
                    goto illegal;
                }
                }
              memcpy (_dst, _src, count);
              memcpy (_dst, _src, count);
 
 
              h8_set_reg (sd, R5_REGNUM, h8_get_reg (sd, R5_REGNUM) + count);
              h8_set_reg (sd, R5_REGNUM, h8_get_reg (sd, R5_REGNUM) + count);
              h8_set_reg (sd, R6_REGNUM, h8_get_reg (sd, R6_REGNUM) + count);
              h8_set_reg (sd, R6_REGNUM, h8_get_reg (sd, R6_REGNUM) + count);
              h8_set_reg (sd, R4_REGNUM, h8_get_reg (sd, R4_REGNUM) &
              h8_set_reg (sd, R4_REGNUM, h8_get_reg (sd, R4_REGNUM) &
                          ((code->opcode == O (O_EEPMOV, SW))
                          ((code->opcode == O (O_EEPMOV, SW))
                          ? (~0xffff) : (~0xff)));
                          ? (~0xffff) : (~0xff)));
              cycles += 2 * count;
              cycles += 2 * count;
              goto next;
              goto next;
            }
            }
          goto illegal;
          goto illegal;
 
 
        case O (O_ADDS, SL):            /* adds (.l) */
        case O (O_ADDS, SL):            /* adds (.l) */
          /* FIXME fetch.
          /* FIXME fetch.
           * This insn only uses register operands, but still
           * This insn only uses register operands, but still
           * it would be cleaner to use fetch and store...  */
           * it would be cleaner to use fetch and store...  */
          SET_L_REG (code->dst.reg,
          SET_L_REG (code->dst.reg,
                     GET_L_REG (code->dst.reg)
                     GET_L_REG (code->dst.reg)
                     + code->src.literal);
                     + code->src.literal);
 
 
          goto next;
          goto next;
 
 
        case O (O_SUBS, SL):            /* subs (.l) */
        case O (O_SUBS, SL):            /* subs (.l) */
          /* FIXME fetch.
          /* FIXME fetch.
           * This insn only uses register operands, but still
           * This insn only uses register operands, but still
           * it would be cleaner to use fetch and store...  */
           * it would be cleaner to use fetch and store...  */
          SET_L_REG (code->dst.reg,
          SET_L_REG (code->dst.reg,
                     GET_L_REG (code->dst.reg)
                     GET_L_REG (code->dst.reg)
                     - code->src.literal);
                     - code->src.literal);
          goto next;
          goto next;
 
 
        case O (O_CMP, SB):             /* cmp.b */
        case O (O_CMP, SB):             /* cmp.b */
          if (fetch (sd, &code->dst, &rd))
          if (fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = -ea;
          ea = -ea;
          res = rd + ea;
          res = rd + ea;
          goto just_flags_alu8;
          goto just_flags_alu8;
 
 
        case O (O_CMP, SW):             /* cmp.w */
        case O (O_CMP, SW):             /* cmp.w */
          if (fetch (sd, &code->dst, &rd))
          if (fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = -ea;
          ea = -ea;
          res = rd + ea;
          res = rd + ea;
          goto just_flags_alu16;
          goto just_flags_alu16;
 
 
        case O (O_CMP, SL):             /* cmp.l */
        case O (O_CMP, SL):             /* cmp.l */
          if (fetch (sd, &code->dst, &rd))
          if (fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (fetch (sd, &code->src, &ea))
          if (fetch (sd, &code->src, &ea))
            goto end;
            goto end;
          ea = -ea;
          ea = -ea;
          res = rd + ea;
          res = rd + ea;
          goto just_flags_alu32;
          goto just_flags_alu32;
 
 
        case O (O_DEC, SB):             /* dec.b */
        case O (O_DEC, SB):             /* dec.b */
          /* FIXME fetch.
          /* FIXME fetch.
           * This insn only uses register operands, but still
           * This insn only uses register operands, but still
           * it would be cleaner to use fetch and store...  */
           * it would be cleaner to use fetch and store...  */
          rd = GET_B_REG (code->src.reg);
          rd = GET_B_REG (code->src.reg);
          ea = -1;
          ea = -1;
          res = rd + ea;
          res = rd + ea;
          SET_B_REG (code->src.reg, res);
          SET_B_REG (code->src.reg, res);
          goto just_flags_inc8;
          goto just_flags_inc8;
 
 
        case O (O_DEC, SW):             /* dec.w */
        case O (O_DEC, SW):             /* dec.w */
          /* FIXME fetch.
          /* FIXME fetch.
           * This insn only uses register operands, but still
           * This insn only uses register operands, but still
           * it would be cleaner to use fetch and store...  */
           * it would be cleaner to use fetch and store...  */
          rd = GET_W_REG (code->dst.reg);
          rd = GET_W_REG (code->dst.reg);
          ea = -code->src.literal;
          ea = -code->src.literal;
          res = rd + ea;
          res = rd + ea;
          SET_W_REG (code->dst.reg, res);
          SET_W_REG (code->dst.reg, res);
          goto just_flags_inc16;
          goto just_flags_inc16;
 
 
        case O (O_DEC, SL):             /* dec.l */
        case O (O_DEC, SL):             /* dec.l */
          /* FIXME fetch.
          /* FIXME fetch.
           * This insn only uses register operands, but still
           * This insn only uses register operands, but still
           * it would be cleaner to use fetch and store...  */
           * it would be cleaner to use fetch and store...  */
          rd = GET_L_REG (code->dst.reg);
          rd = GET_L_REG (code->dst.reg);
          ea = -code->src.literal;
          ea = -code->src.literal;
          res = rd + ea;
          res = rd + ea;
          SET_L_REG (code->dst.reg, res);
          SET_L_REG (code->dst.reg, res);
          goto just_flags_inc32;
          goto just_flags_inc32;
 
 
        case O (O_INC, SB):             /* inc.b */
        case O (O_INC, SB):             /* inc.b */
          /* FIXME fetch.
          /* FIXME fetch.
           * This insn only uses register operands, but still
           * This insn only uses register operands, but still
           * it would be cleaner to use fetch and store...  */
           * it would be cleaner to use fetch and store...  */
          rd = GET_B_REG (code->src.reg);
          rd = GET_B_REG (code->src.reg);
          ea = 1;
          ea = 1;
          res = rd + ea;
          res = rd + ea;
          SET_B_REG (code->src.reg, res);
          SET_B_REG (code->src.reg, res);
          goto just_flags_inc8;
          goto just_flags_inc8;
 
 
        case O (O_INC, SW):             /* inc.w */
        case O (O_INC, SW):             /* inc.w */
          /* FIXME fetch.
          /* FIXME fetch.
           * This insn only uses register operands, but still
           * This insn only uses register operands, but still
           * it would be cleaner to use fetch and store...  */
           * it would be cleaner to use fetch and store...  */
          rd = GET_W_REG (code->dst.reg);
          rd = GET_W_REG (code->dst.reg);
          ea = code->src.literal;
          ea = code->src.literal;
          res = rd + ea;
          res = rd + ea;
          SET_W_REG (code->dst.reg, res);
          SET_W_REG (code->dst.reg, res);
          goto just_flags_inc16;
          goto just_flags_inc16;
 
 
        case O (O_INC, SL):             /* inc.l */
        case O (O_INC, SL):             /* inc.l */
          /* FIXME fetch.
          /* FIXME fetch.
           * This insn only uses register operands, but still
           * This insn only uses register operands, but still
           * it would be cleaner to use fetch and store...  */
           * it would be cleaner to use fetch and store...  */
          rd = GET_L_REG (code->dst.reg);
          rd = GET_L_REG (code->dst.reg);
          ea = code->src.literal;
          ea = code->src.literal;
          res = rd + ea;
          res = rd + ea;
          SET_L_REG (code->dst.reg, res);
          SET_L_REG (code->dst.reg, res);
          goto just_flags_inc32;
          goto just_flags_inc32;
 
 
        case O (O_LDC, SB):             /* ldc.b */
        case O (O_LDC, SB):             /* ldc.b */
          if (fetch (sd, &code->src, &res))
          if (fetch (sd, &code->src, &res))
            goto end;
            goto end;
          goto setc;
          goto setc;
 
 
        case O (O_LDC, SW):             /* ldc.w */
        case O (O_LDC, SW):             /* ldc.w */
          if (fetch (sd, &code->src, &res))
          if (fetch (sd, &code->src, &res))
            goto end;
            goto end;
 
 
          /* Word operand, value from MSB, must be shifted.  */
          /* Word operand, value from MSB, must be shifted.  */
          res >>= 8;
          res >>= 8;
          goto setc;
          goto setc;
 
 
        case O (O_LDC, SL):             /* ldc.l */
        case O (O_LDC, SL):             /* ldc.l */
          if (fetch (sd, &code->src, &res))
          if (fetch (sd, &code->src, &res))
            goto end;
            goto end;
          switch (code->dst.type) {
          switch (code->dst.type) {
          case X (OP_SBR, SL):
          case X (OP_SBR, SL):
            h8_set_sbr (sd, res);
            h8_set_sbr (sd, res);
            break;
            break;
          case X (OP_VBR, SL):
          case X (OP_VBR, SL):
            h8_set_vbr (sd, res);
            h8_set_vbr (sd, res);
            break;
            break;
          default:
          default:
            goto illegal;
            goto illegal;
          }
          }
          goto next;
          goto next;
 
 
        case O (O_STC, SW):             /* stc.w */
        case O (O_STC, SW):             /* stc.w */
        case O (O_STC, SB):             /* stc.b */
        case O (O_STC, SB):             /* stc.b */
          if (code->src.type == X (OP_CCR, SB))
          if (code->src.type == X (OP_CCR, SB))
            {
            {
              BUILDSR (sd);
              BUILDSR (sd);
              res = h8_get_ccr (sd);
              res = h8_get_ccr (sd);
            }
            }
          else if (code->src.type == X (OP_EXR, SB) && h8300smode)
          else if (code->src.type == X (OP_EXR, SB) && h8300smode)
            {
            {
              if (h8300smode)
              if (h8300smode)
                h8_set_exr (sd, (trace << 7) | intMask);
                h8_set_exr (sd, (trace << 7) | intMask);
              res = h8_get_exr (sd);
              res = h8_get_exr (sd);
            }
            }
          else
          else
            goto illegal;
            goto illegal;
 
 
          /* Word operand, value to MSB, must be shifted.  */
          /* Word operand, value to MSB, must be shifted.  */
          if (code->opcode == X (O_STC, SW))
          if (code->opcode == X (O_STC, SW))
            res <<= 8;
            res <<= 8;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto next;
          goto next;
        case O (O_STC, SL):             /* stc.l */
        case O (O_STC, SL):             /* stc.l */
          switch (code->src.type) {
          switch (code->src.type) {
          case X (OP_SBR, SL):
          case X (OP_SBR, SL):
            res = h8_get_sbr (sd);
            res = h8_get_sbr (sd);
            break;
            break;
          case X (OP_VBR, SL):
          case X (OP_VBR, SL):
            res = h8_get_vbr (sd);
            res = h8_get_vbr (sd);
            break;
            break;
          default:
          default:
            goto illegal;
            goto illegal;
          }
          }
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_ANDC, SB):            /* andc.b */
        case O (O_ANDC, SB):            /* andc.b */
          if (code->dst.type == X (OP_CCR, SB))
          if (code->dst.type == X (OP_CCR, SB))
            {
            {
              BUILDSR (sd);
              BUILDSR (sd);
              rd = h8_get_ccr (sd);
              rd = h8_get_ccr (sd);
            }
            }
          else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
          else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
            {
            {
              if (h8300smode)
              if (h8300smode)
                h8_set_exr (sd, (trace << 7) | intMask);
                h8_set_exr (sd, (trace << 7) | intMask);
              rd = h8_get_exr (sd);
              rd = h8_get_exr (sd);
            }
            }
          else
          else
            goto illegal;
            goto illegal;
          ea = code->src.literal;
          ea = code->src.literal;
          res = rd & ea;
          res = rd & ea;
          goto setc;
          goto setc;
 
 
        case O (O_ORC, SB):             /* orc.b */
        case O (O_ORC, SB):             /* orc.b */
          if (code->dst.type == X (OP_CCR, SB))
          if (code->dst.type == X (OP_CCR, SB))
            {
            {
              BUILDSR (sd);
              BUILDSR (sd);
              rd = h8_get_ccr (sd);
              rd = h8_get_ccr (sd);
            }
            }
          else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
          else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
            {
            {
              if (h8300smode)
              if (h8300smode)
                h8_set_exr (sd, (trace << 7) | intMask);
                h8_set_exr (sd, (trace << 7) | intMask);
              rd = h8_get_exr (sd);
              rd = h8_get_exr (sd);
            }
            }
          else
          else
            goto illegal;
            goto illegal;
          ea = code->src.literal;
          ea = code->src.literal;
          res = rd | ea;
          res = rd | ea;
          goto setc;
          goto setc;
 
 
        case O (O_XORC, SB):            /* xorc.b */
        case O (O_XORC, SB):            /* xorc.b */
          if (code->dst.type == X (OP_CCR, SB))
          if (code->dst.type == X (OP_CCR, SB))
            {
            {
              BUILDSR (sd);
              BUILDSR (sd);
              rd = h8_get_ccr (sd);
              rd = h8_get_ccr (sd);
            }
            }
          else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
          else if (code->dst.type == X (OP_EXR, SB) && h8300smode)
            {
            {
              if (h8300smode)
              if (h8300smode)
                h8_set_exr (sd, (trace << 7) | intMask);
                h8_set_exr (sd, (trace << 7) | intMask);
              rd = h8_get_exr (sd);
              rd = h8_get_exr (sd);
            }
            }
          else
          else
            goto illegal;
            goto illegal;
          ea = code->src.literal;
          ea = code->src.literal;
          res = rd ^ ea;
          res = rd ^ ea;
          goto setc;
          goto setc;
 
 
        case O (O_BRAS, SB):            /* bra/s  */
        case O (O_BRAS, SB):            /* bra/s  */
          /* This is basically an ordinary branch, with a delay slot.  */
          /* This is basically an ordinary branch, with a delay slot.  */
          if (fetch (sd, &code->src, &res))
          if (fetch (sd, &code->src, &res))
            goto end;
            goto end;
 
 
          if ((res & 1) == 0)
          if ((res & 1) == 0)
            goto illegal;
            goto illegal;
 
 
          res -= 1;
          res -= 1;
 
 
          /* Execution continues at next instruction, but
          /* Execution continues at next instruction, but
             delayed_branch is set up for next cycle.  */
             delayed_branch is set up for next cycle.  */
          h8_set_delayed_branch (sd, code->next_pc + res);
          h8_set_delayed_branch (sd, code->next_pc + res);
          pc = code->next_pc;
          pc = code->next_pc;
          goto end;
          goto end;
 
 
        case O (O_BRAB, SB):            /* bra rd.b */
        case O (O_BRAB, SB):            /* bra rd.b */
        case O (O_BRAW, SW):            /* bra rd.w */
        case O (O_BRAW, SW):            /* bra rd.w */
        case O (O_BRAL, SL):            /* bra erd.l */
        case O (O_BRAL, SL):            /* bra erd.l */
          if (fetch (sd, &code->src, &rd))
          if (fetch (sd, &code->src, &rd))
            goto end;
            goto end;
          switch (OP_SIZE (code->opcode)) {
          switch (OP_SIZE (code->opcode)) {
          case SB:      rd &= 0xff;             break;
          case SB:      rd &= 0xff;             break;
          case SW:      rd &= 0xffff;           break;
          case SW:      rd &= 0xffff;           break;
          case SL:      rd &= 0xffffffff;       break;
          case SL:      rd &= 0xffffffff;       break;
          }
          }
          pc = code->next_pc + rd;
          pc = code->next_pc + rd;
          goto end;
          goto end;
 
 
        case O (O_BRABC, SB):           /* bra/bc, branch if bit clear */
        case O (O_BRABC, SB):           /* bra/bc, branch if bit clear */
        case O (O_BRABS, SB):           /* bra/bs, branch if bit set   */
        case O (O_BRABS, SB):           /* bra/bs, branch if bit set   */
        case O (O_BSRBC, SB):           /* bsr/bc, call   if bit clear */
        case O (O_BSRBC, SB):           /* bsr/bc, call   if bit clear */
        case O (O_BSRBS, SB):           /* bsr/bs, call   if bit set   */
        case O (O_BSRBS, SB):           /* bsr/bs, call   if bit set   */
          if (fetch (sd, &code->dst, &rd) ||
          if (fetch (sd, &code->dst, &rd) ||
              fetch (sd, &code->src, &bit))
              fetch (sd, &code->src, &bit))
            goto end;
            goto end;
 
 
          if (code->opcode == O (O_BRABC, SB) || /* branch if clear */
          if (code->opcode == O (O_BRABC, SB) || /* branch if clear */
              code->opcode == O (O_BSRBC, SB))   /* call   if clear */
              code->opcode == O (O_BSRBC, SB))   /* call   if clear */
            {
            {
              if ((rd & (1 << bit)))            /* no branch */
              if ((rd & (1 << bit)))            /* no branch */
                goto next;
                goto next;
            }
            }
          else                                  /* branch/call if set */
          else                                  /* branch/call if set */
            {
            {
              if (!(rd & (1 << bit)))           /* no branch */
              if (!(rd & (1 << bit)))           /* no branch */
                goto next;
                goto next;
            }
            }
 
 
          if (fetch (sd, &code->op3, &res))     /* branch */
          if (fetch (sd, &code->op3, &res))     /* branch */
            goto end;
            goto end;
          pc = code->next_pc + res;
          pc = code->next_pc + res;
 
 
          if (code->opcode == O (O_BRABC, SB) ||
          if (code->opcode == O (O_BRABC, SB) ||
              code->opcode == O (O_BRABS, SB))  /* branch */
              code->opcode == O (O_BRABS, SB))  /* branch */
            goto end;
            goto end;
          else                                  /* call   */
          else                                  /* call   */
            goto call;
            goto call;
 
 
        case O (O_BRA, SN):
        case O (O_BRA, SN):
        case O (O_BRA, SL):
        case O (O_BRA, SL):
        case O (O_BRA, SW):
        case O (O_BRA, SW):
        case O (O_BRA, SB):             /* bra, branch always */
        case O (O_BRA, SB):             /* bra, branch always */
          if (1)
          if (1)
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
 
 
        case O (O_BRN, SB):             /* brn, ;-/  branch never? */
        case O (O_BRN, SB):             /* brn, ;-/  branch never? */
          if (0)
          if (0)
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
 
 
        case O (O_BHI, SB):             /* bhi */
        case O (O_BHI, SB):             /* bhi */
          if ((C || Z) == 0)
          if ((C || Z) == 0)
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
 
 
 
 
        case O (O_BLS, SB):             /* bls */
        case O (O_BLS, SB):             /* bls */
          if ((C || Z))
          if ((C || Z))
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
 
 
        case O (O_BCS, SB):             /* bcs, branch if carry set */
        case O (O_BCS, SB):             /* bcs, branch if carry set */
          if ((C == 1))
          if ((C == 1))
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
 
 
        case O (O_BCC, SB):             /* bcc, branch if carry clear */
        case O (O_BCC, SB):             /* bcc, branch if carry clear */
          if ((C == 0))
          if ((C == 0))
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
 
 
        case O (O_BEQ, SB):             /* beq, branch if zero set */
        case O (O_BEQ, SB):             /* beq, branch if zero set */
          if (Z)
          if (Z)
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
        case O (O_BGT, SB):             /* bgt */
        case O (O_BGT, SB):             /* bgt */
          if (((Z || (N ^ V)) == 0))
          if (((Z || (N ^ V)) == 0))
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
 
 
        case O (O_BLE, SB):             /* ble */
        case O (O_BLE, SB):             /* ble */
          if (((Z || (N ^ V)) == 1))
          if (((Z || (N ^ V)) == 1))
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
 
 
        case O (O_BGE, SB):             /* bge */
        case O (O_BGE, SB):             /* bge */
          if ((N ^ V) == 0)
          if ((N ^ V) == 0)
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
        case O (O_BLT, SB):             /* blt */
        case O (O_BLT, SB):             /* blt */
          if ((N ^ V))
          if ((N ^ V))
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
        case O (O_BMI, SB):             /* bmi */
        case O (O_BMI, SB):             /* bmi */
          if ((N))
          if ((N))
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
        case O (O_BNE, SB):             /* bne, branch if zero clear */
        case O (O_BNE, SB):             /* bne, branch if zero clear */
          if ((Z == 0))
          if ((Z == 0))
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
 
 
        case O (O_BPL, SB):             /* bpl */
        case O (O_BPL, SB):             /* bpl */
          if (N == 0)
          if (N == 0)
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
        case O (O_BVC, SB):             /* bvc */
        case O (O_BVC, SB):             /* bvc */
          if ((V == 0))
          if ((V == 0))
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
        case O (O_BVS, SB):             /* bvs */
        case O (O_BVS, SB):             /* bvs */
          if ((V == 1))
          if ((V == 1))
            goto condtrue;
            goto condtrue;
          goto next;
          goto next;
 
 
        /* Trap for Command Line setup.  */
        /* Trap for Command Line setup.  */
        case O (O_SYS_CMDLINE, SB):
        case O (O_SYS_CMDLINE, SB):
          {
          {
            int i = 0;           /* Loop counter.  */
            int i = 0;           /* Loop counter.  */
            int j = 0;           /* Loop counter.  */
            int j = 0;           /* Loop counter.  */
            int ind_arg_len = 0; /* Length of each argument.  */
            int ind_arg_len = 0; /* Length of each argument.  */
            int no_of_args = 0;  /* The no. or cmdline args.  */
            int no_of_args = 0;  /* The no. or cmdline args.  */
            int current_location = 0;    /* Location of string.  */
            int current_location = 0;    /* Location of string.  */
            int old_sp = 0;      /* The Initial Stack Pointer.  */
            int old_sp = 0;      /* The Initial Stack Pointer.  */
            int no_of_slots = 0; /* No. of slots required on the stack
            int no_of_slots = 0; /* No. of slots required on the stack
                                           for storing cmdline args.  */
                                           for storing cmdline args.  */
            int sp_move = 0;     /* No. of locations by which the stack needs
            int sp_move = 0;     /* No. of locations by which the stack needs
                                   to grow.  */
                                   to grow.  */
            int new_sp = 0;      /* The final stack pointer location passed
            int new_sp = 0;      /* The final stack pointer location passed
                                   back.  */
                                   back.  */
            int *argv_ptrs;     /* Pointers of argv strings to be stored.  */
            int *argv_ptrs;     /* Pointers of argv strings to be stored.  */
            int argv_ptrs_location = 0;  /* Location of pointers to cmdline
            int argv_ptrs_location = 0;  /* Location of pointers to cmdline
                                           args on the stack.  */
                                           args on the stack.  */
            int char_ptr_size = 0;       /* Size of a character pointer on
            int char_ptr_size = 0;       /* Size of a character pointer on
                                           target machine.  */
                                           target machine.  */
            int addr_cmdline = 0;        /* Memory location where cmdline has
            int addr_cmdline = 0;        /* Memory location where cmdline has
                                           to be stored.  */
                                           to be stored.  */
            int size_cmdline = 0;        /* Size of cmdline.  */
            int size_cmdline = 0;        /* Size of cmdline.  */
 
 
            /* Set the address of 256 free locations where command line is
            /* Set the address of 256 free locations where command line is
               stored.  */
               stored.  */
            addr_cmdline = cmdline_location();
            addr_cmdline = cmdline_location();
            h8_set_reg (sd, 0, addr_cmdline);
            h8_set_reg (sd, 0, addr_cmdline);
 
 
            /* Counting the no. of commandline arguments.  */
            /* Counting the no. of commandline arguments.  */
            for (i = 0; h8_get_cmdline_arg (sd, i) != NULL; i++)
            for (i = 0; h8_get_cmdline_arg (sd, i) != NULL; i++)
              continue;
              continue;
 
 
            /* No. of arguments in the command line.  */
            /* No. of arguments in the command line.  */
            no_of_args = i;
            no_of_args = i;
 
 
            /* Current location is just a temporary variable,which we are
            /* Current location is just a temporary variable,which we are
               setting to the point to the start of our commandline string.  */
               setting to the point to the start of our commandline string.  */
            current_location = addr_cmdline;
            current_location = addr_cmdline;
 
 
            /* Allocating space for storing pointers of the command line
            /* Allocating space for storing pointers of the command line
               arguments.  */
               arguments.  */
            argv_ptrs = (int *) malloc (sizeof (int) * no_of_args);
            argv_ptrs = (int *) malloc (sizeof (int) * no_of_args);
 
 
            /* Setting char_ptr_size to the sizeof (char *) on the different
            /* Setting char_ptr_size to the sizeof (char *) on the different
               architectures.  */
               architectures.  */
            if ((h8300hmode || h8300smode) && !h8300_normal_mode)
            if ((h8300hmode || h8300smode) && !h8300_normal_mode)
              {
              {
                char_ptr_size = 4;
                char_ptr_size = 4;
              }
              }
            else
            else
              {
              {
                char_ptr_size = 2;
                char_ptr_size = 2;
              }
              }
 
 
            for (i = 0; i < no_of_args; i++)
            for (i = 0; i < no_of_args; i++)
              {
              {
                ind_arg_len = 0;
                ind_arg_len = 0;
 
 
                /* The size of the commandline argument.  */
                /* The size of the commandline argument.  */
                ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
                ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
 
 
                /* The total size of the command line string.  */
                /* The total size of the command line string.  */
                size_cmdline += ind_arg_len;
                size_cmdline += ind_arg_len;
 
 
                /* As we have only 256 bytes, we need to provide a graceful
                /* As we have only 256 bytes, we need to provide a graceful
                   exit. Anyways, a program using command line arguments
                   exit. Anyways, a program using command line arguments
                   where we cannot store all the command line arguments
                   where we cannot store all the command line arguments
                   given may behave unpredictably.  */
                   given may behave unpredictably.  */
                if (size_cmdline >= 256)
                if (size_cmdline >= 256)
                  {
                  {
                    h8_set_reg (sd, 0, 0);
                    h8_set_reg (sd, 0, 0);
                    goto next;
                    goto next;
                  }
                  }
                else
                else
                  {
                  {
                    /* current_location points to the memory where the next
                    /* current_location points to the memory where the next
                       commandline argument is stored.  */
                       commandline argument is stored.  */
                    argv_ptrs[i] = current_location;
                    argv_ptrs[i] = current_location;
                    for (j = 0; j < ind_arg_len; j++)
                    for (j = 0; j < ind_arg_len; j++)
                      {
                      {
                        SET_MEMORY_B ((current_location +
                        SET_MEMORY_B ((current_location +
                                       (sizeof (char) * j)),
                                       (sizeof (char) * j)),
                                      *(h8_get_cmdline_arg (sd, i) +
                                      *(h8_get_cmdline_arg (sd, i) +
                                       sizeof (char) * j));
                                       sizeof (char) * j));
                      }
                      }
 
 
                    /* Setting current_location to the starting of next
                    /* Setting current_location to the starting of next
                       argument.  */
                       argument.  */
                    current_location += ind_arg_len;
                    current_location += ind_arg_len;
                  }
                  }
              }
              }
 
 
            /* This is the original position of the stack pointer.  */
            /* This is the original position of the stack pointer.  */
            old_sp = h8_get_reg (sd, SP_REGNUM);
            old_sp = h8_get_reg (sd, SP_REGNUM);
 
 
            /* We need space from the stack to store the pointers to argvs.  */
            /* We need space from the stack to store the pointers to argvs.  */
            /* As we will infringe on the stack, we need to shift the stack
            /* As we will infringe on the stack, we need to shift the stack
               pointer so that the data is not overwritten. We calculate how
               pointer so that the data is not overwritten. We calculate how
               much space is required.  */
               much space is required.  */
            sp_move = (no_of_args) * (char_ptr_size);
            sp_move = (no_of_args) * (char_ptr_size);
 
 
            /* The final position of stack pointer, we have thus taken some
            /* The final position of stack pointer, we have thus taken some
               space from the stack.  */
               space from the stack.  */
            new_sp = old_sp - sp_move;
            new_sp = old_sp - sp_move;
 
 
            /* Temporary variable holding value where the argv pointers need
            /* Temporary variable holding value where the argv pointers need
               to be stored.  */
               to be stored.  */
            argv_ptrs_location = new_sp;
            argv_ptrs_location = new_sp;
 
 
            /* The argv pointers are stored at sequential locations. As per
            /* The argv pointers are stored at sequential locations. As per
               the H8300 ABI.  */
               the H8300 ABI.  */
            for (i = 0; i < no_of_args; i++)
            for (i = 0; i < no_of_args; i++)
              {
              {
                /* Saving the argv pointer.  */
                /* Saving the argv pointer.  */
                if ((h8300hmode || h8300smode) && !h8300_normal_mode)
                if ((h8300hmode || h8300smode) && !h8300_normal_mode)
                  {
                  {
                    SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
                    SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
                  }
                  }
                else
                else
                  {
                  {
                    SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]);
                    SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]);
                  }
                  }
 
 
                /* The next location where the pointer to the next argv
                /* The next location where the pointer to the next argv
                   string has to be stored.  */
                   string has to be stored.  */
                argv_ptrs_location += char_ptr_size;
                argv_ptrs_location += char_ptr_size;
              }
              }
 
 
            /* Required by POSIX, Setting 0x0 at the end of the list of argv
            /* Required by POSIX, Setting 0x0 at the end of the list of argv
               pointers.  */
               pointers.  */
            if ((h8300hmode || h8300smode) && !h8300_normal_mode)
            if ((h8300hmode || h8300smode) && !h8300_normal_mode)
              {
              {
                SET_MEMORY_L (old_sp, 0x0);
                SET_MEMORY_L (old_sp, 0x0);
              }
              }
            else
            else
              {
              {
                SET_MEMORY_W (old_sp, 0x0);
                SET_MEMORY_W (old_sp, 0x0);
              }
              }
 
 
            /* Freeing allocated memory.  */
            /* Freeing allocated memory.  */
            free (argv_ptrs);
            free (argv_ptrs);
            for (i = 0; i <= no_of_args; i++)
            for (i = 0; i <= no_of_args; i++)
              {
              {
                free (h8_get_cmdline_arg (sd, i));
                free (h8_get_cmdline_arg (sd, i));
              }
              }
            free (h8_get_command_line (sd));
            free (h8_get_command_line (sd));
 
 
            /* The no. of argv arguments are returned in Reg 0.  */
            /* The no. of argv arguments are returned in Reg 0.  */
            h8_set_reg (sd, 0, no_of_args);
            h8_set_reg (sd, 0, no_of_args);
            /* The Pointer to argv in Register 1.  */
            /* The Pointer to argv in Register 1.  */
            h8_set_reg (sd, 1, new_sp);
            h8_set_reg (sd, 1, new_sp);
            /* Setting the stack pointer to the new value.  */
            /* Setting the stack pointer to the new value.  */
            h8_set_reg (sd, SP_REGNUM, new_sp);
            h8_set_reg (sd, SP_REGNUM, new_sp);
          }
          }
          goto next;
          goto next;
 
 
          /* System call processing starts.  */
          /* System call processing starts.  */
        case O (O_SYS_OPEN, SB):
        case O (O_SYS_OPEN, SB):
          {
          {
            int len = 0; /* Length of filename.  */
            int len = 0; /* Length of filename.  */
            char *filename;     /* Filename would go here.  */
            char *filename;     /* Filename would go here.  */
            char temp_char;     /* Temporary character */
            char temp_char;     /* Temporary character */
            int mode = 0;        /* Mode bits for the file.  */
            int mode = 0;        /* Mode bits for the file.  */
            int open_return;    /* Return value of open, file descriptor.  */
            int open_return;    /* Return value of open, file descriptor.  */
            int i;              /* Loop counter */
            int i;              /* Loop counter */
            int filename_ptr;   /* Pointer to filename in cpu memory.  */
            int filename_ptr;   /* Pointer to filename in cpu memory.  */
 
 
            /* Setting filename_ptr to first argument of open,  */
            /* Setting filename_ptr to first argument of open,  */
            /* and trying to get mode.  */
            /* and trying to get mode.  */
            if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
            if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
              {
              {
                filename_ptr = GET_L_REG (0);
                filename_ptr = GET_L_REG (0);
                mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4);
                mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4);
              }
              }
            else
            else
              {
              {
                filename_ptr = GET_W_REG (0);
                filename_ptr = GET_W_REG (0);
                mode = GET_MEMORY_W (h8_get_reg (sd, SP_REGNUM) + 2);
                mode = GET_MEMORY_W (h8_get_reg (sd, SP_REGNUM) + 2);
              }
              }
 
 
            /* Trying to find the length of the filename.  */
            /* Trying to find the length of the filename.  */
            temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
            temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
 
 
            len = 1;
            len = 1;
            while (temp_char != '\0')
            while (temp_char != '\0')
              {
              {
                temp_char = GET_MEMORY_B (filename_ptr + len);
                temp_char = GET_MEMORY_B (filename_ptr + len);
                len++;
                len++;
              }
              }
 
 
            /* Allocating space for the filename.  */
            /* Allocating space for the filename.  */
            filename = (char *) malloc (sizeof (char) * len);
            filename = (char *) malloc (sizeof (char) * len);
 
 
            /* String copying the filename from memory.  */
            /* String copying the filename from memory.  */
            for (i = 0; i < len; i++)
            for (i = 0; i < len; i++)
              {
              {
                temp_char = GET_MEMORY_B (filename_ptr + i);
                temp_char = GET_MEMORY_B (filename_ptr + i);
                filename[i] = temp_char;
                filename[i] = temp_char;
              }
              }
 
 
            /* Callback to open and return the file descriptor.  */
            /* Callback to open and return the file descriptor.  */
            open_return = sim_callback->open (sim_callback, filename, mode);
            open_return = sim_callback->open (sim_callback, filename, mode);
 
 
            /* Return value in register 0.  */
            /* Return value in register 0.  */
            h8_set_reg (sd, 0, open_return);
            h8_set_reg (sd, 0, open_return);
 
 
            /* Freeing memory used for filename. */
            /* Freeing memory used for filename. */
            free (filename);
            free (filename);
          }
          }
          goto next;
          goto next;
 
 
        case O (O_SYS_READ, SB):
        case O (O_SYS_READ, SB):
          {
          {
            char *char_ptr;     /* Where characters read would be stored.  */
            char *char_ptr;     /* Where characters read would be stored.  */
            int fd;             /* File descriptor */
            int fd;             /* File descriptor */
            int buf_size;       /* BUF_SIZE parameter in read.  */
            int buf_size;       /* BUF_SIZE parameter in read.  */
            int i = 0;           /* Temporary Loop counter */
            int i = 0;           /* Temporary Loop counter */
            int read_return = 0; /* Return value from callback to
            int read_return = 0; /* Return value from callback to
                                           read.  */
                                           read.  */
 
 
            fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
            fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
            buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
            buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
 
 
            char_ptr = (char *) malloc (sizeof (char) * buf_size);
            char_ptr = (char *) malloc (sizeof (char) * buf_size);
 
 
            /* Callback to read and return the no. of characters read.  */
            /* Callback to read and return the no. of characters read.  */
            read_return =
            read_return =
              sim_callback->read (sim_callback, fd, char_ptr, buf_size);
              sim_callback->read (sim_callback, fd, char_ptr, buf_size);
 
 
            /* The characters read are stored in cpu memory.  */
            /* The characters read are stored in cpu memory.  */
            for (i = 0; i < buf_size; i++)
            for (i = 0; i < buf_size; i++)
              {
              {
                SET_MEMORY_B ((h8_get_reg (sd, 1) + (sizeof (char) * i)),
                SET_MEMORY_B ((h8_get_reg (sd, 1) + (sizeof (char) * i)),
                              *(char_ptr + (sizeof (char) * i)));
                              *(char_ptr + (sizeof (char) * i)));
              }
              }
 
 
            /* Return value in Register 0.  */
            /* Return value in Register 0.  */
            h8_set_reg (sd, 0, read_return);
            h8_set_reg (sd, 0, read_return);
 
 
            /* Freeing memory used as buffer.  */
            /* Freeing memory used as buffer.  */
            free (char_ptr);
            free (char_ptr);
          }
          }
          goto next;
          goto next;
 
 
        case O (O_SYS_WRITE, SB):
        case O (O_SYS_WRITE, SB):
          {
          {
            int fd;             /* File descriptor */
            int fd;             /* File descriptor */
            char temp_char;     /* Temporary character */
            char temp_char;     /* Temporary character */
            int len;            /* Length of write, Parameter II to write.  */
            int len;            /* Length of write, Parameter II to write.  */
            int char_ptr;       /* Character Pointer, Parameter I of write.  */
            int char_ptr;       /* Character Pointer, Parameter I of write.  */
            char *ptr;          /* Where characters to be written are stored.
            char *ptr;          /* Where characters to be written are stored.
                                 */
                                 */
            int write_return;   /* Return value from callback to write.  */
            int write_return;   /* Return value from callback to write.  */
            int i = 0;           /* Loop counter */
            int i = 0;           /* Loop counter */
 
 
            fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
            fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
            char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
            char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
            len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
            len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
 
 
            /* Allocating space for the characters to be written.  */
            /* Allocating space for the characters to be written.  */
            ptr = (char *) malloc (sizeof (char) * len);
            ptr = (char *) malloc (sizeof (char) * len);
 
 
            /* Fetching the characters from cpu memory.  */
            /* Fetching the characters from cpu memory.  */
            for (i = 0; i < len; i++)
            for (i = 0; i < len; i++)
              {
              {
                temp_char = GET_MEMORY_B (char_ptr + i);
                temp_char = GET_MEMORY_B (char_ptr + i);
                ptr[i] = temp_char;
                ptr[i] = temp_char;
              }
              }
 
 
            /* Callback write and return the no. of characters written.  */
            /* Callback write and return the no. of characters written.  */
            write_return = sim_callback->write (sim_callback, fd, ptr, len);
            write_return = sim_callback->write (sim_callback, fd, ptr, len);
 
 
            /* Return value in Register 0.  */
            /* Return value in Register 0.  */
            h8_set_reg (sd, 0, write_return);
            h8_set_reg (sd, 0, write_return);
 
 
            /* Freeing memory used as buffer.  */
            /* Freeing memory used as buffer.  */
            free (ptr);
            free (ptr);
          }
          }
          goto next;
          goto next;
 
 
        case O (O_SYS_LSEEK, SB):
        case O (O_SYS_LSEEK, SB):
          {
          {
            int fd;             /* File descriptor */
            int fd;             /* File descriptor */
            int offset;         /* Offset */
            int offset;         /* Offset */
            int origin;         /* Origin */
            int origin;         /* Origin */
            int lseek_return;   /* Return value from callback to lseek.  */
            int lseek_return;   /* Return value from callback to lseek.  */
 
 
            fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
            fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
            offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
            offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
            origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
            origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
 
 
            /* Callback lseek and return offset.  */
            /* Callback lseek and return offset.  */
            lseek_return =
            lseek_return =
              sim_callback->lseek (sim_callback, fd, offset, origin);
              sim_callback->lseek (sim_callback, fd, offset, origin);
 
 
            /* Return value in register 0.  */
            /* Return value in register 0.  */
            h8_set_reg (sd, 0, lseek_return);
            h8_set_reg (sd, 0, lseek_return);
          }
          }
          goto next;
          goto next;
 
 
        case O (O_SYS_CLOSE, SB):
        case O (O_SYS_CLOSE, SB):
          {
          {
            int fd;             /* File descriptor */
            int fd;             /* File descriptor */
            int close_return;   /* Return value from callback to close.  */
            int close_return;   /* Return value from callback to close.  */
 
 
            fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
            fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
 
 
            /* Callback close and return.  */
            /* Callback close and return.  */
            close_return = sim_callback->close (sim_callback, fd);
            close_return = sim_callback->close (sim_callback, fd);
 
 
            /* Return value in register 0.  */
            /* Return value in register 0.  */
            h8_set_reg (sd, 0, close_return);
            h8_set_reg (sd, 0, close_return);
          }
          }
          goto next;
          goto next;
 
 
        case O (O_SYS_FSTAT, SB):
        case O (O_SYS_FSTAT, SB):
          {
          {
            int fd;             /* File descriptor */
            int fd;             /* File descriptor */
            struct stat stat_rec;       /* Stat record */
            struct stat stat_rec;       /* Stat record */
            int fstat_return;   /* Return value from callback to stat.  */
            int fstat_return;   /* Return value from callback to stat.  */
            int stat_ptr;       /* Pointer to stat record.  */
            int stat_ptr;       /* Pointer to stat record.  */
            char *temp_stat_ptr;        /* Temporary stat_rec pointer.  */
            char *temp_stat_ptr;        /* Temporary stat_rec pointer.  */
 
 
            fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
            fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
 
 
            /* Setting stat_ptr to second argument of stat.  */
            /* Setting stat_ptr to second argument of stat.  */
            stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
            stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
 
 
            /* Callback stat and return.  */
            /* Callback stat and return.  */
            fstat_return = sim_callback->fstat (sim_callback, fd, &stat_rec);
            fstat_return = sim_callback->fstat (sim_callback, fd, &stat_rec);
 
 
            /* Have stat_ptr point to starting of stat_rec.  */
            /* Have stat_ptr point to starting of stat_rec.  */
            temp_stat_ptr = (char *) (&stat_rec);
            temp_stat_ptr = (char *) (&stat_rec);
 
 
            /* Setting up the stat structure returned.  */
            /* Setting up the stat structure returned.  */
            SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
            SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
            SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
            SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
            stat_ptr += 4;
            stat_ptr += 4;
            SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
            SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
            SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
            SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
            SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_L (stat_ptr, stat_rec.st_size);
            SET_MEMORY_L (stat_ptr, stat_rec.st_size);
            stat_ptr += 4;
            stat_ptr += 4;
            SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
            SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
            stat_ptr += 8;
            stat_ptr += 8;
            SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
            SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
            stat_ptr += 8;
            stat_ptr += 8;
            SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
            SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
 
 
            /* Return value in register 0.  */
            /* Return value in register 0.  */
            h8_set_reg (sd, 0, fstat_return);
            h8_set_reg (sd, 0, fstat_return);
          }
          }
          goto next;
          goto next;
 
 
        case O (O_SYS_STAT, SB):
        case O (O_SYS_STAT, SB):
          {
          {
            int len = 0; /* Length of filename.  */
            int len = 0; /* Length of filename.  */
            char *filename;     /* Filename would go here.  */
            char *filename;     /* Filename would go here.  */
            char temp_char;     /* Temporary character */
            char temp_char;     /* Temporary character */
            int filename_ptr;   /* Pointer to filename in cpu memory.  */
            int filename_ptr;   /* Pointer to filename in cpu memory.  */
            struct stat stat_rec;       /* Stat record */
            struct stat stat_rec;       /* Stat record */
            int stat_return;    /* Return value from callback to stat */
            int stat_return;    /* Return value from callback to stat */
            int stat_ptr;       /* Pointer to stat record.  */
            int stat_ptr;       /* Pointer to stat record.  */
            char *temp_stat_ptr;        /* Temporary stat_rec pointer.  */
            char *temp_stat_ptr;        /* Temporary stat_rec pointer.  */
            int i = 0;           /* Loop Counter */
            int i = 0;           /* Loop Counter */
 
 
            /* Setting filename_ptr to first argument of open.  */
            /* Setting filename_ptr to first argument of open.  */
            filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
            filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
 
 
            /* Trying to find the length of the filename.  */
            /* Trying to find the length of the filename.  */
            temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
            temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
 
 
            len = 1;
            len = 1;
            while (temp_char != '\0')
            while (temp_char != '\0')
              {
              {
                temp_char = GET_MEMORY_B (filename_ptr + len);
                temp_char = GET_MEMORY_B (filename_ptr + len);
                len++;
                len++;
              }
              }
 
 
            /* Allocating space for the filename.  */
            /* Allocating space for the filename.  */
            filename = (char *) malloc (sizeof (char) * len);
            filename = (char *) malloc (sizeof (char) * len);
 
 
            /* String copying the filename from memory.  */
            /* String copying the filename from memory.  */
            for (i = 0; i < len; i++)
            for (i = 0; i < len; i++)
              {
              {
                temp_char = GET_MEMORY_B (filename_ptr + i);
                temp_char = GET_MEMORY_B (filename_ptr + i);
                filename[i] = temp_char;
                filename[i] = temp_char;
              }
              }
 
 
            /* Setting stat_ptr to second argument of stat.  */
            /* Setting stat_ptr to second argument of stat.  */
            /* stat_ptr = h8_get_reg (sd, 1); */
            /* stat_ptr = h8_get_reg (sd, 1); */
            stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
            stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
 
 
            /* Callback stat and return.  */
            /* Callback stat and return.  */
            stat_return =
            stat_return =
              sim_callback->stat (sim_callback, filename, &stat_rec);
              sim_callback->stat (sim_callback, filename, &stat_rec);
 
 
            /* Have stat_ptr point to starting of stat_rec.  */
            /* Have stat_ptr point to starting of stat_rec.  */
            temp_stat_ptr = (char *) (&stat_rec);
            temp_stat_ptr = (char *) (&stat_rec);
 
 
            /* Freeing memory used for filename.  */
            /* Freeing memory used for filename.  */
            free (filename);
            free (filename);
 
 
            /* Setting up the stat structure returned.  */
            /* Setting up the stat structure returned.  */
            SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
            SET_MEMORY_W (stat_ptr, stat_rec.st_dev);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
            SET_MEMORY_W (stat_ptr, stat_rec.st_ino);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
            SET_MEMORY_L (stat_ptr, stat_rec.st_mode);
            stat_ptr += 4;
            stat_ptr += 4;
            SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
            SET_MEMORY_W (stat_ptr, stat_rec.st_nlink);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
            SET_MEMORY_W (stat_ptr, stat_rec.st_uid);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
            SET_MEMORY_W (stat_ptr, stat_rec.st_gid);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
            SET_MEMORY_W (stat_ptr, stat_rec.st_rdev);
            stat_ptr += 2;
            stat_ptr += 2;
            SET_MEMORY_L (stat_ptr, stat_rec.st_size);
            SET_MEMORY_L (stat_ptr, stat_rec.st_size);
            stat_ptr += 4;
            stat_ptr += 4;
            SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
            SET_MEMORY_L (stat_ptr, stat_rec.st_atime);
            stat_ptr += 8;
            stat_ptr += 8;
            SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
            SET_MEMORY_L (stat_ptr, stat_rec.st_mtime);
            stat_ptr += 8;
            stat_ptr += 8;
            SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
            SET_MEMORY_L (stat_ptr, stat_rec.st_ctime);
 
 
            /* Return value in register 0.  */
            /* Return value in register 0.  */
            h8_set_reg (sd, 0, stat_return);
            h8_set_reg (sd, 0, stat_return);
          }
          }
          goto next;
          goto next;
          /* End of system call processing.  */
          /* End of system call processing.  */
 
 
        case O (O_NOT, SB):             /* not.b */
        case O (O_NOT, SB):             /* not.b */
          if (fetch2 (sd, &code->src, &rd))
          if (fetch2 (sd, &code->src, &rd))
            goto end;
            goto end;
          rd = ~rd;
          rd = ~rd;
          v = 0;
          v = 0;
          goto shift8;
          goto shift8;
 
 
        case O (O_NOT, SW):             /* not.w */
        case O (O_NOT, SW):             /* not.w */
          if (fetch2 (sd, &code->src, &rd))
          if (fetch2 (sd, &code->src, &rd))
            goto end;
            goto end;
          rd = ~rd;
          rd = ~rd;
          v = 0;
          v = 0;
          goto shift16;
          goto shift16;
 
 
        case O (O_NOT, SL):             /* not.l */
        case O (O_NOT, SL):             /* not.l */
          if (fetch2 (sd, &code->src, &rd))
          if (fetch2 (sd, &code->src, &rd))
            goto end;
            goto end;
          rd = ~rd;
          rd = ~rd;
          v = 0;
          v = 0;
          goto shift32;
          goto shift32;
 
 
        case O (O_SHLL, SB):    /* shll.b */
        case O (O_SHLL, SB):    /* shll.b */
        case O (O_SHLR, SB):    /* shlr.b */
        case O (O_SHLR, SB):    /* shlr.b */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
          if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
            ea = 1;             /* unary  op */
            ea = 1;             /* unary  op */
          else                  /* binary op */
          else                  /* binary op */
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
 
 
          if (code->opcode == O (O_SHLL, SB))
          if (code->opcode == O (O_SHLL, SB))
            {
            {
              v = (ea > 8);
              v = (ea > 8);
              c = rd & (0x80 >> (ea - 1));
              c = rd & (0x80 >> (ea - 1));
              rd <<= ea;
              rd <<= ea;
            }
            }
          else
          else
            {
            {
              v = 0;
              v = 0;
              c = rd & (1 << (ea - 1));
              c = rd & (1 << (ea - 1));
              rd = (unsigned char) rd >> ea;
              rd = (unsigned char) rd >> ea;
            }
            }
          goto shift8;
          goto shift8;
 
 
        case O (O_SHLL, SW):    /* shll.w */
        case O (O_SHLL, SW):    /* shll.w */
        case O (O_SHLR, SW):    /* shlr.w */
        case O (O_SHLR, SW):    /* shlr.w */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
          if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
            ea = 1;             /* unary  op */
            ea = 1;             /* unary  op */
          else
          else
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
 
 
          if (code->opcode == O (O_SHLL, SW))
          if (code->opcode == O (O_SHLL, SW))
            {
            {
              v = (ea > 16);
              v = (ea > 16);
              c = rd & (0x8000 >> (ea - 1));
              c = rd & (0x8000 >> (ea - 1));
              rd <<= ea;
              rd <<= ea;
            }
            }
          else
          else
            {
            {
              v = 0;
              v = 0;
              c = rd & (1 << (ea - 1));
              c = rd & (1 << (ea - 1));
              rd = (unsigned short) rd >> ea;
              rd = (unsigned short) rd >> ea;
            }
            }
          goto shift16;
          goto shift16;
 
 
        case O (O_SHLL, SL):    /* shll.l */
        case O (O_SHLL, SL):    /* shll.l */
        case O (O_SHLR, SL):    /* shlr.l */
        case O (O_SHLR, SL):    /* shlr.l */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
          if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
            ea = 1;             /* unary  op */
            ea = 1;             /* unary  op */
          else
          else
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
 
 
          if (code->opcode == O (O_SHLL, SL))
          if (code->opcode == O (O_SHLL, SL))
            {
            {
              v = (ea > 32);
              v = (ea > 32);
              c = rd & (0x80000000 >> (ea - 1));
              c = rd & (0x80000000 >> (ea - 1));
              rd <<= ea;
              rd <<= ea;
            }
            }
          else
          else
            {
            {
              v = 0;
              v = 0;
              c = rd & (1 << (ea - 1));
              c = rd & (1 << (ea - 1));
              rd = (unsigned int) rd >> ea;
              rd = (unsigned int) rd >> ea;
            }
            }
          goto shift32;
          goto shift32;
 
 
        case O (O_SHAL, SB):
        case O (O_SHAL, SB):
        case O (O_SHAR, SB):
        case O (O_SHAR, SB):
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (code->src.type == X (OP_IMM, SB))
          if (code->src.type == X (OP_IMM, SB))
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
          else
          else
            ea = 1;
            ea = 1;
 
 
          if (code->opcode == O (O_SHAL, SB))
          if (code->opcode == O (O_SHAL, SB))
            {
            {
              c = rd & (0x80 >> (ea - 1));
              c = rd & (0x80 >> (ea - 1));
              res = rd >> (7 - ea);
              res = rd >> (7 - ea);
              v = ((res & 1) && !(res & 2))
              v = ((res & 1) && !(res & 2))
                || (!(res & 1) && (res & 2));
                || (!(res & 1) && (res & 2));
              rd <<= ea;
              rd <<= ea;
            }
            }
          else
          else
            {
            {
              c = rd & (1 << (ea - 1));
              c = rd & (1 << (ea - 1));
              v = 0;
              v = 0;
              rd = ((signed char) rd) >> ea;
              rd = ((signed char) rd) >> ea;
            }
            }
          goto shift8;
          goto shift8;
 
 
        case O (O_SHAL, SW):
        case O (O_SHAL, SW):
        case O (O_SHAR, SW):
        case O (O_SHAR, SW):
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (code->src.type == X (OP_IMM, SW))
          if (code->src.type == X (OP_IMM, SW))
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
          else
          else
            ea = 1;
            ea = 1;
 
 
          if (code->opcode == O (O_SHAL, SW))
          if (code->opcode == O (O_SHAL, SW))
            {
            {
              c = rd & (0x8000 >> (ea - 1));
              c = rd & (0x8000 >> (ea - 1));
              res = rd >> (15 - ea);
              res = rd >> (15 - ea);
              v = ((res & 1) && !(res & 2))
              v = ((res & 1) && !(res & 2))
                || (!(res & 1) && (res & 2));
                || (!(res & 1) && (res & 2));
              rd <<= ea;
              rd <<= ea;
            }
            }
          else
          else
            {
            {
              c = rd & (1 << (ea - 1));
              c = rd & (1 << (ea - 1));
              v = 0;
              v = 0;
              rd = ((signed short) rd) >> ea;
              rd = ((signed short) rd) >> ea;
            }
            }
          goto shift16;
          goto shift16;
 
 
        case O (O_SHAL, SL):
        case O (O_SHAL, SL):
        case O (O_SHAR, SL):
        case O (O_SHAR, SL):
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (code->src.type == X (OP_IMM, SL))
          if (code->src.type == X (OP_IMM, SL))
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
          else
          else
            ea = 1;
            ea = 1;
 
 
          if (code->opcode == O (O_SHAL, SL))
          if (code->opcode == O (O_SHAL, SL))
            {
            {
              c = rd & (0x80000000 >> (ea - 1));
              c = rd & (0x80000000 >> (ea - 1));
              res = rd >> (31 - ea);
              res = rd >> (31 - ea);
              v = ((res & 1) && !(res & 2))
              v = ((res & 1) && !(res & 2))
                || (!(res & 1) && (res & 2));
                || (!(res & 1) && (res & 2));
              rd <<= ea;
              rd <<= ea;
            }
            }
          else
          else
            {
            {
              c = rd & (1 << (ea - 1));
              c = rd & (1 << (ea - 1));
              v = 0;
              v = 0;
              rd = ((signed int) rd) >> ea;
              rd = ((signed int) rd) >> ea;
            }
            }
          goto shift32;
          goto shift32;
 
 
        case O (O_ROTL, SB):
        case O (O_ROTL, SB):
        case O (O_ROTR, SB):
        case O (O_ROTR, SB):
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (code->src.type == X (OP_IMM, SB))
          if (code->src.type == X (OP_IMM, SB))
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
          else
          else
            ea = 1;
            ea = 1;
 
 
          while (ea--)
          while (ea--)
            if (code->opcode == O (O_ROTL, SB))
            if (code->opcode == O (O_ROTL, SB))
              {
              {
                c = rd & 0x80;
                c = rd & 0x80;
                rd <<= 1;
                rd <<= 1;
                if (c)
                if (c)
                  rd |= 1;
                  rd |= 1;
              }
              }
            else
            else
              {
              {
                c = rd & 1;
                c = rd & 1;
                rd = ((unsigned char) rd) >> 1;
                rd = ((unsigned char) rd) >> 1;
                if (c)
                if (c)
                  rd |= 0x80;
                  rd |= 0x80;
              }
              }
 
 
          v = 0;
          v = 0;
          goto shift8;
          goto shift8;
 
 
        case O (O_ROTL, SW):
        case O (O_ROTL, SW):
        case O (O_ROTR, SW):
        case O (O_ROTR, SW):
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (code->src.type == X (OP_IMM, SW))
          if (code->src.type == X (OP_IMM, SW))
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
          else
          else
            ea = 1;
            ea = 1;
 
 
          while (ea--)
          while (ea--)
            if (code->opcode == O (O_ROTL, SW))
            if (code->opcode == O (O_ROTL, SW))
              {
              {
                c = rd & 0x8000;
                c = rd & 0x8000;
                rd <<= 1;
                rd <<= 1;
                if (c)
                if (c)
                  rd |= 1;
                  rd |= 1;
              }
              }
            else
            else
              {
              {
                c = rd & 1;
                c = rd & 1;
                rd = ((unsigned short) rd) >> 1;
                rd = ((unsigned short) rd) >> 1;
                if (c)
                if (c)
                  rd |= 0x8000;
                  rd |= 0x8000;
              }
              }
 
 
          v = 0;
          v = 0;
          goto shift16;
          goto shift16;
 
 
        case O (O_ROTL, SL):
        case O (O_ROTL, SL):
        case O (O_ROTR, SL):
        case O (O_ROTR, SL):
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (code->src.type == X (OP_IMM, SL))
          if (code->src.type == X (OP_IMM, SL))
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
          else
          else
            ea = 1;
            ea = 1;
 
 
          while (ea--)
          while (ea--)
            if (code->opcode == O (O_ROTL, SL))
            if (code->opcode == O (O_ROTL, SL))
              {
              {
                c = rd & 0x80000000;
                c = rd & 0x80000000;
                rd <<= 1;
                rd <<= 1;
                if (c)
                if (c)
                  rd |= 1;
                  rd |= 1;
              }
              }
            else
            else
              {
              {
                c = rd & 1;
                c = rd & 1;
                rd = ((unsigned int) rd) >> 1;
                rd = ((unsigned int) rd) >> 1;
                if (c)
                if (c)
                  rd |= 0x80000000;
                  rd |= 0x80000000;
              }
              }
 
 
          v = 0;
          v = 0;
          goto shift32;
          goto shift32;
 
 
        case O (O_ROTXL, SB):
        case O (O_ROTXL, SB):
        case O (O_ROTXR, SB):
        case O (O_ROTXR, SB):
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (code->src.type == X (OP_IMM, SB))
          if (code->src.type == X (OP_IMM, SB))
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
          else
          else
            ea = 1;
            ea = 1;
 
 
          while (ea--)
          while (ea--)
            if (code->opcode == O (O_ROTXL, SB))
            if (code->opcode == O (O_ROTXL, SB))
              {
              {
                res = rd & 0x80;
                res = rd & 0x80;
                rd <<= 1;
                rd <<= 1;
                if (C)
                if (C)
                  rd |= 1;
                  rd |= 1;
                c = res;
                c = res;
              }
              }
            else
            else
              {
              {
                res = rd & 1;
                res = rd & 1;
                rd = ((unsigned char) rd) >> 1;
                rd = ((unsigned char) rd) >> 1;
                if (C)
                if (C)
                  rd |= 0x80;
                  rd |= 0x80;
                c = res;
                c = res;
              }
              }
 
 
          v = 0;
          v = 0;
          goto shift8;
          goto shift8;
 
 
        case O (O_ROTXL, SW):
        case O (O_ROTXL, SW):
        case O (O_ROTXR, SW):
        case O (O_ROTXR, SW):
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (code->src.type == X (OP_IMM, SW))
          if (code->src.type == X (OP_IMM, SW))
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
          else
          else
            ea = 1;
            ea = 1;
 
 
          while (ea--)
          while (ea--)
            if (code->opcode == O (O_ROTXL, SW))
            if (code->opcode == O (O_ROTXL, SW))
              {
              {
                res = rd & 0x8000;
                res = rd & 0x8000;
                rd <<= 1;
                rd <<= 1;
                if (C)
                if (C)
                  rd |= 1;
                  rd |= 1;
                c = res;
                c = res;
              }
              }
            else
            else
              {
              {
                res = rd & 1;
                res = rd & 1;
                rd = ((unsigned short) rd) >> 1;
                rd = ((unsigned short) rd) >> 1;
                if (C)
                if (C)
                  rd |= 0x8000;
                  rd |= 0x8000;
                c = res;
                c = res;
              }
              }
 
 
          v = 0;
          v = 0;
          goto shift16;
          goto shift16;
 
 
        case O (O_ROTXL, SL):
        case O (O_ROTXL, SL):
        case O (O_ROTXR, SL):
        case O (O_ROTXR, SL):
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (code->src.type == X (OP_IMM, SL))
          if (code->src.type == X (OP_IMM, SL))
            fetch (sd, &code->src, &ea);
            fetch (sd, &code->src, &ea);
          else
          else
            ea = 1;
            ea = 1;
 
 
          while (ea--)
          while (ea--)
            if (code->opcode == O (O_ROTXL, SL))
            if (code->opcode == O (O_ROTXL, SL))
              {
              {
                res = rd & 0x80000000;
                res = rd & 0x80000000;
                rd <<= 1;
                rd <<= 1;
                if (C)
                if (C)
                  rd |= 1;
                  rd |= 1;
                c = res;
                c = res;
              }
              }
            else
            else
              {
              {
                res = rd & 1;
                res = rd & 1;
                rd = ((unsigned int) rd) >> 1;
                rd = ((unsigned int) rd) >> 1;
                if (C)
                if (C)
                  rd |= 0x80000000;
                  rd |= 0x80000000;
                c = res;
                c = res;
              }
              }
 
 
          v = 0;
          v = 0;
          goto shift32;
          goto shift32;
 
 
        case O (O_JMP, SN):
        case O (O_JMP, SN):
        case O (O_JMP, SL):
        case O (O_JMP, SL):
        case O (O_JMP, SB):             /* jmp */
        case O (O_JMP, SB):             /* jmp */
        case O (O_JMP, SW):
        case O (O_JMP, SW):
          fetch (sd, &code->src, &pc);
          fetch (sd, &code->src, &pc);
          goto end;
          goto end;
 
 
        case O (O_JSR, SN):
        case O (O_JSR, SN):
        case O (O_JSR, SL):
        case O (O_JSR, SL):
        case O (O_JSR, SB):             /* jsr, jump to subroutine */
        case O (O_JSR, SB):             /* jsr, jump to subroutine */
        case O (O_JSR, SW):
        case O (O_JSR, SW):
          if (fetch (sd, &code->src, &pc))
          if (fetch (sd, &code->src, &pc))
            goto end;
            goto end;
        call:
        call:
          tmp = h8_get_reg (sd, SP_REGNUM);
          tmp = h8_get_reg (sd, SP_REGNUM);
 
 
          if (h8300hmode && !h8300_normal_mode)
          if (h8300hmode && !h8300_normal_mode)
            {
            {
              tmp -= 4;
              tmp -= 4;
              SET_MEMORY_L (tmp, code->next_pc);
              SET_MEMORY_L (tmp, code->next_pc);
            }
            }
          else
          else
            {
            {
              tmp -= 2;
              tmp -= 2;
              SET_MEMORY_W (tmp, code->next_pc);
              SET_MEMORY_W (tmp, code->next_pc);
            }
            }
          h8_set_reg (sd, SP_REGNUM, tmp);
          h8_set_reg (sd, SP_REGNUM, tmp);
 
 
          goto end;
          goto end;
 
 
        case O (O_BSR, SW):
        case O (O_BSR, SW):
        case O (O_BSR, SL):
        case O (O_BSR, SL):
        case O (O_BSR, SB):             /* bsr, branch to subroutine */
        case O (O_BSR, SB):             /* bsr, branch to subroutine */
          if (fetch (sd, &code->src, &res))
          if (fetch (sd, &code->src, &res))
            goto end;
            goto end;
          pc = code->next_pc + res;
          pc = code->next_pc + res;
          goto call;
          goto call;
 
 
        case O (O_RTE, SN):             /* rte, return from exception */
        case O (O_RTE, SN):             /* rte, return from exception */
        rte:
        rte:
          /* Pops exr and ccr before pc -- otherwise identical to rts.  */
          /* Pops exr and ccr before pc -- otherwise identical to rts.  */
          tmp = h8_get_reg (sd, SP_REGNUM);
          tmp = h8_get_reg (sd, SP_REGNUM);
 
 
          if (h8300smode)                       /* pop exr */
          if (h8300smode)                       /* pop exr */
            {
            {
              h8_set_exr (sd, GET_MEMORY_L (tmp));
              h8_set_exr (sd, GET_MEMORY_L (tmp));
              tmp += 4;
              tmp += 4;
            }
            }
          if (h8300hmode && !h8300_normal_mode)
          if (h8300hmode && !h8300_normal_mode)
            {
            {
              h8_set_ccr (sd, GET_MEMORY_L (tmp));
              h8_set_ccr (sd, GET_MEMORY_L (tmp));
              tmp += 4;
              tmp += 4;
              pc = GET_MEMORY_L (tmp);
              pc = GET_MEMORY_L (tmp);
              tmp += 4;
              tmp += 4;
            }
            }
          else
          else
            {
            {
              h8_set_ccr (sd, GET_MEMORY_W (tmp));
              h8_set_ccr (sd, GET_MEMORY_W (tmp));
              tmp += 2;
              tmp += 2;
              pc = GET_MEMORY_W (tmp);
              pc = GET_MEMORY_W (tmp);
              tmp += 2;
              tmp += 2;
            }
            }
 
 
          GETSR (sd);
          GETSR (sd);
          h8_set_reg (sd, SP_REGNUM, tmp);
          h8_set_reg (sd, SP_REGNUM, tmp);
          goto end;
          goto end;
 
 
        case O (O_RTS, SN):             /* rts, return from subroutine */
        case O (O_RTS, SN):             /* rts, return from subroutine */
        rts:
        rts:
          tmp = h8_get_reg (sd, SP_REGNUM);
          tmp = h8_get_reg (sd, SP_REGNUM);
 
 
          if (h8300hmode && !h8300_normal_mode)
          if (h8300hmode && !h8300_normal_mode)
            {
            {
              pc = GET_MEMORY_L (tmp);
              pc = GET_MEMORY_L (tmp);
              tmp += 4;
              tmp += 4;
            }
            }
          else
          else
            {
            {
              pc = GET_MEMORY_W (tmp);
              pc = GET_MEMORY_W (tmp);
              tmp += 2;
              tmp += 2;
            }
            }
 
 
          h8_set_reg (sd, SP_REGNUM, tmp);
          h8_set_reg (sd, SP_REGNUM, tmp);
          goto end;
          goto end;
 
 
        case O (O_ILL, SB):             /* illegal */
        case O (O_ILL, SB):             /* illegal */
          sim_engine_set_run_state (sd, sim_stopped, SIGILL);
          sim_engine_set_run_state (sd, sim_stopped, SIGILL);
          goto end;
          goto end;
 
 
        case O (O_SLEEP, SN):           /* sleep */
        case O (O_SLEEP, SN):           /* sleep */
          /* Check for magic numbers in r1 and r2.  */
          /* Check for magic numbers in r1 and r2.  */
          if ((h8_get_reg (sd, R1_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC1 &&
          if ((h8_get_reg (sd, R1_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC1 &&
              (h8_get_reg (sd, R2_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC2 &&
              (h8_get_reg (sd, R2_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC2 &&
              SIM_WIFEXITED (h8_get_reg (sd, 0)))
              SIM_WIFEXITED (h8_get_reg (sd, 0)))
            {
            {
              /* This trap comes from _exit, not from gdb.  */
              /* This trap comes from _exit, not from gdb.  */
              sim_engine_set_run_state (sd, sim_exited,
              sim_engine_set_run_state (sd, sim_exited,
                                        SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
                                        SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
            }
            }
#if 0
#if 0
          /* Unfortunately this won't really work, because
          /* Unfortunately this won't really work, because
             when we take a breakpoint trap, R0 has a "random",
             when we take a breakpoint trap, R0 has a "random",
             user-defined value.  Don't see any immediate solution.  */
             user-defined value.  Don't see any immediate solution.  */
          else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
          else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
            {
            {
              /* Pass the stop signal up to gdb.  */
              /* Pass the stop signal up to gdb.  */
              sim_engine_set_run_state (sd, sim_stopped,
              sim_engine_set_run_state (sd, sim_stopped,
                                        SIM_WSTOPSIG (h8_get_reg (sd, 0)));
                                        SIM_WSTOPSIG (h8_get_reg (sd, 0)));
            }
            }
#endif
#endif
          else
          else
            {
            {
              /* Treat it as a sigtrap.  */
              /* Treat it as a sigtrap.  */
              sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
              sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
            }
            }
          goto end;
          goto end;
 
 
        case O (O_TRAPA, SB):           /* trapa */
        case O (O_TRAPA, SB):           /* trapa */
          if (fetch (sd, &code->src, &res))
          if (fetch (sd, &code->src, &res))
            goto end;                   /* res is vector number.  */
            goto end;                   /* res is vector number.  */
 
 
          tmp = h8_get_reg (sd, SP_REGNUM);
          tmp = h8_get_reg (sd, SP_REGNUM);
          if(h8300_normal_mode)
          if(h8300_normal_mode)
            {
            {
              tmp -= 2;
              tmp -= 2;
              SET_MEMORY_W (tmp, code->next_pc);
              SET_MEMORY_W (tmp, code->next_pc);
              tmp -= 2;
              tmp -= 2;
              SET_MEMORY_W (tmp, h8_get_ccr (sd));
              SET_MEMORY_W (tmp, h8_get_ccr (sd));
            }
            }
          else
          else
            {
            {
              tmp -= 4;
              tmp -= 4;
              SET_MEMORY_L (tmp, code->next_pc);
              SET_MEMORY_L (tmp, code->next_pc);
              tmp -= 4;
              tmp -= 4;
              SET_MEMORY_L (tmp, h8_get_ccr (sd));
              SET_MEMORY_L (tmp, h8_get_ccr (sd));
            }
            }
          intMaskBit = 1;
          intMaskBit = 1;
          BUILDSR (sd);
          BUILDSR (sd);
 
 
          if (h8300smode)
          if (h8300smode)
            {
            {
              tmp -= 4;
              tmp -= 4;
              SET_MEMORY_L (tmp, h8_get_exr (sd));
              SET_MEMORY_L (tmp, h8_get_exr (sd));
            }
            }
 
 
          h8_set_reg (sd, SP_REGNUM, tmp);
          h8_set_reg (sd, SP_REGNUM, tmp);
 
 
          if(h8300_normal_mode)
          if(h8300_normal_mode)
            pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
            pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
          else
          else
            pc = GET_MEMORY_L (0x20 + res * 4);
            pc = GET_MEMORY_L (0x20 + res * 4);
          goto end;
          goto end;
 
 
        case O (O_BPT, SN):
        case O (O_BPT, SN):
          sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
          sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
          goto end;
          goto end;
 
 
        case O (O_BSETEQ, SB):
        case O (O_BSETEQ, SB):
          if (Z)
          if (Z)
            goto bset;
            goto bset;
          goto next;
          goto next;
 
 
        case O (O_BSETNE, SB):
        case O (O_BSETNE, SB):
          if (!Z)
          if (!Z)
            goto bset;
            goto bset;
          goto next;
          goto next;
 
 
        case O (O_BCLREQ, SB):
        case O (O_BCLREQ, SB):
          if (Z)
          if (Z)
            goto bclr;
            goto bclr;
          goto next;
          goto next;
 
 
        case O (O_BCLRNE, SB):
        case O (O_BCLRNE, SB):
          if (!Z)
          if (!Z)
            goto bclr;
            goto bclr;
          goto next;
          goto next;
 
 
          OBITOP (O_BNOT, 1, 1, ea ^= m);               /* bnot */
          OBITOP (O_BNOT, 1, 1, ea ^= m);               /* bnot */
          OBITOP (O_BTST, 1, 0, nz = ea & m);            /* btst */
          OBITOP (O_BTST, 1, 0, nz = ea & m);            /* btst */
        bset:
        bset:
          OBITOP (O_BSET, 1, 1, ea |= m);               /* bset */
          OBITOP (O_BSET, 1, 1, ea |= m);               /* bset */
        bclr:
        bclr:
          OBITOP (O_BCLR, 1, 1, ea &= ~m);              /* bclr */
          OBITOP (O_BCLR, 1, 1, ea &= ~m);              /* bclr */
          OBITOP (O_BLD, 1, 0, c = ea & m);              /* bld  */
          OBITOP (O_BLD, 1, 0, c = ea & m);              /* bld  */
          OBITOP (O_BILD, 1, 0, c = !(ea & m));          /* bild */
          OBITOP (O_BILD, 1, 0, c = !(ea & m));          /* bild */
          OBITOP (O_BST, 1, 1, ea &= ~m;
          OBITOP (O_BST, 1, 1, ea &= ~m;
                  if (C) ea |= m);                      /* bst  */
                  if (C) ea |= m);                      /* bst  */
          OBITOP (O_BIST, 1, 1, ea &= ~m;
          OBITOP (O_BIST, 1, 1, ea &= ~m;
                  if (!C) ea |= m);                     /* bist */
                  if (!C) ea |= m);                     /* bist */
          OBITOP (O_BSTZ, 1, 1, ea &= ~m;
          OBITOP (O_BSTZ, 1, 1, ea &= ~m;
                  if (Z) ea |= m);                      /* bstz */
                  if (Z) ea |= m);                      /* bstz */
          OBITOP (O_BISTZ, 1, 1, ea &= ~m;
          OBITOP (O_BISTZ, 1, 1, ea &= ~m;
                  if (!Z) ea |= m);                     /* bistz */
                  if (!Z) ea |= m);                     /* bistz */
          OBITOP (O_BAND, 1, 0, c = (ea & m) && C);      /* band */
          OBITOP (O_BAND, 1, 0, c = (ea & m) && C);      /* band */
          OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C);    /* biand */
          OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C);    /* biand */
          OBITOP (O_BOR, 1, 0, c = (ea & m) || C);       /* bor  */
          OBITOP (O_BOR, 1, 0, c = (ea & m) || C);       /* bor  */
          OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C);     /* bior */
          OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C);     /* bior */
          OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C); /* bxor */
          OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C); /* bxor */
          OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C);    /* bixor */
          OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C);    /* bixor */
 
 
        case O (O_BFLD, SB):                            /* bfld */
        case O (O_BFLD, SB):                            /* bfld */
          /* bitfield load */
          /* bitfield load */
          ea = 0;
          ea = 0;
          if (fetch (sd, &code->src, &bit))
          if (fetch (sd, &code->src, &bit))
            goto end;
            goto end;
 
 
          if (bit != 0)
          if (bit != 0)
            {
            {
              if (fetch (sd, &code->dst, &ea))
              if (fetch (sd, &code->dst, &ea))
                goto end;
                goto end;
 
 
              ea &= bit;
              ea &= bit;
              while (!(bit & 1))
              while (!(bit & 1))
                {
                {
                  ea  >>= 1;
                  ea  >>= 1;
                  bit >>= 1;
                  bit >>= 1;
                }
                }
            }
            }
          if (store (sd, &code->op3, ea))
          if (store (sd, &code->op3, ea))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O(O_BFST, SB):                     /* bfst */
        case O(O_BFST, SB):                     /* bfst */
          /* bitfield store */
          /* bitfield store */
          /* NOTE: the imm8 value is in dst, and the ea value
          /* NOTE: the imm8 value is in dst, and the ea value
             (which is actually the destination) is in op3.
             (which is actually the destination) is in op3.
             It has to be that way, to avoid breaking the assembler.  */
             It has to be that way, to avoid breaking the assembler.  */
 
 
          if (fetch (sd, &code->dst, &bit))     /* imm8 */
          if (fetch (sd, &code->dst, &bit))     /* imm8 */
            goto end;
            goto end;
          if (bit == 0)                          /* noop -- nothing to do.  */
          if (bit == 0)                          /* noop -- nothing to do.  */
            goto next;
            goto next;
 
 
          if (fetch (sd, &code->src, &rd))      /* reg8 src */
          if (fetch (sd, &code->src, &rd))      /* reg8 src */
            goto end;
            goto end;
 
 
          if (fetch2 (sd, &code->op3, &ea))     /* ea dst */
          if (fetch2 (sd, &code->op3, &ea))     /* ea dst */
            goto end;
            goto end;
 
 
          /* Left-shift the register data into position.  */
          /* Left-shift the register data into position.  */
          for (tmp = bit; !(tmp & 1); tmp >>= 1)
          for (tmp = bit; !(tmp & 1); tmp >>= 1)
            rd <<= 1;
            rd <<= 1;
 
 
          /* Combine it with the neighboring bits.  */
          /* Combine it with the neighboring bits.  */
          ea = (ea & ~bit) | (rd & bit);
          ea = (ea & ~bit) | (rd & bit);
 
 
          /* Put it back.  */
          /* Put it back.  */
          if (store2 (sd, &code->op3, ea))
          if (store2 (sd, &code->op3, ea))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_CLRMAC, SN):          /* clrmac */
        case O (O_CLRMAC, SN):          /* clrmac */
          h8_set_mach (sd, 0);
          h8_set_mach (sd, 0);
          h8_set_macl (sd, 0);
          h8_set_macl (sd, 0);
          h8_set_macZ (sd, 1);
          h8_set_macZ (sd, 1);
          h8_set_macV (sd, 0);
          h8_set_macV (sd, 0);
          h8_set_macN (sd, 0);
          h8_set_macN (sd, 0);
          goto next;
          goto next;
 
 
        case O (O_STMAC, SL):           /* stmac, 260 */
        case O (O_STMAC, SL):           /* stmac, 260 */
          switch (code->src.type) {
          switch (code->src.type) {
          case X (OP_MACH, SL):
          case X (OP_MACH, SL):
            res = h8_get_mach (sd);
            res = h8_get_mach (sd);
            if (res & 0x200)            /* sign extend */
            if (res & 0x200)            /* sign extend */
              res |= 0xfffffc00;
              res |= 0xfffffc00;
            break;
            break;
          case X (OP_MACL, SL):
          case X (OP_MACL, SL):
            res = h8_get_macl (sd);
            res = h8_get_macl (sd);
            break;
            break;
          default:      goto illegal;
          default:      goto illegal;
          }
          }
          nz = !h8_get_macZ (sd);
          nz = !h8_get_macZ (sd);
          n = h8_get_macN (sd);
          n = h8_get_macN (sd);
          v = h8_get_macV (sd);
          v = h8_get_macV (sd);
 
 
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O (O_LDMAC, SL):           /* ldmac, 179 */
        case O (O_LDMAC, SL):           /* ldmac, 179 */
          if (fetch (sd, &code->src, &rd))
          if (fetch (sd, &code->src, &rd))
            goto end;
            goto end;
 
 
          switch (code->dst.type) {
          switch (code->dst.type) {
          case X (OP_MACH, SL):
          case X (OP_MACH, SL):
            rd &= 0x3ff;                /* Truncate to 10 bits */
            rd &= 0x3ff;                /* Truncate to 10 bits */
            h8_set_mach (sd, rd);
            h8_set_mach (sd, rd);
            break;
            break;
          case X (OP_MACL, SL):
          case X (OP_MACL, SL):
            h8_set_macl (sd, rd);
            h8_set_macl (sd, rd);
            break;
            break;
          default:      goto illegal;
          default:      goto illegal;
          }
          }
          h8_set_macV (sd, 0);
          h8_set_macV (sd, 0);
          goto next;
          goto next;
 
 
        case O (O_MAC, SW):
        case O (O_MAC, SW):
          if (fetch (sd, &code->src, &rd) ||
          if (fetch (sd, &code->src, &rd) ||
              fetch (sd, &code->dst, &res))
              fetch (sd, &code->dst, &res))
            goto end;
            goto end;
 
 
          /* Ye gods, this is non-portable!
          /* Ye gods, this is non-portable!
             However, the existing mul/div code is similar.  */
             However, the existing mul/div code is similar.  */
          res = SEXTSHORT (res) * SEXTSHORT (rd);
          res = SEXTSHORT (res) * SEXTSHORT (rd);
 
 
          if (h8_get_macS (sd))         /* Saturating mode */
          if (h8_get_macS (sd))         /* Saturating mode */
            {
            {
              long long mac = h8_get_macl (sd);
              long long mac = h8_get_macl (sd);
 
 
              if (mac & 0x80000000)             /* sign extend */
              if (mac & 0x80000000)             /* sign extend */
                mac |= 0xffffffff00000000LL;
                mac |= 0xffffffff00000000LL;
 
 
              mac += res;
              mac += res;
              if (mac > 0x7fffffff || mac < 0xffffffff80000000LL)
              if (mac > 0x7fffffff || mac < 0xffffffff80000000LL)
                h8_set_macV (sd, 1);
                h8_set_macV (sd, 1);
              h8_set_macZ (sd, (mac == 0));
              h8_set_macZ (sd, (mac == 0));
              h8_set_macN (sd, (mac  < 0));
              h8_set_macN (sd, (mac  < 0));
              h8_set_macl (sd, (int) mac);
              h8_set_macl (sd, (int) mac);
            }
            }
          else                          /* "Less Saturating" mode */
          else                          /* "Less Saturating" mode */
            {
            {
              long long mac = h8_get_mach (sd);
              long long mac = h8_get_mach (sd);
              mac <<= 32;
              mac <<= 32;
              mac += h8_get_macl (sd);
              mac += h8_get_macl (sd);
 
 
              if (mac & 0x20000000000LL)        /* sign extend */
              if (mac & 0x20000000000LL)        /* sign extend */
                mac |= 0xfffffc0000000000LL;
                mac |= 0xfffffc0000000000LL;
 
 
              mac += res;
              mac += res;
              if (mac > 0x1ffffffffffLL ||
              if (mac > 0x1ffffffffffLL ||
                  mac < (long long) 0xfffffe0000000000LL)
                  mac < (long long) 0xfffffe0000000000LL)
                h8_set_macV (sd, 1);
                h8_set_macV (sd, 1);
              h8_set_macZ (sd, (mac == 0));
              h8_set_macZ (sd, (mac == 0));
              h8_set_macN (sd, (mac  < 0));
              h8_set_macN (sd, (mac  < 0));
              h8_set_macl (sd, (int) mac);
              h8_set_macl (sd, (int) mac);
              mac >>= 32;
              mac >>= 32;
              h8_set_mach (sd, (int) (mac & 0x3ff));
              h8_set_mach (sd, (int) (mac & 0x3ff));
            }
            }
          goto next;
          goto next;
 
 
        case O (O_MULS, SW):            /* muls.w */
        case O (O_MULS, SW):            /* muls.w */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          ea = SEXTSHORT (ea);
          ea = SEXTSHORT (ea);
          res = SEXTSHORT (ea * SEXTSHORT (rd));
          res = SEXTSHORT (ea * SEXTSHORT (rd));
 
 
          n  = res & 0x8000;
          n  = res & 0x8000;
          nz = res & 0xffff;
          nz = res & 0xffff;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O (O_MULS, SL):            /* muls.l */
        case O (O_MULS, SL):            /* muls.l */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          res = ea * rd;
          res = ea * rd;
 
 
          n  = res & 0x80000000;
          n  = res & 0x80000000;
          nz = res & 0xffffffff;
          nz = res & 0xffffffff;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_MULSU, SL):           /* muls/u.l */
        case O (O_MULSU, SL):           /* muls/u.l */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          /* Compute upper 32 bits of the 64-bit result.  */
          /* Compute upper 32 bits of the 64-bit result.  */
          res = (((long long) ea) * ((long long) rd)) >> 32;
          res = (((long long) ea) * ((long long) rd)) >> 32;
 
 
          n  = res & 0x80000000;
          n  = res & 0x80000000;
          nz = res & 0xffffffff;
          nz = res & 0xffffffff;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_MULU, SW):            /* mulu.w */
        case O (O_MULU, SW):            /* mulu.w */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd)));
          res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd)));
 
 
          /* Don't set Z or N.  */
          /* Don't set Z or N.  */
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O (O_MULU, SL):            /* mulu.l */
        case O (O_MULU, SL):            /* mulu.l */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          res = ea * rd;
          res = ea * rd;
 
 
          /* Don't set Z or N.  */
          /* Don't set Z or N.  */
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O (O_MULUU, SL):           /* mulu/u.l */
        case O (O_MULUU, SL):           /* mulu/u.l */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          /* Compute upper 32 bits of the 64-bit result.  */
          /* Compute upper 32 bits of the 64-bit result.  */
          res = (((unsigned long long) (unsigned) ea) *
          res = (((unsigned long long) (unsigned) ea) *
                 ((unsigned long long) (unsigned) rd)) >> 32;
                 ((unsigned long long) (unsigned) rd)) >> 32;
 
 
          /* Don't set Z or N.  */
          /* Don't set Z or N.  */
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O (O_MULXS, SB):           /* mulxs.b */
        case O (O_MULXS, SB):           /* mulxs.b */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          ea = SEXTCHAR (ea);
          ea = SEXTCHAR (ea);
          res = ea * SEXTCHAR (rd);
          res = ea * SEXTCHAR (rd);
 
 
          n  = res & 0x8000;
          n  = res & 0x8000;
          nz = res & 0xffff;
          nz = res & 0xffff;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O (O_MULXS, SW):           /* mulxs.w */
        case O (O_MULXS, SW):           /* mulxs.w */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          ea = SEXTSHORT (ea);
          ea = SEXTSHORT (ea);
          res = ea * SEXTSHORT (rd & 0xffff);
          res = ea * SEXTSHORT (rd & 0xffff);
 
 
          n  = res & 0x80000000;
          n  = res & 0x80000000;
          nz = res & 0xffffffff;
          nz = res & 0xffffffff;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O (O_MULXU, SB):           /* mulxu.b */
        case O (O_MULXU, SB):           /* mulxu.b */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          res = UEXTCHAR (ea) * UEXTCHAR (rd);
          res = UEXTCHAR (ea) * UEXTCHAR (rd);
 
 
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O (O_MULXU, SW):           /* mulxu.w */
        case O (O_MULXU, SW):           /* mulxu.w */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          res = UEXTSHORT (ea) * UEXTSHORT (rd);
          res = UEXTSHORT (ea) * UEXTSHORT (rd);
 
 
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
 
 
          goto next;
          goto next;
 
 
        case O (O_TAS, SB):             /* tas (test and set) */
        case O (O_TAS, SB):             /* tas (test and set) */
          if (!h8300sxmode)             /* h8sx can use any register. */
          if (!h8300sxmode)             /* h8sx can use any register. */
            switch (code->src.reg)
            switch (code->src.reg)
              {
              {
              case R0_REGNUM:
              case R0_REGNUM:
              case R1_REGNUM:
              case R1_REGNUM:
              case R4_REGNUM:
              case R4_REGNUM:
              case R5_REGNUM:
              case R5_REGNUM:
                break;
                break;
              default:
              default:
                goto illegal;
                goto illegal;
              }
              }
 
 
          if (fetch (sd, &code->src, &res))
          if (fetch (sd, &code->src, &res))
            goto end;
            goto end;
          if (store (sd, &code->src, res | 0x80))
          if (store (sd, &code->src, res | 0x80))
            goto end;
            goto end;
 
 
          goto just_flags_log8;
          goto just_flags_log8;
 
 
        case O (O_DIVU, SW):                    /* divu.w */
        case O (O_DIVU, SW):                    /* divu.w */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          n  = ea & 0x8000;
          n  = ea & 0x8000;
          nz = ea & 0xffff;
          nz = ea & 0xffff;
          if (ea)
          if (ea)
            res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea));
            res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea));
          else
          else
            res = 0;
            res = 0;
 
 
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_DIVU, SL):                    /* divu.l */
        case O (O_DIVU, SL):                    /* divu.l */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          n  = ea & 0x80000000;
          n  = ea & 0x80000000;
          nz = ea & 0xffffffff;
          nz = ea & 0xffffffff;
          if (ea)
          if (ea)
            res = (unsigned) rd / ea;
            res = (unsigned) rd / ea;
          else
          else
            res = 0;
            res = 0;
 
 
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_DIVS, SW):                    /* divs.w */
        case O (O_DIVS, SW):                    /* divs.w */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (ea)
          if (ea)
            {
            {
              res = SEXTSHORT (rd) / SEXTSHORT (ea);
              res = SEXTSHORT (rd) / SEXTSHORT (ea);
              nz  = 1;
              nz  = 1;
            }
            }
          else
          else
            {
            {
              res = 0;
              res = 0;
              nz  = 0;
              nz  = 0;
            }
            }
 
 
          n = res & 0x8000;
          n = res & 0x8000;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_DIVS, SL):                    /* divs.l */
        case O (O_DIVS, SL):                    /* divs.l */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          if (ea)
          if (ea)
            {
            {
              res = rd / ea;
              res = rd / ea;
              nz  = 1;
              nz  = 1;
            }
            }
          else
          else
            {
            {
              res = 0;
              res = 0;
              nz  = 0;
              nz  = 0;
            }
            }
 
 
          n = res & 0x80000000;
          n = res & 0x80000000;
          if (store (sd, &code->dst, res))
          if (store (sd, &code->dst, res))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_DIVXU, SB):                   /* divxu.b */
        case O (O_DIVXU, SB):                   /* divxu.b */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          rd = UEXTSHORT (rd);
          rd = UEXTSHORT (rd);
          ea = UEXTCHAR (ea);
          ea = UEXTCHAR (ea);
 
 
          n  = ea & 0x80;
          n  = ea & 0x80;
          nz = ea & 0xff;
          nz = ea & 0xff;
          if (ea)
          if (ea)
            {
            {
              tmp = (unsigned) rd % ea;
              tmp = (unsigned) rd % ea;
              res = (unsigned) rd / ea;
              res = (unsigned) rd / ea;
            }
            }
          else
          else
            {
            {
              tmp = 0;
              tmp = 0;
              res = 0;
              res = 0;
            }
            }
 
 
          if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
          if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_DIVXU, SW):                   /* divxu.w */
        case O (O_DIVXU, SW):                   /* divxu.w */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          ea = UEXTSHORT (ea);
          ea = UEXTSHORT (ea);
 
 
          n  = ea & 0x8000;
          n  = ea & 0x8000;
          nz = ea & 0xffff;
          nz = ea & 0xffff;
          if (ea)
          if (ea)
            {
            {
              tmp = (unsigned) rd % ea;
              tmp = (unsigned) rd % ea;
              res = (unsigned) rd / ea;
              res = (unsigned) rd / ea;
            }
            }
          else
          else
            {
            {
              tmp = 0;
              tmp = 0;
              res = 0;
              res = 0;
            }
            }
 
 
          if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
          if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_DIVXS, SB):                   /* divxs.b */
        case O (O_DIVXS, SB):                   /* divxs.b */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          rd = SEXTSHORT (rd);
          rd = SEXTSHORT (rd);
          ea = SEXTCHAR (ea);
          ea = SEXTCHAR (ea);
 
 
          if (ea)
          if (ea)
            {
            {
              tmp = (int) rd % (int) ea;
              tmp = (int) rd % (int) ea;
              res = (int) rd / (int) ea;
              res = (int) rd / (int) ea;
              nz  = 1;
              nz  = 1;
            }
            }
          else
          else
            {
            {
              tmp = 0;
              tmp = 0;
              res = 0;
              res = 0;
              nz  = 0;
              nz  = 0;
            }
            }
 
 
          n = res & 0x8000;
          n = res & 0x8000;
          if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
          if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_DIVXS, SW):                   /* divxs.w */
        case O (O_DIVXS, SW):                   /* divxs.w */
          if (fetch (sd, &code->src, &ea) ||
          if (fetch (sd, &code->src, &ea) ||
              fetch (sd, &code->dst, &rd))
              fetch (sd, &code->dst, &rd))
            goto end;
            goto end;
 
 
          ea = SEXTSHORT (ea);
          ea = SEXTSHORT (ea);
 
 
          if (ea)
          if (ea)
            {
            {
              tmp = (int) rd % (int) ea;
              tmp = (int) rd % (int) ea;
              res = (int) rd / (int) ea;
              res = (int) rd / (int) ea;
              nz  = 1;
              nz  = 1;
            }
            }
          else
          else
            {
            {
              tmp = 0;
              tmp = 0;
              res = 0;
              res = 0;
              nz  = 0;
              nz  = 0;
            }
            }
 
 
          n = res & 0x80000000;
          n = res & 0x80000000;
          if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
          if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16)))
            goto end;
            goto end;
          goto next;
          goto next;
 
 
        case O (O_EXTS, SW):                    /* exts.w, signed extend */
        case O (O_EXTS, SW):                    /* exts.w, signed extend */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          ea = rd & 0x80 ? -256 : 0;
          ea = rd & 0x80 ? -256 : 0;
          res = (rd & 0xff) + ea;
          res = (rd & 0xff) + ea;
          goto log16;
          goto log16;
 
 
        case O (O_EXTS, SL):                    /* exts.l, signed extend */
        case O (O_EXTS, SL):                    /* exts.l, signed extend */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (code->src.type == X (OP_IMM, SL))
          if (code->src.type == X (OP_IMM, SL))
            {
            {
              if (fetch (sd, &code->src, &ea))
              if (fetch (sd, &code->src, &ea))
                goto end;
                goto end;
 
 
              if (ea == 2)                      /* exts.l #2, nn */
              if (ea == 2)                      /* exts.l #2, nn */
                {
                {
                  /* Sign-extend from 8-bit to 32-bit.  */
                  /* Sign-extend from 8-bit to 32-bit.  */
                  ea = rd & 0x80 ? -256 : 0;
                  ea = rd & 0x80 ? -256 : 0;
                  res = (rd & 0xff) + ea;
                  res = (rd & 0xff) + ea;
                  goto log32;
                  goto log32;
                }
                }
            }
            }
          /* Sign-extend from 16-bit to 32-bit.  */
          /* Sign-extend from 16-bit to 32-bit.  */
          ea = rd & 0x8000 ? -65536 : 0;
          ea = rd & 0x8000 ? -65536 : 0;
          res = (rd & 0xffff) + ea;
          res = (rd & 0xffff) + ea;
          goto log32;
          goto log32;
 
 
        case O (O_EXTU, SW):                    /* extu.w, unsigned extend */
        case O (O_EXTU, SW):                    /* extu.w, unsigned extend */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          ea = 0;
          ea = 0;
          res = (rd & 0xff) + ea;
          res = (rd & 0xff) + ea;
          goto log16;
          goto log16;
 
 
        case O (O_EXTU, SL):                    /* extu.l, unsigned extend */
        case O (O_EXTU, SL):                    /* extu.l, unsigned extend */
          if (fetch2 (sd, &code->dst, &rd))
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
            goto end;
          if (code->src.type == X (OP_IMM, SL))
          if (code->src.type == X (OP_IMM, SL))
            {
            {
              if (fetch (sd, &code->src, &ea))
              if (fetch (sd, &code->src, &ea))
                goto end;
                goto end;
 
 
              if (ea == 2)                      /* extu.l #2, nn */
              if (ea == 2)                      /* extu.l #2, nn */
                {
                {
                  /* Zero-extend from 8-bit to 32-bit.  */
                  /* Zero-extend from 8-bit to 32-bit.  */
                  ea = 0;
                  ea = 0;
                  res = (rd & 0xff) + ea;
                  res = (rd & 0xff) + ea;
                  goto log32;
                  goto log32;
                }
                }
            }
            }
          /* Zero-extend from 16-bit to 32-bit.  */
          /* Zero-extend from 16-bit to 32-bit.  */
          ea = 0;
          ea = 0;
          res = (rd & 0xffff) + ea;
          res = (rd & 0xffff) + ea;
          goto log32;
          goto log32;
 
 
        case O (O_NOP, SN):                     /* nop */
        case O (O_NOP, SN):                     /* nop */
          goto next;
          goto next;
 
 
        case O (O_STM, SL):                     /* stm, store to memory */
        case O (O_STM, SL):                     /* stm, store to memory */
          {
          {
            int nregs, firstreg, i;
            int nregs, firstreg, i;
 
 
            nregs = GET_MEMORY_B (pc + 1);
            nregs = GET_MEMORY_B (pc + 1);
            nregs >>= 4;
            nregs >>= 4;
            nregs &= 0xf;
            nregs &= 0xf;
            firstreg = code->src.reg;
            firstreg = code->src.reg;
            firstreg &= 0xf;
            firstreg &= 0xf;
            for (i = firstreg; i <= firstreg + nregs; i++)
            for (i = firstreg; i <= firstreg + nregs; i++)
              {
              {
                h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) - 4);
                h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) - 4);
                SET_MEMORY_L (h8_get_reg (sd, SP_REGNUM), h8_get_reg (sd, i));
                SET_MEMORY_L (h8_get_reg (sd, SP_REGNUM), h8_get_reg (sd, i));
              }
              }
          }
          }
          goto next;
          goto next;
 
 
        case O (O_LDM, SL):                     /* ldm,  load from memory */
        case O (O_LDM, SL):                     /* ldm,  load from memory */
        case O (O_RTEL, SN):                    /* rte/l, ldm plus rte */
        case O (O_RTEL, SN):                    /* rte/l, ldm plus rte */
        case O (O_RTSL, SN):                    /* rts/l, ldm plus rts */
        case O (O_RTSL, SN):                    /* rts/l, ldm plus rts */
          {
          {
            int nregs, firstreg, i;
            int nregs, firstreg, i;
 
 
            nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
            nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
            firstreg = code->dst.reg & 0xf;
            firstreg = code->dst.reg & 0xf;
            for (i = firstreg; i >= firstreg - nregs; i--)
            for (i = firstreg; i >= firstreg - nregs; i--)
              {
              {
                h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
                h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
                h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
                h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
              }
              }
          }
          }
          switch (code->opcode) {
          switch (code->opcode) {
          case O (O_RTEL, SN):
          case O (O_RTEL, SN):
            goto rte;
            goto rte;
          case O (O_RTSL, SN):
          case O (O_RTSL, SN):
            goto rts;
            goto rts;
          case O (O_LDM, SL):
          case O (O_LDM, SL):
            goto next;
            goto next;
          default:
          default:
            goto illegal;
            goto illegal;
          }
          }
 
 
        case O (O_DAA, SB):
        case O (O_DAA, SB):
          /* Decimal Adjust Addition.  This is for BCD arithmetic.  */
          /* Decimal Adjust Addition.  This is for BCD arithmetic.  */
          res = GET_B_REG (code->src.reg);      /* FIXME fetch? */
          res = GET_B_REG (code->src.reg);      /* FIXME fetch? */
          if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) &&
          if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) &&
              !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
              !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
            res = res;          /* Value added == 0.  */
            res = res;          /* Value added == 0.  */
          else if (!c && (0  <= (res >>  4) && (res >>  4) <=  8) &&
          else if (!c && (0  <= (res >>  4) && (res >>  4) <=  8) &&
                   !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
                   !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
            res = res + 0x6;            /* Value added == 6.  */
            res = res + 0x6;            /* Value added == 6.  */
          else if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) &&
          else if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) &&
                    h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
                    h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
            res = res + 0x6;            /* Value added == 6.  */
            res = res + 0x6;            /* Value added == 6.  */
          else if (!c && (10 <= (res >>  4) && (res >>  4) <= 15) &&
          else if (!c && (10 <= (res >>  4) && (res >>  4) <= 15) &&
                   !h && (0  <= (res & 0xf) && (res & 0xf) <=  9))
                   !h && (0  <= (res & 0xf) && (res & 0xf) <=  9))
            res = res + 0x60;           /* Value added == 60.  */
            res = res + 0x60;           /* Value added == 60.  */
          else if (!c && (9  <= (res >>  4) && (res >>  4) <= 15) &&
          else if (!c && (9  <= (res >>  4) && (res >>  4) <= 15) &&
                   !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
                   !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
            res = res + 0x66;           /* Value added == 66.  */
            res = res + 0x66;           /* Value added == 66.  */
          else if (!c && (10 <= (res >>  4) && (res >>  4) <= 15) &&
          else if (!c && (10 <= (res >>  4) && (res >>  4) <= 15) &&
                    h && (0  <= (res & 0xf) && (res & 0xf) <=  3))
                    h && (0  <= (res & 0xf) && (res & 0xf) <=  3))
            res = res + 0x66;           /* Value added == 66.  */
            res = res + 0x66;           /* Value added == 66.  */
          else if ( c && (1 <= (res >>  4) && (res >>  4) <= 2) &&
          else if ( c && (1 <= (res >>  4) && (res >>  4) <= 2) &&
                   !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
                   !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
            res = res + 0x60;           /* Value added == 60.  */
            res = res + 0x60;           /* Value added == 60.  */
          else if ( c && (1  <= (res >>  4) && (res >>  4) <=  2) &&
          else if ( c && (1  <= (res >>  4) && (res >>  4) <=  2) &&
                   !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
                   !h && (10 <= (res & 0xf) && (res & 0xf) <= 15))
            res = res + 0x66;           /* Value added == 66.  */
            res = res + 0x66;           /* Value added == 66.  */
          else if (c && (1 <= (res >>  4) && (res >>  4) <= 3) &&
          else if (c && (1 <= (res >>  4) && (res >>  4) <= 3) &&
                   h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
                   h && (0 <= (res & 0xf) && (res & 0xf) <= 3))
            res = res + 0x66;           /* Value added == 66.  */
            res = res + 0x66;           /* Value added == 66.  */
 
 
          goto alu8;
          goto alu8;
 
 
        case O (O_DAS, SB):
        case O (O_DAS, SB):
          /* Decimal Adjust Subtraction.  This is for BCD arithmetic.  */
          /* Decimal Adjust Subtraction.  This is for BCD arithmetic.  */
          res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
          res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */
          if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) &&
          if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) &&
              !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
              !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
            res = res;          /* Value added == 0.  */
            res = res;          /* Value added == 0.  */
          else if (!c && (0 <= (res >>  4) && (res >>  4) <=  8) &&
          else if (!c && (0 <= (res >>  4) && (res >>  4) <=  8) &&
                    h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
                    h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
            res = res + 0xfa;           /* Value added == 0xfa.  */
            res = res + 0xfa;           /* Value added == 0xfa.  */
          else if ( c && (7 <= (res >>  4) && (res >>  4) <= 15) &&
          else if ( c && (7 <= (res >>  4) && (res >>  4) <= 15) &&
                   !h && (0 <= (res & 0xf) && (res & 0xf) <=  9))
                   !h && (0 <= (res & 0xf) && (res & 0xf) <=  9))
            res = res + 0xa0;           /* Value added == 0xa0.  */
            res = res + 0xa0;           /* Value added == 0xa0.  */
          else if (c && (6 <= (res >>  4) && (res >>  4) <= 15) &&
          else if (c && (6 <= (res >>  4) && (res >>  4) <= 15) &&
                   h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
                   h && (6 <= (res & 0xf) && (res & 0xf) <= 15))
            res = res + 0x9a;           /* Value added == 0x9a.  */
            res = res + 0x9a;           /* Value added == 0x9a.  */
 
 
          goto alu8;
          goto alu8;
 
 
        default:
        default:
        illegal:
        illegal:
          sim_engine_set_run_state (sd, sim_stopped, SIGILL);
          sim_engine_set_run_state (sd, sim_stopped, SIGILL);
          goto end;
          goto end;
 
 
        }
        }
 
 
      (*sim_callback->printf_filtered) (sim_callback,
      (*sim_callback->printf_filtered) (sim_callback,
                                        "sim_resume: internal error.\n");
                                        "sim_resume: internal error.\n");
      sim_engine_set_run_state (sd, sim_stopped, SIGILL);
      sim_engine_set_run_state (sd, sim_stopped, SIGILL);
      goto end;
      goto end;
 
 
    setc:
    setc:
      if (code->dst.type == X (OP_CCR, SB) ||
      if (code->dst.type == X (OP_CCR, SB) ||
          code->dst.type == X (OP_CCR, SW))
          code->dst.type == X (OP_CCR, SW))
        {
        {
          h8_set_ccr (sd, res);
          h8_set_ccr (sd, res);
          GETSR (sd);
          GETSR (sd);
        }
        }
      else if (h8300smode &&
      else if (h8300smode &&
               (code->dst.type == X (OP_EXR, SB) ||
               (code->dst.type == X (OP_EXR, SB) ||
                code->dst.type == X (OP_EXR, SW)))
                code->dst.type == X (OP_EXR, SW)))
        {
        {
          h8_set_exr (sd, res);
          h8_set_exr (sd, res);
          if (h8300smode)       /* Get exr.  */
          if (h8300smode)       /* Get exr.  */
            {
            {
              trace = (h8_get_exr (sd) >> 7) & 1;
              trace = (h8_get_exr (sd) >> 7) & 1;
              intMask = h8_get_exr (sd) & 7;
              intMask = h8_get_exr (sd) & 7;
            }
            }
        }
        }
      else
      else
        goto illegal;
        goto illegal;
 
 
      goto next;
      goto next;
 
 
    condtrue:
    condtrue:
      /* When a branch works */
      /* When a branch works */
      if (fetch (sd, &code->src, &res))
      if (fetch (sd, &code->src, &res))
        goto end;
        goto end;
      if (res & 1)              /* bad address */
      if (res & 1)              /* bad address */
        goto illegal;
        goto illegal;
      pc = code->next_pc + res;
      pc = code->next_pc + res;
      goto end;
      goto end;
 
 
      /* Set the cond codes from res */
      /* Set the cond codes from res */
    bitop:
    bitop:
 
 
      /* Set the flags after an 8 bit inc/dec operation */
      /* Set the flags after an 8 bit inc/dec operation */
    just_flags_inc8:
    just_flags_inc8:
      n = res & 0x80;
      n = res & 0x80;
      nz = res & 0xff;
      nz = res & 0xff;
      v = (rd & 0x7f) == 0x7f;
      v = (rd & 0x7f) == 0x7f;
      goto next;
      goto next;
 
 
      /* Set the flags after an 16 bit inc/dec operation */
      /* Set the flags after an 16 bit inc/dec operation */
    just_flags_inc16:
    just_flags_inc16:
      n = res & 0x8000;
      n = res & 0x8000;
      nz = res & 0xffff;
      nz = res & 0xffff;
      v = (rd & 0x7fff) == 0x7fff;
      v = (rd & 0x7fff) == 0x7fff;
      goto next;
      goto next;
 
 
      /* Set the flags after an 32 bit inc/dec operation */
      /* Set the flags after an 32 bit inc/dec operation */
    just_flags_inc32:
    just_flags_inc32:
      n = res & 0x80000000;
      n = res & 0x80000000;
      nz = res & 0xffffffff;
      nz = res & 0xffffffff;
      v = (rd & 0x7fffffff) == 0x7fffffff;
      v = (rd & 0x7fffffff) == 0x7fffffff;
      goto next;
      goto next;
 
 
    shift8:
    shift8:
      /* Set flags after an 8 bit shift op, carry,overflow set in insn */
      /* Set flags after an 8 bit shift op, carry,overflow set in insn */
      n = (rd & 0x80);
      n = (rd & 0x80);
      nz = rd & 0xff;
      nz = rd & 0xff;
      if (store2 (sd, &code->dst, rd))
      if (store2 (sd, &code->dst, rd))
        goto end;
        goto end;
      goto next;
      goto next;
 
 
    shift16:
    shift16:
      /* Set flags after an 16 bit shift op, carry,overflow set in insn */
      /* Set flags after an 16 bit shift op, carry,overflow set in insn */
      n = (rd & 0x8000);
      n = (rd & 0x8000);
      nz = rd & 0xffff;
      nz = rd & 0xffff;
      if (store2 (sd, &code->dst, rd))
      if (store2 (sd, &code->dst, rd))
        goto end;
        goto end;
      goto next;
      goto next;
 
 
    shift32:
    shift32:
      /* Set flags after an 32 bit shift op, carry,overflow set in insn */
      /* Set flags after an 32 bit shift op, carry,overflow set in insn */
      n = (rd & 0x80000000);
      n = (rd & 0x80000000);
      nz = rd & 0xffffffff;
      nz = rd & 0xffffffff;
      if (store2 (sd, &code->dst, rd))
      if (store2 (sd, &code->dst, rd))
        goto end;
        goto end;
      goto next;
      goto next;
 
 
    log32:
    log32:
      if (store2 (sd, &code->dst, res))
      if (store2 (sd, &code->dst, res))
        goto end;
        goto end;
 
 
    just_flags_log32:
    just_flags_log32:
      /* flags after a 32bit logical operation */
      /* flags after a 32bit logical operation */
      n = res & 0x80000000;
      n = res & 0x80000000;
      nz = res & 0xffffffff;
      nz = res & 0xffffffff;
      v = 0;
      v = 0;
      goto next;
      goto next;
 
 
    log16:
    log16:
      if (store2 (sd, &code->dst, res))
      if (store2 (sd, &code->dst, res))
        goto end;
        goto end;
 
 
    just_flags_log16:
    just_flags_log16:
      /* flags after a 16bit logical operation */
      /* flags after a 16bit logical operation */
      n = res & 0x8000;
      n = res & 0x8000;
      nz = res & 0xffff;
      nz = res & 0xffff;
      v = 0;
      v = 0;
      goto next;
      goto next;
 
 
    log8:
    log8:
      if (store2 (sd, &code->dst, res))
      if (store2 (sd, &code->dst, res))
        goto end;
        goto end;
 
 
    just_flags_log8:
    just_flags_log8:
      n = res & 0x80;
      n = res & 0x80;
      nz = res & 0xff;
      nz = res & 0xff;
      v = 0;
      v = 0;
      goto next;
      goto next;
 
 
    alu8:
    alu8:
      if (store2 (sd, &code->dst, res))
      if (store2 (sd, &code->dst, res))
        goto end;
        goto end;
 
 
    just_flags_alu8:
    just_flags_alu8:
      n = res & 0x80;
      n = res & 0x80;
      nz = res & 0xff;
      nz = res & 0xff;
      c = (res & 0x100);
      c = (res & 0x100);
      switch (code->opcode / 4)
      switch (code->opcode / 4)
        {
        {
        case O_ADD:
        case O_ADD:
        case O_ADDX:
        case O_ADDX:
          v = ((rd & 0x80) == (ea & 0x80)
          v = ((rd & 0x80) == (ea & 0x80)
               && (rd & 0x80) != (res & 0x80));
               && (rd & 0x80) != (res & 0x80));
          break;
          break;
        case O_SUB:
        case O_SUB:
        case O_SUBX:
        case O_SUBX:
        case O_CMP:
        case O_CMP:
          v = ((rd & 0x80) != (-ea & 0x80)
          v = ((rd & 0x80) != (-ea & 0x80)
               && (rd & 0x80) != (res & 0x80));
               && (rd & 0x80) != (res & 0x80));
          break;
          break;
        case O_NEG:
        case O_NEG:
          v = (rd == 0x80);
          v = (rd == 0x80);
          break;
          break;
        case O_DAA:
        case O_DAA:
        case O_DAS:
        case O_DAS:
          break;        /* No effect on v flag.  */
          break;        /* No effect on v flag.  */
        }
        }
      goto next;
      goto next;
 
 
    alu16:
    alu16:
      if (store2 (sd, &code->dst, res))
      if (store2 (sd, &code->dst, res))
        goto end;
        goto end;
 
 
    just_flags_alu16:
    just_flags_alu16:
      n = res & 0x8000;
      n = res & 0x8000;
      nz = res & 0xffff;
      nz = res & 0xffff;
      c = (res & 0x10000);
      c = (res & 0x10000);
      switch (code->opcode / 4)
      switch (code->opcode / 4)
        {
        {
        case O_ADD:
        case O_ADD:
        case O_ADDX:
        case O_ADDX:
          v = ((rd & 0x8000) == (ea & 0x8000)
          v = ((rd & 0x8000) == (ea & 0x8000)
               && (rd & 0x8000) != (res & 0x8000));
               && (rd & 0x8000) != (res & 0x8000));
          break;
          break;
        case O_SUB:
        case O_SUB:
        case O_SUBX:
        case O_SUBX:
        case O_CMP:
        case O_CMP:
          v = ((rd & 0x8000) != (-ea & 0x8000)
          v = ((rd & 0x8000) != (-ea & 0x8000)
               && (rd & 0x8000) != (res & 0x8000));
               && (rd & 0x8000) != (res & 0x8000));
          break;
          break;
        case O_NEG:
        case O_NEG:
          v = (rd == 0x8000);
          v = (rd == 0x8000);
          break;
          break;
        }
        }
      goto next;
      goto next;
 
 
    alu32:
    alu32:
      if (store2 (sd, &code->dst, res))
      if (store2 (sd, &code->dst, res))
        goto end;
        goto end;
 
 
    just_flags_alu32:
    just_flags_alu32:
      n = res & 0x80000000;
      n = res & 0x80000000;
      nz = res & 0xffffffff;
      nz = res & 0xffffffff;
      switch (code->opcode / 4)
      switch (code->opcode / 4)
        {
        {
        case O_ADD:
        case O_ADD:
        case O_ADDX:
        case O_ADDX:
          v = ((rd & 0x80000000) == (ea & 0x80000000)
          v = ((rd & 0x80000000) == (ea & 0x80000000)
               && (rd & 0x80000000) != (res & 0x80000000));
               && (rd & 0x80000000) != (res & 0x80000000));
          c = ((unsigned) res < (unsigned) rd) ||
          c = ((unsigned) res < (unsigned) rd) ||
            ((unsigned) res < (unsigned) ea);
            ((unsigned) res < (unsigned) ea);
          break;
          break;
        case O_SUB:
        case O_SUB:
        case O_SUBX:
        case O_SUBX:
        case O_CMP:
        case O_CMP:
          v = ((rd & 0x80000000) != (-ea & 0x80000000)
          v = ((rd & 0x80000000) != (-ea & 0x80000000)
               && (rd & 0x80000000) != (res & 0x80000000));
               && (rd & 0x80000000) != (res & 0x80000000));
          c = (unsigned) rd < (unsigned) -ea;
          c = (unsigned) rd < (unsigned) -ea;
          break;
          break;
        case O_NEG:
        case O_NEG:
          v = (rd == 0x80000000);
          v = (rd == 0x80000000);
          c = res != 0;
          c = res != 0;
          break;
          break;
        }
        }
      goto next;
      goto next;
 
 
    next:
    next:
      if ((res = h8_get_delayed_branch (sd)) != 0)
      if ((res = h8_get_delayed_branch (sd)) != 0)
        {
        {
          pc = res;
          pc = res;
          h8_set_delayed_branch (sd, 0);
          h8_set_delayed_branch (sd, 0);
        }
        }
      else
      else
        pc = code->next_pc;
        pc = code->next_pc;
 
 
    end:
    end:
 
 
      if (--poll_count < 0)
      if (--poll_count < 0)
        {
        {
          poll_count = POLL_QUIT_INTERVAL;
          poll_count = POLL_QUIT_INTERVAL;
          if ((*sim_callback->poll_quit) != NULL
          if ((*sim_callback->poll_quit) != NULL
              && (*sim_callback->poll_quit) (sim_callback))
              && (*sim_callback->poll_quit) (sim_callback))
            sim_engine_set_run_state (sd, sim_stopped, SIGINT);
            sim_engine_set_run_state (sd, sim_stopped, SIGINT);
        }
        }
      sim_engine_get_run_state (sd, &reason, &sigrc);
      sim_engine_get_run_state (sd, &reason, &sigrc);
    } while (reason == sim_running);
    } while (reason == sim_running);
 
 
  h8_set_ticks (sd, h8_get_ticks (sd) + get_now () - tick_start);
  h8_set_ticks (sd, h8_get_ticks (sd) + get_now () - tick_start);
  h8_set_cycles (sd, h8_get_cycles (sd) + cycles);
  h8_set_cycles (sd, h8_get_cycles (sd) + cycles);
  h8_set_insts (sd, h8_get_insts (sd) + insts);
  h8_set_insts (sd, h8_get_insts (sd) + insts);
  h8_set_pc (sd, pc);
  h8_set_pc (sd, pc);
  BUILDSR (sd);
  BUILDSR (sd);
 
 
  if (h8300smode)
  if (h8300smode)
    h8_set_exr (sd, (trace<<7) | intMask);
    h8_set_exr (sd, (trace<<7) | intMask);
 
 
  h8_set_mask (sd, oldmask);
  h8_set_mask (sd, oldmask);
  signal (SIGINT, prev);
  signal (SIGINT, prev);
}
}
 
 
int
int
sim_trace (SIM_DESC sd)
sim_trace (SIM_DESC sd)
{
{
  /* FIXME: Unfinished.  */
  /* FIXME: Unfinished.  */
  (*sim_callback->printf_filtered) (sim_callback,
  (*sim_callback->printf_filtered) (sim_callback,
                                    "sim_trace: trace not supported.\n");
                                    "sim_trace: trace not supported.\n");
  return 1;     /* Done.  */
  return 1;     /* Done.  */
}
}
 
 
int
int
sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
{
{
  int i;
  int i;
 
 
  init_pointers (sd);
  init_pointers (sd);
  if (addr < 0)
  if (addr < 0)
    return 0;
    return 0;
  for (i = 0; i < size; i++)
  for (i = 0; i < size; i++)
    {
    {
      if (addr < memory_size)
      if (addr < memory_size)
        {
        {
          h8_set_memory    (sd, addr + i, buffer[i]);
          h8_set_memory    (sd, addr + i, buffer[i]);
          h8_set_cache_idx (sd, addr + i,  0);
          h8_set_cache_idx (sd, addr + i,  0);
        }
        }
      else
      else
        {
        {
          h8_set_eightbit (sd, (addr + i) & 0xff, buffer[i]);
          h8_set_eightbit (sd, (addr + i) & 0xff, buffer[i]);
        }
        }
    }
    }
  return size;
  return size;
}
}
 
 
int
int
sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
{
{
  init_pointers (sd);
  init_pointers (sd);
  if (addr < 0)
  if (addr < 0)
    return 0;
    return 0;
  if (addr < memory_size)
  if (addr < memory_size)
    memcpy (buffer, h8_get_memory_buf (sd) + addr, size);
    memcpy (buffer, h8_get_memory_buf (sd) + addr, size);
  else
  else
    memcpy (buffer, h8_get_eightbit_buf (sd) + (addr & 0xff), size);
    memcpy (buffer, h8_get_eightbit_buf (sd) + (addr & 0xff), size);
  return size;
  return size;
}
}
 
 
 
 
int
int
sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
{
{
  int longval;
  int longval;
  int shortval;
  int shortval;
  int intval;
  int intval;
  longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
  longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
  shortval = (value[0] << 8) | (value[1]);
  shortval = (value[0] << 8) | (value[1]);
  intval = h8300hmode ? longval : shortval;
  intval = h8300hmode ? longval : shortval;
 
 
  init_pointers (sd);
  init_pointers (sd);
  switch (rn)
  switch (rn)
    {
    {
    case PC_REGNUM:
    case PC_REGNUM:
      if(h8300_normal_mode)
      if(h8300_normal_mode)
        h8_set_pc (sd, shortval); /* PC for Normal mode is 2 bytes */
        h8_set_pc (sd, shortval); /* PC for Normal mode is 2 bytes */
      else
      else
        h8_set_pc (sd, intval);
        h8_set_pc (sd, intval);
      break;
      break;
    default:
    default:
      (*sim_callback->printf_filtered) (sim_callback,
      (*sim_callback->printf_filtered) (sim_callback,
                                        "sim_store_register: bad regnum %d.\n",
                                        "sim_store_register: bad regnum %d.\n",
                                        rn);
                                        rn);
    case R0_REGNUM:
    case R0_REGNUM:
    case R1_REGNUM:
    case R1_REGNUM:
    case R2_REGNUM:
    case R2_REGNUM:
    case R3_REGNUM:
    case R3_REGNUM:
    case R4_REGNUM:
    case R4_REGNUM:
    case R5_REGNUM:
    case R5_REGNUM:
    case R6_REGNUM:
    case R6_REGNUM:
    case R7_REGNUM:
    case R7_REGNUM:
      h8_set_reg (sd, rn, intval);
      h8_set_reg (sd, rn, intval);
      break;
      break;
    case CCR_REGNUM:
    case CCR_REGNUM:
      h8_set_ccr (sd, intval);
      h8_set_ccr (sd, intval);
      break;
      break;
    case EXR_REGNUM:
    case EXR_REGNUM:
      h8_set_exr (sd, intval);
      h8_set_exr (sd, intval);
      break;
      break;
    case SBR_REGNUM:
    case SBR_REGNUM:
      h8_set_sbr (sd, intval);
      h8_set_sbr (sd, intval);
      break;
      break;
    case VBR_REGNUM:
    case VBR_REGNUM:
      h8_set_vbr (sd, intval);
      h8_set_vbr (sd, intval);
      break;
      break;
    case MACH_REGNUM:
    case MACH_REGNUM:
      h8_set_mach (sd, intval);
      h8_set_mach (sd, intval);
      break;
      break;
    case MACL_REGNUM:
    case MACL_REGNUM:
      h8_set_macl (sd, intval);
      h8_set_macl (sd, intval);
      break;
      break;
    case CYCLE_REGNUM:
    case CYCLE_REGNUM:
      h8_set_cycles (sd, longval);
      h8_set_cycles (sd, longval);
      break;
      break;
 
 
    case INST_REGNUM:
    case INST_REGNUM:
      h8_set_insts (sd, longval);
      h8_set_insts (sd, longval);
      break;
      break;
 
 
    case TICK_REGNUM:
    case TICK_REGNUM:
      h8_set_ticks (sd, longval);
      h8_set_ticks (sd, longval);
      break;
      break;
    }
    }
  return -1;
  return -1;
}
}
 
 
int
int
sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
{
{
  int v;
  int v;
  int longreg = 0;
  int longreg = 0;
 
 
  init_pointers (sd);
  init_pointers (sd);
 
 
  if (!h8300smode && rn >= EXR_REGNUM)
  if (!h8300smode && rn >= EXR_REGNUM)
    rn++;
    rn++;
  switch (rn)
  switch (rn)
    {
    {
    default:
    default:
      (*sim_callback->printf_filtered) (sim_callback,
      (*sim_callback->printf_filtered) (sim_callback,
                                        "sim_fetch_register: bad regnum %d.\n",
                                        "sim_fetch_register: bad regnum %d.\n",
                                        rn);
                                        rn);
      v = 0;
      v = 0;
      break;
      break;
    case CCR_REGNUM:
    case CCR_REGNUM:
      v = h8_get_ccr (sd);
      v = h8_get_ccr (sd);
      break;
      break;
    case EXR_REGNUM:
    case EXR_REGNUM:
      v = h8_get_exr (sd);
      v = h8_get_exr (sd);
      break;
      break;
    case PC_REGNUM:
    case PC_REGNUM:
      v = h8_get_pc (sd);
      v = h8_get_pc (sd);
      break;
      break;
    case SBR_REGNUM:
    case SBR_REGNUM:
      v = h8_get_sbr (sd);
      v = h8_get_sbr (sd);
      break;
      break;
    case VBR_REGNUM:
    case VBR_REGNUM:
      v = h8_get_vbr (sd);
      v = h8_get_vbr (sd);
      break;
      break;
    case MACH_REGNUM:
    case MACH_REGNUM:
      v = h8_get_mach (sd);
      v = h8_get_mach (sd);
      break;
      break;
    case MACL_REGNUM:
    case MACL_REGNUM:
      v = h8_get_macl (sd);
      v = h8_get_macl (sd);
      break;
      break;
    case R0_REGNUM:
    case R0_REGNUM:
    case R1_REGNUM:
    case R1_REGNUM:
    case R2_REGNUM:
    case R2_REGNUM:
    case R3_REGNUM:
    case R3_REGNUM:
    case R4_REGNUM:
    case R4_REGNUM:
    case R5_REGNUM:
    case R5_REGNUM:
    case R6_REGNUM:
    case R6_REGNUM:
    case R7_REGNUM:
    case R7_REGNUM:
      v = h8_get_reg (sd, rn);
      v = h8_get_reg (sd, rn);
      break;
      break;
    case CYCLE_REGNUM:
    case CYCLE_REGNUM:
      v = h8_get_cycles (sd);
      v = h8_get_cycles (sd);
      longreg = 1;
      longreg = 1;
      break;
      break;
    case TICK_REGNUM:
    case TICK_REGNUM:
      v = h8_get_ticks (sd);
      v = h8_get_ticks (sd);
      longreg = 1;
      longreg = 1;
      break;
      break;
    case INST_REGNUM:
    case INST_REGNUM:
      v = h8_get_insts (sd);
      v = h8_get_insts (sd);
      longreg = 1;
      longreg = 1;
      break;
      break;
    }
    }
  /* In Normal mode PC is 2 byte, but other registers are 4 byte */
  /* In Normal mode PC is 2 byte, but other registers are 4 byte */
  if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
  if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
    {
    {
      buf[0] = v >> 24;
      buf[0] = v >> 24;
      buf[1] = v >> 16;
      buf[1] = v >> 16;
      buf[2] = v >> 8;
      buf[2] = v >> 8;
      buf[3] = v >> 0;
      buf[3] = v >> 0;
    }
    }
  else
  else
    {
    {
      buf[0] = v >> 8;
      buf[0] = v >> 8;
      buf[1] = v;
      buf[1] = v;
    }
    }
  return -1;
  return -1;
}
}
 
 
void
void
sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
{
{
  sim_engine_get_run_state (sd, reason, sigrc);
  sim_engine_get_run_state (sd, reason, sigrc);
}
}
 
 
/* FIXME: Rename to sim_set_mem_size.  */
/* FIXME: Rename to sim_set_mem_size.  */
 
 
void
void
sim_size (int n)
sim_size (int n)
{
{
  /* Memory size is fixed.  */
  /* Memory size is fixed.  */
}
}
 
 
static void
static void
set_simcache_size (SIM_DESC sd, int n)
set_simcache_size (SIM_DESC sd, int n)
{
{
  if (sd->sim_cache)
  if (sd->sim_cache)
    free (sd->sim_cache);
    free (sd->sim_cache);
  if (n < 2)
  if (n < 2)
    n = 2;
    n = 2;
  sd->sim_cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
  sd->sim_cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
  memset (sd->sim_cache, 0, sizeof (decoded_inst) * n);
  memset (sd->sim_cache, 0, sizeof (decoded_inst) * n);
  sd->sim_cache_size = n;
  sd->sim_cache_size = n;
}
}
 
 
 
 
void
void
sim_info (SIM_DESC sd, int verbose)
sim_info (SIM_DESC sd, int verbose)
{
{
  double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
  double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
  double virttime = h8_get_cycles (sd) / 10.0e6;
  double virttime = h8_get_cycles (sd) / 10.0e6;
 
 
  (*sim_callback->printf_filtered) (sim_callback,
  (*sim_callback->printf_filtered) (sim_callback,
                                    "\n\n#instructions executed  %10d\n",
                                    "\n\n#instructions executed  %10d\n",
                                    h8_get_insts (sd));
                                    h8_get_insts (sd));
  (*sim_callback->printf_filtered) (sim_callback,
  (*sim_callback->printf_filtered) (sim_callback,
                                    "#cycles (v approximate) %10d\n",
                                    "#cycles (v approximate) %10d\n",
                                    h8_get_cycles (sd));
                                    h8_get_cycles (sd));
  (*sim_callback->printf_filtered) (sim_callback,
  (*sim_callback->printf_filtered) (sim_callback,
                                    "#real time taken        %10.4f\n",
                                    "#real time taken        %10.4f\n",
                                    timetaken);
                                    timetaken);
  (*sim_callback->printf_filtered) (sim_callback,
  (*sim_callback->printf_filtered) (sim_callback,
                                    "#virtual time taken     %10.4f\n",
                                    "#virtual time taken     %10.4f\n",
                                    virttime);
                                    virttime);
  if (timetaken != 0.0)
  if (timetaken != 0.0)
    (*sim_callback->printf_filtered) (sim_callback,
    (*sim_callback->printf_filtered) (sim_callback,
                                      "#simulation ratio       %10.4f\n",
                                      "#simulation ratio       %10.4f\n",
                                      virttime / timetaken);
                                      virttime / timetaken);
  (*sim_callback->printf_filtered) (sim_callback,
  (*sim_callback->printf_filtered) (sim_callback,
                                    "#compiles               %10d\n",
                                    "#compiles               %10d\n",
                                    h8_get_compiles (sd));
                                    h8_get_compiles (sd));
  (*sim_callback->printf_filtered) (sim_callback,
  (*sim_callback->printf_filtered) (sim_callback,
                                    "#cache size             %10d\n",
                                    "#cache size             %10d\n",
                                    sd->sim_cache_size);
                                    sd->sim_cache_size);
 
 
#ifdef ADEBUG
#ifdef ADEBUG
  /* This to be conditional on `what' (aka `verbose'),
  /* This to be conditional on `what' (aka `verbose'),
     however it was never passed as non-zero.  */
     however it was never passed as non-zero.  */
  if (1)
  if (1)
    {
    {
      int i;
      int i;
      for (i = 0; i < O_LAST; i++)
      for (i = 0; i < O_LAST; i++)
        {
        {
          if (h8_get_stats (sd, i))
          if (h8_get_stats (sd, i))
            (*sim_callback->printf_filtered) (sim_callback, "%d: %d\n",
            (*sim_callback->printf_filtered) (sim_callback, "%d: %d\n",
                                              i, h8_get_stats (sd, i));
                                              i, h8_get_stats (sd, i));
        }
        }
    }
    }
#endif
#endif
}
}
 
 
/* Indicate whether the cpu is an H8/300 or H8/300H.
/* Indicate whether the cpu is an H8/300 or H8/300H.
   FLAG is non-zero for the H8/300H.  */
   FLAG is non-zero for the H8/300H.  */
 
 
void
void
set_h8300h (unsigned long machine)
set_h8300h (unsigned long machine)
{
{
  /* FIXME: Much of the code in sim_load can be moved to sim_open.
  /* FIXME: Much of the code in sim_load can be moved to sim_open.
     This function being replaced by a sim_open:ARGV configuration
     This function being replaced by a sim_open:ARGV configuration
     option.  */
     option.  */
 
 
  h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
  h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
 
 
  if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
  if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
    h8300sxmode = 1;
    h8300sxmode = 1;
 
 
  if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
  if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
    h8300smode = 1;
    h8300smode = 1;
 
 
  if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
  if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
    h8300hmode = 1;
    h8300hmode = 1;
 
 
  if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
  if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
    h8300_normal_mode = 1;
    h8300_normal_mode = 1;
}
}
 
 
/* Cover function of sim_state_free to free the cpu buffers as well.  */
/* Cover function of sim_state_free to free the cpu buffers as well.  */
 
 
static void
static void
free_state (SIM_DESC sd)
free_state (SIM_DESC sd)
{
{
  if (STATE_MODULES (sd) != NULL)
  if (STATE_MODULES (sd) != NULL)
    sim_module_uninstall (sd);
    sim_module_uninstall (sd);
 
 
  /* Fixme: free buffers in _sim_cpu.  */
  /* Fixme: free buffers in _sim_cpu.  */
  sim_state_free (sd);
  sim_state_free (sd);
}
}
 
 
SIM_DESC
SIM_DESC
sim_open (SIM_OPEN_KIND kind,
sim_open (SIM_OPEN_KIND kind,
          struct host_callback_struct *callback,
          struct host_callback_struct *callback,
          struct bfd *abfd,
          struct bfd *abfd,
          char **argv)
          char **argv)
{
{
  SIM_DESC sd;
  SIM_DESC sd;
  sim_cpu *cpu;
  sim_cpu *cpu;
 
 
  sd = sim_state_alloc (kind, callback);
  sd = sim_state_alloc (kind, callback);
  sd->cpu = sim_cpu_alloc (sd, 0);
  sd->cpu = sim_cpu_alloc (sd, 0);
  cpu = STATE_CPU (sd, 0);
  cpu = STATE_CPU (sd, 0);
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  sim_state_initialize (sd, cpu);
  sim_state_initialize (sd, cpu);
  /* sim_cpu object is new, so some initialization is needed.  */
  /* sim_cpu object is new, so some initialization is needed.  */
  init_pointers_needed = 1;
  init_pointers_needed = 1;
 
 
  /* For compatibility (FIXME: is this right?).  */
  /* For compatibility (FIXME: is this right?).  */
  current_alignment = NONSTRICT_ALIGNMENT;
  current_alignment = NONSTRICT_ALIGNMENT;
  current_target_byte_order = BIG_ENDIAN;
  current_target_byte_order = BIG_ENDIAN;
 
 
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    {
    {
      free_state (sd);
      free_state (sd);
      return 0;
      return 0;
    }
    }
 
 
    /* getopt will print the error message so we just have to exit if
    /* getopt will print the error message so we just have to exit if
       this fails.  FIXME: Hmmm...  in the case of gdb we need getopt
       this fails.  FIXME: Hmmm...  in the case of gdb we need getopt
       to call print_filtered.  */
       to call print_filtered.  */
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
    {
    {
      /* Uninstall the modules to avoid memory leaks,
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
         file descriptor leaks, etc.  */
      free_state (sd);
      free_state (sd);
      return 0;
      return 0;
    }
    }
 
 
  /* Check for/establish the a reference program image.  */
  /* Check for/establish the a reference program image.  */
  if (sim_analyze_program (sd,
  if (sim_analyze_program (sd,
                           (STATE_PROG_ARGV (sd) != NULL
                           (STATE_PROG_ARGV (sd) != NULL
                            ? *STATE_PROG_ARGV (sd)
                            ? *STATE_PROG_ARGV (sd)
                            : NULL), abfd) != SIM_RC_OK)
                            : NULL), abfd) != SIM_RC_OK)
    {
    {
      free_state (sd);
      free_state (sd);
      return 0;
      return 0;
    }
    }
 
 
  /* Establish any remaining configuration options.  */
  /* Establish any remaining configuration options.  */
  if (sim_config (sd) != SIM_RC_OK)
  if (sim_config (sd) != SIM_RC_OK)
    {
    {
      free_state (sd);
      free_state (sd);
      return 0;
      return 0;
    }
    }
 
 
  if (sim_post_argv_init (sd) != SIM_RC_OK)
  if (sim_post_argv_init (sd) != SIM_RC_OK)
    {
    {
      /* Uninstall the modules to avoid memory leaks,
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
         file descriptor leaks, etc.  */
      free_state (sd);
      free_state (sd);
      return 0;
      return 0;
    }
    }
 
 
  /*  sim_hw_configure (sd); */
  /*  sim_hw_configure (sd); */
 
 
  /* FIXME: Much of the code in sim_load can be moved here.  */
  /* FIXME: Much of the code in sim_load can be moved here.  */
 
 
  sim_kind = kind;
  sim_kind = kind;
  myname = argv[0];
  myname = argv[0];
  sim_callback = callback;
  sim_callback = callback;
  return sd;
  return sd;
}
}
 
 
void
void
sim_close (SIM_DESC sd, int quitting)
sim_close (SIM_DESC sd, int quitting)
{
{
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
 
 
/* Called by gdb to load a program into memory.  */
/* Called by gdb to load a program into memory.  */
 
 
SIM_RC
SIM_RC
sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
{
{
  bfd *prog_bfd;
  bfd *prog_bfd;
 
 
  /* FIXME: The code below that sets a specific variant of the H8/300
  /* FIXME: The code below that sets a specific variant of the H8/300
     being simulated should be moved to sim_open().  */
     being simulated should be moved to sim_open().  */
 
 
  /* See if the file is for the H8/300 or H8/300H.  */
  /* See if the file is for the H8/300 or H8/300H.  */
  /* ??? This may not be the most efficient way.  The z8k simulator
  /* ??? This may not be the most efficient way.  The z8k simulator
     does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO).  */
     does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO).  */
  if (abfd != NULL)
  if (abfd != NULL)
    prog_bfd = abfd;
    prog_bfd = abfd;
  else
  else
    prog_bfd = bfd_openr (prog, NULL);
    prog_bfd = bfd_openr (prog, NULL);
  if (prog_bfd != NULL)
  if (prog_bfd != NULL)
    {
    {
      /* Set the cpu type.  We ignore failure from bfd_check_format
      /* Set the cpu type.  We ignore failure from bfd_check_format
         and bfd_openr as sim_load_file checks too.  */
         and bfd_openr as sim_load_file checks too.  */
      if (bfd_check_format (prog_bfd, bfd_object))
      if (bfd_check_format (prog_bfd, bfd_object))
        {
        {
          set_h8300h (bfd_get_mach (prog_bfd));
          set_h8300h (bfd_get_mach (prog_bfd));
        }
        }
    }
    }
 
 
  /* If we're using gdb attached to the simulator, then we have to
  /* If we're using gdb attached to the simulator, then we have to
     reallocate memory for the simulator.
     reallocate memory for the simulator.
 
 
     When gdb first starts, it calls fetch_registers (among other
     When gdb first starts, it calls fetch_registers (among other
     functions), which in turn calls init_pointers, which allocates
     functions), which in turn calls init_pointers, which allocates
     simulator memory.
     simulator memory.
 
 
     The problem is when we do that, we don't know whether we're
     The problem is when we do that, we don't know whether we're
     debugging an H8/300 or H8/300H program.
     debugging an H8/300 or H8/300H program.
 
 
     This is the first point at which we can make that determination,
     This is the first point at which we can make that determination,
     so we just reallocate memory now; this will also allow us to handle
     so we just reallocate memory now; this will also allow us to handle
     switching between H8/300 and H8/300H programs without exiting
     switching between H8/300 and H8/300H programs without exiting
     gdb.  */
     gdb.  */
 
 
  if (h8300smode && !h8300_normal_mode)
  if (h8300smode && !h8300_normal_mode)
    memory_size = H8300S_MSIZE;
    memory_size = H8300S_MSIZE;
  else if (h8300hmode && !h8300_normal_mode)
  else if (h8300hmode && !h8300_normal_mode)
    memory_size = H8300H_MSIZE;
    memory_size = H8300H_MSIZE;
  else
  else
    memory_size = H8300_MSIZE;
    memory_size = H8300_MSIZE;
 
 
  if (h8_get_memory_buf (sd))
  if (h8_get_memory_buf (sd))
    free (h8_get_memory_buf (sd));
    free (h8_get_memory_buf (sd));
  if (h8_get_cache_idx_buf (sd))
  if (h8_get_cache_idx_buf (sd))
    free (h8_get_cache_idx_buf (sd));
    free (h8_get_cache_idx_buf (sd));
  if (h8_get_eightbit_buf (sd))
  if (h8_get_eightbit_buf (sd))
    free (h8_get_eightbit_buf (sd));
    free (h8_get_eightbit_buf (sd));
 
 
  h8_set_memory_buf (sd, (unsigned char *)
  h8_set_memory_buf (sd, (unsigned char *)
                     calloc (sizeof (char), memory_size));
                     calloc (sizeof (char), memory_size));
  h8_set_cache_idx_buf (sd, (unsigned short *)
  h8_set_cache_idx_buf (sd, (unsigned short *)
                        calloc (sizeof (short), memory_size));
                        calloc (sizeof (short), memory_size));
  sd->memory_size = memory_size;
  sd->memory_size = memory_size;
  h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
  h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
 
 
  /* `msize' must be a power of two.  */
  /* `msize' must be a power of two.  */
  if ((memory_size & (memory_size - 1)) != 0)
  if ((memory_size & (memory_size - 1)) != 0)
    {
    {
      (*sim_callback->printf_filtered) (sim_callback,
      (*sim_callback->printf_filtered) (sim_callback,
                                        "sim_load: bad memory size.\n");
                                        "sim_load: bad memory size.\n");
      return SIM_RC_FAIL;
      return SIM_RC_FAIL;
    }
    }
  h8_set_mask (sd, memory_size - 1);
  h8_set_mask (sd, memory_size - 1);
 
 
  if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
  if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
                     sim_kind == SIM_OPEN_DEBUG,
                     sim_kind == SIM_OPEN_DEBUG,
                     0, sim_write)
                     0, sim_write)
      == NULL)
      == NULL)
    {
    {
      /* Close the bfd if we opened it.  */
      /* Close the bfd if we opened it.  */
      if (abfd == NULL && prog_bfd != NULL)
      if (abfd == NULL && prog_bfd != NULL)
        bfd_close (prog_bfd);
        bfd_close (prog_bfd);
      return SIM_RC_FAIL;
      return SIM_RC_FAIL;
    }
    }
 
 
  /* Close the bfd if we opened it.  */
  /* Close the bfd if we opened it.  */
  if (abfd == NULL && prog_bfd != NULL)
  if (abfd == NULL && prog_bfd != NULL)
    bfd_close (prog_bfd);
    bfd_close (prog_bfd);
  return SIM_RC_OK;
  return SIM_RC_OK;
}
}
 
 
SIM_RC
SIM_RC
sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
{
{
  int i = 0;
  int i = 0;
  int len_arg = 0;
  int len_arg = 0;
  int no_of_args = 0;
  int no_of_args = 0;
 
 
  if (abfd != NULL)
  if (abfd != NULL)
    h8_set_pc (sd, bfd_get_start_address (abfd));
    h8_set_pc (sd, bfd_get_start_address (abfd));
  else
  else
    h8_set_pc (sd, 0);
    h8_set_pc (sd, 0);
 
 
  /* Command Line support.  */
  /* Command Line support.  */
  if (argv != NULL)
  if (argv != NULL)
    {
    {
      /* Counting the no. of commandline arguments.  */
      /* Counting the no. of commandline arguments.  */
      for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
      for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++)
        continue;
        continue;
 
 
      /* Allocating memory for the argv pointers.  */
      /* Allocating memory for the argv pointers.  */
      h8_set_command_line (sd, (char **) malloc ((sizeof (char *))
      h8_set_command_line (sd, (char **) malloc ((sizeof (char *))
                                                 * (no_of_args + 1)));
                                                 * (no_of_args + 1)));
 
 
      for (i = 0; i < no_of_args; i++)
      for (i = 0; i < no_of_args; i++)
        {
        {
          /* Copying the argument string.  */
          /* Copying the argument string.  */
          h8_set_cmdline_arg (sd, i, (char *) strdup (argv[i]));
          h8_set_cmdline_arg (sd, i, (char *) strdup (argv[i]));
        }
        }
      h8_set_cmdline_arg (sd, i, NULL);
      h8_set_cmdline_arg (sd, i, NULL);
    }
    }
 
 
  return SIM_RC_OK;
  return SIM_RC_OK;
}
}
 
 
void
void
sim_do_command (SIM_DESC sd, char *cmd)
sim_do_command (SIM_DESC sd, char *cmd)
{
{
  (*sim_callback->printf_filtered) (sim_callback,
  (*sim_callback->printf_filtered) (sim_callback,
                                    "This simulator does not accept any commands.\n");
                                    "This simulator does not accept any commands.\n");
}
}
 
 
void
void
sim_set_callbacks (struct host_callback_struct *ptr)
sim_set_callbacks (struct host_callback_struct *ptr)
{
{
  sim_callback = ptr;
  sim_callback = ptr;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.