[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 5/5] target/tricore: Fix tricore_tr_translate_insn
From: |
Bastian Koppelmann |
Subject: |
[Qemu-devel] [PULL 5/5] target/tricore: Fix tricore_tr_translate_insn |
Date: |
Thu, 22 Aug 2019 12:20:46 +0200 |
we now fetch 2 bytes first, check whether we have a 32 bit insn, and only then
fetch another 2 bytes. We also make sure that a 16 bit insn that still fits
into the current page does not end up in the next page.
Reviewed-by: Richard Henderson <address@hidden>
Signed-off-by: Bastian Koppelmann <address@hidden>
---
target/tricore/translate.c | 47 +++++++++++++++++++++++++++-----------
1 file changed, 34 insertions(+), 13 deletions(-)
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
index 88b2840ad1..4f10407477 100644
--- a/target/tricore/translate.c
+++ b/target/tricore/translate.c
@@ -8781,17 +8781,9 @@ static void decode_32Bit_opc(DisasContext *ctx)
}
}
-static void decode_opc(DisasContext *ctx)
+static bool tricore_insn_is_16bit(uint32_t insn)
{
- /* 16-Bit Instruction */
- if ((ctx->opcode & 0x1) == 0) {
- ctx->pc_succ_insn = ctx->base.pc_next + 2;
- decode_16Bit_opc(ctx);
- /* 32-Bit Instruction */
- } else {
- ctx->pc_succ_insn = ctx->base.pc_next + 4;
- decode_32Bit_opc(ctx);
- }
+ return (insn & 0x1) == 0;
}
static void tricore_tr_init_disas_context(DisasContextBase *dcbase,
@@ -8829,20 +8821,49 @@ static bool
tricore_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
return true;
}
+static bool insn_crosses_page(CPUTriCoreState *env, DisasContext *ctx)
+{
+ /*
+ * Return true if the insn at ctx->base.pc_next might cross a page
boundary.
+ * (False positives are OK, false negatives are not.)
+ * Our caller ensures we are only called if dc->base.pc_next is less than
+ * 4 bytes from the page boundary, so we cross the page if the first
+ * 16 bits indicate that this is a 32 bit insn.
+ */
+ uint16_t insn = cpu_lduw_code(env, ctx->base.pc_next);
+
+ return !tricore_insn_is_16bit(insn);
+}
+
+
static void tricore_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
CPUTriCoreState *env = cpu->env_ptr;
+ uint16_t insn_lo;
+ bool is_16bit;
- ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
- decode_opc(ctx);
+ insn_lo = cpu_lduw_code(env, ctx->base.pc_next);
+ is_16bit = tricore_insn_is_16bit(insn_lo);
+ if (is_16bit) {
+ ctx->opcode = insn_lo;
+ ctx->pc_succ_insn = ctx->base.pc_next + 2;
+ decode_16Bit_opc(ctx);
+ } else {
+ uint32_t insn_hi = cpu_lduw_code(env, ctx->base.pc_next + 2);
+ ctx->opcode = insn_hi << 16 | insn_lo;
+ ctx->pc_succ_insn = ctx->base.pc_next + 4;
+ decode_32Bit_opc(ctx);
+ }
ctx->base.pc_next = ctx->pc_succ_insn;
if (ctx->base.is_jmp == DISAS_NEXT) {
target_ulong page_start;
page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
- if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE) {
+ if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE
+ || (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE - 3
+ && insn_crosses_page(env, ctx))) {
ctx->base.is_jmp = DISAS_TOO_MANY;
}
}
--
2.23.0
- [Qemu-devel] [PULL 0/5] tricore queue, Bastian Koppelmann, 2019/08/22
- [Qemu-devel] [PULL 1/5] target/tricore: Use DisasContextBase API, Bastian Koppelmann, 2019/08/22
- [Qemu-devel] [PULL 3/5] target/tricore: Use translate_loop, Bastian Koppelmann, 2019/08/22
- [Qemu-devel] [PULL 4/5] target/tricore: Implement a qemu excptions helper, Bastian Koppelmann, 2019/08/22
- [Qemu-devel] [PULL 5/5] target/tricore: Fix tricore_tr_translate_insn,
Bastian Koppelmann <=
- [Qemu-devel] [PULL 2/5] target-tricore: Make env a member of DisasContext, Bastian Koppelmann, 2019/08/22
- Re: [Qemu-devel] [PULL 0/5] tricore queue, no-reply, 2019/08/22
- Re: [Qemu-devel] [PULL 0/5] tricore queue, no-reply, 2019/08/22
- Re: [Qemu-devel] [PULL 0/5] tricore queue, Peter Maydell, 2019/08/22