diff mbox series

[v3,16/23] target/mips: Extract trap code into env->error_code

Message ID 20211103140847.454070-17-richard.henderson@linaro.org
State Superseded
Headers show
Series linux-user: Clean up siginfo_t handling | expand

Commit Message

Richard Henderson Nov. 3, 2021, 2:08 p.m. UTC
Simplify cpu_loop by doing all of the decode in translate.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/mips/cpu_loop.c                | 41 +----------------------
 target/mips/tcg/translate.c               | 24 ++++++++++---
 target/mips/tcg/micromips_translate.c.inc |  4 +--
 target/mips/tcg/nanomips_translate.c.inc  |  4 +--
 4 files changed, 25 insertions(+), 48 deletions(-)

-- 
2.25.1

Comments

Philippe Mathieu-Daudé Nov. 3, 2021, 3:21 p.m. UTC | #1
On 11/3/21 15:08, Richard Henderson wrote:
> Simplify cpu_loop by doing all of the decode in translate.

> 

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---

>  linux-user/mips/cpu_loop.c                | 41 +----------------------

>  target/mips/tcg/translate.c               | 24 ++++++++++---

>  target/mips/tcg/micromips_translate.c.inc |  4 +--

>  target/mips/tcg/nanomips_translate.c.inc  |  4 +--

>  4 files changed, 25 insertions(+), 48 deletions(-)


> diff --git a/target/mips/tcg/micromips_translate.c.inc b/target/mips/tcg/micromips_translate.c.inc

> index f91f7a96cd..7e7d26a91b 100644

> --- a/target/mips/tcg/micromips_translate.c.inc

> +++ b/target/mips/tcg/micromips_translate.c.inc

> @@ -1047,7 +1047,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)

>      case TNE:

>          mips32_op = OPC_TNE;

>      do_trap:

> -        gen_trap(ctx, mips32_op, rs, rt, -1);

> +        gen_trap(ctx, mips32_op, rs, rt, -1, extract32(ctx->opcode, 12, 4));

>          break;

>  #ifndef CONFIG_USER_ONLY

>      case MFC0:

> @@ -2439,7 +2439,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)

>              check_insn_opc_removed(ctx, ISA_MIPS_R6);

>              mips32_op = OPC_TEQI;

>          do_trapi:

> -            gen_trap(ctx, mips32_op, rs, -1, imm);

> +            gen_trap(ctx, mips32_op, rs, -1, imm, 0);


IIUC the microMIPS manual (MD00594):

               gen_trap(ctx, mips32_op, rs, -1, imm,
                        extract32(ctx->opcode, 12, 4));

>              break;
Richard Henderson Nov. 3, 2021, 3:46 p.m. UTC | #2
On 11/3/21 11:21 AM, Philippe Mathieu-Daudé wrote:
>>       do_trap:

>> -        gen_trap(ctx, mips32_op, rs, rt, -1);

>> +        gen_trap(ctx, mips32_op, rs, rt, -1, extract32(ctx->opcode, 12, 4));

>>           break;

>>   #ifndef CONFIG_USER_ONLY

>>       case MFC0:

>> @@ -2439,7 +2439,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)

>>               check_insn_opc_removed(ctx, ISA_MIPS_R6);

>>               mips32_op = OPC_TEQI;

>>           do_trapi:

>> -            gen_trap(ctx, mips32_op, rs, -1, imm);

>> +            gen_trap(ctx, mips32_op, rs, -1, imm, 0);

> 

> IIUC the microMIPS manual (MD00594):

> 

>                 gen_trap(ctx, mips32_op, rs, -1, imm,

>                          extract32(ctx->opcode, 12, 4));


No, there is no code for trap-immediate.
You can see the 12:4 code above for trap-register.

See the 3.05 revision of the manual, which still contains TEQI.  Note that all 
trap-immediate opcodes were removed for R6.


