diff options
author | Stan Shebs <shebs@codesourcery.com> | 1999-04-26 18:34:20 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1999-04-26 18:34:20 +0000 |
commit | 7a292a7adf506b866905b06b3024c0fd411c4583 (patch) | |
tree | 5b208bb48269b8a82d5c3a5f19c87b45a62a22f4 /sim/sh | |
parent | 1996fae84682e8ddd146215dd2959ad1ec924c09 (diff) | |
download | gdb-7a292a7adf506b866905b06b3024c0fd411c4583.zip gdb-7a292a7adf506b866905b06b3024c0fd411c4583.tar.gz gdb-7a292a7adf506b866905b06b3024c0fd411c4583.tar.bz2 |
import gdb-19990422 snapshot
Diffstat (limited to 'sim/sh')
-rw-r--r-- | sim/sh/ChangeLog | 54 | ||||
-rw-r--r-- | sim/sh/gencode.c | 168 | ||||
-rw-r--r-- | sim/sh/interp.c | 237 |
3 files changed, 431 insertions, 28 deletions
diff --git a/sim/sh/ChangeLog b/sim/sh/ChangeLog index 1939d18..61de57b 100644 --- a/sim/sh/ChangeLog +++ b/sim/sh/ChangeLog @@ -1,3 +1,10 @@ +1999-04-02 Keith Seitz <keiths@cygnus.com> + + * interp.c (POLL_QUIT_INTERVAL): Define. Used to tweak the + frequency at which the poll_quit callback is called. + (sim_resume): Use POLL_QUIT_INTERVAL instead of a + hard-coded value. + Thu Sep 10 02:16:39 1997 J"orn Rennecke <amylaar@cygnus.co.uk> * interp.c (saved_state.asregs): Add new member pad_dummy. @@ -143,16 +150,51 @@ Mon Jun 23 15:49:14 1997 Andrew Cagney <cagney@b1.cygnus.com> FP's around. (set_dr): Ditto. +Mon Jun 23 15:02:40 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * interp.c (XD, SET_XD): Delete. + (XF, SET_XF, XD_TO_XF): Define, move around registers in either + FP bank. + + * gencode.c (fmov): Update. + Sun Jun 22 19:33:33 1997 Andrew Cagney <cagney@b1.cygnus.com> * interp.c (set_fpscr1): From J"orn Rennecke <amylaar@cygnus.co.uk>, Fix typo. Ditto for comment. +Tue Aug 12 00:19:11 1997 J"orn Rennecke <amylaar@cygnus.co.uk> + + * interp.c (special_address): New function. + (BUSERROR): Call it. Added parameters bits_written and data. + Changed all callers. + * gencode.c (tab): Fixed ocbwb and pref. + +Fri Jun 20 22:03:18 1997 J"orn Rennecke <amylaar@cygnus.co.uk> + + * interp.c (do_wdat, do_wdat): Fix bug in register number calculation. + Thu Jun 19 00:28:08 1997 Andrew Cagney <cagney@b1.cygnus.com> * interp.c (sim_create_inferior): Clear registers each time an inferior is started. +Mon Jun 16 14:01:55 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * interp.c (*FP, FP_OP, FP_CMP, FP_UNARY): Provide a hook for + when a host doesn't support IEEE FP. + (*DP): Provide alternative definition that supports 64bit floating + point. + (target_little_endian): Combine little_endian and little_endian_p. + (saved_state_type): Make fpscr and sr simple integers. + (SET_FPSCR, GET_FPSCR): Use macros to update fpscr register. + (set_fpscr1): New function. Handle swapping when PR / FR bits + changed. Call via *_FPSCR macro. + (SET_SR*, GET_SR*): Use macro's to access the SR bits - avoids + endian problems. + + * gencode.c (tab): Update. + Sun Jun 15 15:22:52 1997 Andrew Cagney <cagney@b1.cygnus.com> * gencode.c (main): Perform basic checks on tab entries. @@ -185,10 +227,22 @@ Fri Jun 13 15:33:53 1997 J"orn Rennecke <amylaar@cygnus.co.uk> * interp.c (init_pointers): Fix little endian test. +Thu Jun 5 12:56:08 1997 J"orn Rennecke <amylaar@cygnus.co.uk> + + * interp.c (init_pointers): SH4 hardware is always WORDS_BIT_ENDIAN. + * gencode (fmov from/to memory): take endian_mismatch into account + for 32 bit moves too. + Wed May 28 23:42:35 1997 J"orn Rennecke <amylaar@cygnus.co.uk> * gencode.c (swap.b): Fix treatment of high word. +Wed May 28 23:42:35 1997 J"orn Rennecke <amylaar@cygnus.co.uk> + + * sh/gencode.c, + * interp.c: experimental SH4 support. + DFmode moves are probaly broken for target little endian. + Tue May 20 10:23:28 1997 Andrew Cagney <cagney@b1.cygnus.com> * interp.c (sim_open): Add callback argument. diff --git a/sim/sh/gencode.c b/sim/sh/gencode.c index 338b934..be10e59 100644 --- a/sim/sh/gencode.c +++ b/sim/sh/gencode.c @@ -244,12 +244,43 @@ op tab[] = "FP_CMP (n, >, m);", }, + /* sh4 */ + { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101", + "if (! FPSCR_PR || n & 1)", + " saved_state.asregs.exception = SIGILL;", + "else", + "{", + " char buf[4];", + " *(float *)buf = DR(n);", + " FPUL = *(int *)buf;", + "}", + }, + + /* sh4 */ + { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101", + "if (! FPSCR_PR || n & 1)", + " saved_state.asregs.exception = SIGILL;", + "else", + "{", + " char buf[4];", + " *(int *)buf = FPUL;", + " SET_DR(n, *(float *)buf);", + "}", + }, + /* sh3e */ { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011", "FP_OP (n, /, m);", "/* FIXME: check for DP and (n & 1) == 0? */", }, + /* sh4 */ + { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101", + "/* FIXME: not implemented */", + "saved_state.asregs.exception = SIGILL;", + "/* FIXME: check for DP and (n & 1) == 0? */", + }, + /* sh3e */ { "", "", "fldi0 <FREG_N>", "1111nnnn10001101", "SET_FR (n, (float)0.0);", @@ -271,6 +302,10 @@ op tab[] = /* sh3e */ { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101", + /* sh4 */ + "if (FPSCR_PR)", + " SET_DR (n, (double)FPUL);", + "else", "{", " SET_FR (n, (float)FPUL);", "}", @@ -284,12 +319,26 @@ op tab[] = /* sh3e */ { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100", + /* sh4 */ + "if (FPSCR_SZ) {", + " int ni = XD_TO_XF (n);", + " int mi = XD_TO_XF (m);", + " SET_XF (ni + 0, XF (mi + 0));", + " SET_XF (ni + 1, XF (mi + 1));", + "}", + "else", "{", " SET_FR (n, FR (m));", "}", }, /* sh3e */ { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010", + /* sh4 */ + "if (FPSCR_SZ) {", + " MA (2);", + " WDAT (R[n], m);", + "}", + "else", "{", " MA (1);", " WLAT (R[n], FI(m));", @@ -297,6 +346,12 @@ op tab[] = }, /* sh3e */ { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000", + /* sh4 */ + "if (FPSCR_SZ) {", + " MA (2);", + " RDAT (R[m], n);", + "}", + "else", "{", " MA (1);", " SET_FI(n, RLAT(R[m]));", @@ -304,6 +359,13 @@ op tab[] = }, /* sh3e */ { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001", + /* sh4 */ + "if (FPSCR_SZ) {", + " MA (2);", + " RDAT (R[m], n);", + " R[m] += 8;", + "}", + "else", "{", " MA (1);", " SET_FI (n, RLAT (R[m]));", @@ -312,6 +374,13 @@ op tab[] = }, /* sh3e */ { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011", + /* sh4 */ + "if (FPSCR_SZ) {", + " MA (2);", + " R[n] -= 8;", + " WDAT (R[n], m);", + "}", + "else", "{", " MA (1);", " R[n] -= 4;", @@ -320,6 +389,12 @@ op tab[] = }, /* sh3e */ { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110", + /* sh4 */ + "if (FPSCR_SZ) {", + " MA (2);", + " RDAT (R[0]+R[m], n);", + "}", + "else", "{", " MA (1);", " SET_FI(n, RLAT(R[0] + R[m]));", @@ -327,12 +402,20 @@ op tab[] = }, /* sh3e */ { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111", + /* sh4 */ + "if (FPSCR_SZ) {", + " MA (2);", + " WDAT (R[0]+R[n], m);", + "}", + "else", "{", " MA (1);", " WLAT((R[0]+R[n]), FI(m));", "}", }, + /* sh4: See fmov instructions above for move to/from extended fp registers */ + /* sh3e */ { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010", "FP_OP(n, *, m);", @@ -343,6 +426,16 @@ op tab[] = "FP_UNARY(n, -);", }, + /* sh4 */ + { "", "", "frchg", "1111101111111101", + "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);", + }, + + /* sh4 */ + { "", "", "fschg", "1111001111111101", + "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);", + }, + /* sh3e */ { "", "", "fsqrt <FREG_N>", "1111nnnn01101101", "FP_UNARY(n, sqrt);", @@ -355,6 +448,14 @@ op tab[] = /* sh3e */ { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101", + /* sh4 */ + "if (FPSCR_PR) {", + " if (DR(n) != DR(n)) /* NaN */", + " FPUL = 0x80000000;", + " else", + " FPUL = (int)DR(n);", + "}", + "else", "if (FR(n) != FR(n)) /* NaN */", " FPUL = 0x80000000;", "else", @@ -362,10 +463,6 @@ op tab[] = }, /* sh3e */ - { "", "", "ftst/nan <FREG_N>", "1111nnnn01111101", - "SET_SR_T (isnan (FR(n)));", - }, - /* sh3e */ { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101", "char buf[4];", "*(int *)buf = FPUL;", @@ -405,6 +502,12 @@ op tab[] = "SPC = R[n];", "/* FIXME: user mode */", }, +#if 0 + { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010", + "DBR = R[n];", + "/* FIXME: user mode */", + }, +#endif { "", "n", "ldc <REG_N>,R0_BANK", "0100nnnn10001110", "SET_Rn_BANK (0, R[n]);", "/* FIXME: user mode */", @@ -467,6 +570,14 @@ op tab[] = "R[n] += 4;", "/* FIXME: user mode */", }, +#if 0 + { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110", + "MA (1);", + "DBR = RLAT (R[n]);", + "R[n] += 4;", + "/* FIXME: user mode */", + }, +#endif { "", "n", "ldc.l @<REG_N>+,R0_BANK", "0100nnnn10000111", "MA (1);", "SET_Rn_BANK (0, RLAT (R[n]));", @@ -740,6 +851,11 @@ op tab[] = "R0 = ((i + 4 + PC) & ~0x3);", }, + { "0", "", "movca.l @R0, <REG_N>", "0000nnnn11000011", + "/* FIXME: Not implemented */", + "saved_state.asregs.exception = SIGILL;", + }, + { "n", "", "movt <REG_N>", "0000nnnn00101001", "R[n] = T;", }, @@ -783,6 +899,21 @@ op tab[] = "R[n] = ~R[m];", }, + { "0", "", "ocbi @<REG_N>", "0000nnnn10010011", + "/* FIXME: Not implemented */", + "saved_state.asregs.exception = SIGILL;", + }, + + { "0", "", "ocbp @<REG_N>", "0000nnnn10100011", + "/* FIXME: Not implemented */", + "saved_state.asregs.exception = SIGILL;", + }, + + { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011", + "RSBAT (R[n]); /* Take exceptions like byte load. */", + "/* FIXME: Cache not implemented */", + }, + { "0", "", "or #<imm>,R0", "11001011i8*1....", "R0 |= i;", }, @@ -920,6 +1051,14 @@ op tab[] = { "n", "", "stc SPC,<REG_N>", "0000nnnn01000010", "R[n] = SPC;", }, +#if 0 + { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010", + "R[n] = SGR;", + }, + { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010", + "R[n] = DBR;", + }, +#endif { "n", "", "stc R0_BANK,<REG_N>", "0000nnnn10000010", "R[n] = Rn_BANK (0);", }, @@ -969,6 +1108,18 @@ op tab[] = "R[n] -= 4;", "WLAT (R[n], SPC);", }, +#if 0 + { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010", + "MA (1);", + "R[n] -= 4;", + "WLAT (R[n], SGR);", + }, + { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010", + "MA (1);", + "R[n] -= 4;", + "WLAT (R[n], DBR);", + }, +#endif { "n", "", "stc R0_BANK,@-<REG_N>", "0100nnnn10000010", "MA (1);", "R[n] -= 4;", @@ -1153,6 +1304,15 @@ op tab[] = " | ((R[m] << 16) & 0xffff0000));", }, +#if 0 + { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110", + "divl(0,R[n],R[m]);", + }, + { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101", + "divl(0,R[n],R[m]);", + }, +#endif + {0, 0}}; /* Tables of things to put into enums for sh-opc.h */ diff --git a/sim/sh/interp.c b/sim/sh/interp.c index bd26967..4d7c5cf 100644 --- a/sim/sh/interp.c +++ b/sim/sh/interp.c @@ -56,11 +56,19 @@ #define DEFINE_TABLE #define DISASSEMBLER_TABLE +/* Define the rate at which the simulator should poll the host + for a quit. */ +#define POLL_QUIT_INTERVAL 0x60000 + typedef union { struct { + /* On targets like sparc-sun-solaris, fregs will be aligned on a 64 bit + boundary (because of the d member). To avoid padding between + registers - which whould make the job of sim_fetch_register harder, + we add padding at the start. */ int pad_dummy; int regs[16]; int pc; @@ -84,7 +92,7 @@ typedef union double d[8]; int i[16]; } - fregs; + fregs[2]; int ssr; int spc; @@ -221,9 +229,34 @@ set_sr (new_sr) /* Manipulate FPSCR */ -#define set_fpscr1(x) -#define SET_FPSCR(x) (saved_state.asregs.fpscr = (x)) +#define FPSCR_MASK_FR (1 << 21) +#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) + +static void +set_fpscr1 (x) + int x; +{ + int old = saved_state.asregs.fpscr; + saved_state.asregs.fpscr = (x); + /* swap the floating point register banks */ + if ((saved_state.asregs.fpscr ^ old) & FPSCR_MASK_FR) + { + union fregs_u tmpf = saved_state.asregs.fregs[0]; + saved_state.asregs.fregs[0] = saved_state.asregs.fregs[1]; + saved_state.asregs.fregs[1] = tmpf; + } +} + #define GET_FPSCR() (saved_state.asregs.fpscr) +#define SET_FPSCR(x) \ +do { \ + set_fpscr1 (x); \ +} while (0) int @@ -232,6 +265,21 @@ fail () abort (); } +int +special_address (addr, bits_written, data) + void *addr; + int bits_written, data; +{ + if ((unsigned) addr >> 24 == 0xf0 && bits_written == 32 && (data & 1) == 0) + /* This invalidates (if not associative) or might invalidate + (if associative) an instruction cache line. This is used for + trampolines. Since we don't simulate the cache, this is a no-op + as far as the simulator is concerned. */ + return 1; + /* We can't do anything useful with the other stuff, so fail. */ + return 0; +} + /* This function exists solely for the purpose of setting a breakpoint to catch simulated bus errors when running the simulator under GDB. */ @@ -244,8 +292,14 @@ bp_holder () being implemented by ../common/sim_resume.c and the below should make a call to sim_engine_halt */ -#define BUSERROR(addr, mask) \ - if (addr & ~mask) { saved_state.asregs.exception = SIGBUS; bp_holder (); } +#define BUSERROR(addr, mask, bits_written, data) \ + if (addr & ~mask) \ + { \ + if (special_address (addr, bits_written, data)) \ + return; \ + saved_state.asregs.exception = SIGBUS; \ + bp_holder (); \ + } /* Define this to enable register lifetime checking. The compiler generates "add #0,rn" insns to mark registers as invalid, @@ -276,15 +330,98 @@ static host_callback *callback; /* Floating point registers */ -#define FI(n) (saved_state.asregs.fregs.i[(n)]) -#define FR(n) (saved_state.asregs.fregs.f[(n)]) +#define DR(n) (get_dr (n)) +static double +get_dr (n) + int n; +{ + n = (n & ~1); + if (host_little_endian) + { + union + { + int i[2]; + double d; + } dr; + dr.i[1] = saved_state.asregs.fregs[0].i[n + 0]; + dr.i[0] = saved_state.asregs.fregs[0].i[n + 1]; + return dr.d; + } + else + return (saved_state.asregs.fregs[0].d[n >> 1]); +} + +#define SET_DR(n, EXP) set_dr ((n), (EXP)) +static void +set_dr (n, exp) + int n; + double exp; +{ + n = (n & ~1); + if (host_little_endian) + { + union + { + int i[2]; + double d; + } dr; + dr.d = exp; + saved_state.asregs.fregs[0].i[n + 0] = dr.i[1]; + saved_state.asregs.fregs[0].i[n + 1] = dr.i[0]; + } + else + saved_state.asregs.fregs[0].d[n >> 1] = exp; +} + +#define SET_FI(n,EXP) (saved_state.asregs.fregs[0].i[(n)] = (EXP)) +#define FI(n) (saved_state.asregs.fregs[0].i[(n)]) -#define SET_FI(n,EXP) (saved_state.asregs.fregs.i[(n)] = (EXP)) -#define SET_FR(n,EXP) (saved_state.asregs.fregs.f[(n)] = (EXP)) +#define FR(n) (saved_state.asregs.fregs[0].f[(n)]) +#define SET_FR(n,EXP) (saved_state.asregs.fregs[0].f[(n)] = (EXP)) -#define FP_OP(n, OP, m) (SET_FR(n, (FR(n) OP FR(m)))) -#define FP_UNARY(n, OP) (SET_FR(n, (OP (FR(n))))) -#define FP_CMP(n, OP, m) SET_SR_T(FR(n) OP FR(m)) +#define XD_TO_XF(n) ((((n) & 1) << 5) | ((n) & 0x1e)) +#define XF(n) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f]) +#define SET_XF(n,EXP) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f] = (EXP)) + + +#define FP_OP(n, OP, m) \ +{ \ + if (FPSCR_PR) \ + { \ + if (((n) & 1) || ((m) & 1)) \ + saved_state.asregs.exception = SIGILL; \ + else \ + SET_DR(n, (DR(n) OP DR(m))); \ + } \ + else \ + SET_FR(n, (FR(n) OP FR(m))); \ +} while (0) + +#define FP_UNARY(n, OP) \ +{ \ + if (FPSCR_PR) \ + { \ + if ((n) & 1) \ + saved_state.asregs.exception = SIGILL; \ + else \ + SET_DR(n, (OP (DR(n)))); \ + } \ + else \ + SET_FR(n, (OP (FR(n)))); \ +} while (0) + +#define FP_CMP(n, OP, m) \ +{ \ + if (FPSCR_PR) \ + { \ + if (((n) & 1) || ((m) & 1)) \ + saved_state.asregs.exception = SIGILL; \ + else \ + SET_SR_T (DR(n) OP DR(m)); \ + } \ + else \ + SET_SR_T (FR(n) OP FR(m)); \ +} while (0) @@ -294,7 +431,7 @@ wlat_little (memory, x, value, maskl) { int v = value; unsigned char *p = memory + ((x) & maskl); - BUSERROR(x, maskl); + BUSERROR(x, maskl, 32, v); p[3] = v >> 24; p[2] = v >> 16; p[1] = v >> 8; @@ -307,7 +444,7 @@ wwat_little (memory, x, value, maskw) { int v = value; unsigned char *p = memory + ((x) & maskw); - BUSERROR(x, maskw); + BUSERROR(x, maskw, 16, v); p[1] = v >> 8; p[0] = v; @@ -320,7 +457,7 @@ wbat_any (memory, x, value, maskb) unsigned char *p = memory + (x & maskb); if (x > 0x5000000) IOMEM (x, 1, value); - BUSERROR(x, maskb); + BUSERROR(x, maskb, 8, value); p[0] = value; } @@ -331,7 +468,7 @@ wlat_big (memory, x, value, maskl) { int v = value; unsigned char *p = memory + ((x) & maskl); - BUSERROR(x, maskl); + BUSERROR(x, maskl, 32, v); p[0] = v >> 24; p[1] = v >> 16; @@ -345,7 +482,7 @@ wwat_big (memory, x, value, maskw) { int v = value; unsigned char *p = memory + ((x) & maskw); - BUSERROR(x, maskw); + BUSERROR(x, maskw, 16, v); p[0] = v >> 8; p[1] = v; @@ -356,7 +493,7 @@ wbat_big (memory, x, value, maskb) unsigned char *memory; { unsigned char *p = memory + (x & maskb); - BUSERROR(x, maskb); + BUSERROR(x, maskb, 8, value); if (x > 0x5000000) IOMEM (x, 1, value); @@ -370,7 +507,7 @@ rlat_little (memory, x, maskl) unsigned char *memory; { unsigned char *p = memory + ((x) & maskl); - BUSERROR(x, maskl); + BUSERROR(x, maskl, -32, -1); return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]; } @@ -380,7 +517,7 @@ rwat_little (memory, x, maskw) unsigned char *memory; { unsigned char *p = memory + ((x) & maskw); - BUSERROR(x, maskw); + BUSERROR(x, maskw, -16, -1); return (p[1] << 8) | p[0]; } @@ -390,7 +527,7 @@ rbat_any (memory, x, maskb) unsigned char *memory; { unsigned char *p = memory + ((x) & maskb); - BUSERROR(x, maskb); + BUSERROR(x, maskb, -8, -1); return p[0]; } @@ -400,7 +537,7 @@ rlat_big (memory, x, maskl) unsigned char *memory; { unsigned char *p = memory + ((x) & maskl); - BUSERROR(x, maskl); + BUSERROR(x, maskl, -32, -1); return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; } @@ -410,7 +547,7 @@ rwat_big (memory, x, maskw) unsigned char *memory; { unsigned char *p = memory + ((x) & maskw); - BUSERROR(x, maskw); + BUSERROR(x, maskw, -16, -1); return (p[0] << 8) | p[1]; } @@ -426,7 +563,59 @@ rwat_big (memory, x, maskw) #define RSWAT(x) ((short)(RWAT(x))) #define RSBAT(x) (SEXT(RBAT(x))) +#define RDAT(x, n) (do_rdat (memory, (x), (n), (little_endian))) +static int +do_rdat (memory, x, n, little_endian) + char *memory; + int x; + int n; + int little_endian; +{ + int f0; + int f1; + int i = (n & 1); + int j = (n & ~1); + if (little_endian) + { + f0 = rlat_little (memory, x + 0, maskl); + f1 = rlat_little (memory, x + 4, maskl); + } + else + { + f0 = rlat_big (memory, x + 0, maskl); + f1 = rlat_big (memory, x + 4, maskl); + } + saved_state.asregs.fregs[i].i[(j + 0)] = f0; + saved_state.asregs.fregs[i].i[(j + 1)] = f1; + return 0; +} +#define WDAT(x, n) (do_wdat (memory, (x), (n), (little_endian))) +static int +do_wdat (memory, x, n, little_endian) + char *memory; + int x; + int n; + int little_endian; +{ + int f0; + int f1; + int i = (n & 1); + int j = (n & ~1); + f0 = saved_state.asregs.fregs[i].i[(j + 0)]; + f1 = saved_state.asregs.fregs[i].i[(j + 1)]; + if (little_endian) + { + wlat_little (memory, (x + 0), f0, maskl); + wlat_little (memory, (x + 4), f1, maskl); + } + else + { + wlat_big (memory, (x + 0), f0, maskl); + wlat_big (memory, (x + 4), f1, maskl); + } + return 0; +} #define MA(n) do { memstalls += (((pc & 3) != 0) ? (n) : ((n) - 1)); } while (0) @@ -1070,7 +1259,7 @@ sim_resume (sd, step, siggnal) if (--pollcount < 0) { - pollcount = 1000; + pollcount = POLL_QUIT_INTERVAL; if ((*callback->poll_quit) != NULL && (*callback->poll_quit) (callback)) { |