aboutsummaryrefslogtreecommitdiff
path: root/sim/d10v
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2000-02-09 05:08:42 +0000
committerAndrew Cagney <cagney@redhat.com>2000-02-09 05:08:42 +0000
commit7fc5b5adca549dda57f47043626d22c3f1e94430 (patch)
treecdef0374ca62b628a043bf132ec07913b53edb2d /sim/d10v
parent489137c0360f94c18f650b810f1129569f3b3d70 (diff)
downloadfsf-binutils-gdb-7fc5b5adca549dda57f47043626d22c3f1e94430.zip
fsf-binutils-gdb-7fc5b5adca549dda57f47043626d22c3f1e94430.tar.gz
fsf-binutils-gdb-7fc5b5adca549dda57f47043626d22c3f1e94430.tar.bz2
Report SIGBUS and halt simulation when ld/st detect a misaligned address.
Diffstat (limited to 'sim/d10v')
-rw-r--r--sim/d10v/d10v_sim.h1
-rw-r--r--sim/d10v/interp.c37
-rw-r--r--sim/d10v/simops.c76
3 files changed, 80 insertions, 34 deletions
diff --git a/sim/d10v/d10v_sim.h b/sim/d10v/d10v_sim.h
index 5cf43e2..3566da0 100644
--- a/sim/d10v/d10v_sim.h
+++ b/sim/d10v/d10v_sim.h
@@ -395,6 +395,7 @@ enum
#define SIG_D10V_STOP -1
#define SIG_D10V_EXIT -2
+#define SIG_D10V_BUS -3
#define SEXT3(x) ((((x)&0x7)^(~3))+4)
diff --git a/sim/d10v/interp.c b/sim/d10v/interp.c
index 33b5dca..80898ab 100644
--- a/sim/d10v/interp.c
+++ b/sim/d10v/interp.c
@@ -965,6 +965,25 @@ sim_resume (sd, step, siggnal)
if (step)
sim_stop (sd);
+ switch (siggnal)
+ {
+ case 0:
+ break;
+#ifdef SIGBUS
+ case SIGBUS:
+#endif
+ case SIGSEGV:
+ SET_BPC (PC);
+ SET_BPSW (PSW);
+ SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
+ JMP (AE_VECTOR_START);
+ SLOT_FLUSH ();
+ break;
+ default:
+ /* just ignore it */
+ break;
+ }
+
do
{
iaddr = imem_addr ((uint32)PC << 2);
@@ -1057,11 +1076,16 @@ int
sim_trace (sd)
SIM_DESC sd;
{
+ enum sim_stop reason;
+ static int sigrc = 0;
#ifdef DEBUG
d10v_debug = DEBUG;
#endif
- sim_resume (sd, 0, 0);
- return 1;
+ /* NOTE: SIGRC starts with zero and is then, always the value
+ returned by the last sim_stop_reason() call. */
+ sim_resume (sd, 0, sigrc);
+ sim_stop_reason (sd, &reason, &sigrc);
+ return (reason != sim_stopped || sigrc != SIGINT);
}
void
@@ -1267,6 +1291,15 @@ sim_stop_reason (sd, reason, sigrc)
*sigrc = GPR (0);
break;
+ case SIG_D10V_BUS:
+ *reason = sim_stopped;
+#ifdef SIGBUS
+ *sigrc = SIGBUS;
+#else
+ *sigrc = SIGSEGV;
+#endif
+ break;
+
default: /* some signal */
*reason = sim_stopped;
if (stop_simulator && !State.exception)
diff --git a/sim/d10v/simops.c b/sim/d10v/simops.c
index 23bc9da..cb0fa56 100644
--- a/sim/d10v/simops.c
+++ b/sim/d10v/simops.c
@@ -118,16 +118,6 @@ move_to_cr (int cr, reg_t mask, reg_t val, int psw_hw_p)
return val;
}
-/* Modify registers according to an AE - address exception. */
-static void
-address_exception (void)
-{
- SET_BPC (PC);
- SET_BPSW (PSW);
- SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
- JMP (AE_VECTOR_START);
-}
-
#ifdef DEBUG
static void trace_input_func PARAMS ((char *name,
enum op_types in1,
@@ -1327,7 +1317,8 @@ OP_30000000 ()
trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -1345,7 +1336,8 @@ OP_6401 ()
trace_input ("ld", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -1365,7 +1357,8 @@ OP_6001 ()
trace_input ("ld", OP_REG_OUTPUT, OP_POSTINC, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -1385,7 +1378,8 @@ OP_6000 ()
trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -1403,7 +1397,8 @@ OP_32010000 ()
trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF3, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -1421,7 +1416,8 @@ OP_31000000 ()
trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -1439,7 +1435,8 @@ OP_6601 ()
trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -1459,7 +1456,8 @@ OP_6201 ()
trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTINC, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -1479,7 +1477,8 @@ OP_6200 ()
trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -1497,7 +1496,8 @@ OP_33010000 ()
trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF3, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2741,7 +2741,8 @@ OP_34000000 ()
trace_input ("st", OP_REG, OP_MEMREF2, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2757,7 +2758,8 @@ OP_6800 ()
trace_input ("st", OP_REG, OP_MEMREF, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2780,7 +2782,8 @@ OP_6C1F ()
}
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2797,7 +2800,8 @@ OP_6801 ()
trace_input ("st", OP_REG, OP_POSTINC, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2820,7 +2824,8 @@ OP_6C01 ()
}
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2837,7 +2842,8 @@ OP_36010000 ()
trace_input ("st", OP_REG, OP_MEMREF3, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2853,7 +2859,8 @@ OP_35000000 ()
trace_input ("st2w", OP_DREG, OP_MEMREF2, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2870,7 +2877,8 @@ OP_6A00 ()
trace_input ("st2w", OP_DREG, OP_MEMREF, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2893,7 +2901,8 @@ OP_6E1F ()
}
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2911,7 +2920,8 @@ OP_6A01 ()
trace_input ("st2w", OP_DREG, OP_POSTINC, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2935,7 +2945,8 @@ OP_6E01 ()
}
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}
@@ -2953,7 +2964,8 @@ OP_37010000 ()
trace_input ("st2w", OP_DREG, OP_MEMREF3, OP_VOID);
if ((addr & 1))
{
- address_exception ();
+ State.exception = SIG_D10V_BUS;
+ State.pc_changed = 1; /* Don't increment the PC. */
trace_output_void ();
return;
}