OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [sim/] [sh/] [interp.c] - Diff between revs 579 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 579 Rev 1765
/* Simulator for the Hitachi SH architecture.
/* Simulator for the Hitachi SH architecture.
 
 
   Written by Steve Chamberlain of Cygnus Support.
   Written by Steve Chamberlain of Cygnus Support.
   sac@cygnus.com
   sac@cygnus.com
 
 
   This file is part of SH sim
   This file is part of SH sim
 
 
 
 
                THIS SOFTWARE IS NOT COPYRIGHTED
                THIS SOFTWARE IS NOT COPYRIGHTED
 
 
   Cygnus offers the following for use in the public domain.  Cygnus
   Cygnus offers the following for use in the public domain.  Cygnus
   makes no warranty with regard to the software or it's performance
   makes no warranty with regard to the software or it's performance
   and the user accepts the software "AS IS" with all faults.
   and the user accepts the software "AS IS" with all faults.
 
 
   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
 
*/
*/
 
 
#include "config.h"
#include "config.h"
 
 
#include <signal.h>
#include <signal.h>
#ifdef HAVE_UNISTD_H
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#include <unistd.h>
#endif
#endif
 
 
#include "sysdep.h"
#include "sysdep.h"
#include "bfd.h"
#include "bfd.h"
#include "callback.h"
#include "callback.h"
#include "remote-sim.h"
#include "remote-sim.h"
 
 
/* This file is local - if newlib changes, then so should this.  */
/* This file is local - if newlib changes, then so should this.  */
#include "syscall.h"
#include "syscall.h"
 
 
#include <math.h>
#include <math.h>
 
 
#ifdef _WIN32
#ifdef _WIN32
#include <float.h>              /* Needed for _isnan() */
#include <float.h>              /* Needed for _isnan() */
#define isnan _isnan
#define isnan _isnan
#endif
#endif
 
 
#ifndef SIGBUS
#ifndef SIGBUS
#define SIGBUS SIGSEGV
#define SIGBUS SIGSEGV
#endif
#endif
 
 
#ifndef SIGQUIT
#ifndef SIGQUIT
#define SIGQUIT SIGTERM
#define SIGQUIT SIGTERM
#endif
#endif
 
 
#ifndef SIGTRAP
#ifndef SIGTRAP
#define SIGTRAP 5
#define SIGTRAP 5
#endif
#endif
 
 
#define O_RECOMPILE 85
#define O_RECOMPILE 85
#define DEFINE_TABLE
#define DEFINE_TABLE
#define DISASSEMBLER_TABLE
#define DISASSEMBLER_TABLE
 
 
/* Define the rate at which the simulator should poll the host
/* Define the rate at which the simulator should poll the host
   for a quit. */
   for a quit. */
#define POLL_QUIT_INTERVAL 0x60000
#define POLL_QUIT_INTERVAL 0x60000
 
 
typedef union
typedef union
{
{
 
 
  struct
  struct
  {
  {
    /* On targets like sparc-sun-solaris, fregs will be aligned on a 64 bit
    /* On targets like sparc-sun-solaris, fregs will be aligned on a 64 bit
       boundary (because of the d member).  To avoid padding between
       boundary (because of the d member).  To avoid padding between
       registers - which whould make the job of sim_fetch_register harder,
       registers - which whould make the job of sim_fetch_register harder,
       we add padding at the start.  */
       we add padding at the start.  */
    int pad_dummy;
    int pad_dummy;
    int regs[16];
    int regs[16];
    int pc;
    int pc;
    int pr;
    int pr;
 
 
    int gbr;
    int gbr;
    int vbr;
    int vbr;
    int mach;
    int mach;
    int macl;
    int macl;
 
 
    int sr;
    int sr;
 
 
    int fpul;
    int fpul;
 
 
    int fpscr;
    int fpscr;
 
 
    /* sh3e */
    /* sh3e */
    union fregs_u
    union fregs_u
      {
      {
        float f[16];
        float f[16];
        double d[8];
        double d[8];
        int i[16];
        int i[16];
      }
      }
    fregs[2];
    fregs[2];
 
 
    int ssr;
    int ssr;
    int spc;
    int spc;
    /* sh3 */
    /* sh3 */
    int bank[2][8];
    int bank[2][8];
 
 
    int ticks;
    int ticks;
    int stalls;
    int stalls;
    int memstalls;
    int memstalls;
    int cycles;
    int cycles;
    int insts;
    int insts;
 
 
    int prevlock;
    int prevlock;
    int thislock;
    int thislock;
    int exception;
    int exception;
 
 
    int end_of_registers;
    int end_of_registers;
 
 
    int msize;
    int msize;
#define PROFILE_FREQ 1
#define PROFILE_FREQ 1
#define PROFILE_SHIFT 2
#define PROFILE_SHIFT 2
    int profile;
    int profile;
    unsigned short *profile_hist;
    unsigned short *profile_hist;
    unsigned char *memory;
    unsigned char *memory;
  }
  }
  asregs;
  asregs;
  int asints[40];
  int asints[40];
} saved_state_type;
} saved_state_type;
 
 
saved_state_type saved_state;
saved_state_type saved_state;
 
 
 
 
/* These variables are at file scope so that functions other than
/* These variables are at file scope so that functions other than
   sim_resume can use the fetch/store macros */
   sim_resume can use the fetch/store macros */
 
 
