diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2011-01-14 20:39:18 +0100 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2011-01-14 20:39:18 +0100 |
commit | fd4bab102c14171f8a5a6b04def6434b75a658a2 (patch) | |
tree | 33cfe40125bdc27090ab0acaffd3db31916c850f /target-sh4 | |
parent | 17075f10ff9e2c8bd59ecbf9569421e437707e43 (diff) | |
download | qemu-fd4bab102c14171f8a5a6b04def6434b75a658a2.zip qemu-fd4bab102c14171f8a5a6b04def6434b75a658a2.tar.gz qemu-fd4bab102c14171f8a5a6b04def6434b75a658a2.tar.bz2 |
target-sh4: optimize exceptions
As exception is not the normal path, don't bother saving PC, before
raising one, instead rely on code retranslation to get the CPU state.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-sh4')
-rw-r--r-- | target-sh4/op_helper.c | 22 | ||||
-rw-r--r-- | target-sh4/translate.c | 5 |
2 files changed, 12 insertions, 15 deletions
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c index 525b060..9d7652f 100644 --- a/target-sh4/op_helper.c +++ b/target-sh4/op_helper.c @@ -83,28 +83,31 @@ void helper_ldtlb(void) #endif } -void helper_raise_illegal_instruction(void) +static inline void raise_exception(int index, void *retaddr) { - env->exception_index = 0x180; + env->exception_index = index; + cpu_restore_state_from_retaddr(retaddr); cpu_loop_exit(); } +void helper_raise_illegal_instruction(void) +{ + raise_exception(0x180, GETPC()); +} + void helper_raise_slot_illegal_instruction(void) { - env->exception_index = 0x1a0; - cpu_loop_exit(); + raise_exception(0x1a0, GETPC()); } void helper_raise_fpu_disable(void) { - env->exception_index = 0x800; - cpu_loop_exit(); + raise_exception(0x800, GETPC()); } void helper_raise_slot_fpu_disable(void) { - env->exception_index = 0x820; - cpu_loop_exit(); + raise_exception(0x820, GETPC()); } void helper_debug(void) @@ -124,8 +127,7 @@ void helper_sleep(uint32_t next_pc) void helper_trapa(uint32_t tra) { env->tra = tra << 2; - env->exception_index = 0x160; - cpu_loop_exit(); + raise_exception(0x160, GETPC()); } void helper_movcal(uint32_t address, uint32_t value) diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 65b6ea4..69d507d 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -471,7 +471,6 @@ 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(); \ ctx->bstate = BS_EXCP; \ return; \ @@ -479,7 +478,6 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg) #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 { \ @@ -491,7 +489,6 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg) #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(); \ } else { \ @@ -1380,7 +1377,6 @@ 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(imm); tcg_temp_free(imm); @@ -1888,7 +1884,6 @@ 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(); } else { |