diff options
-rw-r--r-- | target-sh4/helper.h | 14 | ||||
-rw-r--r-- | target-sh4/op_helper.c | 30 | ||||
-rw-r--r-- | target-sh4/translate.c | 18 |
3 files changed, 32 insertions, 30 deletions
diff --git a/target-sh4/helper.h b/target-sh4/helper.h index a00b7dd1e7..6c1a47da9f 100644 --- a/target-sh4/helper.h +++ b/target-sh4/helper.h @@ -1,13 +1,13 @@ #include "def-helper.h" DEF_HELPER_1(ldtlb, void, env) -DEF_HELPER_1(raise_illegal_instruction, void, env) -DEF_HELPER_1(raise_slot_illegal_instruction, void, env) -DEF_HELPER_1(raise_fpu_disable, void, env) -DEF_HELPER_1(raise_slot_fpu_disable, void, env) -DEF_HELPER_1(debug, void, env) -DEF_HELPER_2(sleep, void, env, i32) -DEF_HELPER_2(trapa, void, env, i32) +DEF_HELPER_1(raise_illegal_instruction, noreturn, env) +DEF_HELPER_1(raise_slot_illegal_instruction, noreturn, env) +DEF_HELPER_1(raise_fpu_disable, noreturn, env) +DEF_HELPER_1(raise_slot_fpu_disable, noreturn, env) +DEF_HELPER_1(debug, noreturn, env) +DEF_HELPER_1(sleep, noreturn, env) +DEF_HELPER_2(trapa, noreturn, env, i32) DEF_HELPER_3(movcal, void, env, i32, i32) DEF_HELPER_1(discard_movcal_backup, void, env) diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c index 4f1f754680..60ec4cbc4d 100644 --- a/target-sh4/op_helper.c +++ b/target-sh4/op_helper.c @@ -21,7 +21,8 @@ #include "cpu.h" #include "helper.h" -static void cpu_restore_state_from_retaddr(CPUSH4State *env, uintptr_t retaddr) +static inline void cpu_restore_state_from_retaddr(CPUSH4State *env, + uintptr_t retaddr) { TranslationBlock *tb; @@ -77,8 +78,8 @@ void helper_ldtlb(CPUSH4State *env) #endif } -static inline void raise_exception(CPUSH4State *env, int index, - uintptr_t retaddr) +static inline void QEMU_NORETURN raise_exception(CPUSH4State *env, int index, + uintptr_t retaddr) { env->exception_index = index; cpu_restore_state_from_retaddr(env, retaddr); @@ -87,43 +88,40 @@ static inline void raise_exception(CPUSH4State *env, int index, void helper_raise_illegal_instruction(CPUSH4State *env) { - raise_exception(env, 0x180, GETPC()); + raise_exception(env, 0x180, 0); } void helper_raise_slot_illegal_instruction(CPUSH4State *env) { - raise_exception(env, 0x1a0, GETPC()); + raise_exception(env, 0x1a0, 0); } void helper_raise_fpu_disable(CPUSH4State *env) { - raise_exception(env, 0x800, GETPC()); + raise_exception(env, 0x800, 0); } void helper_raise_slot_fpu_disable(CPUSH4State *env) { - raise_exception(env, 0x820, GETPC()); + raise_exception(env, 0x820, 0); } void helper_debug(CPUSH4State *env) { - env->exception_index = EXCP_DEBUG; - cpu_loop_exit(env); + raise_exception(env, EXCP_DEBUG, 0); } -void helper_sleep(CPUSH4State *env, uint32_t next_pc) +void helper_sleep(CPUSH4State *env) { env->halted = 1; env->in_sleep = 1; - env->exception_index = EXCP_HLT; - env->pc = next_pc; - cpu_loop_exit(env); + raise_exception(env, EXCP_HLT, 0); } void helper_trapa(CPUSH4State *env, uint32_t tra) { env->tra = tra << 2; - raise_exception(env, 0x160, GETPC()); + raise_exception(env, 0x160, 0); } void helper_movcal(CPUSH4State *env, uint32_t address, uint32_t value) @@ -385,9 +383,7 @@ static void update_fpscr(CPUSH4State *env, uintptr_t retaddr) cause = (env->fpscr & FPSCR_CAUSE_MASK) >> FPSCR_CAUSE_SHIFT; enable = (env->fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT; if (cause & enable) { - cpu_restore_state_from_retaddr(env, retaddr); - env->exception_index = 0x120; - cpu_loop_exit(env); + raise_exception(env, 0x120, retaddr); } } } diff --git a/target-sh4/translate.c b/target-sh4/translate.c index cdc4e3bc5f..6305db80f7 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -427,30 +427,33 @@ 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); \ gen_helper_raise_slot_illegal_instruction(cpu_env); \ - ctx->bstate = BS_EXCP; \ + ctx->bstate = BS_BRANCH; \ 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(cpu_env); \ } else { \ gen_helper_raise_illegal_instruction(cpu_env); \ } \ - ctx->bstate = BS_EXCP; \ + ctx->bstate = BS_BRANCH; \ 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)) { \ gen_helper_raise_slot_fpu_disable(cpu_env); \ } else { \ gen_helper_raise_fpu_disable(cpu_env); \ } \ - ctx->bstate = BS_EXCP; \ + ctx->bstate = BS_BRANCH; \ return; \ } @@ -541,7 +544,8 @@ static void _decode_opc(DisasContext * ctx) return; case 0x001b: /* sleep */ CHECK_PRIVILEGED - gen_helper_sleep(cpu_env, tcg_const_i32(ctx->pc + 2)); + tcg_gen_movi_i32(cpu_pc, ctx->pc + 2); + gen_helper_sleep(cpu_env); return; } @@ -1411,6 +1415,7 @@ static void _decode_opc(DisasContext * ctx) { TCGv imm; CHECK_NOT_DELAY_SLOT + tcg_gen_movi_i32(cpu_pc, ctx->pc); imm = tcg_const_i32(B7_0); gen_helper_trapa(cpu_env, imm); tcg_temp_free(imm); @@ -1909,12 +1914,13 @@ static void _decode_opc(DisasContext * ctx) ctx->opcode, ctx->pc); fflush(stderr); #endif + tcg_gen_movi_i32(cpu_pc, ctx->pc); if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { gen_helper_raise_slot_illegal_instruction(cpu_env); } else { gen_helper_raise_illegal_instruction(cpu_env); } - ctx->bstate = BS_EXCP; + ctx->bstate = BS_BRANCH; } static void decode_opc(DisasContext * ctx) @@ -1992,7 +1998,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb, /* We have hit a breakpoint - make sure PC is up-to-date */ tcg_gen_movi_i32(cpu_pc, ctx.pc); gen_helper_debug(cpu_env); - ctx.bstate = BS_EXCP; + ctx.bstate = BS_BRANCH; break; } } |