diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2022-01-07 13:32:35 -0800 |
---|---|---|
committer | Laurent Vivier <laurent@vivier.eu> | 2022-01-11 18:40:44 +0100 |
commit | 6f3533dd1b6afbce8d215bb89027fa5b7caa4168 (patch) | |
tree | 35b02ea7dc72f42e2cb6776807b06a81252cc453 /target/mips/tcg | |
parent | 73c0aa6a85253d1d5df6a7dfa14c7568e084cf96 (diff) |
target/mips: Extract break code into env->error_code
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.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220107213243.212806-17-richard.henderson@linaro.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Diffstat (limited to 'target/mips/tcg')
-rw-r--r-- | target/mips/tcg/micromips_translate.c.inc | 6 | ||||
-rw-r--r-- | target/mips/tcg/mips16e_translate.c.inc | 2 | ||||
-rw-r--r-- | target/mips/tcg/translate.c | 12 | ||||
-rw-r--r-- | target/mips/tcg/translate.h | 1 |
4 files changed, 16 insertions, 5 deletions
diff --git a/target/mips/tcg/micromips_translate.c.inc b/target/mips/tcg/micromips_translate.c.inc index 0760941431..9013f84037 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); diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 1c2264417c..7f0cc81a90 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/translate.h b/target/mips/tcg/translate.h index 6111493651..ae01515efe 100644 --- a/target/mips/tcg/translate.h +++ b/target/mips/tcg/translate.h @@ -129,6 +129,7 @@ enum { void generate_exception(DisasContext *ctx, int excp); void generate_exception_err(DisasContext *ctx, int excp, int err); void generate_exception_end(DisasContext *ctx, int excp); +void generate_exception_break(DisasContext *ctx, int code); void gen_reserved_instruction(DisasContext *ctx); void check_insn(DisasContext *ctx, uint64_t flags); |