[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 07/25] target/openrisc: Link more translation blocks
From: |
Stafford Horne |
Subject: |
[Qemu-devel] [PULL 07/25] target/openrisc: Link more translation blocks |
Date: |
Mon, 2 Jul 2018 22:57:48 +0900 |
From: Richard Henderson <address@hidden>
Track direct jumps via dc->jmp_pc_imm. Use that in
preference to jmp_pc when possible. Emit goto_tb in
that case, and lookup_and_goto_tb otherwise.
Reviewed-by: Stafford Horne <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
Signed-off-by: Stafford Horne <address@hidden>
---
target/openrisc/translate.c | 96 +++++++++++++++++++++----------------
1 file changed, 55 insertions(+), 41 deletions(-)
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 22848b17ad..a618d39242 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -38,13 +38,16 @@
/* is_jmp field values */
#define DISAS_EXIT DISAS_TARGET_0 /* force exit to main loop */
-#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
+#define DISAS_JUMP DISAS_TARGET_1 /* exit via jmp_pc/jmp_pc_imm */
typedef struct DisasContext {
DisasContextBase base;
uint32_t mem_idx;
uint32_t tb_flags;
uint32_t delayed_branch;
+
+ /* If not -1, jmp_pc contains this value and so is a direct jump. */
+ target_ulong jmp_pc_imm;
} DisasContext;
/* Include the auto-generated decoder. */
@@ -160,34 +163,6 @@ static void check_ov64s(DisasContext *dc)
} \
} while (0)
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
-{
- if (unlikely(dc->base.singlestep_enabled)) {
- return false;
- }
-
-#ifndef CONFIG_USER_ONLY
- return (dc->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
- return true;
-#endif
-}
-
-static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
-{
- if (use_goto_tb(dc, dest)) {
- tcg_gen_movi_tl(cpu_pc, dest);
- tcg_gen_goto_tb(n);
- tcg_gen_exit_tb(dc->base.tb, n);
- } else {
- tcg_gen_movi_tl(cpu_pc, dest);
- if (dc->base.singlestep_enabled) {
- gen_exception(dc, EXCP_DEBUG);
- }
- tcg_gen_exit_tb(NULL, 0);
- }
-}
-
static void gen_ove_cy(DisasContext *dc)
{
if (dc->tb_flags & SR_OVE) {
@@ -621,6 +596,7 @@ static bool trans_l_j(DisasContext *dc, arg_l_j *a,
uint32_t insn)
target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
tcg_gen_movi_tl(jmp_pc, tmp_pc);
+ dc->jmp_pc_imm = tmp_pc;
dc->delayed_branch = 2;
return true;
}
@@ -634,6 +610,7 @@ static bool trans_l_jal(DisasContext *dc, arg_l_jal *a,
uint32_t insn)
/* Optimize jal being used to load the PC for PIC. */
if (tmp_pc != ret_pc) {
tcg_gen_movi_tl(jmp_pc, tmp_pc);
+ dc->jmp_pc_imm = tmp_pc;
dc->delayed_branch = 2;
}
return true;
@@ -1267,6 +1244,8 @@ static void
openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
dc->mem_idx = cpu_mmu_index(env, false);
dc->tb_flags = dc->base.tb->flags;
dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
+ dc->jmp_pc_imm = -1;
+
bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
dc->base.max_insns = MIN(dc->base.max_insns, bound);
}
@@ -1319,37 +1298,72 @@ static void openrisc_tr_translate_insn(DisasContextBase
*dcbase, CPUState *cs)
}
dc->base.pc_next += 4;
- /* delay slot */
- if (dc->delayed_branch) {
- dc->delayed_branch--;
- if (!dc->delayed_branch) {
- tcg_gen_mov_tl(cpu_pc, jmp_pc);
- tcg_gen_discard_tl(jmp_pc);
- dc->base.is_jmp = DISAS_UPDATE;
- return;
- }
+ /* When exiting the delay slot normally, exit via jmp_pc.
+ * For DISAS_NORETURN, we have raised an exception and already exited.
+ * For DISAS_EXIT, we found l.rfe in a delay slot. There's nothing
+ * in the manual saying this is illegal, but it surely it should.
+ * At least or1ksim overrides pcnext and ignores the branch.
+ */
+ if (dc->delayed_branch
+ && --dc->delayed_branch == 0
+ && dc->base.is_jmp == DISAS_NEXT) {
+ dc->base.is_jmp = DISAS_JUMP;
}
}
static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
+ target_ulong jmp_dest;
/* If we have already exited the TB, nothing following has effect. */
if (dc->base.is_jmp == DISAS_NORETURN) {
return;
}
+ /* Adjust the delayed branch state for the next TB. */
if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
}
- tcg_gen_movi_tl(cpu_ppc, dc->base.pc_next - 4);
+ /* For DISAS_TOO_MANY, jump to the next insn. */
+ jmp_dest = dc->base.pc_next;
+ tcg_gen_movi_tl(cpu_ppc, jmp_dest - 4);
+
switch (dc->base.is_jmp) {
+ case DISAS_JUMP:
+ jmp_dest = dc->jmp_pc_imm;
+ if (jmp_dest == -1) {
+ /* The jump destination is indirect/computed; use jmp_pc. */
+ tcg_gen_mov_tl(cpu_pc, jmp_pc);
+ tcg_gen_discard_tl(jmp_pc);
+ if (unlikely(dc->base.singlestep_enabled)) {
+ gen_exception(dc, EXCP_DEBUG);
+ } else {
+ tcg_gen_lookup_and_goto_ptr();
+ }
+ break;
+ }
+ /* The jump destination is direct; use jmp_pc_imm.
+ However, we will have stored into jmp_pc as well;
+ we know now that it wasn't needed. */
+ tcg_gen_discard_tl(jmp_pc);
+ /* fallthru */
+
case DISAS_TOO_MANY:
- gen_goto_tb(dc, 0, dc->base.pc_next);
+ if (unlikely(dc->base.singlestep_enabled)) {
+ tcg_gen_movi_tl(cpu_pc, jmp_dest);
+ gen_exception(dc, EXCP_DEBUG);
+ } else if ((dc->base.pc_first ^ jmp_dest) & TARGET_PAGE_MASK) {
+ tcg_gen_movi_tl(cpu_pc, jmp_dest);
+ tcg_gen_lookup_and_goto_ptr();
+ } else {
+ tcg_gen_goto_tb(0);
+ tcg_gen_movi_tl(cpu_pc, jmp_dest);
+ tcg_gen_exit_tb(dc->base.tb, 0);
+ }
break;
- case DISAS_UPDATE:
+
case DISAS_EXIT:
if (unlikely(dc->base.singlestep_enabled)) {
gen_exception(dc, EXCP_DEBUG);
--
2.17.0
- [Qemu-devel] [PULL 00/25] OpenRISC updates for 3.0, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 01/25] target/openrisc: Fix mtspr shadow gprs, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 03/25] target/openrisc: Log interrupts, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 05/25] target/openrisc: Use exit_tb instead of CPU_INTERRUPT_EXITTB, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 04/25] target/openrisc: Remove DISAS_JUMP & DISAS_TB_JUMP, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 02/25] target/openrisc: Add print_insn_or1k, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 06/25] target/openrisc: Fix singlestep_enabled, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 07/25] target/openrisc: Link more translation blocks,
Stafford Horne <=
- [Qemu-devel] [PULL 09/25] target/openrisc: Exit the TB after l.mtspr, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 10/25] target/openrisc: Form the spr index from tcg, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 11/25] target/openrisc: Merge tlb allocation into CPUOpenRISCState, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 12/25] target/openrisc: Remove indirect function calls for mmu, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 13/25] target/openrisc: Merge mmu_helper.c into mmu.c, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 14/25] target/openrisc: Reduce tlb to a single dimension, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 15/25] target/openrisc: Fix tlb flushing in mtspr, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 16/25] target/openrisc: Fix cpu_mmu_index, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 17/25] target/openrisc: Use identical sizes for ITLB and DTLB, Stafford Horne, 2018/07/02
- [Qemu-devel] [PULL 18/25] target/openrisc: Stub out handle_mmu_fault for softmmu, Stafford Horne, 2018/07/02