diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2011-01-11 16:13:34 +0100 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2011-01-11 17:25:24 +0100 |
commit | 86865c5ff16bd1a2ef2b9ce217a7bb8f39e2126c (patch) | |
tree | beba6e94dc1b7b7eea1425dfedf961f3134e6e39 | |
parent | 05bf441eb69a813d3893174d54faa6afa8c0d39b (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.c | 28 |
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; } |