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>
This commit is contained in:
Aurelien Jarno 2011-01-14 20:39:18 +01:00
parent 17075f10ff
commit fd4bab102c
2 changed files with 12 additions and 15 deletions

View File

@ -83,28 +83,31 @@ void helper_ldtlb(void)
#endif #endif
} }
static inline void raise_exception(int index, void *retaddr)
{
env->exception_index = index;
cpu_restore_state_from_retaddr(retaddr);
cpu_loop_exit();
}
void helper_raise_illegal_instruction(void) void helper_raise_illegal_instruction(void)
{ {
env->exception_index = 0x180; raise_exception(0x180, GETPC());
cpu_loop_exit();
} }
void helper_raise_slot_illegal_instruction(void) void helper_raise_slot_illegal_instruction(void)
{ {
env->exception_index = 0x1a0; raise_exception(0x1a0, GETPC());
cpu_loop_exit();
} }
void helper_raise_fpu_disable(void) void helper_raise_fpu_disable(void)
{ {
env->exception_index = 0x800; raise_exception(0x800, GETPC());
cpu_loop_exit();
} }
void helper_raise_slot_fpu_disable(void) void helper_raise_slot_fpu_disable(void)
{ {
env->exception_index = 0x820; raise_exception(0x820, GETPC());
cpu_loop_exit();
} }
void helper_debug(void) void helper_debug(void)
@ -124,8 +127,7 @@ void helper_sleep(uint32_t next_pc)
void helper_trapa(uint32_t tra) void helper_trapa(uint32_t tra)
{ {
env->tra = tra << 2; env->tra = tra << 2;
env->exception_index = 0x160; raise_exception(0x160, GETPC());
cpu_loop_exit();
} }
void helper_movcal(uint32_t address, uint32_t value) void helper_movcal(uint32_t address, uint32_t value)

View File

@ -471,7 +471,6 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
#define CHECK_NOT_DELAY_SLOT \ #define CHECK_NOT_DELAY_SLOT \
if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
{ \ { \
tcg_gen_movi_i32(cpu_pc, ctx->pc); \
gen_helper_raise_slot_illegal_instruction(); \ gen_helper_raise_slot_illegal_instruction(); \
ctx->bstate = BS_EXCP; \ ctx->bstate = BS_EXCP; \
return; \ return; \
@ -479,7 +478,6 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
#define CHECK_PRIVILEGED \ #define CHECK_PRIVILEGED \
if (IS_USER(ctx)) { \ if (IS_USER(ctx)) { \
tcg_gen_movi_i32(cpu_pc, ctx->pc); \
if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
gen_helper_raise_slot_illegal_instruction(); \ gen_helper_raise_slot_illegal_instruction(); \
} else { \ } else { \
@ -491,7 +489,6 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
#define CHECK_FPU_ENABLED \ #define CHECK_FPU_ENABLED \
if (ctx->flags & SR_FD) { \ if (ctx->flags & SR_FD) { \
tcg_gen_movi_i32(cpu_pc, ctx->pc); \
if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
gen_helper_raise_slot_fpu_disable(); \ gen_helper_raise_slot_fpu_disable(); \
} else { \ } else { \
@ -1380,7 +1377,6 @@ static void _decode_opc(DisasContext * ctx)
{ {
TCGv imm; TCGv imm;
CHECK_NOT_DELAY_SLOT CHECK_NOT_DELAY_SLOT
tcg_gen_movi_i32(cpu_pc, ctx->pc);
imm = tcg_const_i32(B7_0); imm = tcg_const_i32(B7_0);
gen_helper_trapa(imm); gen_helper_trapa(imm);
tcg_temp_free(imm); tcg_temp_free(imm);
@ -1888,7 +1884,6 @@ static void _decode_opc(DisasContext * ctx)
ctx->opcode, ctx->pc); ctx->opcode, ctx->pc);
fflush(stderr); fflush(stderr);
#endif #endif
tcg_gen_movi_i32(cpu_pc, ctx->pc);
if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
gen_helper_raise_slot_illegal_instruction(); gen_helper_raise_slot_illegal_instruction();
} else { } else {