static int target_little_endian;
static int target_little_endian;
static int host_little_endian;
static int host_little_endian;
 
 
#if 1
#if 1
static int maskl = ~0;
static int maskl = ~0;
static int maskw = ~0;
static int maskw = ~0;
#endif
#endif
 
 
static SIM_OPEN_KIND sim_kind;
static SIM_OPEN_KIND sim_kind;
static char *myname;
static char *myname;
 
 
 
 
/* Short hand definitions of the registers */
/* Short hand definitions of the registers */
 
 
#define SBIT(x) ((x)&sbit)
#define SBIT(x) ((x)&sbit)
#define R0      saved_state.asregs.regs[0]
#define R0      saved_state.asregs.regs[0]
#define Rn      saved_state.asregs.regs[n]
#define Rn      saved_state.asregs.regs[n]
#define Rm      saved_state.asregs.regs[m]
#define Rm      saved_state.asregs.regs[m]
#define UR0     (unsigned int)(saved_state.asregs.regs[0])
#define UR0     (unsigned int)(saved_state.asregs.regs[0])
#define UR      (unsigned int)R
#define UR      (unsigned int)R
#define UR      (unsigned int)R
#define UR      (unsigned int)R
#define SR0     saved_state.asregs.regs[0]
#define SR0     saved_state.asregs.regs[0]
#define GBR     saved_state.asregs.gbr
#define GBR     saved_state.asregs.gbr
#define VBR     saved_state.asregs.vbr
#define VBR     saved_state.asregs.vbr
#define SSR     saved_state.asregs.ssr
#define SSR     saved_state.asregs.ssr
#define SPC     saved_state.asregs.spc
#define SPC     saved_state.asregs.spc
#define MACH    saved_state.asregs.mach
#define MACH    saved_state.asregs.mach
#define MACL    saved_state.asregs.macl
#define MACL    saved_state.asregs.macl
#define FPUL    saved_state.asregs.fpul
#define FPUL    saved_state.asregs.fpul
 
 
#define PC pc
#define PC pc
 
 
 
 
 
 
/* Alternate bank of registers r0-r6 */
/* Alternate bank of registers r0-r6 */
 
 
/* Note: code controling SR handles flips between BANK0 and BANK1 */
/* Note: code controling SR handles flips between BANK0 and BANK1 */
#define Rn_BANK(n) (saved_state.asregs.bank[!SR_RB][(n)])
#define Rn_BANK(n) (saved_state.asregs.bank[!SR_RB][(n)])
#define SET_Rn_BANK(n, EXP) do { saved_state.asregs.bank[!SR_RB][(n)] = (EXP); } while (0)
#define SET_Rn_BANK(n, EXP) do { saved_state.asregs.bank[!SR_RB][(n)] = (EXP); } while (0)
 
 
 
 
/* Manipulate SR */
/* Manipulate SR */
 
 
#define SR_MASK_M (1 << 9)
#define SR_MASK_M (1 << 9)
#define SR_MASK_Q (1 << 8)
#define SR_MASK_Q (1 << 8)
#define SR_MASK_I (0xf << 4)
#define SR_MASK_I (0xf << 4)
#define SR_MASK_S (1 << 1)
#define SR_MASK_S (1 << 1)
#define SR_MASK_T (1 << 0)
#define SR_MASK_T (1 << 0)
 
 
#define SR_MASK_BL (1 << 28)
#define SR_MASK_BL (1 << 28)
#define SR_MASK_RB (1 << 29)
#define SR_MASK_RB (1 << 29)
#define SR_MASK_MD (1 << 30)
#define SR_MASK_MD (1 << 30)
 
 
#define M       ((saved_state.asregs.sr & SR_MASK_M) != 0)
#define M       ((saved_state.asregs.sr & SR_MASK_M) != 0)
#define Q       ((saved_state.asregs.sr & SR_MASK_Q) != 0)
#define Q       ((saved_state.asregs.sr & SR_MASK_Q) != 0)
#define S       ((saved_state.asregs.sr & SR_MASK_S) != 0)
#define S       ((saved_state.asregs.sr & SR_MASK_S) != 0)
#define T       ((saved_state.asregs.sr & SR_MASK_T) != 0)
#define T       ((saved_state.asregs.sr & SR_MASK_T) != 0)
 
 
#define SR_BL ((saved_state.asregs.sr & SR_MASK_BL) != 0)
#define SR_BL ((saved_state.asregs.sr & SR_MASK_BL) != 0)
#define SR_RB ((saved_state.asregs.sr & SR_MASK_RB) != 0)
#define SR_RB ((saved_state.asregs.sr & SR_MASK_RB) != 0)
#define SR_MD ((saved_state.asregs.sr & SR_MASK_MD) != 0)
#define SR_MD ((saved_state.asregs.sr & SR_MASK_MD) != 0)
 
 
/* Note: don't use this for privileged bits */
/* Note: don't use this for privileged bits */
#define SET_SR_BIT(EXP, BIT) \
#define SET_SR_BIT(EXP, BIT) \
do { \
do { \
  if ((EXP) & 1) \
  if ((EXP) & 1) \
    saved_state.asregs.sr |= (BIT); \
    saved_state.asregs.sr |= (BIT); \
  else \
  else \
    saved_state.asregs.sr &= ~(BIT); \
    saved_state.asregs.sr &= ~(BIT); \
} while (0)
} while (0)
 
 
#define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
#define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
#define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
#define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
#define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
#define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
#define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T)
#define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T)
 
 
#define GET_SR() (saved_state.asregs.sr - 0)
#define GET_SR() (saved_state.asregs.sr - 0)
#define SET_SR(x) set_sr (x)
#define SET_SR(x) set_sr (x)
static void
static void
set_sr (new_sr)
set_sr (new_sr)
     int new_sr;
     int new_sr;
{
{
  /* do we need to swap banks */
  /* do we need to swap banks */
  int old_gpr = (SR_MD ? !SR_RB : 0);
  int old_gpr = (SR_MD ? !SR_RB : 0);
  int new_gpr = ((new_sr & SR_MASK_MD)
  int new_gpr = ((new_sr & SR_MASK_MD)
                 ? (new_sr & SR_MASK_RB) == 0
                 ? (new_sr & SR_MASK_RB) == 0
                 : 0);
                 : 0);
  if (old_gpr != new_gpr)
  if (old_gpr != new_gpr)
    {
    {
      int i;
      int i;
      for (i = 0; i < 8; i++)
      for (i = 0; i < 8; i++)
        {
        {
          saved_state.asregs.bank[old_gpr][i] = saved_state.asregs.regs[i];
          saved_state.asregs.bank[old_gpr][i] = saved_state.asregs.regs[i];
          saved_state.asregs.regs[i] = saved_state.asregs.bank[new_gpr][i];
          saved_state.asregs.regs[i] = saved_state.asregs.bank[new_gpr][i];
        }
        }
    }
    }
}
}
 
 
 
 
/* Manipulate FPSCR */
/* Manipulate FPSCR */
 
 
#define FPSCR_MASK_FR (1 << 21)
#define FPSCR_MASK_FR (1 << 21)
#define FPSCR_MASK_SZ (1 << 20)
#define FPSCR_MASK_SZ (1 << 20)
#define FPSCR_MASK_PR (1 << 19)
#define FPSCR_MASK_PR (1 << 19)
 
 
#define FPSCR_FR  ((GET_FPSCR() & FPSCR_MASK_FR) != 0)
#define FPSCR_FR  ((GET_FPSCR() & FPSCR_MASK_FR) != 0)
#define FPSCR_SZ  ((GET_FPSCR() & FPSCR_MASK_SZ) != 0)
#define FPSCR_SZ  ((GET_FPSCR() & FPSCR_MASK_SZ) != 0)
#define FPSCR_PR  ((GET_FPSCR() & FPSCR_MASK_PR) != 0)
#define FPSCR_PR  ((GET_FPSCR() & FPSCR_MASK_PR) != 0)
 
 
static void
static void
set_fpscr1 (x)
set_fpscr1 (x)
        int x;
        int x;
{
{
  int old = saved_state.asregs.fpscr;
  int old = saved_state.asregs.fpscr;
  saved_state.asregs.fpscr = (x);
  saved_state.asregs.fpscr = (x);
  /* swap the floating point register banks */
  /* swap the floating point register banks */
  if ((saved_state.asregs.fpscr ^ old) & FPSCR_MASK_FR)
  if ((saved_state.asregs.fpscr ^ old) & FPSCR_MASK_FR)
    {
    {
      union fregs_u tmpf = saved_state.asregs.fregs[0];
      union fregs_u tmpf = saved_state.asregs.fregs[0];
      saved_state.asregs.fregs[0] = saved_state.asregs.fregs[1];
      saved_state.asregs.fregs[0] = saved_state.asregs.fregs[1];
      saved_state.asregs.fregs[1] = tmpf;
      saved_state.asregs.fregs[1] = tmpf;
    }
    }
}
}
 
 
#define GET_FPSCR()  (saved_state.asregs.fpscr)
#define GET_FPSCR()  (saved_state.asregs.fpscr)
#define SET_FPSCR(x) \
#define SET_FPSCR(x) \
do { \
do { \
  set_fpscr1 (x); \
  set_fpscr1 (x); \
} while (0)
} while (0)
 
 
 
 
int
int
fail ()
fail ()
{
{
  abort ();
  abort ();
}
}
 
 
int
int
special_address (addr, bits_written, data)
special_address (addr, bits_written, data)
     void *addr;
     void *addr;
     int bits_written, data;
     int bits_written, data;
{
{
  if ((unsigned) addr >> 24 == 0xf0 && bits_written == 32 && (data & 1) == 0)
  if ((unsigned) addr >> 24 == 0xf0 && bits_written == 32 && (data & 1) == 0)
    /* This invalidates (if not associative) or might invalidate
    /* This invalidates (if not associative) or might invalidate
       (if associative) an instruction cache line.  This is used for
       (if associative) an instruction cache line.  This is used for
       trampolines.  Since we don't simulate the cache, this is a no-op
       trampolines.  Since we don't simulate the cache, this is a no-op
       as far as the simulator is concerned.  */
       as far as the simulator is concerned.  */
    return 1;
    return 1;
  /* We can't do anything useful with the other stuff, so fail.  */
  /* We can't do anything useful with the other stuff, so fail.  */
  return 0;
  return 0;
}
}
 
 
/* This function exists solely for the purpose of setting a breakpoint to
/* This function exists solely for the purpose of setting a breakpoint to
   catch simulated bus errors when running the simulator under GDB.  */
   catch simulated bus errors when running the simulator under GDB.  */
 
 
void
void
bp_holder ()
bp_holder ()
{
{
}
}
 
 
/* FIXME: sim_resume should be renamed to sim_engine_run.  sim_resume
/* FIXME: sim_resume should be renamed to sim_engine_run.  sim_resume
   being implemented by ../common/sim_resume.c and the below should
   being implemented by ../common/sim_resume.c and the below should
   make a call to sim_engine_halt */
   make a call to sim_engine_halt */
 
 
#define BUSERROR(addr, mask, bits_written, data) \
#define BUSERROR(addr, mask, bits_written, data) \
  if (addr & ~mask) \
  if (addr & ~mask) \
    { \
    { \
      if (special_address (addr, bits_written, data)) \
      if (special_address (addr, bits_written, data)) \
        return; \
        return; \
      saved_state.asregs.exception = SIGBUS; \
      saved_state.asregs.exception = SIGBUS; \
      bp_holder (); \
      bp_holder (); \
    }
    }
 
 
