From 7fc5b5adca549dda57f47043626d22c3f1e94430 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Wed, 9 Feb 2000 05:08:42 +0000 Subject: [PATCH] Report SIGBUS and halt simulation when ld/st detect a misaligned address. --- sim/common/ChangeLog | 5 +++ sim/common/run.c | 16 ++++++---- sim/d10v/d10v_sim.h | 1 + sim/d10v/interp.c | 37 +++++++++++++++++++-- sim/d10v/simops.c | 76 +++++++++++++++++++++++++------------------- 5 files changed, 95 insertions(+), 40 deletions(-) diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index 3d190a5209..9aeba03429 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -151,6 +151,11 @@ Mon Sep 20 21:44:06 1999 Geoffrey Keating * sim-fpu.c (i2fpu): Keep the guard bits sticky when converting large values. +Tue Feb 8 16:33:48 2000 Andrew Cagney + + * run.c (main): Check the sim_stop_reason and only halt simulation + when a valid stop condition is identified. + Wed Sep 15 14:12:37 1999 Andrew Cagney * hw-tree.c, hw-properties.c, hw-instances.c: Include "sim-io.h". diff --git a/sim/common/run.c b/sim/common/run.c index a3e38a8e0b..1a4e96908f 100644 --- a/sim/common/run.c +++ b/sim/common/run.c @@ -231,26 +231,30 @@ main (ac, av) if (sim_create_inferior (sd, abfd, prog_args, NULL) == SIM_RC_FAIL) exit (1); - prev_sigint = signal (SIGINT, cntrl_c); if (trace) { int done = 0; + prev_sigint = signal (SIGINT, cntrl_c); while (!done) { done = sim_trace (sd); } + signal (SIGINT, prev_sigint); } else { - sim_resume (sd, 0, 0); + do + { + prev_sigint = signal (SIGINT, cntrl_c); + sim_resume (sd, 0, sigrc); + signal (SIGINT, prev_sigint); + sim_stop_reason (sd, &reason, &sigrc); + } + while (reason == sim_stopped && sigrc != SIGINT); } - signal (SIGINT, prev_sigint); if (verbose) sim_info (sd, 0); - - sim_stop_reason (sd, &reason, &sigrc); - sim_close (sd, 0); /* If reason is sim_exited, then sigrc holds the exit code which we want diff --git a/sim/d10v/d10v_sim.h b/sim/d10v/d10v_sim.h index 5cf43e2dfc..3566da01d2 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 33b5dca30a..80898ab44e 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 23bc9dacec..cb0fa56c88 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; }