r~
Philippe Mathieu-Daudé Nov. 3, 2021, 5:04 p.m. UTC | #3
On 11/3/21 16:46, Richard Henderson wrote:
> On 11/3/21 11:21 AM, Philippe Mathieu-Daudé wrote:

>>>       do_trap:

>>> -        gen_trap(ctx, mips32_op, rs, rt, -1);

>>> +        gen_trap(ctx, mips32_op, rs, rt, -1, extract32(ctx->opcode,

>>> 12, 4));

>>>           break;

>>>   #ifndef CONFIG_USER_ONLY

>>>       case MFC0:

>>> @@ -2439,7 +2439,7 @@ static void decode_micromips32_opc(CPUMIPSState

>>> *env, DisasContext *ctx)

>>>               check_insn_opc_removed(ctx, ISA_MIPS_R6);

>>>               mips32_op = OPC_TEQI;

>>>           do_trapi:

>>> -            gen_trap(ctx, mips32_op, rs, -1, imm);

>>> +            gen_trap(ctx, mips32_op, rs, -1, imm, 0);

>>

>> IIUC the microMIPS manual (MD00594):

>>

>>                 gen_trap(ctx, mips32_op, rs, -1, imm,

>>                          extract32(ctx->opcode, 12, 4));

> 

> No, there is no code for trap-immediate.

> You can see the 12:4 code above for trap-register.

> 

> See the 3.05 revision of the manual, which still contains TEQI.  Note

> that all trap-immediate opcodes were removed for R6.


Oops indeed (checked 3.05 and 5.04).

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
diff mbox series

Patch

diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index 8efb6d2a24..6079c2d600 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -197,51 +197,12 @@  done_syscall:
             do_tr_or_bp(env, code, false);
             break;
         case EXCP_TRAP:
-            {
-                abi_ulong trap_instr;
-                unsigned int code = 0;
-
-                /*
-                 * FIXME: It would be better to decode the trap number
-                 * during translate, and store it in error_code while
-                 * raising the exception.  We should not be re-reading
-                 * the opcode here.
-                 */
-
-                if (env->hflags & MIPS_HFLAG_M16) {
-                    /* microMIPS mode */
-                    abi_ulong instr[2];
-
-                    ret = get_user_u16(instr[0], env->active_tc.PC) ||
-                          get_user_u16(instr[1], env->active_tc.PC + 2);
-
-                    trap_instr = (instr[0] << 16) | instr[1];
-                } else {
-                    ret = get_user_u32(trap_instr, env->active_tc.PC);
-                }
-
-                if (ret != 0) {
-                    goto error;
-                }
-
-                /* The immediate versions don't provide a code.  */
-                if (!(trap_instr & 0xFC000000)) {
-                    if (env->hflags & MIPS_HFLAG_M16) {
-                        /* microMIPS mode */
-                        code = ((trap_instr >> 12) & ((1 << 4) - 1));
-                    } else {
-                        code = ((trap_instr >> 6) & ((1 << 10) - 1));
-                    }
-                }
-
-                do_tr_or_bp(env, code, true);
-            }
+            do_tr_or_bp(env, env->error_code, true);
             break;
         case EXCP_ATOMIC:
             cpu_exec_step_atomic(cs);
             break;
         default:
