X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fsh%2Finterp.c;h=c854174d2bd94cbb6b5ae90772b2eec921698c19;hb=60d847df0b9691b7cb38bfba41b9d6aafd97efc2;hp=286dd2dccba4ed9abbc95a0ac42c9e5b100c19b8;hpb=3c25f8c7b071182238e0833c72552ee0e72fd2ae;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/sh/interp.c b/sim/sh/interp.c index 286dd2dccb..c854174d2b 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,42 @@ #include "config.h" +#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 -#include "sysdep.h" #include "bfd.h" #include "gdb/callback.h" #include "gdb/remote-sim.h" +#include "gdb/sim-sh.h" /* This file is local - if newlib changes, then so should this. */ #include "syscall.h" @@ -52,9 +79,9 @@ #define SIGTRAP 5 #endif -extern unsigned char sh_jump_table[], sh_dsp_table[0x1000], ppi_table[]; +extern unsigned short sh_jump_table[], sh_dsp_table[0x1000], ppi_table[]; -int sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size); +int sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size); #define O_RECOMPILE 85 #define DEFINE_TABLE @@ -64,6 +91,11 @@ int sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size); for a quit. */ #define POLL_QUIT_INTERVAL 0x60000 +typedef struct +{ + int regs[20]; +} regstacktype; + typedef union { @@ -119,6 +151,12 @@ typedef union int re; /* sh3 */ int bank[8]; + int dbr; /* debug base register */ + int sgr; /* saved gr15 */ + int ldst; /* load/store flag (boolean) */ + int tbr; + int ibcr; /* sh2a bank control register */ + int ibnr; /* sh2a bank number register */ } named; int i[16]; } cregs; @@ -148,6 +186,8 @@ typedef union unsigned char *ymem; unsigned char *xmem_offset; unsigned char *ymem_offset; + unsigned long bfd_mach; + regstacktype *regstack; } asregs; int asints[40]; @@ -166,12 +206,12 @@ static int target_dsp; static int host_little_endian; static char **prog_argv; -#if 1 static int maskw = 0; -#endif +static int maskl = 0; static SIM_OPEN_KIND sim_kind; static char *myname; +static int tracing = 0; /* Short hand definitions of the registers */ @@ -180,15 +220,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 +255,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 +271,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 +295,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,9 +326,9 @@ 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) +#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 @@ -316,6 +379,9 @@ fail () #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. */ @@ -323,7 +389,7 @@ void raise_exception (x) int x; { - RAISE_EXCEPTION(x); + RAISE_EXCEPTION (x); } void @@ -398,7 +464,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,22 +473,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 void parse_and_set_memory_size (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); +static void INLINE wlat_fast (unsigned char *, int, int, int); +static void INLINE wwat_fast (unsigned char *, int, int, int, int); +static void INLINE wbat_fast (unsigned char *, int, int, int); +static int INLINE rlat_fast (unsigned char *, int, int); +static int INLINE rwat_fast (unsigned char *, int, int, int); +static int INLINE rbat_fast (unsigned char *, int, int); static host_callback *callback; @@ -515,10 +581,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 +594,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,10 +607,10 @@ 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 @@ -573,7 +639,7 @@ wlat_fast (memory, x, value, maskl) unsigned char *memory; { 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; } @@ -583,7 +649,7 @@ wwat_fast (memory, x, value, maskw, endianw) unsigned char *memory; { 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; } @@ -604,7 +670,7 @@ static int INLINE rlat_fast (memory, x, maskl) unsigned char *memory; { - unsigned int *p = (unsigned int *)(memory + x); + unsigned int *p = (unsigned int *) (memory + x); READ_BUSERROR (x, maskl, process_rlat_addr); return *p; @@ -615,7 +681,7 @@ rwat_fast (memory, x, maskw, endianw) unsigned char *memory; int x, maskw, 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; @@ -625,7 +691,7 @@ static int INLINE riat_fast (insn_ptr, endianw) unsigned char *insn_ptr; { - unsigned short *p = (unsigned short *)((size_t) insn_ptr ^ endianw); + unsigned short *p = (unsigned short *) ((size_t) insn_ptr ^ endianw); return *p; } @@ -648,9 +714,10 @@ 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 @@ -755,11 +822,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 +839,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,15 +862,15 @@ 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; @@ -917,6 +985,10 @@ ptr (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; @@ -929,7 +1001,7 @@ strswaplen (str) return 0; end = str; for (end = str; memory[end ^ endian]; end++) ; - return end - str; + return end - str + 1; } static void @@ -953,12 +1025,14 @@ 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) +static int +trap (i, regs, insn_ptr, memory, maskl, maskw, endianw) int i; int *regs; + unsigned char *insn_ptr; unsigned char *memory; { switch (i) @@ -970,6 +1044,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 +1068,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: @@ -1015,9 +1097,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 +1114,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; } @@ -1141,6 +1225,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,22 +1245,20 @@ 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 @@ -1308,11 +1401,11 @@ macw (regs, memory, n, m, 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,6 +1429,260 @@ macw (regs, memory, n, m, endianw) MACL = sum; } +static void +macl (regs, memory, n, m) + int *regs; + unsigned char *memory; + int m, n; +{ + 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. */ +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. */ +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; + } +} +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; +} + +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_ext (rs, re, memory, mem_end, maskw, endianw) + int rs, re; + unsigned char *memory, *mem_end; + int maskw, 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 (rs, re, memory, mem_end, maskw, endianw) int rs, re; @@ -1375,11 +1722,31 @@ get_loop_bounds (rs, re, memory, mem_end, maskw, endianw) return loop; } -static void -ppi_insn(); +static void ppi_insn (); #include "ppi.c" +/* 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 +void * +mcalloc (size_t nmemb, size_t size) +{ + void *page; + + if (nmemb != 1) + size *= nmemb; + return mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); +} + +#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. */ void @@ -1387,17 +1754,17 @@ sim_size (power) int power; { - saved_state.asregs.msize = 1 << 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 +1773,20 @@ 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; + 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 +1801,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 +1817,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 +1854,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 = (sizeof sh_dsp_table / sizeof sh_dsp_table[0]) - 1; i >= 0; i--) { tmp = sh_jump_table[0xf000 + i]; sh_jump_table[0xf000 + i] = sh_dsp_table[i]; @@ -1500,7 +1875,7 @@ static void init_pointers () { host_little_endian = 0; - *(char*)&host_little_endian = 1; + * (char*) &host_little_endian = 1; host_little_endian &= 1; if (saved_state.asregs.msize != 1 << sim_memory_size) @@ -1582,7 +1957,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 +1969,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 +1985,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 +1993,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); @@ -1657,10 +2038,13 @@ sim_resume (sd, step, siggnal) insts++; #endif top: + if (tracing) + fprintf (stderr, "PC: %08x, insn: %04x\n", PH2T (insn_ptr), iword); #include "code.c" + in_delay_slot = 0; insn_ptr = nip; if (--pollcount < 0) @@ -1717,7 +2101,7 @@ sim_resume (sd, step, siggnal) } /* Check for SIGBUS due to insn fetch. */ else if (! saved_state.asregs.exception) - saved_state.asregs.exception == SIGBUS; + saved_state.asregs.exception = SIGBUS; saved_state.asregs.ticks += get_now () - tick_start; saved_state.asregs.cycles += cycles; @@ -1738,14 +2122,13 @@ 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; + const unsigned char *buffer; int size; { int i; @@ -1777,6 +2160,15 @@ sim_read (sd, addr, buffer, size) return size; } +static int gdb_bank_number; +enum { + REGBANK_MACH = 15, + REGBANK_IVN = 16, + REGBANK_PR = 17, + REGBANK_GBR = 18, + REGBANK_MACL = 19 +}; + int sim_store_register (sd, rn, memory, length) SIM_DESC sd; @@ -1787,106 +2179,171 @@ sim_store_register (sd, rn, memory, 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 @@ -1901,109 +2358,177 @@ sim_fetch_register (sd, rn, memory, length) 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 SIM_SH_Y0_REGNUM: + val = Y0; + break; + case SIM_SH_Y1_REGNUM: + val = Y1; + break; + case SIM_SH_MOD_REGNUM: + val = MOD; break; - case 35: case 36: case 37: case 38: case 39: - val = FI (rn - 25); + case SIM_SH_RS_REGNUM: + val = RS; break; - case 40: - val = target_dsp ? MOD : FI (15); + case SIM_SH_RE_REGNUM: + val = RE; break; - case 41: + 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; + return length; } int sim_trace (sd) SIM_DESC sd; { - return 0; + tracing = 1; + sim_resume (sd, 0, 0); + tracing = 0; + return 1; } void @@ -2031,7 +2556,8 @@ sim_info (sd, verbose) 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", @@ -2080,7 +2606,7 @@ SIM_DESC sim_open (kind, cb, abfd, argv) SIM_OPEN_KIND kind; host_callback *cb; - struct _bfd *abfd; + struct bfd *abfd; char **argv; { char **p; @@ -2137,7 +2663,7 @@ sim_open (kind, cb, abfd, argv) static void parse_and_set_memory_size (str) - char *str; + const char *str; { int n; @@ -2159,7 +2685,7 @@ sim_close (sd, quitting) SIM_RC sim_load (sd, prog, abfd, from_tty) SIM_DESC sd; - char *prog; + const char *prog; bfd *abfd; int from_tty; { @@ -2169,6 +2695,15 @@ sim_load (sd, prog, abfd, from_tty) prog_bfd = sim_load_file (sd, myname, callback, prog, abfd, sim_kind == SIM_OPEN_DEBUG, 0, sim_write); + + /* Set the bfd machine type. */ + if (prog_bfd) + saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd); + else if (abfd) + saved_state.asregs.bfd_mach = bfd_get_mach (abfd); + else + saved_state.asregs.bfd_mach = 0; + if (prog_bfd == NULL) return SIM_RC_FAIL; if (abfd == NULL) @@ -2179,18 +2714,22 @@ sim_load (sd, prog, abfd, from_tty) SIM_RC sim_create_inferior (sd, prog_bfd, argv, env) SIM_DESC sd; - struct _bfd *prog_bfd; + struct bfd *prog_bfd; char **argv; char **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); + /* Set the bfd machine type. */ + if (prog_bfd != NULL) + saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd); + /* Record the program's arguments. */ prog_argv = argv; @@ -2200,9 +2739,9 @@ sim_create_inferior (sd, prog_bfd, argv, env) void sim_do_command (sd, cmd) SIM_DESC sd; - char *cmd; + const char *cmd; { - char *sms_cmd = "set-memory-size"; + const char *sms_cmd = "set-memory-size"; int cmdsize; if (cmd == NULL || *cmd == '\0') @@ -2211,13 +2750,15 @@ 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); } 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 -- Set the number of address bits to use\n"); (callback->printf_filtered) (callback, "\n"); } @@ -2233,3 +2774,9 @@ sim_set_callbacks (p) { callback = p; } + +char ** +sim_complete_command (SIM_DESC sd, const char *text, const char *word) +{ + return NULL; +}