aboutsummaryrefslogtreecommitdiff
path: root/sim/sh
diff options
context:
space:
mode:
authorStan Shebs <shebs@codesourcery.com>1999-04-26 18:34:20 +0000
committerStan Shebs <shebs@codesourcery.com>1999-04-26 18:34:20 +0000
commit7a292a7adf506b866905b06b3024c0fd411c4583 (patch)
tree5b208bb48269b8a82d5c3a5f19c87b45a62a22f4 /sim/sh
parent1996fae84682e8ddd146215dd2959ad1ec924c09 (diff)
downloadfsf-binutils-gdb-7a292a7adf506b866905b06b3024c0fd411c4583.zip
fsf-binutils-gdb-7a292a7adf506b866905b06b3024c0fd411c4583.tar.gz
fsf-binutils-gdb-7a292a7adf506b866905b06b3024c0fd411c4583.tar.bz2
import gdb-19990422 snapshot
Diffstat (limited to 'sim/sh')
-rw-r--r--sim/sh/ChangeLog54
-rw-r--r--sim/sh/gencode.c168
-rw-r--r--sim/sh/interp.c237
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))
{