aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2011-01-11 16:13:34 +0100
committerAurelien Jarno <aurelien@aurel32.net>2011-01-11 17:25:24 +0100
commit86865c5ff16bd1a2ef2b9ce217a7bb8f39e2126c (patch)
treebeba6e94dc1b7b7eea1425dfedf961f3134e6e39
parent05bf441eb69a813d3893174d54faa6afa8c0d39b (diff)
target-sh4: fix fpu disabled/illegal exception
Illegal instructions in a slot delay should generate a slot illegal instruction exception instead of an illegal instruction exception. The current PC should be saved before generating such an exception, but should not be corrected if in a delay slot, given it's already done in the exception handler do_interrupt(). Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r--target-sh4/translate.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index f418139931..37915d5315 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -469,27 +469,30 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
#define CHECK_NOT_DELAY_SLOT \
if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
{ \
- tcg_gen_movi_i32(cpu_pc, ctx->pc-2); \
+ tcg_gen_movi_i32(cpu_pc, ctx->pc); \
gen_helper_raise_slot_illegal_instruction(); \
ctx->bstate = BS_EXCP; \
return; \
}
-#define CHECK_PRIVILEGED \
- if (IS_USER(ctx)) { \
- tcg_gen_movi_i32(cpu_pc, ctx->pc); \
- gen_helper_raise_illegal_instruction(); \
- ctx->bstate = BS_EXCP; \
- return; \
+#define CHECK_PRIVILEGED \
+ if (IS_USER(ctx)) { \
+ tcg_gen_movi_i32(cpu_pc, ctx->pc); \
+ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
+ gen_helper_raise_slot_illegal_instruction(); \
+ } else { \
+ gen_helper_raise_illegal_instruction(); \
+ } \
+ ctx->bstate = BS_EXCP; \
+ return; \
}
#define CHECK_FPU_ENABLED \
if (ctx->flags & SR_FD) { \
+ tcg_gen_movi_i32(cpu_pc, ctx->pc); \
if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
- tcg_gen_movi_i32(cpu_pc, ctx->pc-2); \
gen_helper_raise_slot_fpu_disable(); \
} else { \
- tcg_gen_movi_i32(cpu_pc, ctx->pc); \
gen_helper_raise_fpu_disable(); \
} \
ctx->bstate = BS_EXCP; \
@@ -1860,7 +1863,12 @@ static void _decode_opc(DisasContext * ctx)
ctx->opcode, ctx->pc);
fflush(stderr);
#endif
- gen_helper_raise_illegal_instruction();
+ tcg_gen_movi_i32(cpu_pc, ctx->pc);
+ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
+ gen_helper_raise_slot_illegal_instruction();
+ } else {
+ gen_helper_raise_illegal_instruction();
+ }
ctx->bstate = BS_EXCP;
}