target-sh4: fix fpu disabled/illegal exception
authorAurelien Jarno <aurelien@aurel32.net>
Tue, 11 Jan 2011 15:13:34 +0000 (16:13 +0100)
committerAurelien Jarno <aurelien@aurel32.net>
Tue, 11 Jan 2011 16:25:24 +0000 (17:25 +0100)
Illegal instructions in a slot delay should generate a slot illegal
instruction exception instead of an illegal instruction exception.

The current PC should be saved before generating such an exception,
but should not be corrected if in a delay slot, given it's already
done in the exception handler do_interrupt().

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
target-sh4/translate.c

index f418139..37915d5 100644 (file)
@@ -469,27 +469,30 @@ 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-2);                    \
+      tcg_gen_movi_i32(cpu_pc, ctx->pc);                      \
       gen_helper_raise_slot_illegal_instruction();            \
       ctx->bstate = BS_EXCP;                                  \
       return;                                                 \
   }
 
-#define CHECK_PRIVILEGED                                      \
-  if (IS_USER(ctx)) {                                         \
-      tcg_gen_movi_i32(cpu_pc, ctx->pc);                      \
-      gen_helper_raise_illegal_instruction();                 \
-      ctx->bstate = BS_EXCP;                                  \
-      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();           \
+      } else {                                                  \
+         gen_helper_raise_illegal_instruction();                \
+      }                                                         \
+      ctx->bstate = BS_EXCP;                                    \
+      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)) { \
-          tcg_gen_movi_i32(cpu_pc, ctx->pc-2);                  \
           gen_helper_raise_slot_fpu_disable();                  \
       } else {                                                  \
-          tcg_gen_movi_i32(cpu_pc, ctx->pc);                    \
           gen_helper_raise_fpu_disable();                       \
       }                                                         \
       ctx->bstate = BS_EXCP;                                    \
@@ -1860,7 +1863,12 @@ static void _decode_opc(DisasContext * ctx)
            ctx->opcode, ctx->pc);
     fflush(stderr);
 #endif
-    gen_helper_raise_illegal_instruction();
+    tcg_gen_movi_i32(cpu_pc, ctx->pc);
+    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
+       gen_helper_raise_slot_illegal_instruction();
+    } else {
+       gen_helper_raise_illegal_instruction();
+    }
     ctx->bstate = BS_EXCP;
 }