aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2011-01-14 20:39:18 +0100
committerAurelien Jarno <aurelien@aurel32.net>2011-01-14 20:39:18 +0100
commitfd4bab102c14171f8a5a6b04def6434b75a658a2 (patch)
tree33cfe40125bdc27090ab0acaffd3db31916c850f
parent17075f10ff9e2c8bd59ecbf9569421e437707e43 (diff)
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>
-rw-r--r--target-sh4/op_helper.c22
-rw-r--r--target-sh4/translate.c5
2 files changed, 12 insertions, 15 deletions
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index 525b0609cc..9d7652f3c7 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 65b6ea413c..69d507d864 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 {