target-sh4: optimize exceptions
authorAurelien Jarno <aurelien@aurel32.net>
Fri, 14 Jan 2011 19:39:18 +0000 (20:39 +0100)
committerAurelien Jarno <aurelien@aurel32.net>
Fri, 14 Jan 2011 19:39:18 +0000 (20:39 +0100)
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>
target-sh4/op_helper.c
target-sh4/translate.c

index 525b060..9d7652f 100644 (file)
@@ -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)
index 65b6ea4..69d507d 100644 (file)
@@ -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 {