-error:
             EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
             abort();
         }
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index a42f507aed..98c0f1aab3 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -4733,7 +4733,7 @@  static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
 
 /* Traps */
 static void gen_trap(DisasContext *ctx, uint32_t opc,
-                     int rs, int rt, int16_t imm)
+                     int rs, int rt, int16_t imm, int code)
 {
     int cond;
     TCGv t0 = tcg_temp_new();
@@ -4778,6 +4778,11 @@  static void gen_trap(DisasContext *ctx, uint32_t opc,
         case OPC_TGEU:  /* rs >= rs unsigned */
         case OPC_TGEIU: /* r0 >= 0  unsigned */
             /* Always trap */
+#ifdef CONFIG_USER_ONLY
+            /* Pass the break code along to cpu_loop. */
+            tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
+                           offsetof(CPUMIPSState, error_code));
+#endif
             generate_exception_end(ctx, EXCP_TRAP);
             break;
         case OPC_TLT:   /* rs < rs           */
@@ -4818,6 +4823,18 @@  static void gen_trap(DisasContext *ctx, uint32_t opc,
             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
             break;
         }
+#ifdef CONFIG_USER_ONLY
+        /* Pass the break code along to cpu_loop. */
+        tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
+                       offsetof(CPUMIPSState, error_code));
+#endif
+        /* Like save_cpu_state, only don't update saved values. */
+        if (ctx->base.pc_next != ctx->saved_pc) {
+            gen_save_pc(ctx->base.pc_next);
+        }
+        if (ctx->hflags != ctx->saved_hflags) {
+            tcg_gen_movi_i32(hflags, ctx->hflags);
+        }
         generate_exception(ctx, EXCP_TRAP);
         gen_set_label(l1);
     }
@@ -14155,7 +14172,7 @@  static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
     case OPC_TEQ:
     case OPC_TNE:
         check_insn(ctx, ISA_MIPS2);
-        gen_trap(ctx, op1, rs, rt, -1);
+        gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
         break;
     case OPC_PMON:
         /* Pmon entry point, also R4010 selsl */
@@ -15289,11 +15306,10 @@  static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
         case OPC_TLTI:
         case OPC_TLTIU:
         case OPC_TEQI:
-
         case OPC_TNEI:
             check_insn(ctx, ISA_MIPS2);
             check_insn_opc_removed(ctx, ISA_MIPS_R6);
-            gen_trap(ctx, op1, rs, -1, imm);
+            gen_trap(ctx, op1, rs, -1, imm, 0);
             break;
         case OPC_SIGRIE:
             check_insn(ctx, ISA_MIPS_R6);
diff --git a/target/mips/tcg/micromips_translate.c.inc b/target/mips/tcg/micromips_translate.c.inc
index f91f7a96cd..7e7d26a91b 100644
--- a/target/mips/tcg/micromips_translate.c.inc
+++ b/target/mips/tcg/micromips_translate.c.inc
@@ -1047,7 +1047,7 @@  static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
     case TNE:
         mips32_op = OPC_TNE;
     do_trap:
-        gen_trap(ctx, mips32_op, rs, rt, -1);
+        gen_trap(ctx, mips32_op, rs, rt, -1, extract32(ctx->opcode, 12, 4));
         break;
 #ifndef CONFIG_USER_ONLY
     case MFC0:
@@ -2439,7 +2439,7 @@  static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             check_insn_opc_removed(ctx, ISA_MIPS_R6);
             mips32_op = OPC_TEQI;
         do_trapi:
-            gen_trap(ctx, mips32_op, rs, -1, imm);
+            gen_trap(ctx, mips32_op, rs, -1, imm, 0);
             break;
 
         case BNEZC:
diff --git a/target/mips/tcg/nanomips_translate.c.inc b/target/mips/tcg/nanomips_translate.c.inc
index 2c022a49f2..916cece4d2 100644
--- a/target/mips/tcg/nanomips_translate.c.inc
+++ b/target/mips/tcg/nanomips_translate.c.inc
@@ -1268,11 +1268,11 @@  static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
         switch (extract32(ctx->opcode, 10, 1)) {
         case NM_TEQ:
             check_nms(ctx);
-            gen_trap(ctx, OPC_TEQ, rs, rt, -1);
+            gen_trap(ctx, OPC_TEQ, rs, rt, -1, rd);
             break;
         case NM_TNE:
             check_nms(ctx);
-            gen_trap(ctx, OPC_TNE, rs, rt, -1);
+            gen_trap(ctx, OPC_TNE, rs, rt, -1, rd);
             break;
         }
         break;