/* Define this to enable register lifetime checking.
/* Define this to enable register lifetime checking.
   The compiler generates "add #0,rn" insns to mark registers as invalid,
   The compiler generates "add #0,rn" insns to mark registers as invalid,
   the simulator uses this info to call fail if it finds a ref to an invalid
   the simulator uses this info to call fail if it finds a ref to an invalid
   register before a def
   register before a def
 
 
   #define PARANOID
   #define PARANOID
*/
*/
 
 
#ifdef PARANOID
#ifdef PARANOID
int valid[16];
int valid[16];
#define CREF(x)  if(!valid[x]) fail();
#define CREF(x)  if(!valid[x]) fail();
#define CDEF(x)  valid[x] = 1;
#define CDEF(x)  valid[x] = 1;
#define UNDEF(x) valid[x] = 0;
#define UNDEF(x) valid[x] = 0;
#else
#else
#define CREF(x)
#define CREF(x)
#define CDEF(x)
#define CDEF(x)
#define UNDEF(x)
#define UNDEF(x)
#endif
#endif
 
 
static void parse_and_set_memory_size PARAMS ((char *str));
static void parse_and_set_memory_size PARAMS ((char *str));
 
 
static int IOMEM PARAMS ((int addr, int write, int value));
static int IOMEM PARAMS ((int addr, int write, int value));
 
 
static host_callback *callback;
static host_callback *callback;
 
 
 
 
 
 
/* Floating point registers */
/* Floating point registers */
 
 
#define DR(n) (get_dr (n))
#define DR(n) (get_dr (n))
static double
static double
get_dr (n)
get_dr (n)
     int n;
     int n;
{
{
  n = (n & ~1);
  n = (n & ~1);
  if (host_little_endian)
  if (host_little_endian)
    {
    {
      union
      union
      {
      {
        int i[2];
        int i[2];
        double d;
        double d;
      } dr;
      } dr;
      dr.i[1] = saved_state.asregs.fregs[0].i[n + 0];
      dr.i[1] = saved_state.asregs.fregs[0].i[n + 0];
      dr.i[0] = saved_state.asregs.fregs[0].i[n + 1];
      dr.i[0] = saved_state.asregs.fregs[0].i[n + 1];
      return dr.d;
      return dr.d;
    }
    }
  else
  else
    return (saved_state.asregs.fregs[0].d[n >> 1]);
    return (saved_state.asregs.fregs[0].d[n >> 1]);
}
}
 
 
#define SET_DR(n, EXP) set_dr ((n), (EXP))
#define SET_DR(n, EXP) set_dr ((n), (EXP))
static void
static void
set_dr (n, exp)
set_dr (n, exp)
     int n;
     int n;
     double exp;
     double exp;
{
{
  n = (n & ~1);
  n = (n & ~1);
  if (host_little_endian)
  if (host_little_endian)
    {
    {
      union
      union
      {
      {
        int i[2];
        int i[2];
        double d;
        double d;
      } dr;
      } dr;
      dr.d = exp;
      dr.d = exp;
      saved_state.asregs.fregs[0].i[n + 0] = dr.i[1];
      saved_state.asregs.fregs[0].i[n + 0] = dr.i[1];
      saved_state.asregs.fregs[0].i[n + 1] = dr.i[0];
      saved_state.asregs.fregs[0].i[n + 1] = dr.i[0];
    }
    }
  else
  else
    saved_state.asregs.fregs[0].d[n >> 1] = exp;
    saved_state.asregs.fregs[0].d[n >> 1] = exp;
}
}
 
 
#define SET_FI(n,EXP) (saved_state.asregs.fregs[0].i[(n)] = (EXP))
#define SET_FI(n,EXP) (saved_state.asregs.fregs[0].i[(n)] = (EXP))
#define FI(n) (saved_state.asregs.fregs[0].i[(n)])
#define FI(n) (saved_state.asregs.fregs[0].i[(n)])
 
 
#define FR(n) (saved_state.asregs.fregs[0].f[(n)])
#define FR(n) (saved_state.asregs.fregs[0].f[(n)])
#define SET_FR(n,EXP) (saved_state.asregs.fregs[0].f[(n)] = (EXP))
#define SET_FR(n,EXP) (saved_state.asregs.fregs[0].f[(n)] = (EXP))
 
 
#define XD_TO_XF(n) ((((n) & 1) << 5) | ((n) & 0x1e))
#define XD_TO_XF(n) ((((n) & 1) << 5) | ((n) & 0x1e))
#define XF(n) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f])
#define XF(n) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f])
#define SET_XF(n,EXP) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f] = (EXP))
#define SET_XF(n,EXP) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f] = (EXP))
 
 
 
 
#define FP_OP(n, OP, m) \
#define FP_OP(n, OP, m) \
{ \
{ \
  if (FPSCR_PR) \
  if (FPSCR_PR) \
    { \
    { \
      if (((n) & 1) || ((m) & 1)) \
      if (((n) & 1) || ((m) & 1)) \
        saved_state.asregs.exception = SIGILL; \
        saved_state.asregs.exception = SIGILL; \
      else \
      else \
        SET_DR(n, (DR(n) OP DR(m))); \
        SET_DR(n, (DR(n) OP DR(m))); \
    } \
    } \
  else \
  else \
    SET_FR(n, (FR(n) OP FR(m))); \
    SET_FR(n, (FR(n) OP FR(m))); \
} while (0)
} while (0)
 
 
#define FP_UNARY(n, OP) \
#define FP_UNARY(n, OP) \
{ \
{ \
  if (FPSCR_PR) \
  if (FPSCR_PR) \
    { \
    { \
      if ((n) & 1) \
      if ((n) & 1) \
        saved_state.asregs.exception = SIGILL; \
        saved_state.asregs.exception = SIGILL; \
      else \
      else \
        SET_DR(n, (OP (DR(n)))); \
        SET_DR(n, (OP (DR(n)))); \
    } \
    } \
  else \
  else \
    SET_FR(n, (OP (FR(n)))); \
    SET_FR(n, (OP (FR(n)))); \
} while (0)
} while (0)
 
 
#define FP_CMP(n, OP, m) \
#define FP_CMP(n, OP, m) \
{ \
{ \
  if (FPSCR_PR) \
  if (FPSCR_PR) \
    { \
    { \
      if (((n) & 1) || ((m) & 1)) \
      if (((n) & 1) || ((m) & 1)) \
        saved_state.asregs.exception = SIGILL; \
        saved_state.asregs.exception = SIGILL; \
      else \
      else \
        SET_SR_T (DR(n) OP DR(m)); \
        SET_SR_T (DR(n) OP DR(m)); \
    } \
    } \
  else \
  else \
    SET_SR_T (FR(n) OP FR(m)); \
    SET_SR_T (FR(n) OP FR(m)); \
} while (0)
} while (0)
 
 
 
 
 
 
static void INLINE
static void INLINE
wlat_little (memory, x, value, maskl)
wlat_little (memory, x, value, maskl)
     unsigned char *memory;
     unsigned char *memory;
{
{
  int v = value;
  int v = value;
  unsigned char *p = memory + ((x) & maskl);
  unsigned char *p = memory + ((x) & maskl);
  BUSERROR(x, maskl, 32, v);
  BUSERROR(x, maskl, 32, v);
  p[3] = v >> 24;
  p[3] = v >> 24;
  p[2] = v >> 16;
  p[2] = v >> 16;
  p[1] = v >> 8;
  p[1] = v >> 8;
  p[0] = v;
  p[0] = v;
}
}
 
 
static void INLINE
static void INLINE
wwat_little (memory, x, value, maskw)
wwat_little (memory, x, value, maskw)
     unsigned char *memory;
     unsigned char *memory;
{
{
  int v = value;
  int v = value;
  unsigned char *p = memory + ((x) & maskw);
  unsigned char *p = memory + ((x) & maskw);
  BUSERROR(x, maskw, 16, v);
  BUSERROR(x, maskw, 16, v);
 
 
  p[1] = v >> 8;
  p[1] = v >> 8;
  p[0] = v;
  p[0] = v;
}
}
 
 
static void INLINE
static void INLINE
wbat_any (memory, x, value, maskb)
wbat_any (memory, x, value, maskb)
     unsigned char *memory;
     unsigned char *memory;
{
{
  unsigned char *p = memory + (x & maskb);
  unsigned char *p = memory + (x & maskb);
  if (x > 0x5000000)
  if (x > 0x5000000)
    IOMEM (x, 1, value);
    IOMEM (x, 1, value);
  BUSERROR(x, maskb, 8, value);
  BUSERROR(x, maskb, 8, value);
 
 
  p[0] = value;
  p[0] = value;
}
}
 
 
static void INLINE
static void INLINE
wlat_big (memory, x, value, maskl)
wlat_big (memory, x, value, maskl)
     unsigned char *memory;
     unsigned char *memory;
{
{
  int v = value;
  int v = value;
  unsigned char *p = memory + ((x) & maskl);
  unsigned char *p = memory + ((x) & maskl);
  BUSERROR(x, maskl, 32, v);
  BUSERROR(x, maskl, 32, v);
 
 
  p[0] = v >> 24;
  p[0] = v >> 24;
  p[1] = v >> 16;
  p[1] = v >> 16;
  p[2] = v >> 8;
  p[2] = v >> 8;
  p[3] = v;
  p[3] = v;
}
}
 
 
static void INLINE
static void INLINE
wwat_big (memory, x, value, maskw)
wwat_big (memory, x, value, maskw)
     unsigned char *memory;
     unsigned char *memory;
{
{
  int v = value;
  int v = value;
  unsigned char *p = memory + ((x) & maskw);
  unsigned char *p = memory + ((x) & maskw);
  BUSERROR(x, maskw, 16, v);
  BUSERROR(x, maskw, 16, v);
 
 
  p[0] = v >> 8;
  p[0] = v >> 8;
  p[1] = v;
  p[1] = v;
}
}
 
 
static void INLINE
static void INLINE
wbat_big (memory, x, value, maskb)
wbat_big (memory, x, value, maskb)
     unsigned char *memory;
     unsigned char *memory;
{
{
  unsigned char *p = memory + (x & maskb);
  unsigned char *p = memory + (x & maskb);
  BUSERROR(x, maskb, 8, value);
  BUSERROR(x, maskb, 8, value);
 
 
  if (x > 0x5000000)
  if (x > 0x5000000)
    IOMEM (x, 1, value);
    IOMEM (x, 1, value);
  p[0] = value;
  p[0] = value;
}
}
 
 
/* Read functions */
/* Read functions */
 
 
static int INLINE
static int INLINE
rlat_little (memory, x, maskl)
rlat_little (memory, x, maskl)
     unsigned char *memory;
     unsigned char *memory;
{
{
  unsigned char *p = memory + ((x) & maskl);
  unsigned char *p = memory + ((x) & maskl);
  BUSERROR(x, maskl, -32, -1);
  BUSERROR(x, maskl, -32, -1);
 
 
  return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
  return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
}
}
 
 
static int INLINE
static int INLINE
rwat_little (memory, x, maskw)
rwat_little (memory, x, maskw)
     unsigned char *memory;
     unsigned char *memory;
{
{
  unsigned char *p = memory + ((x) & maskw);
  unsigned char *p = memory + ((x) & maskw);
  BUSERROR(x, maskw, -16, -1);
  BUSERROR(x, maskw, -16, -1);
 
 
  return (p[1] << 8) | p[0];
  return (p[1] << 8) | p[0];
}
}
 
 
static int INLINE
static int INLINE
rbat_any (memory, x, maskb)
rbat_any (memory, x, maskb)
     unsigned char *memory;
     unsigned char *memory;
{
{
  unsigned char *p = memory + ((x) & maskb);
  unsigned char *p = memory + ((x) & maskb);
  BUSERROR(x, maskb, -8, -1);
  BUSERROR(x, maskb, -8, -1);
 
 
  return p[0];
  return p[0];
}
}
 
 
static int INLINE
static int INLINE
rlat_big (memory, x, maskl)
rlat_big (memory, x, maskl)
     unsigned char *memory;
     unsigned char *memory;
{
{
  unsigned char *p = memory + ((x) & maskl);
  unsigned char *p = memory + ((x) & maskl);
  BUSERROR(x, maskl, -32, -1);
  BUSERROR(x, maskl, -32, -1);
 
 
  return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
  return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
}
 
 
static int INLINE
static int INLINE
rwat_big (memory, x, maskw)
rwat_big (memory, x, maskw)
     unsigned char *memory;
     unsigned char *memory;
{
{
  unsigned char *p = memory + ((x) & maskw);
  unsigned char *p = memory + ((x) & maskw);
  BUSERROR(x, maskw, -16, -1);
  BUSERROR(x, maskw, -16, -1);
 
 
  return (p[0] << 8) | p[1];
  return (p[0] << 8) | p[1];
}
}
 
 
#define RWAT(x)         (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
#define RWAT(x)         (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
#define RLAT(x)         (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
#define RLAT(x)         (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
#define RBAT(x)         (rbat_any (memory, x, maskb))
#define RBAT(x)         (rbat_any (memory, x, maskb))
#define WWAT(x,v)       (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
#define WWAT(x,v)       (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
#define WLAT(x,v)       (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
#define WLAT(x,v)       (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
#define WBAT(x,v)       (wbat_any (memory, x, v, maskb))
#define WBAT(x,v)       (wbat_any (memory, x, v, maskb))
 
 
#define RUWAT(x)  (RWAT(x) & 0xffff)
#define RUWAT(x)  (RWAT(x) & 0xffff)
#define RSWAT(x)  ((short)(RWAT(x)))
#define RSWAT(x)  ((short)(RWAT(x)))
#define RSBAT(x)  (SEXT(RBAT(x)))
#define RSBAT(x)  (SEXT(RBAT(x)))
 
 
#define RDAT(x, n) (do_rdat (memory, (x), (n), (little_endian)))
#define RDAT(x, n) (do_rdat (memory, (x), (n), (little_endian)))
static int
static int
do_rdat (memory, x, n, little_endian)
do_rdat (memory, x, n, little_endian)
     char *memory;
     char *memory;
     int x;
     int x;
     int n;
     int n;
     int little_endian;
     int little_endian;
{
{
  int f0;
  int f0;
  int f1;
  int f1;
  int i = (n & 1);
  int i = (n & 1);
  int j = (n & ~1);
  int j = (n & ~1);
  if (little_endian)
  if (little_endian)
    {
    {
      f0 = rlat_little (memory, x + 0, maskl);
      f0 = rlat_little (memory, x + 0, maskl);
      f1 = rlat_little (memory, x + 4, maskl);
      f1 = rlat_little (memory, x + 4, maskl);
    }
    }
  else
  else
    {
    {
      f0 = rlat_big (memory, x + 0, maskl);
      f0 = rlat_big (memory, x + 0, maskl);
      f1 = rlat_big (memory, x + 4, maskl);
      f1 = rlat_big (memory, x + 4, maskl);
    }
    }
  saved_state.asregs.fregs[i].i[(j + 0)] = f0;
  saved_state.asregs.fregs[i].i[(j + 0)] = f0;
  saved_state.asregs.fregs[i].i[(j + 1)] = f1;
  saved_state.asregs.fregs[i].i[(j + 1)] = f1;
  return 0;
  return 0;
}
}
 
 
#define WDAT(x, n) (do_wdat (memory, (x), (n), (little_endian)))
#define WDAT(x, n) (do_wdat (memory, (x), (n), (little_endian)))
static int
static int
do_wdat (memory, x, n, little_endian)
do_wdat (memory, x, n, little_endian)
     char *memory;
     char *memory;
     int x;
     int x;
     int n;
     int n;
     int little_endian;
     int little_endian;
{
{
  int f0;
  int f0;
  int f1;
  int f1;
  int i = (n & 1);
  int i = (n & 1);
  int j = (n & ~1);
  int j = (n & ~1);
  f0 = saved_state.asregs.fregs[i].i[(j + 0)];
  f0 = saved_state.asregs.fregs[i].i[(j + 0)];
  f1 = saved_state.asregs.fregs[i].i[(j + 1)];
  f1 = saved_state.asregs.fregs[i].i[(j + 1)];
  if (little_endian)
  if (little_endian)
    {
    {
      wlat_little (memory, (x + 0), f0, maskl);
      wlat_little (memory, (x + 0), f0, maskl);
      wlat_little (memory, (x + 4), f1, maskl);
      wlat_little (memory, (x + 4), f1, maskl);
    }
    }
  else
  else
    {
    {
      wlat_big (memory, (x + 0), f0, maskl);
      wlat_big (memory, (x + 0), f0, maskl);
      wlat_big (memory, (x + 4), f1, maskl);
      wlat_big (memory, (x + 4), f1, maskl);
    }
    }
  return 0;
  return 0;
}
}
 
 
 
 
#define MA(n) do { memstalls += (((pc & 3) != 0) ? (n) : ((n) - 1)); } while (0)
#define MA(n) do { memstalls += (((pc & 3) != 0) ? (n) : ((n) - 1)); } while (0)
 
 
#define SEXT(x)         (((x &  0xff) ^ (~0x7f))+0x80)
#define SEXT(x)         (((x &  0xff) ^ (~0x7f))+0x80)
#define SEXT12(x)       (((x & 0xfff) ^ 0x800) - 0x800)
#define SEXT12(x)       (((x & 0xfff) ^ 0x800) - 0x800)
#define SEXTW(y)        ((int)((short)y))
#define SEXTW(y)        ((int)((short)y))
 
 
#define Delay_Slot(TEMPPC)      iword = RUWAT(TEMPPC); goto top;
#define Delay_Slot(TEMPPC)      iword = RUWAT(TEMPPC); goto top;
 
 
int empty[16];
int empty[16];
 
 
#define L(x)   thislock = x;
#define L(x)   thislock = x;
#define TL(x)  if ((x) == prevlock) stalls++;
#define TL(x)  if ((x) == prevlock) stalls++;
#define TB(x,y)  if ((x) == prevlock || (y)==prevlock) stalls++;
#define TB(x,y)  if ((x) == prevlock || (y)==prevlock) stalls++;
 
 
#if defined(__GO32__) || defined(_WIN32)
#if defined(__GO32__) || defined(_WIN32)
int sim_memory_size = 19;
int sim_memory_size = 19;
#else
#else
int sim_memory_size = 24;
int sim_memory_size = 24;
#endif
#endif
 
 
static int sim_profile_size = 17;
static int sim_profile_size = 17;
static int nsamples;
static int nsamples;
 
 
#undef TB
#undef TB
#define TB(x,y)
#define TB(x,y)
 
 
#define SMR1 (0x05FFFEC8)       /* Channel 1  serial mode register */
#define SMR1 (0x05FFFEC8)       /* Channel 1  serial mode register */
#define BRR1 (0x05FFFEC9)       /* Channel 1  bit rate register */
#define BRR1 (0x05FFFEC9)       /* Channel 1  bit rate register */
#define SCR1 (0x05FFFECA)       /* Channel 1  serial control register */
#define SCR1 (0x05FFFECA)       /* Channel 1  serial control register */
#define TDR1 (0x05FFFECB)       /* Channel 1  transmit data register */
#define TDR1 (0x05FFFECB)       /* Channel 1  transmit data register */
#define SSR1 (0x05FFFECC)       /* Channel 1  serial status register */
#define SSR1 (0x05FFFECC)       /* Channel 1  serial status register */
#define RDR1 (0x05FFFECD)       /* Channel 1  receive data register */
#define RDR1 (0x05FFFECD)       /* Channel 1  receive data register */
 
 
#define SCI_RDRF         0x40   /* Recieve data register full */
#define SCI_RDRF         0x40   /* Recieve data register full */
#define SCI_TDRE        0x80    /* Transmit data register empty */
#define SCI_TDRE        0x80    /* Transmit data register empty */
 
 
static int
static int
IOMEM (addr, write, value)
IOMEM (addr, write, value)
     int addr;
     int addr;
     int write;
     int write;
     int value;
     int value;
{
{
  if (write)
  if (write)
    {
    {
      switch (addr)
      switch (addr)
        {
        {
        case TDR1:
        case TDR1:
          if (value != '\r')
          if (value != '\r')
            {
            {
              putchar (value);
              putchar (value);
              fflush (stdout);
              fflush (stdout);
            }
            }
          break;
          break;
        }
        }
    }
    }
  else
  else
    {
    {
      switch (addr)
      switch (addr)
        {
        {
        case RDR1:
        case RDR1:
          return getchar ();
          return getchar ();
        }
        }
    }
    }
  return 0;
  return 0;
}
}
 
 
static int
static int
get_now ()
get_now ()
{
{
  return time ((long *) 0);
  return time ((long *) 0);
}
}
 
 
static int
static int
now_persec ()
now_persec ()
{
{
  return 1;
  return 1;
}
}
 
 
static FILE *profile_file;
static FILE *profile_file;
 
 
static void
static void
swap (memory, n)
swap (memory, n)
     unsigned char *memory;
     unsigned char *memory;
     int n;
     int n;
{
{
  int little_endian = target_little_endian;
  int little_endian = target_little_endian;
  WLAT (0, n);
  WLAT (0, n);
}
}
 
 
static void
static void
swap16 (memory, n)
swap16 (memory, n)
     unsigned char *memory;
     unsigned char *memory;
     int n;
     int n;
{
{
  int little_endian = target_little_endian;
  int little_endian = target_little_endian;
  WWAT (0, n);
  WWAT (0, n);
}
}
 
 
static void
static void
swapout (n)
swapout (n)
     int n;
     int n;
{
{
  if (profile_file)
  if (profile_file)
    {
    {
      char b[4];
      char b[4];
      swap (b, n);
      swap (b, n);
      fwrite (b, 4, 1, profile_file);
      fwrite (b, 4, 1, profile_file);
    }
    }
}
}
 
 
static void
static void
swapout16 (n)
swapout16 (n)
     int n;
     int n;
{
{
  char b[4];
  char b[4];
  swap16 (b, n);
  swap16 (b, n);
  fwrite (b, 2, 1, profile_file);
  fwrite (b, 2, 1, profile_file);
}
}
 
 
/* Turn a pointer in a register into a pointer into real memory. */
/* Turn a pointer in a register into a pointer into real memory. */
 
 
static char *
static char *
ptr (x)
ptr (x)
     int x;
     int x;
{
{
  return (char *) (x + saved_state.asregs.memory);
  return (char *) (x + saved_state.asregs.memory);
}
}
 
 
/* Simulate a monitor trap, put the result into r0 and errno into r1 */
/* Simulate a monitor trap, put the result into r0 and errno into r1 */
 
 
static void
static void
trap (i, regs, memory, maskl, maskw, little_endian)
trap (i, regs, memory, maskl, maskw, little_endian)
     int i;
     int i;
     int *regs;
     int *regs;
     unsigned char *memory;
     unsigned char *memory;
{
{
  switch (i)
  switch (i)
    {
    {
    case 1:
    case 1:
      printf ("%c", regs[0]);
      printf ("%c", regs[0]);
      break;
      break;
    case 2:
    case 2:
      saved_state.asregs.exception = SIGQUIT;
      saved_state.asregs.exception = SIGQUIT;
      break;
      break;
    case 3:                     /* FIXME: for backwards compat, should be removed */
    case 3:                     /* FIXME: for backwards compat, should be removed */
    case 34:
    case 34:
      {
      {
        extern int errno;
        extern int errno;
        int perrno = errno;
        int perrno = errno;
        errno = 0;
        errno = 0;
 
 
        switch (regs[4])
        switch (regs[4])
          {
          {
 
 
#if !defined(__GO32__) && !defined(_WIN32)
#if !defined(__GO32__) && !defined(_WIN32)
          case SYS_fork:
          case SYS_fork:
            regs[0] = fork ();
            regs[0] = fork ();
            break;
            break;
          case SYS_execve:
          case SYS_execve:
            regs[0] = execve (ptr (regs[5]), (char **)ptr (regs[6]), (char **)ptr (regs[7]));
            regs[0] = execve (ptr (regs[5]), (char **)ptr (regs[6]), (char **)ptr (regs[7]));
            break;
            break;
          case SYS_execv:
          case SYS_execv:
            regs[0] = execve (ptr (regs[5]),(char **) ptr (regs[6]), 0);
            regs[0] = execve (ptr (regs[5]),(char **) ptr (regs[6]), 0);
            break;
            break;
          case SYS_pipe:
          case SYS_pipe:
            {
            {
              char *buf;
              char *buf;
              int host_fd[2];
              int host_fd[2];
 
 
              buf = ptr (regs[5]);
              buf = ptr (regs[5]);
 
 
              regs[0] = pipe (host_fd);
              regs[0] = pipe (host_fd);
 
 
              WLAT (buf, host_fd[0]);
              WLAT (buf, host_fd[0]);
              buf += 4;
              buf += 4;
              WLAT (buf, host_fd[1]);
              WLAT (buf, host_fd[1]);
            }
            }
            break;
            break;
 
 
          case SYS_wait:
          case SYS_wait:
            regs[0] = wait (ptr (regs[5]));
            regs[0] = wait (ptr (regs[5]));
            break;
            break;
#endif
#endif
 
 
          case SYS_read:
          case SYS_read:
            regs[0] = callback->read (callback, regs[5], ptr (regs[6]), regs[7]);
            regs[0] = callback->read (callback, regs[5], ptr (regs[6]), regs[7]);
            break;
            break;
          case SYS_write:
          case SYS_write:
            if (regs[5] == 1)
            if (regs[5] == 1)
              regs[0] = (int)callback->write_stdout (callback, ptr(regs[6]), regs[7]);
              regs[0] = (int)callback->write_stdout (callback, ptr(regs[6]), regs[7]);
            else
            else
              regs[0] = (int)callback->write (callback, regs[5], ptr (regs[6]), regs[7]);
              regs[0] = (int)callback->write (callback, regs[5], ptr (regs[6]), regs[7]);
            break;
            break;
          case SYS_lseek:
          case SYS_lseek:
            regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]);
            regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]);
            break;
            break;
          case SYS_close:
          case SYS_close:
            regs[0] = callback->close (callback,regs[5]);
            regs[0] = callback->close (callback,regs[5]);
            break;
            break;
          case SYS_open:
          case SYS_open:
            regs[0] = callback->open (callback,ptr (regs[5]), regs[6]);
            regs[0] = callback->open (callback,ptr (regs[5]), regs[6]);
            break;
            break;
          case SYS_exit:
          case SYS_exit:
            /* EXIT - caller can look in r5 to work out the reason */
            /* EXIT - caller can look in r5 to work out the reason */
            saved_state.asregs.exception = SIGQUIT;
            saved_state.asregs.exception = SIGQUIT;
            regs[0] = regs[5];
            regs[0] = regs[5];
            break;
            break;
 
 
          case SYS_stat:        /* added at hmsi */
          case SYS_stat:        /* added at hmsi */
            /* stat system call */
            /* stat system call */
            {
            {
              struct stat host_stat;
              struct stat host_stat;
              char *buf;
              char *buf;
 
 
              regs[0] = stat (ptr (regs[5]), &host_stat);
              regs[0] = stat (ptr (regs[5]), &host_stat);
 
 
              buf = ptr (regs[6]);
              buf = ptr (regs[6]);
 
 
              WWAT (buf, host_stat.st_dev);
              WWAT (buf, host_stat.st_dev);
              buf += 2;
              buf += 2;
              WWAT (buf, host_stat.st_ino);
              WWAT (buf, host_stat.st_ino);
              buf += 2;
              buf += 2;
              WLAT (buf, host_stat.st_mode);
              WLAT (buf, host_stat.st_mode);
              buf += 4;
              buf += 4;
              WWAT (buf, host_stat.st_nlink);
              WWAT (buf, host_stat.st_nlink);
              buf += 2;
              buf += 2;
              WWAT (buf, host_stat.st_uid);
              WWAT (buf, host_stat.st_uid);
              buf += 2;
              buf += 2;
              WWAT (buf, host_stat.st_gid);
              WWAT (buf, host_stat.st_gid);
              buf += 2;
              buf += 2;
              WWAT (buf, host_stat.st_rdev);
              WWAT (buf, host_stat.st_rdev);
              buf += 2;
              buf += 2;
              WLAT (buf, host_stat.st_size);
              WLAT (buf, host_stat.st_size);
              buf += 4;
              buf += 4;
              WLAT (buf, host_stat.st_atime);
              WLAT (buf, host_stat.st_atime);
              buf += 4;
              buf += 4;
              WLAT (buf, 0);
              WLAT (buf, 0);
              buf += 4;
              buf += 4;
              WLAT (buf, host_stat.st_mtime);
              WLAT (buf, host_stat.st_mtime);
              buf += 4;
              buf += 4;
              WLAT (buf, 0);
              WLAT (buf, 0);
              buf += 4;
              buf += 4;
              WLAT (buf, host_stat.st_ctime);
              WLAT (buf, host_stat.st_ctime);
              buf += 4;
              buf += 4;
              WLAT (buf, 0);
              WLAT (buf, 0);
              buf += 4;
              buf += 4;
              WLAT (buf, 0);
              WLAT (buf, 0);
              buf += 4;
              buf += 4;
              WLAT (buf, 0);
              WLAT (buf, 0);
              buf += 4;
              buf += 4;
            }
            }
            break;
            break;
 
 
#ifndef _WIN32
#ifndef _WIN32
          case SYS_chown:
          case SYS_chown:
            regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
            regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
            break;
            break;
#endif /* _WIN32 */
#endif /* _WIN32 */
          case SYS_chmod:
          case SYS_chmod:
            regs[0] = chmod (ptr (regs[5]), regs[6]);
            regs[0] = chmod (ptr (regs[5]), regs[6]);
            break;
            break;
          case SYS_utime:
          case SYS_utime:
            /* Cast the second argument to void *, to avoid type mismatch
            /* Cast the second argument to void *, to avoid type mismatch
               if a prototype is present.  */
               if a prototype is present.  */
            regs[0] = utime (ptr (regs[5]), (void *) ptr (regs[6]));
            regs[0] = utime (ptr (regs[5]), (void *) ptr (regs[6]));
            break;
            break;
          default:
          default:
            abort ();
            abort ();
          }
          }
        regs[1] = callback->get_errno (callback);
        regs[1] = callback->get_errno (callback);
        errno = perrno;
        errno = perrno;
      }
      }
      break;
      break;
 
 
    case 0xc3:
    case 0xc3:
    case 255:
    case 255:
      saved_state.asregs.exception = SIGTRAP;
      saved_state.asregs.exception = SIGTRAP;
      break;
      break;
    }
    }
 
 
}
}
 
 
void
void
control_c (sig, code, scp, addr)
control_c (sig, code, scp, addr)
     int sig;
     int sig;
     int code;
     int code;
     char *scp;
     char *scp;
     char *addr;
     char *addr;
{
{
  saved_state.asregs.exception = SIGINT;
  saved_state.asregs.exception = SIGINT;
}
}
 
 
static int
static int
div1 (R, iRn2, iRn1/*, T*/)
div1 (R, iRn2, iRn1/*, T*/)
     int *R;
     int *R;
     int iRn1;
     int iRn1;
     int iRn2;
     int iRn2;
     /* int T;*/
     /* int T;*/
{
{
  unsigned long tmp0;
  unsigned long tmp0;
  unsigned char old_q, tmp1;
  unsigned char old_q, tmp1;
 
 
  old_q = Q;
  old_q = Q;
  SET_SR_Q ((unsigned char) ((0x80000000 & R[iRn1]) != 0));
  SET_SR_Q ((unsigned char) ((0x80000000 & R[iRn1]) != 0));
  R[iRn1] <<= 1;
  R[iRn1] <<= 1;
  R[iRn1] |= (unsigned long) T;
  R[iRn1] |= (unsigned long) T;
 
 
  switch (old_q)
  switch (old_q)
    {
    {
    case 0:
    case 0:
      switch (M)
      switch (M)
        {
        {
        case 0:
        case 0:
          tmp0 = R[iRn1];
          tmp0 = R[iRn1];
          R[iRn1] -= R[iRn2];
          R[iRn1] -= R[iRn2];
          tmp1 = (R[iRn1] > tmp0);
          tmp1 = (R[iRn1] > tmp0);
          switch (Q)
          switch (Q)
            {
            {
            case 0:
            case 0:
              SET_SR_Q (tmp1);
              SET_SR_Q (tmp1);
              break;
              break;
            case 1:
            case 1:
              SET_SR_Q ((unsigned char) (tmp1 == 0));
              SET_SR_Q ((unsigned char) (tmp1 == 0));
              break;
              break;
            }
            }
          break;
          break;
        case 1:
        case 1:
          tmp0 = R[iRn1];
          tmp0 = R[iRn1];
          R[iRn1] += R[iRn2];
          R[iRn1] += R[iRn2];
          tmp1 = (R[iRn1] < tmp0);
          tmp1 = (R[iRn1] < tmp0);
          switch (Q)
          switch (Q)
            {
            {
            case 0:
            case 0:
              SET_SR_Q ((unsigned char) (tmp1 == 0));
              SET_SR_Q ((unsigned char) (tmp1 == 0));
              break;
              break;
            case 1:
            case 1:
              SET_SR_Q (tmp1);
              SET_SR_Q (tmp1);
              break;
              break;
            }
            }
          break;
          break;
        }
        }
      break;
      break;
    case 1:
    case 1:
      switch (M)
      switch (M)
        {
        {
        case 0:
        case 0:
          tmp0 = R[iRn1];
          tmp0 = R[iRn1];
          R[iRn1] += R[iRn2];
          R[iRn1] += R[iRn2];
          tmp1 = (R[iRn1] < tmp0);
          tmp1 = (R[iRn1] < tmp0);
          switch (Q)
          switch (Q)
            {
            {
            case 0:
            case 0:
              SET_SR_Q (tmp1);
              SET_SR_Q (tmp1);
              break;
              break;
            case 1:
            case 1:
              SET_SR_Q ((unsigned char) (tmp1 == 0));
              SET_SR_Q ((unsigned char) (tmp1 == 0));
              break;
              break;
            }
            }
          break;
          break;
        case 1:
        case 1:
          tmp0 = R[iRn1];
          tmp0 = R[iRn1];
          R[iRn1] -= R[iRn2];
          R[iRn1] -= R[iRn2];
          tmp1 = (R[iRn1] > tmp0);
          tmp1 = (R[iRn1] > tmp0);
          switch (Q)
          switch (Q)
            {
            {
            case 0:
            case 0:
              SET_SR_Q ((unsigned char) (tmp1 == 0));
              SET_SR_Q ((unsigned char) (tmp1 == 0));
              break;
              break;
            case 1:
            case 1:
              SET_SR_Q (tmp1);
              SET_SR_Q (tmp1);
              break;
              break;
            }
            }
          break;
          break;
        }
        }
      break;
      break;
    }
    }
  /*T = (Q == M);*/
  /*T = (Q == M);*/
  SET_SR_T (Q == M);
  SET_SR_T (Q == M);
  /*return T;*/
  /*return T;*/
}
}
 
 
static void
static void
dmul (sign, rm, rn)
dmul (sign, rm, rn)
     int sign;
     int sign;
     unsigned int rm;
     unsigned int rm;
     unsigned int rn;
     unsigned int rn;
{
{
  unsigned long RnL, RnH;
  unsigned long RnL, RnH;
  unsigned long RmL, RmH;
  unsigned long RmL, RmH;
  unsigned long temp0, temp1, temp2, temp3;
  unsigned long temp0, temp1, temp2, temp3;
  unsigned long Res2, Res1, Res0;
  unsigned long Res2, Res1, Res0;
 
 
  RnL = rn & 0xffff;
  RnL = rn & 0xffff;
  RnH = (rn >> 16) & 0xffff;
  RnH = (rn >> 16) & 0xffff;
  RmL = rm & 0xffff;
  RmL = rm & 0xffff;
  RmH = (rm >> 16) & 0xffff;
  RmH = (rm >> 16) & 0xffff;
  temp0 = RmL * RnL;
  temp0 = RmL * RnL;
  temp1 = RmH * RnL;
  temp1 = RmH * RnL;
  temp2 = RmL * RnH;
  temp2 = RmL * RnH;
  temp3 = RmH * RnH;
  temp3 = RmH * RnH;
  Res2 = 0;
  Res2 = 0;
  Res1 = temp1 + temp2;
  Res1 = temp1 + temp2;
  if (Res1 < temp1)
  if (Res1 < temp1)
    Res2 += 0x00010000;
    Res2 += 0x00010000;
  temp1 = (Res1 << 16) & 0xffff0000;
  temp1 = (Res1 << 16) & 0xffff0000;
  Res0 = temp0 + temp1;
  Res0 = temp0 + temp1;
  if (Res0 < temp0)
  if (Res0 < temp0)
    Res2 += 1;
    Res2 += 1;
  Res2 += ((Res1 >> 16) & 0xffff) + temp3;
  Res2 += ((Res1 >> 16) & 0xffff) + temp3;
 
 
  if (sign)
  if (sign)
    {
    {
      if (rn & 0x80000000)
      if (rn & 0x80000000)
        Res2 -= rm;
        Res2 -= rm;
      if (rm & 0x80000000)
      if (rm & 0x80000000)
        Res2 -= rn;
        Res2 -= rn;
    }
    }
 
 
  MACH = Res2;
  MACH = Res2;
  MACL = Res0;
  MACL = Res0;
}
}
 
 
static void
static void
macw (regs, memory, n, m)
macw (regs, memory, n, m)
     int *regs;
     int *regs;
     unsigned char *memory;
     unsigned char *memory;
     int m, n;
     int m, n;
{
{
  int little_endian = target_little_endian;
  int little_endian = target_little_endian;
  long tempm, tempn;
  long tempm, tempn;
  long prod, macl, sum;
  long prod, macl, sum;
 
 
  tempm=RSWAT(regs[m]); regs[m]+=2;
  tempm=RSWAT(regs[m]); regs[m]+=2;
  tempn=RSWAT(regs[n]); regs[n]+=2;
  tempn=RSWAT(regs[n]); regs[n]+=2;
 
 
  macl = MACL;
  macl = MACL;
  prod = (long)(short) tempm * (long)(short) tempn;
  prod = (long)(short) tempm * (long)(short) tempn;
  sum = prod + macl;
  sum = prod + macl;
  if (S)
  if (S)
    {
    {
      if ((~(prod ^ macl) & (sum ^ prod)) < 0)
      if ((~(prod ^ macl) & (sum ^ prod)) < 0)
        {
        {
          /* MACH's lsb is a sticky overflow bit.  */
          /* MACH's lsb is a sticky overflow bit.  */
          MACH |= 1;
          MACH |= 1;
          /* Store the smallest negative number in MACL if prod is
          /* Store the smallest negative number in MACL if prod is
             negative, and the largest positive number otherwise.  */
             negative, and the largest positive number otherwise.  */
          sum = 0x7fffffff + (prod < 0);
          sum = 0x7fffffff + (prod < 0);
        }
        }
    }
    }
  else
  else
    {
    {
      long mach;
      long mach;
      /* Add to MACH the sign extended product, and carry from low sum.  */
      /* Add to MACH the sign extended product, and carry from low sum.  */
      mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
      mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
      /* Sign extend at 10:th bit in MACH.  */
      /* Sign extend at 10:th bit in MACH.  */
      MACH = (mach & 0x1ff) | -(mach & 0x200);
      MACH = (mach & 0x1ff) | -(mach & 0x200);
    }
    }
  MACL = sum;
  MACL = sum;
}
}
 
 
/* Set the memory size to the power of two provided. */
/* Set the memory size to the power of two provided. */
 
 
void
void
sim_size (power)
sim_size (power)
     int power;
     int power;
 
 
{
{
  saved_state.asregs.msize = 1 << power;
  saved_state.asregs.msize = 1 << power;
 
 
  sim_memory_size = power;
  sim_memory_size = power;
 
 
  if (saved_state.asregs.memory)
  if (saved_state.asregs.memory)
    {
    {
      free (saved_state.asregs.memory);
      free (saved_state.asregs.memory);
    }
    }
 
 
  saved_state.asregs.memory =
  saved_state.asregs.memory =
    (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
    (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
 
 
  if (!saved_state.asregs.memory)
  if (!saved_state.asregs.memory)
    {
    {
      fprintf (stderr,
      fprintf (stderr,
               "Not enough VM for simulation of %d bytes of RAM\n",
               "Not enough VM for simulation of %d bytes of RAM\n",
               saved_state.asregs.msize);
               saved_state.asregs.msize);
 
 
      saved_state.asregs.msize = 1;
      saved_state.asregs.msize = 1;
      saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
      saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
    }
    }
}
}
 
 
static void
static void
init_pointers ()
init_pointers ()
{
{
  host_little_endian = 0;
  host_little_endian = 0;
  *(char*)&host_little_endian = 1;
  *(char*)&host_little_endian = 1;
  host_little_endian &= 1;
  host_little_endian &= 1;
 
 
  if (saved_state.asregs.msize != 1 << sim_memory_size)
  if (saved_state.asregs.msize != 1 << sim_memory_size)
    {
    {
      sim_size (sim_memory_size);
      sim_size (sim_memory_size);
    }
    }
 
 
  if (saved_state.asregs.profile && !profile_file)
  if (saved_state.asregs.profile && !profile_file)
    {
    {
      profile_file = fopen ("gmon.out", "wb");
      profile_file = fopen ("gmon.out", "wb");
      /* Seek to where to put the call arc data */
      /* Seek to where to put the call arc data */
      nsamples = (1 << sim_profile_size);
      nsamples = (1 << sim_profile_size);
 
 
      fseek (profile_file, nsamples * 2 + 12, 0);
      fseek (profile_file, nsamples * 2 + 12, 0);
 
 
      if (!profile_file)
      if (!profile_file)
        {
        {
          fprintf (stderr, "Can't open gmon.out\n");
          fprintf (stderr, "Can't open gmon.out\n");
        }
        }
      else
      else
        {
        {
          saved_state.asregs.profile_hist =
          saved_state.asregs.profile_hist =
            (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
            (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
        }
        }
    }
    }
}
}
 
 
static void
static void
dump_profile ()
dump_profile ()
{
{
  unsigned int minpc;
  unsigned int minpc;
  unsigned int maxpc;
  unsigned int maxpc;
  unsigned short *p;
  unsigned short *p;
  int i;
  int i;
 
 
  p = saved_state.asregs.profile_hist;
  p = saved_state.asregs.profile_hist;
  minpc = 0;
  minpc = 0;
  maxpc = (1 << sim_profile_size);
  maxpc = (1 << sim_profile_size);
 
 
  fseek (profile_file, 0L, 0);
  fseek (profile_file, 0L, 0);
  swapout (minpc << PROFILE_SHIFT);
  swapout (minpc << PROFILE_SHIFT);
  swapout (maxpc << PROFILE_SHIFT);
  swapout (maxpc << PROFILE_SHIFT);
  swapout (nsamples * 2 + 12);
  swapout (nsamples * 2 + 12);
  for (i = 0; i < nsamples; i++)
  for (i = 0; i < nsamples; i++)
    swapout16 (saved_state.asregs.profile_hist[i]);
    swapout16 (saved_state.asregs.profile_hist[i]);
 
 
}
}
 
 
static void
static void
gotcall (from, to)
gotcall (from, to)
     int from;
     int from;
     int to;
     int to;
{
{
  swapout (from);
  swapout (from);
  swapout (to);
  swapout (to);
  swapout (1);
  swapout (1);
}
}
 
 
#define MMASKB ((saved_state.asregs.msize -1) & ~0)
#define MMASKB ((saved_state.asregs.msize -1) & ~0)
 
 
int
int
sim_stop (sd)
sim_stop (sd)
     SIM_DESC sd;
     SIM_DESC sd;
{
{
  saved_state.asregs.exception = SIGINT;
  saved_state.asregs.exception = SIGINT;
  return 1;
  return 1;
}
}
 
 
void
void
sim_resume (sd, step, siggnal)
sim_resume (sd, step, siggnal)
     SIM_DESC sd;
     SIM_DESC sd;
     int step, siggnal;
     int step, siggnal;
{
{
  register unsigned int pc;
  register unsigned int pc;
  register int cycles = 0;
  register int cycles = 0;
  register int stalls = 0;
  register int stalls = 0;
  register int memstalls = 0;
  register int memstalls = 0;
  register int insts = 0;
  register int insts = 0;
  register int prevlock;
  register int prevlock;
  register int thislock;
  register int thislock;
  register unsigned int doprofile;
  register unsigned int doprofile;
  register int pollcount = 0;
  register int pollcount = 0;
  register int little_endian = target_little_endian;
  register int little_endian = target_little_endian;
 
 
  int tick_start = get_now ();
  int tick_start = get_now ();
  void (*prev) ();
  void (*prev) ();
  void (*prev_fpe) ();
  void (*prev_fpe) ();
  extern unsigned char sh_jump_table0[];
  extern unsigned char sh_jump_table0[];
 
 
  register unsigned char *jump_table = sh_jump_table0;
  register unsigned char *jump_table = sh_jump_table0;
 
 
  register int *R = &(saved_state.asregs.regs[0]);
  register int *R = &(saved_state.asregs.regs[0]);
  /*register int T;*/
  /*register int T;*/
  register int PR;
  register int PR;
 
 
  register int maskb = ((saved_state.asregs.msize - 1) & ~0);
  register int maskb = ((saved_state.asregs.msize - 1) & ~0);
  register int maskw = ((saved_state.asregs.msize - 1) & ~1);
  register int maskw = ((saved_state.asregs.msize - 1) & ~1);
  register int maskl = ((saved_state.asregs.msize - 1) & ~3);
  register int maskl = ((saved_state.asregs.msize - 1) & ~3);
  register unsigned char *memory;
  register unsigned char *memory;
  register unsigned int sbit = ((unsigned int) 1 << 31);
  register unsigned int sbit = ((unsigned int) 1 << 31);
 
 
  prev = signal (SIGINT, control_c);
  prev = signal (SIGINT, control_c);
  prev_fpe = signal (SIGFPE, SIG_IGN);
  prev_fpe = signal (SIGFPE, SIG_IGN);
 
 
  init_pointers ();
  init_pointers ();
 
 
  memory = saved_state.asregs.memory;
  memory = saved_state.asregs.memory;
 
 
  if (step)
  if (step)
    {
    {
      saved_state.asregs.exception = SIGTRAP;
      saved_state.asregs.exception = SIGTRAP;
    }
    }
  else
  else
    {
    {
      saved_state.asregs.exception = 0;
      saved_state.asregs.exception = 0;
    }
    }
 
 
  pc = saved_state.asregs.pc;
  pc = saved_state.asregs.pc;
  PR = saved_state.asregs.pr;
  PR = saved_state.asregs.pr;
  /*T = GET_SR () & SR_MASK_T;*/
  /*T = GET_SR () & SR_MASK_T;*/
  prevlock = saved_state.asregs.prevlock;
  prevlock = saved_state.asregs.prevlock;
  thislock = saved_state.asregs.thislock;
  thislock = saved_state.asregs.thislock;
  doprofile = saved_state.asregs.profile;
  doprofile = saved_state.asregs.profile;
 
 
  /* If profiling not enabled, disable it by asking for
  /* If profiling not enabled, disable it by asking for
     profiles infrequently. */
     profiles infrequently. */
  if (doprofile == 0)
  if (doprofile == 0)
    doprofile = ~0;
    doprofile = ~0;
 
 
  do
  do
    {
    {
      register unsigned int iword = RUWAT (pc);
      register unsigned int iword = RUWAT (pc);
      register unsigned int ult;
      register unsigned int ult;
      register unsigned int nia = pc + 2;
      register unsigned int nia = pc + 2;
#ifndef ACE_FAST
#ifndef ACE_FAST
      insts++;
      insts++;
#endif
#endif
    top:
    top:
 
 
#include "code.c"
#include "code.c"
 
 
 
 
      pc = nia;
      pc = nia;
 
 
      if (--pollcount < 0)
      if (--pollcount < 0)
        {
        {
          pollcount = POLL_QUIT_INTERVAL;
          pollcount = POLL_QUIT_INTERVAL;
          if ((*callback->poll_quit) != NULL
          if ((*callback->poll_quit) != NULL
              && (*callback->poll_quit) (callback))
              && (*callback->poll_quit) (callback))
            {
            {
              sim_stop (sd);
              sim_stop (sd);
            }
            }
        }
        }
 
 
#ifndef ACE_FAST
#ifndef ACE_FAST
      prevlock = thislock;
      prevlock = thislock;
      thislock = 30;
      thislock = 30;
      cycles++;
      cycles++;
 
 
      if (cycles >= doprofile)
      if (cycles >= doprofile)
        {
        {
 
 
          saved_state.asregs.cycles += doprofile;
          saved_state.asregs.cycles += doprofile;
          cycles -= doprofile;
          cycles -= doprofile;
          if (saved_state.asregs.profile_hist)
          if (saved_state.asregs.profile_hist)
            {
            {
              int n = pc >> PROFILE_SHIFT;
              int n = pc >> PROFILE_SHIFT;
              if (n < nsamples)
              if (n < nsamples)
                {
                {
                  int i = saved_state.asregs.profile_hist[n];
                  int i = saved_state.asregs.profile_hist[n];
                  if (i < 65000)
                  if (i < 65000)
                    saved_state.asregs.profile_hist[n] = i + 1;
                    saved_state.asregs.profile_hist[n] = i + 1;
                }
                }
 
 
            }
            }
        }
        }
#endif
#endif
    }
    }
  while (!saved_state.asregs.exception);
  while (!saved_state.asregs.exception);
 
 
  if (saved_state.asregs.exception == SIGILL
  if (saved_state.asregs.exception == SIGILL
      || saved_state.asregs.exception == SIGBUS)
      || saved_state.asregs.exception == SIGBUS)
    {
    {
      pc -= 2;
      pc -= 2;
    }
    }
 
 
  saved_state.asregs.ticks += get_now () - tick_start;
  saved_state.asregs.ticks += get_now () - tick_start;
  saved_state.asregs.cycles += cycles;
  saved_state.asregs.cycles += cycles;
  saved_state.asregs.stalls += stalls;
  saved_state.asregs.stalls += stalls;
  saved_state.asregs.memstalls += memstalls;
  saved_state.asregs.memstalls += memstalls;
  saved_state.asregs.insts += insts;
  saved_state.asregs.insts += insts;
  saved_state.asregs.pc = pc;
  saved_state.asregs.pc = pc;
  /* restore the T and other cached SR bits */
  /* restore the T and other cached SR bits */
  SET_SR (GET_SR());
  SET_SR (GET_SR());
  saved_state.asregs.pr = PR;
  saved_state.asregs.pr = PR;
 
 
  saved_state.asregs.prevlock = prevlock;
  saved_state.asregs.prevlock = prevlock;
  saved_state.asregs.thislock = thislock;
  saved_state.asregs.thislock = thislock;
 
 
  if (profile_file)
  if (profile_file)
    {
    {
      dump_profile ();
      dump_profile ();
    }
    }
 
 
  signal (SIGFPE, prev_fpe);
  signal (SIGFPE, prev_fpe);
  signal (SIGINT, prev);
  signal (SIGINT, prev);
}
}
 
 
int
int
sim_write (sd, addr, buffer, size)
sim_write (sd, addr, buffer, size)
     SIM_DESC sd;
     SIM_DESC sd;
     SIM_ADDR addr;
     SIM_ADDR addr;
     unsigned char *buffer;
     unsigned char *buffer;
     int size;
     int size;
{
{
  int i;
  int i;
 
 
  init_pointers ();
  init_pointers ();
 
 
  for (i = 0; i < size; i++)
  for (i = 0; i < size; i++)
    {
    {
      saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
      saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
    }
    }
  return size;
  return size;
}
}
 
 
int
int
sim_read (sd, addr, buffer, size)
sim_read (sd, addr, buffer, size)
     SIM_DESC sd;
     SIM_DESC sd;
     SIM_ADDR addr;
     SIM_ADDR addr;
     unsigned char *buffer;
     unsigned char *buffer;
     int size;
     int size;
{
{
  int i;
  int i;
 
 
  init_pointers ();
  init_pointers ();
 
 
  for (i = 0; i < size; i++)
  for (i = 0; i < size; i++)
    {
    {
      buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
      buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
    }
    }
  return size;
  return size;
}
}
 
 
/* We have to add one to RN as an index into asints because of the padding
/* We have to add one to RN as an index into asints because of the padding
   added at the start of asregs.  */
   added at the start of asregs.  */
int
int
sim_store_register (sd, rn, memory, length)
sim_store_register (sd, rn, memory, length)
     SIM_DESC sd;
     SIM_DESC sd;
     int rn;
     int rn;
     unsigned char *memory;
     unsigned char *memory;
     int length;
     int length;
{
{
  int little_endian;
  int little_endian;
  init_pointers ();
  init_pointers ();
  little_endian = target_little_endian;
  little_endian = target_little_endian;
  if (&saved_state.asints[rn+1]
  if (&saved_state.asints[rn+1]
      == &saved_state.asregs.fpscr)
      == &saved_state.asregs.fpscr)
    set_fpscr1 (RLAT(0));
    set_fpscr1 (RLAT(0));
  else
  else
    saved_state.asints[rn+1] = RLAT(0);
    saved_state.asints[rn+1] = RLAT(0);
  return -1;
  return -1;
}
}
 
 
int
int
sim_fetch_register (sd, rn, memory, length)
sim_fetch_register (sd, rn, memory, length)
     SIM_DESC sd;
     SIM_DESC sd;
     int rn;
     int rn;
     unsigned char *memory;
     unsigned char *memory;
     int length;
     int length;
{
{
  int little_endian;
  int little_endian;
  init_pointers ();
  init_pointers ();
  little_endian = target_little_endian;
  little_endian = target_little_endian;
  WLAT (0, saved_state.asints[rn+1]);
  WLAT (0, saved_state.asints[rn+1]);
  return -1;
  return -1;
}
}
 
 
int
int
sim_trace (sd)
sim_trace (sd)
     SIM_DESC sd;
     SIM_DESC sd;
{
{
  return 0;
  return 0;
}
}
 
 
void
void
sim_stop_reason (sd, reason, sigrc)
sim_stop_reason (sd, reason, sigrc)
     SIM_DESC sd;
     SIM_DESC sd;
     enum sim_stop *reason;
     enum sim_stop *reason;
     int *sigrc;
     int *sigrc;
{
{
  /* The SH simulator uses SIGQUIT to indicate that the program has
  /* The SH simulator uses SIGQUIT to indicate that the program has
     exited, so we must check for it here and translate it to exit.  */
     exited, so we must check for it here and translate it to exit.  */
  if (saved_state.asregs.exception == SIGQUIT)
  if (saved_state.asregs.exception == SIGQUIT)
    {
    {
      *reason = sim_exited;
      *reason = sim_exited;
      *sigrc = saved_state.asregs.regs[5];
      *sigrc = saved_state.asregs.regs[5];
    }
    }
  else
  else
    {
    {
      *reason = sim_stopped;
      *reason = sim_stopped;
      *sigrc = saved_state.asregs.exception;
      *sigrc = saved_state.asregs.exception;
    }
    }
}
}
 
 
void
void
sim_info (sd, verbose)
sim_info (sd, verbose)
     SIM_DESC sd;
     SIM_DESC sd;
     int verbose;
     int verbose;
{
{
  double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
  double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
  double virttime = saved_state.asregs.cycles / 36.0e6;
  double virttime = saved_state.asregs.cycles / 36.0e6;
 
 
  callback->printf_filtered (callback, "\n\n# instructions executed  %10d\n",
  callback->printf_filtered (callback, "\n\n# instructions executed  %10d\n",
                             saved_state.asregs.insts);
                             saved_state.asregs.insts);
  callback->printf_filtered (callback, "# cycles                 %10d\n",
  callback->printf_filtered (callback, "# cycles                 %10d\n",
                             saved_state.asregs.cycles);
                             saved_state.asregs.cycles);
  callback->printf_filtered (callback, "# pipeline stalls        %10d\n",
  callback->printf_filtered (callback, "# pipeline stalls        %10d\n",
                             saved_state.asregs.stalls);
                             saved_state.asregs.stalls);
  callback->printf_filtered (callback, "# misaligned load/store  %10d\n",
  callback->printf_filtered (callback, "# misaligned load/store  %10d\n",
                             saved_state.asregs.memstalls);
                             saved_state.asregs.memstalls);
  callback->printf_filtered (callback, "# real time taken        %10.4f\n",
  callback->printf_filtered (callback, "# real time taken        %10.4f\n",
                             timetaken);
                             timetaken);
  callback->printf_filtered (callback, "# virtual time taken     %10.4f\n",
  callback->printf_filtered (callback, "# virtual time taken     %10.4f\n",
                             virttime);
                             virttime);
  callback->printf_filtered (callback, "# profiling size         %10d\n",
  callback->printf_filtered (callback, "# profiling size         %10d\n",
                             sim_profile_size);
                             sim_profile_size);
  callback->printf_filtered (callback, "# profiling frequency    %10d\n",
  callback->printf_filtered (callback, "# profiling frequency    %10d\n",
                             saved_state.asregs.profile);
                             saved_state.asregs.profile);
  callback->printf_filtered (callback, "# profile maxpc          %10x\n",
  callback->printf_filtered (callback, "# profile maxpc          %10x\n",
                             (1 << sim_profile_size) << PROFILE_SHIFT);
                             (1 << sim_profile_size) << PROFILE_SHIFT);
 
 
  if (timetaken != 0)
  if (timetaken != 0)
    {
    {
      callback->printf_filtered (callback, "# cycles/second          %10d\n",
      callback->printf_filtered (callback, "# cycles/second          %10d\n",
                                 (int) (saved_state.asregs.cycles / timetaken));
                                 (int) (saved_state.asregs.cycles / timetaken));
      callback->printf_filtered (callback, "# simulation ratio       %10.4f\n",
      callback->printf_filtered (callback, "# simulation ratio       %10.4f\n",
                                 virttime / timetaken);
                                 virttime / timetaken);
    }
    }
}
}
 
 
void
void
sim_set_profile (n)
sim_set_profile (n)
     int n;
     int n;
{
{
  saved_state.asregs.profile = n;
  saved_state.asregs.profile = n;
}
}
 
 
void
void
sim_set_profile_size (n)
sim_set_profile_size (n)
     int n;
     int n;
{
{
  sim_profile_size = n;
  sim_profile_size = n;
}
}
 
 
SIM_DESC
SIM_DESC
sim_open (kind, cb, abfd, argv)
sim_open (kind, cb, abfd, argv)
     SIM_OPEN_KIND kind;
     SIM_OPEN_KIND kind;
     host_callback *cb;
     host_callback *cb;
     struct _bfd *abfd;
     struct _bfd *abfd;
     char **argv;
     char **argv;
{
{
  char **p;
  char **p;
  int endian_set = 0;
  int endian_set = 0;
 
 
  sim_kind = kind;
  sim_kind = kind;
  myname = argv[0];
  myname = argv[0];
  callback = cb;
  callback = cb;
 
 
  for (p = argv + 1; *p != NULL; ++p)
  for (p = argv + 1; *p != NULL; ++p)
    {
    {
      if (strcmp (*p, "-E") == 0)
      if (strcmp (*p, "-E") == 0)
        {
        {
          ++p;
          ++p;
          if (*p == NULL)
          if (*p == NULL)
            {
            {
              /* FIXME: This doesn't use stderr, but then the rest of the
              /* FIXME: This doesn't use stderr, but then the rest of the
                 file doesn't either.  */
                 file doesn't either.  */
              callback->printf_filtered (callback, "Missing argument to `-E'.\n");
              callback->printf_filtered (callback, "Missing argument to `-E'.\n");
              return 0;
              return 0;
            }
            }
          target_little_endian = strcmp (*p, "big") != 0;
          target_little_endian = strcmp (*p, "big") != 0;
          endian_set = 1;
          endian_set = 1;
        }
        }
      else if (isdigit (**p))
      else if (isdigit (**p))
        parse_and_set_memory_size (*p);
        parse_and_set_memory_size (*p);
    }
    }
 
 
  if (abfd != NULL && ! endian_set)
  if (abfd != NULL && ! endian_set)
      target_little_endian = ! bfd_big_endian (abfd);
      target_little_endian = ! bfd_big_endian (abfd);
 
 
  /* fudge our descriptor for now */
  /* fudge our descriptor for now */
  return (SIM_DESC) 1;
  return (SIM_DESC) 1;
}
}
 
 
static void
static void
parse_and_set_memory_size (str)
parse_and_set_memory_size (str)
     char *str;
     char *str;
{
{
  int n;
  int n;
 
 
  n = strtol (str, NULL, 10);
  n = strtol (str, NULL, 10);
  if (n > 0 && n <= 24)
  if (n > 0 && n <= 24)
    sim_memory_size = n;
    sim_memory_size = n;
  else
  else
    callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
    callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
}
}
 
 
void
void
sim_close (sd, quitting)
sim_close (sd, quitting)
     SIM_DESC sd;
     SIM_DESC sd;
     int quitting;
     int quitting;
{
{
  /* nothing to do */
  /* nothing to do */
}
}
 
 
SIM_RC
SIM_RC
sim_load (sd, prog, abfd, from_tty)
sim_load (sd, prog, abfd, from_tty)
     SIM_DESC sd;
     SIM_DESC sd;
     char *prog;
     char *prog;
     bfd *abfd;
     bfd *abfd;
     int from_tty;
     int from_tty;
{
{
  extern bfd *sim_load_file (); /* ??? Don't know where this should live.  */
  extern bfd *sim_load_file (); /* ??? Don't know where this should live.  */
  bfd *prog_bfd;
  bfd *prog_bfd;
 
 
  prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
  prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
                            sim_kind == SIM_OPEN_DEBUG,
                            sim_kind == SIM_OPEN_DEBUG,
                            0, sim_write);
                            0, sim_write);
  if (prog_bfd == NULL)
  if (prog_bfd == NULL)
    return SIM_RC_FAIL;
    return SIM_RC_FAIL;
  if (abfd == NULL)
  if (abfd == NULL)
    bfd_close (prog_bfd);
    bfd_close (prog_bfd);
  return SIM_RC_OK;
  return SIM_RC_OK;
}
}
 
 
SIM_RC
SIM_RC
sim_create_inferior (sd, prog_bfd, argv, env)
sim_create_inferior (sd, prog_bfd, argv, env)
     SIM_DESC sd;
     SIM_DESC sd;
     struct _bfd *prog_bfd;
     struct _bfd *prog_bfd;
     char **argv;
     char **argv;
     char **env;
     char **env;
{
{
  /* clear the registers */
  /* clear the registers */
  memset (&saved_state, 0,
  memset (&saved_state, 0,
          (char*)&saved_state.asregs.end_of_registers - (char*)&saved_state);
          (char*)&saved_state.asregs.end_of_registers - (char*)&saved_state);
  /* set the PC */
  /* set the PC */
  if (prog_bfd != NULL)
  if (prog_bfd != NULL)
    saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
    saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
  return SIM_RC_OK;
  return SIM_RC_OK;
}
}
 
 
void
void
sim_do_command (sd, cmd)
sim_do_command (sd, cmd)
     SIM_DESC sd;
     SIM_DESC sd;
     char *cmd;
     char *cmd;
{
{
  char *sms_cmd = "set-memory-size";
  char *sms_cmd = "set-memory-size";
  int cmdsize;
  int cmdsize;
 
 
  if (cmd == NULL || *cmd == '\0')
  if (cmd == NULL || *cmd == '\0')
    {
    {
      cmd = "help";
      cmd = "help";
    }
    }
 
 
  cmdsize = strlen (sms_cmd);
  cmdsize = strlen (sms_cmd);
  if (strncmp (cmd, sms_cmd, cmdsize) == 0 && strchr (" \t", cmd[cmdsize]) != NULL)
  if (strncmp (cmd, sms_cmd, cmdsize) == 0 && strchr (" \t", cmd[cmdsize]) != NULL)
    {
    {
      parse_and_set_memory_size (cmd + cmdsize + 1);
      parse_and_set_memory_size (cmd + cmdsize + 1);
    }
    }
  else if (strcmp (cmd, "help") == 0)
  else if (strcmp (cmd, "help") == 0)
    {
    {
      (callback->printf_filtered) (callback, "List of SH simulator commands:\n\n");
      (callback->printf_filtered) (callback, "List of SH simulator commands:\n\n");
      (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
      (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
      (callback->printf_filtered) (callback, "\n");
      (callback->printf_filtered) (callback, "\n");
    }
    }
  else
  else
    {
    {
      (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
      (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
    }
    }
}
}
 
 
void
void
sim_set_callbacks (p)
sim_set_callbacks (p)
     host_callback *p;
     host_callback *p;
{
{
  callback = p;
  callback = p;
}
}
 
 

powered by: WebSVN 2.1.0

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