[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v3 15/23] target/mips: Extract break code into env->error_cod
From: |
Philippe Mathieu-Daudé |
Subject: |
Re: [PATCH v3 15/23] target/mips: Extract break code into env->error_code |
Date: |
Wed, 3 Nov 2021 16:11:13 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.2.0 |
On 11/3/21 15:08, Richard Henderson wrote:
> Simplify cpu_loop by doing all of the decode in translate.
>
> This fixes a bug in that cpu_loop was not handling the
> different layout of the R6 version of break16. This fixes
> a bug in that cpu_loop extracted the wrong bits for the
> mips16e break16 instruction.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/mips/tcg/translate.h | 1 +
> linux-user/mips/cpu_loop.c | 73 +++--------------------
> target/mips/tcg/translate.c | 12 +++-
> target/mips/tcg/micromips_translate.c.inc | 6 +-
> target/mips/tcg/mips16e_translate.c.inc | 2 +-
> 5 files changed, 25 insertions(+), 69 deletions(-)
> diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
> index 034b31f853..8efb6d2a24 100644
> --- a/linux-user/mips/cpu_loop.c
> +++ b/linux-user/mips/cpu_loop.c
> @@ -65,6 +65,7 @@ void cpu_loop(CPUMIPSState *env)
> {
> CPUState *cs = env_cpu(env);
> int trapnr, si_code;
> + unsigned int code;
> abi_long ret;
> # ifdef TARGET_ABI_MIPSO32
> unsigned int syscall_num;
> @@ -185,71 +186,15 @@ done_syscall:
> * handling code in arch/mips/kernel/traps.c.
> */
> case EXCP_BREAK:
> - {
> - abi_ulong trap_instr;
> - unsigned int code;
> -
> - /*
> - * 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) {
> - if (env->insn_flags & ASE_MICROMIPS) {
> - /* microMIPS mode */
> - ret = get_user_u16(trap_instr, env->active_tc.PC);
> - if (ret != 0) {
> - goto error;
> - }
> -
> - if ((trap_instr >> 10) == 0x11) {
> - /* 16-bit instruction */
> - code = trap_instr & 0xf;
> - } else {
> - /* 32-bit instruction */
> - abi_ulong instr_lo;
> -
> - ret = get_user_u16(instr_lo,
> - env->active_tc.PC + 2);
> - if (ret != 0) {
> - goto error;
> - }
> - trap_instr = (trap_instr << 16) | instr_lo;
> - code = ((trap_instr >> 6) & ((1 << 20) - 1));
> - /* Unfortunately, microMIPS also suffers from
> - the old assembler bug... */
> - if (code >= (1 << 10)) {
> - code >>= 10;
> - }
> - }
> - } else {
> - /* MIPS16e mode */
> - ret = get_user_u16(trap_instr, env->active_tc.PC);
> - if (ret != 0) {
> - goto error;
> - }
> - code = (trap_instr >> 6) & 0x3f;
> - }
> - } else {
> - ret = get_user_u32(trap_instr, env->active_tc.PC);
> - if (ret != 0) {
> - goto error;
> - }
> -
> - /* As described in the original Linux kernel code, the
> - * below checks on 'code' are to work around an old
> - * assembly bug.
> - */
> - code = ((trap_instr >> 6) & ((1 << 20) - 1));
> - if (code >= (1 << 10)) {
> - code >>= 10;
> - }
> - }
> -
> - do_tr_or_bp(env, code, false);
> + /*
> + * As described in the original Linux kernel code, the below
> + * checks on 'code' are to work around an old assembly bug.
> + */
> + code = env->error_code;
> + if (code >= (1 << 10)) {
> + code >>= 10;
Shouldn't we also move this to the translation (not in R6_BREAK16)?
> }
> + do_tr_or_bp(env, code, false);
> break;
> case EXCP_TRAP:
> {
> diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
> index 47db35d7dd..a42f507aed 100644
> --- a/target/mips/tcg/translate.c
> +++ b/target/mips/tcg/translate.c
> @@ -1367,6 +1367,16 @@ void generate_exception_end(DisasContext *ctx, int
> excp)
> generate_exception_err(ctx, excp, 0);
> }
>
> +void generate_exception_break(DisasContext *ctx, int code)
> +{
> +#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_BREAK);
> +}
> +
> void gen_reserved_instruction(DisasContext *ctx)
> {
> generate_exception_end(ctx, EXCP_RI);
> @@ -14160,7 +14170,7 @@ static void decode_opc_special(CPUMIPSState *env,
> DisasContext *ctx)
> generate_exception_end(ctx, EXCP_SYSCALL);
> break;
> case OPC_BREAK:
> - generate_exception_end(ctx, EXCP_BREAK);
> + generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
> break;
> case OPC_SYNC:
> check_insn(ctx, ISA_MIPS2);
> diff --git a/target/mips/tcg/micromips_translate.c.inc
> b/target/mips/tcg/micromips_translate.c.inc
> index 0da4c802a3..f91f7a96cd 100644
> --- a/target/mips/tcg/micromips_translate.c.inc
> +++ b/target/mips/tcg/micromips_translate.c.inc
> @@ -822,7 +822,7 @@ static void gen_pool16c_insn(DisasContext *ctx)
> gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
> break;
> case BREAK16:
> - generate_exception_end(ctx, EXCP_BREAK);
> + generate_exception_break(ctx, extract32(ctx->opcode, 0, 4));
> break;
> case SDBBP16:
> if (is_uhi(extract32(ctx->opcode, 0, 4))) {
> @@ -937,7 +937,7 @@ static void gen_pool16c_r6_insn(DisasContext *ctx)
> break;
> case R6_BREAK16:
> /* BREAK16 */
> - generate_exception(ctx, EXCP_BREAK);
> + generate_exception_break(ctx, extract32(ctx->opcode, 6, 4));
> break;
> case R6_SDBBP16:
> /* SDBBP16 */
> @@ -1812,7 +1812,7 @@ static void decode_micromips32_opc(CPUMIPSState *env,
> DisasContext *ctx)
> gen_pool32axf(env, ctx, rt, rs);
> break;
> case BREAK32:
> - generate_exception_end(ctx, EXCP_BREAK);
> + generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
> break;
> case SIGRIE:
> check_insn(ctx, ISA_MIPS_R6);
> diff --git a/target/mips/tcg/mips16e_translate.c.inc
> b/target/mips/tcg/mips16e_translate.c.inc
> index 84d816603a..f57e0a5f2a 100644
> --- a/target/mips/tcg/mips16e_translate.c.inc
> +++ b/target/mips/tcg/mips16e_translate.c.inc
> @@ -969,7 +969,7 @@ static int decode_ase_mips16e(CPUMIPSState *env,
> DisasContext *ctx)
> gen_slt(ctx, OPC_SLTU, 24, rx, ry);
> break;
> case RR_BREAK:
> - generate_exception_end(ctx, EXCP_BREAK);
> + generate_exception_break(ctx, extract32(ctx->opcode, 5, 6));
> break;
> case RR_SLLV:
> gen_shift(ctx, OPC_SLLV, ry, rx, ry);
>
- [PATCH v3 09/23] linux-user/i386: Use force_sig, force_sig_fault, (continued)
- [PATCH v3 09/23] linux-user/i386: Use force_sig, force_sig_fault, Richard Henderson, 2021/11/03
- [PATCH v3 06/23] linux-user/hppa: Use the proper si_code for PRIV_OPR, PRIV_REG, OVERFLOW, Richard Henderson, 2021/11/03
- [PATCH v3 07/23] linux-user/hppa: Set FPE_CONDTRAP for COND, Richard Henderson, 2021/11/03
- [PATCH v3 08/23] linux-user/i386: Split out maybe_handle_vm86_trap, Richard Henderson, 2021/11/03
- [PATCH v3 10/23] linux-user/m68k: Use force_sig_fault, Richard Henderson, 2021/11/03
- [PATCH v3 11/23] linux-user/microblaze: Use force_sig_fault, Richard Henderson, 2021/11/03
- [PATCH v3 12/23] linux-user/microblaze: Fix SIGFPE si_codes, Richard Henderson, 2021/11/03
- [PATCH v3 14/23] linux-user/mips: Use force_sig_fault, Richard Henderson, 2021/11/03
- [PATCH v3 13/23] linux-user/mips: Improve do_break, Richard Henderson, 2021/11/03
- [PATCH v3 15/23] target/mips: Extract break code into env->error_code, Richard Henderson, 2021/11/03
- Re: [PATCH v3 15/23] target/mips: Extract break code into env->error_code,
Philippe Mathieu-Daudé <=
- [PATCH v3 16/23] target/mips: Extract trap code into env->error_code, Richard Henderson, 2021/11/03
- [PATCH v3 20/23] linux-user/s390x: Use force_sig_fault, Richard Henderson, 2021/11/03
- [PATCH v3 17/23] linux-user/openrisc: Use force_sig_fault, Richard Henderson, 2021/11/03
- [PATCH v3 18/23] linux-user/ppc: Use force_sig_fault, Richard Henderson, 2021/11/03