diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2022-07-29 19:17:02 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2022-08-02 12:34:00 -0700 |
commit | d44971e725c02e0656d2f53d4fb564f92e06aef7 (patch) | |
tree | bd997d6fd75f68109c166243284c14ad074e2034 /target/mips/tcg/translate.c | |
parent | 430a388ef4a6e02e762a9c5f86c539f886a6a61a (diff) |
target/mips: Advance pc after semihosting exception
Delay generating the exception until after we know the
insn length, and record that length in env->error_code.
Fixes: 8ec7e3c53d4 ("target/mips: Use an exception for semihosting")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1126
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/mips/tcg/translate.c')
-rw-r--r-- | target/mips/tcg/translate.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 1f6a779808..de1511baaf 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -1213,9 +1213,6 @@ TCGv_i64 fpu_f64[32]; #include "exec/gen-icount.h" -#define DISAS_STOP DISAS_TARGET_0 -#define DISAS_EXIT DISAS_TARGET_1 - static const char regnames_HI[][4] = { "HI0", "HI1", "HI2", "HI3", }; @@ -13902,7 +13899,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) break; case R6_OPC_SDBBP: if (is_uhi(extract32(ctx->opcode, 6, 20))) { - generate_exception_end(ctx, EXCP_SEMIHOST); + ctx->base.is_jmp = DISAS_SEMIHOST; } else { if (ctx->hflags & MIPS_HFLAG_SBRI) { gen_reserved_instruction(ctx); @@ -14314,7 +14311,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) break; case OPC_SDBBP: if (is_uhi(extract32(ctx->opcode, 6, 20))) { - generate_exception_end(ctx, EXCP_SEMIHOST); + ctx->base.is_jmp = DISAS_SEMIHOST; } else { /* * XXX: not clear which exception should be raised @@ -16098,6 +16095,9 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) if (is_slot) { gen_branch(ctx, insn_bytes); } + if (ctx->base.is_jmp == DISAS_SEMIHOST) { + generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes); + } ctx->base.pc_next += insn_bytes; if (ctx->base.is_jmp != DISAS_NEXT) { |