X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fsh%2Finterp.c;h=c77cf3b1d3bf10e38be373542a4db57e5c4cb2c0;hb=17fc27167f678285d2f64040837b8cc41b6a664a;hp=6abff0050a2a4dbe5a1963f03c28958edd37d9fe;hpb=dc9feb5c97ab95cb328406040f47f20f986f0e58;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/sh/interp.c b/sim/sh/interp.c index 6abff0050a..c77cf3b1d3 100644 --- a/sim/sh/interp.c +++ b/sim/sh/interp.c @@ -1,4 +1,4 @@ -/* Simulator for the Hitachi SH architecture. +/* Simulator for the Renesas (formerly Hitachi) / SuperH Inc. SH architecture. Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com @@ -20,15 +20,57 @@ #include "config.h" +#include +#include +#include #include #ifdef HAVE_UNISTD_H #include #endif +#ifdef HAVE_MMAP +#include +# ifndef MAP_FAILED +# define MAP_FAILED -1 +# endif +# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +# endif +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_TIME_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifndef _WIN32 +#include +#include +#endif -#include "sysdep.h" #include "bfd.h" #include "gdb/callback.h" #include "gdb/remote-sim.h" +#include "gdb/sim-sh.h" + +#include "sim-main.h" +#include "sim-base.h" +#include "sim-options.h" /* This file is local - if newlib changes, then so should this. */ #include "syscall.h" @@ -52,9 +94,11 @@ #define SIGTRAP 5 #endif -extern unsigned char sh_jump_table[], sh_dsp_table[0x1000], ppi_table[]; +/* TODO: Stop using these names. */ +#undef SEXT +#undef SEXT32 -int sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size); +extern unsigned short sh_jump_table[], sh_dsp_table[0x1000], ppi_table[]; #define O_RECOMPILE 85 #define DEFINE_TABLE @@ -64,95 +108,7 @@ int sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size); for a quit. */ #define POLL_QUIT_INTERVAL 0x60000 -typedef union -{ - - struct - { - int regs[16]; - int pc; - - /* System registers. For sh-dsp this also includes A0 / X0 / X1 / Y0 / Y1 - which are located in fregs, i.e. strictly speaking, these are - out-of-bounds accesses of sregs.i . This wart of the code could be - fixed by making fregs part of sregs, and including pc too - to avoid - alignment repercussions - but this would cause very onerous union / - structure nesting, which would only be managable with anonymous - unions and structs. */ - union - { - struct - { - int mach; - int macl; - int pr; - int dummy3, dummy4; - int fpul; /* A1 for sh-dsp - but only for movs etc. */ - int fpscr; /* dsr for sh-dsp */ - } named; - int i[7]; - } sregs; - - /* sh3e / sh-dsp */ - union fregs_u - { - float f[16]; - double d[8]; - int i[16]; - } - fregs[2]; - - /* Control registers; on the SH4, ldc / stc is privileged, except when - accessing gbr. */ - union - { - struct - { - int sr; - int gbr; - int vbr; - int ssr; - int spc; - int mod; - /* sh-dsp */ - int rs; - int re; - /* sh3 */ - int bank[8]; - } named; - int i[16]; - } cregs; - - unsigned char *insn_end; - - int ticks; - int stalls; - int memstalls; - int cycles; - int insts; - - int prevlock; - int thislock; - int exception; - - int end_of_registers; - - int msize; -#define PROFILE_FREQ 1 -#define PROFILE_SHIFT 2 - int profile; - unsigned short *profile_hist; - unsigned char *memory; - int xyram_select, xram_start, yram_start; - unsigned char *xmem; - unsigned char *ymem; - unsigned char *xmem_offset; - unsigned char *ymem_offset; - } - asregs; - int asints[40]; -} saved_state_type; - +/* TODO: Move into sim_cpu. */ saved_state_type saved_state; struct loop_bounds { unsigned char *start, *end; }; @@ -160,19 +116,13 @@ struct loop_bounds { unsigned char *start, *end; }; /* These variables are at file scope so that functions other than sim_resume can use the fetch/store macros */ -static int target_little_endian; +#define target_little_endian (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE) static int global_endianw, endianb; static int target_dsp; -static int host_little_endian; -static char **prog_argv; +#define host_little_endian (HOST_BYTE_ORDER == BFD_ENDIAN_LITTLE) -#if 1 static int maskw = 0; -#endif - -static SIM_OPEN_KIND sim_kind; -static char *myname; - +static int maskl = 0; /* Short hand definitions of the registers */ @@ -180,15 +130,22 @@ static char *myname; #define R0 saved_state.asregs.regs[0] #define Rn saved_state.asregs.regs[n] #define Rm saved_state.asregs.regs[m] -#define UR0 (unsigned int)(saved_state.asregs.regs[0]) -#define UR (unsigned int)R -#define UR (unsigned int)R +#define UR0 (unsigned int) (saved_state.asregs.regs[0]) +#define UR (unsigned int) R +#define UR (unsigned int) R #define SR0 saved_state.asregs.regs[0] #define CREG(n) (saved_state.asregs.cregs.i[(n)]) #define GBR saved_state.asregs.cregs.named.gbr #define VBR saved_state.asregs.cregs.named.vbr +#define DBR saved_state.asregs.cregs.named.dbr +#define TBR saved_state.asregs.cregs.named.tbr +#define IBCR saved_state.asregs.cregs.named.ibcr +#define IBNR saved_state.asregs.cregs.named.ibnr +#define BANKN (saved_state.asregs.cregs.named.ibnr & 0x1ff) +#define ME ((saved_state.asregs.cregs.named.ibnr >> 14) & 0x3) #define SSR saved_state.asregs.cregs.named.ssr #define SPC saved_state.asregs.cregs.named.spc +#define SGR saved_state.asregs.cregs.named.sgr #define SREG(n) (saved_state.asregs.sregs.i[(n)]) #define MACH saved_state.asregs.sregs.named.mach #define MACL saved_state.asregs.sregs.named.macl @@ -208,6 +165,8 @@ static char *myname; /* Manipulate SR */ +#define SR_MASK_BO (1 << 14) +#define SR_MASK_CS (1 << 13) #define SR_MASK_DMY (1 << 11) #define SR_MASK_DMX (1 << 10) #define SR_MASK_M (1 << 9) @@ -222,10 +181,13 @@ static char *myname; #define SR_MASK_RC 0x0fff0000 #define SR_RC_INCREMENT -0x00010000 +#define BO ((saved_state.asregs.cregs.named.sr & SR_MASK_BO) != 0) +#define CS ((saved_state.asregs.cregs.named.sr & SR_MASK_CS) != 0) #define M ((saved_state.asregs.cregs.named.sr & SR_MASK_M) != 0) #define Q ((saved_state.asregs.cregs.named.sr & SR_MASK_Q) != 0) #define S ((saved_state.asregs.cregs.named.sr & SR_MASK_S) != 0) #define T ((saved_state.asregs.cregs.named.sr & SR_MASK_T) != 0) +#define LDST ((saved_state.asregs.cregs.named.ldst) != 0) #define SR_BL ((saved_state.asregs.cregs.named.sr & SR_MASK_BL) != 0) #define SR_RB ((saved_state.asregs.cregs.named.sr & SR_MASK_RB) != 0) @@ -243,10 +205,21 @@ do { \ saved_state.asregs.cregs.named.sr &= ~(BIT); \ } while (0) +#define SET_SR_BO(EXP) SET_SR_BIT ((EXP), SR_MASK_BO) +#define SET_SR_CS(EXP) SET_SR_BIT ((EXP), SR_MASK_CS) +#define SET_BANKN(EXP) \ +do { \ + IBNR = (IBNR & 0xfe00) | (EXP & 0x1f); \ +} while (0) +#define SET_ME(EXP) \ +do { \ + IBNR = (IBNR & 0x3fff) | ((EXP & 0x3) << 14); \ +} while (0) #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_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S) #define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T) +#define SET_LDST(EXP) (saved_state.asregs.cregs.named.ldst = ((EXP) != 0)) /* stc currently relies on being able to read SR without modifications. */ #define GET_SR() (saved_state.asregs.cregs.named.sr - 0) @@ -263,27 +236,12 @@ do { \ #define FPSCR_MASK_SZ (1 << 20) #define FPSCR_MASK_PR (1 << 19) -#define FPSCR_FR ((GET_FPSCR() & FPSCR_MASK_FR) != 0) -#define FPSCR_SZ ((GET_FPSCR() & FPSCR_MASK_SZ) != 0) -#define FPSCR_PR ((GET_FPSCR() & FPSCR_MASK_PR) != 0) - -/* Count the number of arguments in an argv. */ -static int -count_argc (char **argv) -{ - int i; - - if (! argv) - return -1; - - for (i = 0; argv[i] != NULL; ++i) - continue; - return i; -} +#define FPSCR_FR ((GET_FPSCR () & FPSCR_MASK_FR) != 0) +#define FPSCR_SZ ((GET_FPSCR () & FPSCR_MASK_SZ) != 0) +#define FPSCR_PR ((GET_FPSCR () & FPSCR_MASK_PR) != 0) static void -set_fpscr1 (x) - int x; +set_fpscr1 (int x) { int old = saved_state.asregs.sregs.named.fpscr; saved_state.asregs.sregs.named.fpscr = (x); @@ -307,27 +265,23 @@ do { \ #define DSR (saved_state.asregs.sregs.named.fpscr) -int -fail () -{ - abort (); -} - #define RAISE_EXCEPTION(x) \ (saved_state.asregs.exception = x, saved_state.asregs.insn_end = 0) +#define RAISE_EXCEPTION_IF_IN_DELAY_SLOT() \ + if (in_delay_slot) RAISE_EXCEPTION (SIGILL) + /* This function exists mainly for the purpose of setting a breakpoint to catch simulated bus errors when running the simulator under GDB. */ -void -raise_exception (x) - int x; +static void +raise_exception (int x) { - RAISE_EXCEPTION(x); + RAISE_EXCEPTION (x); } -void -raise_buserror () +static void +raise_buserror (void) { raise_exception (SIGBUS); } @@ -398,7 +352,7 @@ do { \ #ifdef PARANOID int valid[16]; -#define CREF(x) if(!valid[x]) fail(); +#define CREF(x) if (!valid[x]) fail (); #define CDEF(x) valid[x] = 1; #define UNDEF(x) valid[x] = 0; #else @@ -407,33 +361,22 @@ int valid[16]; #define UNDEF(x) #endif -static void parse_and_set_memory_size PARAMS ((char *str)); -static int IOMEM PARAMS ((int addr, int write, int value)); -static struct loop_bounds get_loop_bounds PARAMS((int, int, unsigned char *, - unsigned char *, int, int)); -static void process_wlat_addr PARAMS((int, int)); -static void process_wwat_addr PARAMS((int, int)); -static void process_wbat_addr PARAMS((int, int)); -static int process_rlat_addr PARAMS((int)); -static int process_rwat_addr PARAMS((int)); -static int process_rbat_addr PARAMS((int)); -static void INLINE wlat_fast PARAMS ((unsigned char *, int, int, int)); -static void INLINE wwat_fast PARAMS ((unsigned char *, int, int, int, int)); -static void INLINE wbat_fast PARAMS ((unsigned char *, int, int, int)); -static int INLINE rlat_fast PARAMS ((unsigned char *, int, int)); -static int INLINE rwat_fast PARAMS ((unsigned char *, int, int, int)); -static int INLINE rbat_fast PARAMS ((unsigned char *, int, int)); - -static host_callback *callback; - - +static void parse_and_set_memory_size (SIM_DESC sd, const char *str); +static int IOMEM (int addr, int write, int value); +static struct loop_bounds get_loop_bounds (int, int, unsigned char *, + unsigned char *, int, int); +static void process_wlat_addr (int, int); +static void process_wwat_addr (int, int); +static void process_wbat_addr (int, int); +static int process_rlat_addr (int); +static int process_rwat_addr (int); +static int process_rbat_addr (int); /* Floating point registers */ #define DR(n) (get_dr (n)) static double -get_dr (n) - int n; +get_dr (int n) { n = (n & ~1); if (host_little_endian) @@ -453,9 +396,7 @@ get_dr (n) #define SET_DR(n, EXP) set_dr ((n), (EXP)) static void -set_dr (n, exp) - int n; - double exp; +set_dr (int n, double exp) { n = (n & ~1); if (host_little_endian) @@ -515,10 +456,10 @@ set_dr (n, exp) if (((n) & 1) || ((m) & 1)) \ RAISE_EXCEPTION (SIGILL); \ else \ - SET_DR(n, (DR(n) OP DR(m))); \ + SET_DR (n, (DR (n) OP DR (m))); \ } \ else \ - SET_FR(n, (FR(n) OP FR(m))); \ + SET_FR (n, (FR (n) OP FR (m))); \ } while (0) #define FP_UNARY(n, OP) \ @@ -528,10 +469,10 @@ set_dr (n, exp) if ((n) & 1) \ RAISE_EXCEPTION (SIGILL); \ else \ - SET_DR(n, (OP (DR(n)))); \ + SET_DR (n, (OP (DR (n)))); \ } \ else \ - SET_FR(n, (OP (FR(n)))); \ + SET_FR (n, (OP (FR (n)))); \ } while (0) #define FP_CMP(n, OP, m) \ @@ -541,15 +482,14 @@ set_dr (n, exp) if (((n) & 1) || ((m) & 1)) \ RAISE_EXCEPTION (SIGILL); \ else \ - SET_SR_T (DR(n) OP DR(m)); \ + SET_SR_T (DR (n) OP DR (m)); \ } \ else \ - SET_SR_T (FR(n) OP FR(m)); \ + SET_SR_T (FR (n) OP FR (m)); \ } while (0) static void -set_sr (new_sr) - int new_sr; +set_sr (int new_sr) { /* do we need to swap banks */ int old_gpr = SR_MD && SR_RB; @@ -568,29 +508,26 @@ set_sr (new_sr) SET_MOD (MOD); } -static void INLINE -wlat_fast (memory, x, value, maskl) - unsigned char *memory; +static INLINE void +wlat_fast (unsigned char *memory, int x, int value, int maskl) { int v = value; - unsigned int *p = (unsigned int *)(memory + x); + unsigned int *p = (unsigned int *) (memory + x); WRITE_BUSERROR (x, maskl, v, process_wlat_addr); *p = v; } -static void INLINE -wwat_fast (memory, x, value, maskw, endianw) - unsigned char *memory; +static INLINE void +wwat_fast (unsigned char *memory, int x, int value, int maskw, int endianw) { int v = value; - unsigned short *p = (unsigned short *)(memory + (x ^ endianw)); + unsigned short *p = (unsigned short *) (memory + (x ^ endianw)); WRITE_BUSERROR (x, maskw, v, process_wwat_addr); *p = v; } -static void INLINE -wbat_fast (memory, x, value, maskb) - unsigned char *memory; +static INLINE void +wbat_fast (unsigned char *memory, int x, int value, int maskb) { unsigned char *p = memory + (x ^ endianb); WRITE_BUSERROR (x, maskb, value, process_wbat_addr); @@ -600,39 +537,34 @@ wbat_fast (memory, x, value, maskb) /* Read functions */ -static int INLINE -rlat_fast (memory, x, maskl) - unsigned char *memory; +static INLINE int +rlat_fast (unsigned char *memory, int x, int maskl) { - unsigned int *p = (unsigned int *)(memory + x); + unsigned int *p = (unsigned int *) (memory + x); READ_BUSERROR (x, maskl, process_rlat_addr); return *p; } -static int INLINE -rwat_fast (memory, x, maskw, endianw) - unsigned char *memory; - int x, maskw, endianw; +static INLINE int +rwat_fast (unsigned char *memory, int x, int maskw, int endianw) { - unsigned short *p = (unsigned short *)(memory + (x ^ endianw)); + unsigned short *p = (unsigned short *) (memory + (x ^ endianw)); READ_BUSERROR (x, maskw, process_rwat_addr); return *p; } -static int INLINE -riat_fast (insn_ptr, endianw) - unsigned char *insn_ptr; +static INLINE int +riat_fast (unsigned char *insn_ptr, int endianw) { - unsigned short *p = (unsigned short *)((size_t) insn_ptr ^ endianw); + unsigned short *p = (unsigned short *) ((uintptr_t) insn_ptr ^ endianw); return *p; } -static int INLINE -rbat_fast (memory, x, maskb) - unsigned char *memory; +static INLINE int +rbat_fast (unsigned char *memory, int x, int maskb) { unsigned char *p = memory + (x ^ endianb); READ_BUSERROR (x, maskb, process_rbat_addr); @@ -648,17 +580,14 @@ rbat_fast (memory, x, maskb) #define WLAT(x,v) (wlat_fast (memory, x, v, maskl)) #define WBAT(x,v) (wbat_fast (memory, x, v, maskb)) -#define RUWAT(x) (RWAT(x) & 0xffff) -#define RSWAT(x) ((short)(RWAT(x))) -#define RSBAT(x) (SEXT(RBAT(x))) +#define RUWAT(x) (RWAT (x) & 0xffff) +#define RSWAT(x) ((short) (RWAT (x))) +#define RSLAT(x) ((long) (RLAT (x))) +#define RSBAT(x) (SEXT (RBAT (x))) #define RDAT(x, n) (do_rdat (memory, (x), (n), (maskl))) static int -do_rdat (memory, x, n, maskl) - char *memory; - int x; - int n; - int maskl; +do_rdat (unsigned char *memory, int x, int n, int maskl) { int f0; int f1; @@ -673,11 +602,7 @@ do_rdat (memory, x, n, maskl) #define WDAT(x, n) (do_wdat (memory, (x), (n), (maskl))) static int -do_wdat (memory, x, n, maskl) - char *memory; - int x; - int n; - int maskl; +do_wdat (unsigned char *memory, int x, int n, int maskl) { int f0; int f1; @@ -691,9 +616,7 @@ do_wdat (memory, x, n, maskl) } static void -process_wlat_addr (addr, value) - int addr; - int value; +process_wlat_addr (int addr, int value) { unsigned int *ptr; @@ -702,9 +625,7 @@ process_wlat_addr (addr, value) } static void -process_wwat_addr (addr, value) - int addr; - int value; +process_wwat_addr (int addr, int value) { unsigned short *ptr; @@ -713,9 +634,7 @@ process_wwat_addr (addr, value) } static void -process_wbat_addr (addr, value) - int addr; - int value; +process_wbat_addr (int addr, int value) { unsigned char *ptr; @@ -724,8 +643,7 @@ process_wbat_addr (addr, value) } static int -process_rlat_addr (addr) - int addr; +process_rlat_addr (int addr) { unsigned char *ptr; @@ -734,8 +652,7 @@ process_rlat_addr (addr) } static int -process_rwat_addr (addr) - int addr; +process_rwat_addr (int addr) { unsigned char *ptr; @@ -744,8 +661,7 @@ process_rwat_addr (addr) } static int -process_rbat_addr (addr) - int addr; +process_rbat_addr (int addr) { unsigned char *ptr; @@ -755,11 +671,11 @@ process_rbat_addr (addr) #define SEXT(x) (((x & 0xff) ^ (~0x7f))+0x80) #define SEXT12(x) (((x & 0xfff) ^ 0x800) - 0x800) -#define SEXTW(y) ((int)((short)y)) +#define SEXTW(y) ((int) ((short) y)) #if 0 -#define SEXT32(x) ((int)((x & 0xffffffff) ^ 0x80000000U) - 0x7fffffff - 1) +#define SEXT32(x) ((int) ((x & 0xffffffff) ^ 0x80000000U) - 0x7fffffff - 1) #else -#define SEXT32(x) ((int)(x)) +#define SEXT32(x) ((int) (x)) #endif #define SIGN32(x) (SEXT32 (x) >> 31) @@ -772,7 +688,8 @@ process_rbat_addr (addr) #define SET_NIP(x) nip = (x); CHECK_INSN_PTR (nip); -#define Delay_Slot(TEMPPC) iword = RIAT (TEMPPC); goto top; +static int in_delay_slot = 0; +#define Delay_Slot(TEMPPC) iword = RIAT (TEMPPC); in_delay_slot = 1; goto top; #define CHECK_INSN_PTR(p) \ do { \ @@ -794,18 +711,18 @@ do { \ #else #define MA(n) \ - do { memstalls += ((((int) PC & 3) != 0) ? (n) : ((n) - 1)); } while (0) + do { memstalls += ((((long) PC & 3) != 0) ? (n) : ((n) - 1)); } while (0) #define L(x) thislock = x; #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++; #endif -#if defined(__GO32__) || defined(_WIN32) +#if defined(__GO32__) int sim_memory_size = 19; #else -int sim_memory_size = 24; +int sim_memory_size = 30; #endif static int sim_profile_size = 17; @@ -825,10 +742,7 @@ static int nsamples; #define SCI_TDRE 0x80 /* Transmit data register empty */ static int -IOMEM (addr, write, value) - int addr; - int write; - int value; +IOMEM (int addr, int write, int value) { if (write) { @@ -855,22 +769,21 @@ IOMEM (addr, write, value) } static int -get_now () +get_now (void) { return time ((long *) 0); } static int -now_persec () +now_persec (void) { return 1; } static FILE *profile_file; -static unsigned INLINE -swap (n) - unsigned n; +static INLINE unsigned +swap (unsigned n) { if (endianb) n = (n << 24 | (n & 0xff00) << 8 @@ -878,9 +791,8 @@ swap (n) return n; } -static unsigned short INLINE -swap16 (n) - unsigned short n; +static INLINE unsigned short +swap16 (unsigned short n) { if (endianb) n = n << 8 | (n & 0xff00) >> 8; @@ -888,8 +800,7 @@ swap16 (n) } static void -swapout (n) - int n; +swapout (int n) { if (profile_file) { @@ -900,8 +811,7 @@ swapout (n) } static void -swapout16 (n) - int n; +swapout16 (int n) { union { char b[4]; int n; } u; u.n = swap16 (n); @@ -911,15 +821,17 @@ swapout16 (n) /* Turn a pointer in a register into a pointer into real memory. */ static char * -ptr (x) - int x; +ptr (int x) { return (char *) (x + saved_state.asregs.memory); } +/* STR points to a zero-terminated string in target byte order. Return + the number of bytes that need to be converted to host byte order in order + to use this string as a zero-terminated string on the host. + (Not counting the rounding up needed to operate on entire words.) */ static int -strswaplen (str) - int str; +strswaplen (int str) { unsigned char *memory = saved_state.asregs.memory; int start, end; @@ -929,13 +841,11 @@ strswaplen (str) return 0; end = str; for (end = str; memory[end ^ endian]; end++) ; - return end - str; + return end - str + 1; } static void -strnswap (str, len) - int str; - int len; +strnswap (int str, int len) { int *start, *end; @@ -953,14 +863,16 @@ strnswap (str, len) while (start < end); } -/* 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 + return offset by which to adjust pc. */ -static void -trap (i, regs, memory, maskl, maskw, endianw) - int i; - int *regs; - unsigned char *memory; +static int +trap (SIM_DESC sd, int i, int *regs, unsigned char *insn_ptr, + unsigned char *memory, int maskl, int maskw, int endianw) { + host_callback *callback = STATE_CALLBACK (sd); + char **prog_argv = STATE_PROG_ARGV (sd); + switch (i) { case 1: @@ -970,6 +882,13 @@ trap (i, regs, memory, maskl, maskw, endianw) raise_exception (SIGQUIT); break; case 3: /* FIXME: for backwards compat, should be removed */ + case 33: + { + unsigned int countp = * (unsigned int *) (insn_ptr + 4); + + WLAT (countp, RLAT (countp) + 1); + return 6; + } case 34: { extern int errno; @@ -987,10 +906,11 @@ trap (i, regs, memory, maskl, maskw, endianw) Besides, it's quite dangerous. */ #if 0 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; 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; #endif case SYS_pipe: @@ -1002,7 +922,7 @@ trap (i, regs, memory, maskl, maskw, endianw) break; case SYS_wait: - regs[0] = wait (ptr (regs[5])); + regs[0] = wait ((int *) ptr (regs[5])); break; #endif /* !defined(__GO32__) && !defined(_WIN32) */ @@ -1015,9 +935,11 @@ trap (i, regs, memory, maskl, maskw, endianw) case SYS_write: strnswap (regs[6], regs[7]); 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 - 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]); strnswap (regs[6], regs[7]); break; case SYS_lseek: @@ -1030,7 +952,7 @@ trap (i, regs, memory, maskl, maskw, endianw) { int len = strswaplen (regs[5]); strnswap (regs[5], len); - regs[0] = callback->open (callback,ptr (regs[5]), regs[6]); + regs[0] = callback->open (callback, ptr (regs[5]), regs[6]); strnswap (regs[5], len); break; } @@ -1120,20 +1042,20 @@ trap (i, regs, memory, maskl, maskw, endianw) break; } case SYS_argc: - regs[0] = count_argc (prog_argv); + regs[0] = countargv (prog_argv); break; case SYS_argnlen: - if (regs[5] < count_argc (prog_argv)) + if (regs[5] < countargv (prog_argv)) regs[0] = strlen (prog_argv[regs[5]]); else regs[0] = -1; break; case SYS_argn: - if (regs[5] < count_argc (prog_argv)) + if (regs[5] < countargv (prog_argv)) { /* Include the termination byte. */ int i = strlen (prog_argv[regs[5]]) + 1; - regs[0] = sim_write (0, regs[6], prog_argv[regs[5]], i); + regs[0] = sim_write (0, regs[6], (void *) prog_argv[regs[5]], i); } else regs[0] = -1; @@ -1141,6 +1063,17 @@ trap (i, regs, memory, maskl, maskw, endianw) case SYS_time: regs[0] = get_now (); break; + case SYS_ftruncate: + regs[0] = callback->ftruncate (callback, regs[5], regs[6]); + break; + case SYS_truncate: + { + int len = strswaplen (regs[5]); + strnswap (regs[5], len); + regs[0] = callback->truncate (callback, ptr (regs[5]), regs[6]); + strnswap (regs[5], len); + break; + } default: regs[0] = -1; break; @@ -1150,30 +1083,24 @@ trap (i, regs, memory, maskl, maskw, endianw) } break; + case 13: /* Set IBNR */ + IBNR = regs[0] & 0xffff; + break; + case 14: /* Set IBCR */ + IBCR = regs[0] & 0xffff; + break; case 0xc3: case 255: raise_exception (SIGTRAP); + if (i == 0xc3) + return -2; break; } - -} - -void -control_c (sig, code, scp, addr) - int sig; - int code; - char *scp; - char *addr; -{ - raise_exception (SIGINT); + return 0; } -static int -div1 (R, iRn2, iRn1/*, T*/) - int *R; - int iRn1; - int iRn2; - /* int T;*/ +static void +div1 (int *R, int iRn2, int iRn1/*, int T*/) { unsigned long tmp0; unsigned char old_q, tmp1; @@ -1258,61 +1185,32 @@ div1 (R, iRn2, iRn1/*, T*/) } static void -dmul (sign, rm, rn) - int sign; - unsigned int rm; - unsigned int rn; +dmul_s (uint32_t rm, uint32_t rn) { - unsigned long RnL, RnH; - unsigned long RmL, RmH; - unsigned long temp0, temp1, temp2, temp3; - unsigned long Res2, Res1, Res0; - - RnL = rn & 0xffff; - RnH = (rn >> 16) & 0xffff; - RmL = rm & 0xffff; - RmH = (rm >> 16) & 0xffff; - temp0 = RmL * RnL; - temp1 = RmH * RnL; - temp2 = RmL * RnH; - temp3 = RmH * RnH; - Res2 = 0; - Res1 = temp1 + temp2; - if (Res1 < temp1) - Res2 += 0x00010000; - temp1 = (Res1 << 16) & 0xffff0000; - Res0 = temp0 + temp1; - if (Res0 < temp0) - Res2 += 1; - Res2 += ((Res1 >> 16) & 0xffff) + temp3; - - if (sign) - { - if (rn & 0x80000000) - Res2 -= rm; - if (rm & 0x80000000) - Res2 -= rn; - } + int64_t res = (int64_t)(int32_t)rm * (int64_t)(int32_t)rn; + MACH = (uint32_t)((uint64_t)res >> 32); + MACL = (uint32_t)res; +} - MACH = Res2; - MACL = Res0; +static void +dmul_u (uint32_t rm, uint32_t rn) +{ + uint64_t res = (uint64_t)(uint32_t)rm * (uint64_t)(uint32_t)rn; + MACH = (uint32_t)(res >> 32); + MACL = (uint32_t)res; } static void -macw (regs, memory, n, m, endianw) - int *regs; - unsigned char *memory; - int m, n; - int endianw; +macw (int *regs, unsigned char *memory, int n, int m, int endianw) { long tempm, tempn; long prod, macl, sum; - tempm=RSWAT(regs[m]); regs[m]+=2; - tempn=RSWAT(regs[n]); regs[n]+=2; + tempm=RSWAT (regs[m]); regs[m]+=2; + tempn=RSWAT (regs[n]); regs[n]+=2; macl = MACL; - prod = (long)(short) tempm * (long)(short) tempn; + prod = (long) (short) tempm * (long) (short) tempn; sum = prod + macl; if (S) { @@ -1336,11 +1234,259 @@ macw (regs, memory, n, m, endianw) MACL = sum; } +static void +macl (int *regs, unsigned char *memory, int n, int m) +{ + long tempm, tempn; + long macl, mach; + long long ans; + long long mac64; + + tempm = RSLAT (regs[m]); + regs[m] += 4; + + tempn = RSLAT (regs[n]); + regs[n] += 4; + + mach = MACH; + macl = MACL; + + mac64 = ((long long) macl & 0xffffffff) | + ((long long) mach & 0xffffffff) << 32; + + ans = (long long) tempm * (long long) tempn; /* Multiply 32bit * 32bit */ + + mac64 += ans; /* Accumulate 64bit + 64 bit */ + + macl = (long) (mac64 & 0xffffffff); + mach = (long) ((mac64 >> 32) & 0xffffffff); + + if (S) /* Store only 48 bits of the result */ + { + if (mach < 0) /* Result is negative */ + { + mach = mach & 0x0000ffff; /* Mask higher 16 bits */ + mach |= 0xffff8000; /* Sign extend higher 16 bits */ + } + else + mach = mach & 0x00007fff; /* Postive Result */ + } + + MACL = macl; + MACH = mach; +} + +enum { + B_BCLR = 0, + B_BSET = 1, + B_BST = 2, + B_BLD = 3, + B_BAND = 4, + B_BOR = 5, + B_BXOR = 6, + B_BLDNOT = 11, + B_BANDNOT = 12, + B_BORNOT = 13, + + MOVB_RM = 0x0000, + MOVW_RM = 0x1000, + MOVL_RM = 0x2000, + FMOV_RM = 0x3000, + MOVB_MR = 0x4000, + MOVW_MR = 0x5000, + MOVL_MR = 0x6000, + FMOV_MR = 0x7000, + MOVU_BMR = 0x8000, + MOVU_WMR = 0x9000, +}; + +/* Do extended displacement move instructions. */ +static void +do_long_move_insn (int op, int disp12, int m, int n, int *thatlock) +{ + int memstalls = 0; + int thislock = *thatlock; + int endianw = global_endianw; + int *R = &(saved_state.asregs.regs[0]); + unsigned char *memory = saved_state.asregs.memory; + int maskb = ~((saved_state.asregs.msize - 1) & ~0); + unsigned char *insn_ptr = PT2H (saved_state.asregs.pc); + + switch (op) { + case MOVB_RM: /* signed */ + WBAT (disp12 * 1 + R[n], R[m]); + break; + case MOVW_RM: + WWAT (disp12 * 2 + R[n], R[m]); + break; + case MOVL_RM: + WLAT (disp12 * 4 + R[n], R[m]); + break; + case FMOV_RM: /* floating point */ + if (FPSCR_SZ) + { + MA (1); + WDAT (R[n] + 8 * disp12, m); + } + else + WLAT (R[n] + 4 * disp12, FI (m)); + break; + case MOVB_MR: + R[n] = RSBAT (disp12 * 1 + R[m]); + L (n); + break; + case MOVW_MR: + R[n] = RSWAT (disp12 * 2 + R[m]); + L (n); + break; + case MOVL_MR: + R[n] = RLAT (disp12 * 4 + R[m]); + L (n); + break; + case FMOV_MR: + if (FPSCR_SZ) { + MA (1); + RDAT (R[m] + 8 * disp12, n); + } + else + SET_FI (n, RLAT (R[m] + 4 * disp12)); + break; + case MOVU_BMR: /* unsigned */ + R[n] = RBAT (disp12 * 1 + R[m]); + L (n); + break; + case MOVU_WMR: + R[n] = RWAT (disp12 * 2 + R[m]); + L (n); + break; + default: + RAISE_EXCEPTION (SIGINT); + exit (1); + } + saved_state.asregs.memstalls += memstalls; + *thatlock = thislock; +} + +/* Do binary logical bit-manipulation insns. */ +static void +do_blog_insn (int imm, int addr, int binop, + unsigned char *memory, int maskb) +{ + int oldval = RBAT (addr); + + switch (binop) { + case B_BCLR: /* bclr.b */ + WBAT (addr, oldval & ~imm); + break; + case B_BSET: /* bset.b */ + WBAT (addr, oldval | imm); + break; + case B_BST: /* bst.b */ + if (T) + WBAT (addr, oldval | imm); + else + WBAT (addr, oldval & ~imm); + break; + case B_BLD: /* bld.b */ + SET_SR_T ((oldval & imm) != 0); + break; + case B_BAND: /* band.b */ + SET_SR_T (T && ((oldval & imm) != 0)); + break; + case B_BOR: /* bor.b */ + SET_SR_T (T || ((oldval & imm) != 0)); + break; + case B_BXOR: /* bxor.b */ + SET_SR_T (T ^ ((oldval & imm) != 0)); + break; + case B_BLDNOT: /* bldnot.b */ + SET_SR_T ((oldval & imm) == 0); + break; + case B_BANDNOT: /* bandnot.b */ + SET_SR_T (T && ((oldval & imm) == 0)); + break; + case B_BORNOT: /* bornot.b */ + SET_SR_T (T || ((oldval & imm) == 0)); + break; + } +} + +static float +fsca_s (int in, double (*f) (double)) +{ + double rad = ldexp ((in & 0xffff), -15) * 3.141592653589793238462643383; + double result = (*f) (rad); + double error, upper, lower, frac; + int exp; + + /* Search the value with the maximum error that is still within the + architectural spec. */ + error = ldexp (1., -21); + /* compensate for calculation inaccuracy by reducing error. */ + error = error - ldexp (1., -50); + upper = result + error; + frac = frexp (upper, &exp); + upper = ldexp (floor (ldexp (frac, 24)), exp - 24); + lower = result - error; + frac = frexp (lower, &exp); + lower = ldexp (ceil (ldexp (frac, 24)), exp - 24); + return abs (upper - result) >= abs (lower - result) ? upper : lower; +} + +static float +fsrra_s (float in) +{ + double result = 1. / sqrt (in); + int exp; + double frac, upper, lower, error, eps; + + /* refine result */ + result = result - (result * result * in - 1) * 0.5 * result; + /* Search the value with the maximum error that is still within the + architectural spec. */ + frac = frexp (result, &exp); + frac = ldexp (frac, 24); + error = 4.0; /* 1 << 24-1-21 */ + /* use eps to compensate for possible 1 ulp error in our 'exact' result. */ + eps = ldexp (1., -29); + upper = floor (frac + error - eps); + if (upper > 16777216.) + upper = floor ((frac + error - eps) * 0.5) * 2.; + lower = ceil ((frac - error + eps) * 2) * .5; + if (lower > 8388608.) + lower = ceil (frac - error + eps); + upper = ldexp (upper, exp - 24); + lower = ldexp (lower, exp - 24); + return upper - result >= result - lower ? upper : lower; +} + + +/* GET_LOOP_BOUNDS {EXTENDED} + These two functions compute the actual starting and ending point + of the repeat loop, based on the RS and RE registers (repeat start, + repeat stop). The extended version is called for LDRC, and the + regular version is called for SETRC. The difference is that for + LDRC, the loop start and end instructions are literally the ones + pointed to by RS and RE -- for SETRC, they're not (see docs). */ + static struct loop_bounds -get_loop_bounds (rs, re, memory, mem_end, maskw, endianw) - int rs, re; - unsigned char *memory, *mem_end; - int maskw, endianw; +get_loop_bounds_ext (int rs, int re, unsigned char *memory, + unsigned char *mem_end, int maskw, int endianw) +{ + struct loop_bounds loop; + + /* FIXME: should I verify RS < RE? */ + loop.start = PT2H (RS); /* FIXME not using the params? */ + loop.end = PT2H (RE & ~1); /* Ignore bit 0 of RE. */ + SKIP_INSN (loop.end); + if (loop.end >= mem_end) + loop.end = PT2H (0); + return loop; +} + +static struct loop_bounds +get_loop_bounds (int rs, int re, unsigned char *memory, unsigned char *mem_end, + int maskw, int endianw) { struct loop_bounds loop; @@ -1375,29 +1521,47 @@ get_loop_bounds (rs, re, memory, mem_end, maskw, endianw) return loop; } -static void -ppi_insn(); +static void ppi_insn (); #include "ppi.c" -/* Set the memory size to the power of two provided. */ +/* Provide calloc / free versions that use an anonymous mmap. This can + significantly cut the start-up time when a large simulator memory is + required, because pages are only zeroed on demand. */ +#ifdef MAP_ANONYMOUS +static void * +mcalloc (size_t nmemb, size_t size) +{ + void *page; -void -sim_size (power) - int power; + if (nmemb != 1) + size *= nmemb; + return mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); +} -{ - saved_state.asregs.msize = 1 << power; +#define mfree(start,length) munmap ((start), (length)) +#else +#define mcalloc calloc +#define mfree(start,length) free(start) +#endif +/* Set the memory size to the power of two provided. */ + +static void +sim_size (int power) +{ sim_memory_size = power; if (saved_state.asregs.memory) { - free (saved_state.asregs.memory); + mfree (saved_state.asregs.memory, saved_state.asregs.msize); } + saved_state.asregs.msize = 1 << power; + saved_state.asregs.memory = - (unsigned char *) calloc (64, saved_state.asregs.msize / 64); + (unsigned char *) mcalloc (1, saved_state.asregs.msize); if (!saved_state.asregs.memory) { @@ -1406,18 +1570,19 @@ sim_size (power) saved_state.asregs.msize); saved_state.asregs.msize = 1; - saved_state.asregs.memory = (unsigned char *) calloc (1, 1); + saved_state.asregs.memory = (unsigned char *) mcalloc (1, 1); } } static void -init_dsp (abfd) - struct _bfd *abfd; +init_dsp (struct bfd *abfd) { int was_dsp = target_dsp; unsigned long mach = bfd_get_mach (abfd); - if (mach == bfd_mach_sh_dsp || mach == bfd_mach_sh3_dsp) + if (mach == bfd_mach_sh_dsp || + mach == bfd_mach_sh4al_dsp || + mach == bfd_mach_sh3_dsp) { int ram_area_size, xram_start, yram_start; int new_select; @@ -1432,7 +1597,7 @@ init_dsp (abfd) xram_start = 0x0800f000; ram_area_size = 0x1000; } - if (mach == bfd_mach_sh3_dsp) + if (mach == bfd_mach_sh3_dsp || mach == bfd_mach_sh4al_dsp) { /* SH7612: 8KB each for X & Y memory; @@ -1448,8 +1613,10 @@ init_dsp (abfd) saved_state.asregs.xyram_select = new_select; free (saved_state.asregs.xmem); free (saved_state.asregs.ymem); - saved_state.asregs.xmem = (unsigned char *) calloc (1, ram_area_size); - saved_state.asregs.ymem = (unsigned char *) calloc (1, ram_area_size); + saved_state.asregs.xmem = + (unsigned char *) calloc (1, ram_area_size); + saved_state.asregs.ymem = + (unsigned char *) calloc (1, ram_area_size); /* Disable use of X / Y mmeory if not allocated. */ if (! saved_state.asregs.xmem || ! saved_state.asregs.ymem) @@ -1483,11 +1650,15 @@ init_dsp (abfd) saved_state.asregs.yram_start = 1; } + if (saved_state.asregs.regstack == NULL) + saved_state.asregs.regstack = + calloc (512, sizeof *saved_state.asregs.regstack); + if (target_dsp != was_dsp) { int i, tmp; - for (i = sizeof sh_dsp_table - 1; i >= 0; i--) + for (i = ARRAY_SIZE (sh_dsp_table) - 1; i >= 0; i--) { tmp = sh_jump_table[0xf000 + i]; sh_jump_table[0xf000 + i] = sh_dsp_table[i]; @@ -1497,12 +1668,8 @@ init_dsp (abfd) } static void -init_pointers () +init_pointers (void) { - host_little_endian = 0; - *(char*)&host_little_endian = 1; - host_little_endian &= 1; - if (saved_state.asregs.msize != 1 << sim_memory_size) { sim_size (sim_memory_size); @@ -1529,7 +1696,7 @@ init_pointers () } static void -dump_profile () +dump_profile (void) { unsigned int minpc; unsigned int maxpc; @@ -1550,9 +1717,7 @@ dump_profile () } static void -gotcall (from, to) - int from; - int to; +gotcall (int from, int to) { swapout (from); swapout (to); @@ -1561,18 +1726,8 @@ gotcall (from, to) #define MMASKB ((saved_state.asregs.msize -1) & ~0) -int -sim_stop (sd) - SIM_DESC sd; -{ - raise_exception (SIGINT); - return 1; -} - void -sim_resume (sd, step, siggnal) - SIM_DESC sd; - int step, siggnal; +sim_resume (SIM_DESC sd, int step, int siggnal) { register unsigned char *insn_ptr; unsigned char *mem_end; @@ -1582,7 +1737,11 @@ sim_resume (sd, step, siggnal) register int memstalls = 0; register int insts = 0; register int prevlock; +#if 1 + int thislock; +#else register int thislock; +#endif register unsigned int doprofile; register int pollcount = 0; /* endianw is used for every insn fetch, hence it makes sense to cache it. @@ -1590,10 +1749,9 @@ sim_resume (sd, step, siggnal) register int endianw = global_endianw; int tick_start = get_now (); - void (*prev) (); void (*prev_fpe) (); - register unsigned char *jump_table = sh_jump_table; + register unsigned short *jump_table = sh_jump_table; register int *R = &(saved_state.asregs.regs[0]); /*register int T;*/ @@ -1607,7 +1765,6 @@ sim_resume (sd, step, siggnal) register unsigned char *memory; register unsigned int sbit = ((unsigned int) 1 << 31); - prev = signal (SIGINT, control_c); prev_fpe = signal (SIGFPE, SIG_IGN); init_pointers (); @@ -1616,7 +1773,11 @@ sim_resume (sd, step, siggnal) memory = saved_state.asregs.memory; mem_end = memory + saved_state.asregs.msize; - loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw); + if (RE & 1) + loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw); + else + loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw); + insn_ptr = PT2H (saved_state.asregs.pc); CHECK_INSN_PTR (insn_ptr); @@ -1661,10 +1822,13 @@ sim_resume (sd, step, siggnal) #include "code.c" + in_delay_slot = 0; insn_ptr = nip; if (--pollcount < 0) { + host_callback *callback = STATE_CALLBACK (sd); + pollcount = POLL_QUIT_INTERVAL; if ((*callback->poll_quit) != NULL && (*callback->poll_quit) (callback)) @@ -1738,15 +1902,10 @@ sim_resume (sd, step, siggnal) } signal (SIGFPE, prev_fpe); - signal (SIGINT, prev); } int -sim_write (sd, addr, buffer, size) - SIM_DESC sd; - SIM_ADDR addr; - unsigned char *buffer; - int size; +sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size) { int i; @@ -1760,11 +1919,7 @@ sim_write (sd, addr, buffer, size) } int -sim_read (sd, addr, buffer, size) - SIM_DESC sd; - SIM_ADDR addr; - unsigned char *buffer; - int size; +sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size) { int i; @@ -1777,240 +1932,361 @@ sim_read (sd, addr, buffer, size) return size; } -int -sim_store_register (sd, rn, memory, length) - SIM_DESC sd; - int rn; - unsigned char *memory; - int length; +static int gdb_bank_number; +enum { + REGBANK_MACH = 15, + REGBANK_IVN = 16, + REGBANK_PR = 17, + REGBANK_GBR = 18, + REGBANK_MACL = 19 +}; + +static int +sh_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length) { unsigned val; init_pointers (); - val = swap (* (int *)memory); + val = swap (* (int *) memory); switch (rn) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: + case SIM_SH_R0_REGNUM: case SIM_SH_R1_REGNUM: case SIM_SH_R2_REGNUM: + case SIM_SH_R3_REGNUM: case SIM_SH_R4_REGNUM: case SIM_SH_R5_REGNUM: + case SIM_SH_R6_REGNUM: case SIM_SH_R7_REGNUM: case SIM_SH_R8_REGNUM: + case SIM_SH_R9_REGNUM: case SIM_SH_R10_REGNUM: case SIM_SH_R11_REGNUM: + case SIM_SH_R12_REGNUM: case SIM_SH_R13_REGNUM: case SIM_SH_R14_REGNUM: + case SIM_SH_R15_REGNUM: saved_state.asregs.regs[rn] = val; break; - case 16: + case SIM_SH_PC_REGNUM: saved_state.asregs.pc = val; break; - case 17: + case SIM_SH_PR_REGNUM: PR = val; break; - case 18: + case SIM_SH_GBR_REGNUM: GBR = val; break; - case 19: + case SIM_SH_VBR_REGNUM: VBR = val; break; - case 20: + case SIM_SH_MACH_REGNUM: MACH = val; break; - case 21: + case SIM_SH_MACL_REGNUM: MACL = val; break; - case 22: + case SIM_SH_SR_REGNUM: SET_SR (val); break; - case 23: + case SIM_SH_FPUL_REGNUM: FPUL = val; break; - case 24: + case SIM_SH_FPSCR_REGNUM: SET_FPSCR (val); break; - case 25: - if (target_dsp) - A0G = val; - else case 26: - if (target_dsp) - A0 = val; - else case 27: - if (target_dsp) - A1G = val; - else case 28: - if (target_dsp) - A1 = val; - else case 29: - if (target_dsp) - M0 = val; - else case 30: - if (target_dsp) - M1 = val; - else case 31: - if (target_dsp) - X0 = val; - else case 32: - if (target_dsp) - X1 = val; - else case 33: - if (target_dsp) - Y0 = val; - else case 34: - if (target_dsp) - Y1 = val; - else case 40: - if (target_dsp) - SET_MOD (val); - else case 35: case 36: case 37: case 38: case 39: - SET_FI (rn - 25, val); - break; - case 41: + case SIM_SH_FR0_REGNUM: case SIM_SH_FR1_REGNUM: case SIM_SH_FR2_REGNUM: + case SIM_SH_FR3_REGNUM: case SIM_SH_FR4_REGNUM: case SIM_SH_FR5_REGNUM: + case SIM_SH_FR6_REGNUM: case SIM_SH_FR7_REGNUM: case SIM_SH_FR8_REGNUM: + case SIM_SH_FR9_REGNUM: case SIM_SH_FR10_REGNUM: case SIM_SH_FR11_REGNUM: + case SIM_SH_FR12_REGNUM: case SIM_SH_FR13_REGNUM: case SIM_SH_FR14_REGNUM: + case SIM_SH_FR15_REGNUM: + SET_FI (rn - SIM_SH_FR0_REGNUM, val); + break; + case SIM_SH_DSR_REGNUM: + DSR = val; + break; + case SIM_SH_A0G_REGNUM: + A0G = val; + break; + case SIM_SH_A0_REGNUM: + A0 = val; + break; + case SIM_SH_A1G_REGNUM: + A1G = val; + break; + case SIM_SH_A1_REGNUM: + A1 = val; + break; + case SIM_SH_M0_REGNUM: + M0 = val; + break; + case SIM_SH_M1_REGNUM: + M1 = val; + break; + case SIM_SH_X0_REGNUM: + X0 = val; + break; + case SIM_SH_X1_REGNUM: + X1 = val; + break; + case SIM_SH_Y0_REGNUM: + Y0 = val; + break; + case SIM_SH_Y1_REGNUM: + Y1 = val; + break; + case SIM_SH_MOD_REGNUM: + SET_MOD (val); + break; + case SIM_SH_RS_REGNUM: + RS = val; + break; + case SIM_SH_RE_REGNUM: + RE = val; + break; + case SIM_SH_SSR_REGNUM: SSR = val; break; - case 42: + case SIM_SH_SPC_REGNUM: SPC = val; break; /* The rn_bank idiosyncracies are not due to hardware differences, but to a weird aliasing naming scheme for sh3 / sh3e / sh4. */ - case 43: - if (target_dsp) - RS = val; - else case 44: - if (target_dsp) - RE = val; - else case 45: case 46: case 47: case 48: case 49: case 50: + case SIM_SH_R0_BANK0_REGNUM: case SIM_SH_R1_BANK0_REGNUM: + case SIM_SH_R2_BANK0_REGNUM: case SIM_SH_R3_BANK0_REGNUM: + case SIM_SH_R4_BANK0_REGNUM: case SIM_SH_R5_BANK0_REGNUM: + case SIM_SH_R6_BANK0_REGNUM: case SIM_SH_R7_BANK0_REGNUM: + if (saved_state.asregs.bfd_mach == bfd_mach_sh2a) + { + rn -= SIM_SH_R0_BANK0_REGNUM; + saved_state.asregs.regstack[gdb_bank_number].regs[rn] = val; + } + else if (SR_MD && SR_RB) - Rn_BANK (rn - 43) = val; + Rn_BANK (rn - SIM_SH_R0_BANK0_REGNUM) = val; else - saved_state.asregs.regs[rn - 43] = val; + saved_state.asregs.regs[rn - SIM_SH_R0_BANK0_REGNUM] = val; break; - case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: - if (target_dsp || ! SR_MD || ! SR_RB) - SET_Rn_BANK (rn - 51, val); + case SIM_SH_R0_BANK1_REGNUM: case SIM_SH_R1_BANK1_REGNUM: + case SIM_SH_R2_BANK1_REGNUM: case SIM_SH_R3_BANK1_REGNUM: + case SIM_SH_R4_BANK1_REGNUM: case SIM_SH_R5_BANK1_REGNUM: + case SIM_SH_R6_BANK1_REGNUM: case SIM_SH_R7_BANK1_REGNUM: + if (saved_state.asregs.bfd_mach == bfd_mach_sh2a) + { + rn -= SIM_SH_R0_BANK1_REGNUM; + saved_state.asregs.regstack[gdb_bank_number].regs[rn + 8] = val; + } + else + if (SR_MD && SR_RB) + saved_state.asregs.regs[rn - SIM_SH_R0_BANK1_REGNUM] = val; else - saved_state.asregs.regs[rn - 51] = val; + Rn_BANK (rn - SIM_SH_R0_BANK1_REGNUM) = val; + break; + case SIM_SH_R0_BANK_REGNUM: case SIM_SH_R1_BANK_REGNUM: + case SIM_SH_R2_BANK_REGNUM: case SIM_SH_R3_BANK_REGNUM: + case SIM_SH_R4_BANK_REGNUM: case SIM_SH_R5_BANK_REGNUM: + case SIM_SH_R6_BANK_REGNUM: case SIM_SH_R7_BANK_REGNUM: + SET_Rn_BANK (rn - SIM_SH_R0_BANK_REGNUM, val); + break; + case SIM_SH_TBR_REGNUM: + TBR = val; + break; + case SIM_SH_IBNR_REGNUM: + IBNR = val; + break; + case SIM_SH_IBCR_REGNUM: + IBCR = val; + break; + case SIM_SH_BANK_REGNUM: + /* This is a pseudo-register maintained just for gdb. + It tells us what register bank gdb would like to read/write. */ + gdb_bank_number = val; + break; + case SIM_SH_BANK_MACL_REGNUM: + saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACL] = val; + break; + case SIM_SH_BANK_GBR_REGNUM: + saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_GBR] = val; + break; + case SIM_SH_BANK_PR_REGNUM: + saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_PR] = val; + break; + case SIM_SH_BANK_IVN_REGNUM: + saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_IVN] = val; + break; + case SIM_SH_BANK_MACH_REGNUM: + saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACH] = val; break; default: return 0; } - return -1; + return length; } -int -sim_fetch_register (sd, rn, memory, length) - SIM_DESC sd; - int rn; - unsigned char *memory; - int length; +static int +sh_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length) { int val; init_pointers (); switch (rn) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: + case SIM_SH_R0_REGNUM: case SIM_SH_R1_REGNUM: case SIM_SH_R2_REGNUM: + case SIM_SH_R3_REGNUM: case SIM_SH_R4_REGNUM: case SIM_SH_R5_REGNUM: + case SIM_SH_R6_REGNUM: case SIM_SH_R7_REGNUM: case SIM_SH_R8_REGNUM: + case SIM_SH_R9_REGNUM: case SIM_SH_R10_REGNUM: case SIM_SH_R11_REGNUM: + case SIM_SH_R12_REGNUM: case SIM_SH_R13_REGNUM: case SIM_SH_R14_REGNUM: + case SIM_SH_R15_REGNUM: val = saved_state.asregs.regs[rn]; break; - case 16: + case SIM_SH_PC_REGNUM: val = saved_state.asregs.pc; break; - case 17: + case SIM_SH_PR_REGNUM: val = PR; break; - case 18: + case SIM_SH_GBR_REGNUM: val = GBR; break; - case 19: + case SIM_SH_VBR_REGNUM: val = VBR; break; - case 20: + case SIM_SH_MACH_REGNUM: val = MACH; break; - case 21: + case SIM_SH_MACL_REGNUM: val = MACL; break; - case 22: + case SIM_SH_SR_REGNUM: val = GET_SR (); break; - case 23: + case SIM_SH_FPUL_REGNUM: val = FPUL; break; - case 24: + case SIM_SH_FPSCR_REGNUM: val = GET_FPSCR (); break; - case 25: - val = target_dsp ? SEXT (A0G) : FI (0); + case SIM_SH_FR0_REGNUM: case SIM_SH_FR1_REGNUM: case SIM_SH_FR2_REGNUM: + case SIM_SH_FR3_REGNUM: case SIM_SH_FR4_REGNUM: case SIM_SH_FR5_REGNUM: + case SIM_SH_FR6_REGNUM: case SIM_SH_FR7_REGNUM: case SIM_SH_FR8_REGNUM: + case SIM_SH_FR9_REGNUM: case SIM_SH_FR10_REGNUM: case SIM_SH_FR11_REGNUM: + case SIM_SH_FR12_REGNUM: case SIM_SH_FR13_REGNUM: case SIM_SH_FR14_REGNUM: + case SIM_SH_FR15_REGNUM: + val = FI (rn - SIM_SH_FR0_REGNUM); break; - case 26: - val = target_dsp ? A0 : FI (1); + case SIM_SH_DSR_REGNUM: + val = DSR; break; - case 27: - val = target_dsp ? SEXT (A1G) : FI (2); + case SIM_SH_A0G_REGNUM: + val = SEXT (A0G); break; - case 28: - val = target_dsp ? A1 : FI (3); + case SIM_SH_A0_REGNUM: + val = A0; break; - case 29: - val = target_dsp ? M0 : FI (4); + case SIM_SH_A1G_REGNUM: + val = SEXT (A1G); break; - case 30: - val = target_dsp ? M1 : FI (5); + case SIM_SH_A1_REGNUM: + val = A1; break; - case 31: - val = target_dsp ? X0 : FI (6); + case SIM_SH_M0_REGNUM: + val = M0; break; - case 32: - val = target_dsp ? X1 : FI (7); + case SIM_SH_M1_REGNUM: + val = M1; break; - case 33: - val = target_dsp ? Y0 : FI (8); + case SIM_SH_X0_REGNUM: + val = X0; break; - case 34: - val = target_dsp ? Y1 : FI (9); + case SIM_SH_X1_REGNUM: + val = X1; break; - case 35: case 36: case 37: case 38: case 39: - val = FI (rn - 25); + case SIM_SH_Y0_REGNUM: + val = Y0; break; - case 40: - val = target_dsp ? MOD : FI (15); + case SIM_SH_Y1_REGNUM: + val = Y1; break; - case 41: + case SIM_SH_MOD_REGNUM: + val = MOD; + break; + case SIM_SH_RS_REGNUM: + val = RS; + break; + case SIM_SH_RE_REGNUM: + val = RE; + break; + case SIM_SH_SSR_REGNUM: val = SSR; break; - case 42: + case SIM_SH_SPC_REGNUM: val = SPC; break; /* The rn_bank idiosyncracies are not due to hardware differences, but to a weird aliasing naming scheme for sh3 / sh3e / sh4. */ - case 43: - if (target_dsp) - val = RS; - else case 44: - if (target_dsp) - val = RE; - else case 45: case 46: case 47: case 48: case 49: case 50: - val = (SR_MD && SR_RB - ? Rn_BANK (rn - 43) - : saved_state.asregs.regs[rn - 43]); - break; - case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: - val = (target_dsp || ! SR_MD || ! SR_RB - ? Rn_BANK (rn - 51) - : saved_state.asregs.regs[rn - 51]); + case SIM_SH_R0_BANK0_REGNUM: case SIM_SH_R1_BANK0_REGNUM: + case SIM_SH_R2_BANK0_REGNUM: case SIM_SH_R3_BANK0_REGNUM: + case SIM_SH_R4_BANK0_REGNUM: case SIM_SH_R5_BANK0_REGNUM: + case SIM_SH_R6_BANK0_REGNUM: case SIM_SH_R7_BANK0_REGNUM: + if (saved_state.asregs.bfd_mach == bfd_mach_sh2a) + { + rn -= SIM_SH_R0_BANK0_REGNUM; + val = saved_state.asregs.regstack[gdb_bank_number].regs[rn]; + } + else + val = (SR_MD && SR_RB + ? Rn_BANK (rn - SIM_SH_R0_BANK0_REGNUM) + : saved_state.asregs.regs[rn - SIM_SH_R0_BANK0_REGNUM]); + break; + case SIM_SH_R0_BANK1_REGNUM: case SIM_SH_R1_BANK1_REGNUM: + case SIM_SH_R2_BANK1_REGNUM: case SIM_SH_R3_BANK1_REGNUM: + case SIM_SH_R4_BANK1_REGNUM: case SIM_SH_R5_BANK1_REGNUM: + case SIM_SH_R6_BANK1_REGNUM: case SIM_SH_R7_BANK1_REGNUM: + if (saved_state.asregs.bfd_mach == bfd_mach_sh2a) + { + rn -= SIM_SH_R0_BANK1_REGNUM; + val = saved_state.asregs.regstack[gdb_bank_number].regs[rn + 8]; + } + else + val = (! SR_MD || ! SR_RB + ? Rn_BANK (rn - SIM_SH_R0_BANK1_REGNUM) + : saved_state.asregs.regs[rn - SIM_SH_R0_BANK1_REGNUM]); + break; + case SIM_SH_R0_BANK_REGNUM: case SIM_SH_R1_BANK_REGNUM: + case SIM_SH_R2_BANK_REGNUM: case SIM_SH_R3_BANK_REGNUM: + case SIM_SH_R4_BANK_REGNUM: case SIM_SH_R5_BANK_REGNUM: + case SIM_SH_R6_BANK_REGNUM: case SIM_SH_R7_BANK_REGNUM: + val = Rn_BANK (rn - SIM_SH_R0_BANK_REGNUM); + break; + case SIM_SH_TBR_REGNUM: + val = TBR; + break; + case SIM_SH_IBNR_REGNUM: + val = IBNR; + break; + case SIM_SH_IBCR_REGNUM: + val = IBCR; + break; + case SIM_SH_BANK_REGNUM: + /* This is a pseudo-register maintained just for gdb. + It tells us what register bank gdb would like to read/write. */ + val = gdb_bank_number; + break; + case SIM_SH_BANK_MACL_REGNUM: + val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACL]; + break; + case SIM_SH_BANK_GBR_REGNUM: + val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_GBR]; + break; + case SIM_SH_BANK_PR_REGNUM: + val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_PR]; + break; + case SIM_SH_BANK_IVN_REGNUM: + val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_IVN]; + break; + case SIM_SH_BANK_MACH_REGNUM: + val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACH]; break; default: return 0; } * (int *) memory = swap (val); - return -1; -} - -int -sim_trace (sd) - SIM_DESC sd; -{ - return 0; + return length; } void -sim_stop_reason (sd, reason, sigrc) - SIM_DESC sd; - enum sim_stop *reason; - int *sigrc; +sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc) { /* The SH simulator uses SIGQUIT to indicate that the program has exited, so we must check for it here and translate it to exit. */ @@ -2027,64 +2303,63 @@ sim_stop_reason (sd, reason, sigrc) } void -sim_info (sd, verbose) - SIM_DESC sd; - int verbose; +sim_info (SIM_DESC sd, 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; - callback->printf_filtered (callback, "\n\n# instructions executed %10d\n", - saved_state.asregs.insts); - callback->printf_filtered (callback, "# cycles %10d\n", - saved_state.asregs.cycles); - callback->printf_filtered (callback, "# pipeline stalls %10d\n", - saved_state.asregs.stalls); - callback->printf_filtered (callback, "# misaligned load/store %10d\n", - saved_state.asregs.memstalls); - callback->printf_filtered (callback, "# real time taken %10.4f\n", - timetaken); - callback->printf_filtered (callback, "# virtual time taken %10.4f\n", - virttime); - callback->printf_filtered (callback, "# profiling size %10d\n", - sim_profile_size); - callback->printf_filtered (callback, "# profiling frequency %10d\n", - saved_state.asregs.profile); - callback->printf_filtered (callback, "# profile maxpc %10x\n", - (1 << sim_profile_size) << PROFILE_SHIFT); + sim_io_printf (sd, "\n\n# instructions executed %10d\n", + saved_state.asregs.insts); + sim_io_printf (sd, "# cycles %10d\n", + saved_state.asregs.cycles); + sim_io_printf (sd, "# pipeline stalls %10d\n", + saved_state.asregs.stalls); + sim_io_printf (sd, "# misaligned load/store %10d\n", + saved_state.asregs.memstalls); + sim_io_printf (sd, "# real time taken %10.4f\n", timetaken); + sim_io_printf (sd, "# virtual time taken %10.4f\n", virttime); + sim_io_printf (sd, "# profiling size %10d\n", sim_profile_size); + sim_io_printf (sd, "# profiling frequency %10d\n", + saved_state.asregs.profile); + sim_io_printf (sd, "# profile maxpc %10x\n", + (1 << sim_profile_size) << PROFILE_SHIFT); if (timetaken != 0) { - callback->printf_filtered (callback, "# cycles/second %10d\n", - (int) (saved_state.asregs.cycles / timetaken)); - callback->printf_filtered (callback, "# simulation ratio %10.4f\n", - virttime / timetaken); + sim_io_printf (sd, "# cycles/second %10d\n", + (int) (saved_state.asregs.cycles / timetaken)); + sim_io_printf (sd, "# simulation ratio %10.4f\n", + virttime / timetaken); } } -void -sim_set_profile (n) - int n; +static sim_cia +sh_pc_get (sim_cpu *cpu) { - saved_state.asregs.profile = n; + return saved_state.asregs.pc; } -void -sim_set_profile_size (n) - int n; +static void +sh_pc_set (sim_cpu *cpu, sim_cia pc) { - sim_profile_size = n; + saved_state.asregs.pc = pc; +} + +static void +free_state (SIM_DESC sd) +{ + if (STATE_MODULES (sd) != NULL) + sim_module_uninstall (sd); + sim_cpu_free_all (sd); + sim_state_free (sd); } SIM_DESC -sim_open (kind, cb, abfd, argv) - SIM_OPEN_KIND kind; - host_callback *cb; - struct _bfd *abfd; - char **argv; +sim_open (SIM_OPEN_KIND kind, host_callback *cb, + struct bfd *abfd, char * const *argv) { char **p; - int endian_set = 0; int i; union { @@ -2094,31 +2369,71 @@ sim_open (kind, cb, abfd, argv) } mem_word; - sim_kind = kind; - myname = argv[0]; - callback = cb; + SIM_DESC sd = sim_state_alloc (kind, cb); + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); - for (p = argv + 1; *p != NULL; ++p) + /* The cpu data is kept in a separately allocated chunk of memory. */ + if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK) { - if (strcmp (*p, "-E") == 0) - { - ++p; - if (*p == NULL) - { - /* FIXME: This doesn't use stderr, but then the rest of the - file doesn't either. */ - callback->printf_filtered (callback, "Missing argument to `-E'.\n"); - return 0; - } - target_little_endian = strcmp (*p, "big") != 0; - endian_set = 1; - } - else if (isdigit (**p)) - parse_and_set_memory_size (*p); + free_state (sd); + return 0; } - if (abfd != NULL && ! endian_set) - target_little_endian = ! bfd_big_endian (abfd); + if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) + { + free_state (sd); + return 0; + } + + /* The parser will print an error message for us, so we silently return. */ + if (sim_parse_args (sd, argv) != SIM_RC_OK) + { + free_state (sd); + return 0; + } + + /* Check for/establish the a reference program image. */ + if (sim_analyze_program (sd, + (STATE_PROG_ARGV (sd) != NULL + ? *STATE_PROG_ARGV (sd) + : NULL), abfd) != SIM_RC_OK) + { + free_state (sd); + return 0; + } + + /* Configure/verify the target byte order and other runtime + configuration options. */ + if (sim_config (sd) != SIM_RC_OK) + { + sim_module_uninstall (sd); + return 0; + } + + if (sim_post_argv_init (sd) != SIM_RC_OK) + { + /* Uninstall the modules to avoid memory leaks, + file descriptor leaks, etc. */ + sim_module_uninstall (sd); + return 0; + } + + /* CPU specific initialization. */ + for (i = 0; i < MAX_NR_PROCESSORS; ++i) + { + SIM_CPU *cpu = STATE_CPU (sd, i); + + CPU_REG_FETCH (cpu) = sh_reg_fetch; + CPU_REG_STORE (cpu) = sh_reg_store; + CPU_PC_FETCH (cpu) = sh_pc_get; + CPU_PC_STORE (cpu) = sh_pc_set; + } + + for (p = argv + 1; *p != NULL; ++p) + { + if (isdigit (**p)) + parse_and_set_memory_size (sd, *p); + } if (abfd) init_dsp (abfd); @@ -2131,78 +2446,47 @@ sim_open (kind, cb, abfd, argv) mem_word.c[i] = i; endianb = mem_word.i >> (target_little_endian ? 0 : 24) & 0xff; - /* fudge our descriptor for now */ - return (SIM_DESC) 1; + return sd; } static void -parse_and_set_memory_size (str) - char *str; +parse_and_set_memory_size (SIM_DESC sd, const char *str) { int n; n = strtol (str, NULL, 10); - if (n > 0 && n <= 24) + if (n > 0 && n <= 31) sim_memory_size = n; else - callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n); -} - -void -sim_close (sd, quitting) - SIM_DESC sd; - int quitting; -{ - /* nothing to do */ + sim_io_printf (sd, "Bad memory size %d; must be 1 to 31, inclusive\n", n); } SIM_RC -sim_load (sd, prog, abfd, from_tty) - SIM_DESC sd; - char *prog; - bfd *abfd; - int from_tty; -{ - extern bfd *sim_load_file (); /* ??? Don't know where this should live. */ - bfd *prog_bfd; - - prog_bfd = sim_load_file (sd, myname, callback, prog, abfd, - sim_kind == SIM_OPEN_DEBUG, - 0, sim_write); - if (prog_bfd == NULL) - return SIM_RC_FAIL; - if (abfd == NULL) - bfd_close (prog_bfd); - return SIM_RC_OK; -} - -SIM_RC -sim_create_inferior (sd, prog_bfd, argv, env) - SIM_DESC sd; - struct _bfd *prog_bfd; - char **argv; - char **env; +sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd, + char * const *argv, char * const *env) { /* Clear the registers. */ 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. */ if (prog_bfd != NULL) saved_state.asregs.pc = bfd_get_start_address (prog_bfd); - /* Record the program's arguments. */ - prog_argv = argv; + /* Set the bfd machine type. */ + if (prog_bfd != NULL) + saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd); + + if (prog_bfd != NULL) + init_dsp (prog_bfd); return SIM_RC_OK; } void -sim_do_command (sd, cmd) - SIM_DESC sd; - char *cmd; +sim_do_command (SIM_DESC sd, const char *cmd) { - char *sms_cmd = "set-memory-size"; + const char *sms_cmd = "set-memory-size"; int cmdsize; if (cmd == NULL || *cmd == '\0') @@ -2211,25 +2495,19 @@ sim_do_command (sd, 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 (sd, cmd + cmdsize + 1); } else if (strcmp (cmd, "help") == 0) { - (callback->printf_filtered) (callback, "List of SH simulator commands:\n\n"); - (callback->printf_filtered) (callback, "set-memory-size -- Set the number of address bits to use\n"); - (callback->printf_filtered) (callback, "\n"); + sim_io_printf (sd, "List of SH simulator commands:\n\n"); + sim_io_printf (sd, "set-memory-size -- Set the number of address bits to use\n"); + sim_io_printf (sd, "\n"); } else { - (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd); + sim_io_printf (sd, "Error: \"%s\" is not a valid SH simulator command.\n", cmd); } } - -void -sim_set_callbacks (p) - host_callback *p; -{ - callback = p; -}