diff mbox series

[4/5] target/mips: Use check_cp0_enabled() returned value

Message ID 20210420193453.1913810-5-f4bug@amsat.org (mailing list archive)
State New
Headers show
Series target/mips: Make check_cp0_enabled() return a boolean | expand

Commit Message

Philippe Mathieu-Daudé April 20, 2021, 7:34 p.m. UTC
If CP0 is disabled, it is pointless to emit more code,
since the 'coprocessor unusable' exception will be raised.
Use the returned value from check_cp0_enabled() to return
early.

Reported-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/translate.c | 144 +++++++++++++++++++++-------------------
 1 file changed, 76 insertions(+), 68 deletions(-)

Comments

Richard Henderson April 21, 2021, 1:43 a.m. UTC | #1
On 4/20/21 12:34 PM, Philippe Mathieu-Daudé wrote:
> @@ -14809,14 +14811,15 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
>           }
>           break;
>       case 0x05:
> +        if (!check_cp0_enabled(ctx)) {
> +            break;
> +        }
>           switch (minor) {
>           case RDPGPR:
> -            check_cp0_enabled(ctx);
>               check_insn(ctx, ISA_MIPS_R2);
>               gen_load_srsgpr(rs, rt);
>               break;
>           case WRPGPR:
> -            check_cp0_enabled(ctx);
>               check_insn(ctx, ISA_MIPS_R2);
>               gen_store_srsgpr(rs, rt);
>               break;

cp0 check before decode complete.  at least 2 more instances in this patch.


r~
diff mbox series

Patch

diff --git a/target/mips/translate.c b/target/mips/translate.c
index be5382b41f2..dfa26569077 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -9417,7 +9417,9 @@  static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
 {
     const char *opn = "ldst";
 
-    check_cp0_enabled(ctx);
+    if (!check_cp0_enabled(ctx)) {
+        return;
+    }
     switch (opc) {
     case OPC_MFC0:
         if (rt == 0) {
@@ -14651,17 +14653,17 @@  static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
 #ifndef CONFIG_USER_ONLY
     case MFC0:
     case MFC0 + 32:
-        check_cp0_enabled(ctx);
-        if (rt == 0) {
-            /* Treat as NOP. */
-            break;
+        if (check_cp0_enabled(ctx)) {
+            if (rt == 0) {
+                /* Treat as NOP. */
+                break;
+            }
+            gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
         }
-        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
         break;
     case MTC0:
     case MTC0 + 32:
-        check_cp0_enabled(ctx);
-        {
+        if (check_cp0_enabled(ctx)) {
             TCGv t0 = tcg_temp_new();
 
             gen_load_gpr(t0, rt);
@@ -14809,14 +14811,15 @@  static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
         }
         break;
     case 0x05:
+        if (!check_cp0_enabled(ctx)) {
+            break;
+        }
         switch (minor) {
         case RDPGPR:
-            check_cp0_enabled(ctx);
             check_insn(ctx, ISA_MIPS_R2);
             gen_load_srsgpr(rs, rt);
             break;
         case WRPGPR:
-            check_cp0_enabled(ctx);
             check_insn(ctx, ISA_MIPS_R2);
             gen_store_srsgpr(rs, rt);
             break;
@@ -14863,8 +14866,7 @@  static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
     case 0x1d:
         switch (minor) {
         case DI:
-            check_cp0_enabled(ctx);
-            {
+            if (check_cp0_enabled(ctx)) {
                 TCGv t0 = tcg_temp_new();
 
                 save_cpu_state(ctx, 1);
@@ -14879,8 +14881,7 @@  static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
             }
             break;
         case EI:
-            check_cp0_enabled(ctx);
-            {
+            if (check_cp0_enabled(ctx)) {
                 TCGv t0 = tcg_temp_new();
 
                 save_cpu_state(ctx, 1);
@@ -15449,8 +15450,7 @@  static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
         minor = (ctx->opcode >> 12) & 0xf;
         switch (minor) {
         case CACHE:
-            check_cp0_enabled(ctx);
-            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
+            if (check_cp0_enabled(ctx) && ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
                 gen_cache_operation(ctx, rt, rs, imm);
             }
             break;
@@ -16211,7 +16211,9 @@  static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
                 gen_reserved_instruction(ctx);
                 break;
             }
-            check_cp0_enabled(ctx);
+            if (!check_cp0_enabled(ctx)) {
+                break;
+            }
 
             minor2 = (ctx->opcode >> 9) & 0x7;
             offset = sextract32(ctx->opcode, 0, 9);
@@ -16250,7 +16252,9 @@  static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
                 gen_reserved_instruction(ctx);
                 break;
             }
-            check_cp0_enabled(ctx);
+            if (!check_cp0_enabled(ctx)) {
+                break;
+            }
 
             minor2 = (ctx->opcode >> 9) & 0x7;
             offset = sextract32(ctx->opcode, 0, 9);
@@ -17995,24 +17999,24 @@  static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
         if (rd == 0) {
             /* P_DVP */
 #ifndef CONFIG_USER_ONLY
-            TCGv t0 = tcg_temp_new();
-            switch (extract32(ctx->opcode, 10, 1)) {
-            case NM_DVP:
-                if (ctx->vp) {
-                    check_cp0_enabled(ctx);
-                    gen_helper_dvp(t0, cpu_env);
-                    gen_store_gpr(t0, rt);
+            if (check_cp0_enabled(ctx)) {
+                TCGv t0 = tcg_temp_new();
+                switch (extract32(ctx->opcode, 10, 1)) {
+                case NM_DVP:
+                    if (ctx->vp) {
+                        gen_helper_dvp(t0, cpu_env);
+                        gen_store_gpr(t0, rt);
+                    }
+                    break;
+                case NM_EVP:
+                    if (ctx->vp) {
+                        gen_helper_evp(t0, cpu_env);
+                        gen_store_gpr(t0, rt);
+                    }
+                    break;
                 }
-                break;
-            case NM_EVP:
-                if (ctx->vp) {
-                    check_cp0_enabled(ctx);
-                    gen_helper_evp(t0, cpu_env);
-                    gen_store_gpr(t0, rt);
-                }
-                break;
+                tcg_temp_free(t0);
             }
-            tcg_temp_free(t0);
 #endif
         } else {
             gen_slt(ctx, OPC_SLTU, rd, rs, rt);
@@ -18067,16 +18071,16 @@  static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
         break;
 #ifndef CONFIG_USER_ONLY
     case NM_MFC0:
-        check_cp0_enabled(ctx);
-        if (rt == 0) {
-            /* Treat as NOP. */
-            break;
+        if (check_cp0_enabled(ctx)) {
+            if (rt == 0) {
+                /* Treat as NOP. */
+                break;
+            }
+            gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
         }
-        gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
         break;
     case NM_MTC0:
-        check_cp0_enabled(ctx);
-        {
+        if (check_cp0_enabled(ctx)) {
             TCGv t0 = tcg_temp_new();
 
             gen_load_gpr(t0, rt);
@@ -18140,19 +18144,23 @@  static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
         break;
     case NM_MFTR:
     case NM_MFHTR:
-        check_cp0_enabled(ctx);
-        if (rd == 0) {
-            /* Treat as NOP. */
-            return;
+        if (check_cp0_enabled(ctx)) {
+            if (rd == 0) {
+                /* Treat as NOP. */
+                return;
+            }
+            gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
+                     extract32(ctx->opcode, 11, 5),
+                     extract32(ctx->opcode, 3, 1));
         }
-        gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
-                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
         break;
     case NM_MTTR:
     case NM_MTHTR:
-        check_cp0_enabled(ctx);
-        gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
-                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
+        if (check_cp0_enabled(ctx)) {
+            gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
+                     extract32(ctx->opcode, 11, 5),
+                     extract32(ctx->opcode, 3, 1));
+        }
         break;
     case NM_YIELD:
         check_mt(ctx);
@@ -18943,8 +18951,7 @@  static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
             gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
             break;
         case NM_DI:
-            check_cp0_enabled(ctx);
-            {
+            if (check_cp0_enabled(ctx)) {
                 TCGv t0 = tcg_temp_new();
 
                 save_cpu_state(ctx, 1);
@@ -18956,8 +18963,7 @@  static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
             }
             break;
         case NM_EI:
-            check_cp0_enabled(ctx);
-            {
+            if (check_cp0_enabled(ctx)) {
                 TCGv t0 = tcg_temp_new();
 
                 save_cpu_state(ctx, 1);
@@ -20900,15 +20906,17 @@  static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
                     }
                     break;
                 case NM_CACHE:
-                    check_cp0_enabled(ctx);
-                    if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
+                    if (check_cp0_enabled(ctx)
+                            && ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
                         gen_cache_operation(ctx, rt, rs, s);
                     }
                     break;
                 }
                 break;
             case NM_P_LS_E0:
-                check_cp0_enabled(ctx);
+                if (check_cp0_enabled(ctx)) {
+                    break;
+                }
                 switch (extract32(ctx->opcode, 11, 4)) {
                 case NM_LBE:
                     check_eva(ctx);
@@ -23770,8 +23778,7 @@  static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
         /* Treat as NOP. */
         break;
     case R6_OPC_CACHE:
-        check_cp0_enabled(ctx);
-        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
+        if (check_cp0_enabled(ctx) && ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
             gen_cache_operation(ctx, rt, rs, imm);
         }
         break;
@@ -23806,7 +23813,9 @@  static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
         if (unlikely(ctx->gi <= 1)) {
             gen_reserved_instruction(ctx);
         }
-        check_cp0_enabled(ctx);
+        if (!check_cp0_enabled(ctx)) {
+            break;
+        }
         switch ((ctx->opcode >> 6) & 3) {
         case 0:    /* GINVI */
             /* Treat as NOP. */
@@ -24493,6 +24502,9 @@  static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
      * EVA is absent.
      */
     if (ctx->eva) {
+        if (!check_cp0_enabled(ctx)) {
+            return;
+        }
         switch (op1) {
         case OPC_LWLE:
         case OPC_LWRE:
@@ -24502,7 +24514,6 @@  static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
         case OPC_LHE:
         case OPC_LLE:
         case OPC_LWE:
-            check_cp0_enabled(ctx);
             gen_ld(ctx, op1, rt, rs, imm);
             return;
         case OPC_SWLE:
@@ -24510,22 +24521,18 @@  static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
         case OPC_SBE:
         case OPC_SHE:
         case OPC_SWE:
-            check_cp0_enabled(ctx);
             gen_st(ctx, op1, rt, rs, imm);
             return;
         case OPC_SCE:
-            check_cp0_enabled(ctx);
             gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
             return;
         case OPC_CACHEE:
             check_eva(ctx);
-            check_cp0_enabled(ctx);
             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
                 gen_cache_operation(ctx, rt, rs, imm);
             }
             return;
         case OPC_PREFE:
-            check_cp0_enabled(ctx);
             /* Treat as NOP. */
             return;
         }
@@ -24750,7 +24757,9 @@  static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case OPC_CP0:
-        check_cp0_enabled(ctx);
+        if (!check_cp0_enabled(ctx)) {
+            break;
+        }
         op1 = MASK_CP0(ctx->opcode);
         switch (op1) {
         case OPC_MFC0:
@@ -24990,9 +24999,8 @@  static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
         gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
         break;
     case OPC_CACHE:
-        check_cp0_enabled(ctx);
         check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
-        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
+        if (check_cp0_enabled(ctx) && ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
             gen_cache_operation(ctx, rt, rs, imm);
         }
         /* Treat as NOP. */