From ab709f13b8d44466787f4f53e6333b747d813afb Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 3 May 2024 09:20:05 +0200 Subject: [PATCH 1/9] target/alpha: Use cpu_env in preference to ALPHA_CPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ALPHA_CPU has a dynamic object type assert, which is unnecessary considering that these are all class hooks. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20240503072014.24751-2-philmd@linaro.org> --- target/alpha/cpu.c | 15 ++++++--------- target/alpha/helper.c | 8 ++++---- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index 05f9ee41e9..f98d022671 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -28,25 +28,22 @@ static void alpha_cpu_set_pc(CPUState *cs, vaddr value) { - AlphaCPU *cpu = ALPHA_CPU(cs); - - cpu->env.pc = value; + CPUAlphaState *env = cpu_env(cs); + env->pc = value; } static vaddr alpha_cpu_get_pc(CPUState *cs) { - AlphaCPU *cpu = ALPHA_CPU(cs); - - return cpu->env.pc; + CPUAlphaState *env = cpu_env(cs); + return env->pc; } static void alpha_restore_state_to_opc(CPUState *cs, const TranslationBlock *tb, const uint64_t *data) { - AlphaCPU *cpu = ALPHA_CPU(cs); - - cpu->env.pc = data[0]; + CPUAlphaState *env = cpu_env(cs); + env->pc = data[0]; } static bool alpha_cpu_has_work(CPUState *cs) diff --git a/target/alpha/helper.c b/target/alpha/helper.c index d6d4353edd..c5e4958f8b 100644 --- a/target/alpha/helper.c +++ b/target/alpha/helper.c @@ -124,7 +124,7 @@ void alpha_cpu_record_sigsegv(CPUState *cs, vaddr address, MMUAccessType access_type, bool maperr, uintptr_t retaddr) { - AlphaCPU *cpu = ALPHA_CPU(cs); + CPUAlphaState *env = cpu_env(cs); target_ulong mmcsr, cause; /* Assuming !maperr, infer the missing protection. */ @@ -155,9 +155,9 @@ void alpha_cpu_record_sigsegv(CPUState *cs, vaddr address, } /* Record the arguments that PALcode would give to the kernel. */ - cpu->env.trap_arg0 = address; - cpu->env.trap_arg1 = mmcsr; - cpu->env.trap_arg2 = cause; + env->trap_arg0 = address; + env->trap_arg1 = mmcsr; + env->trap_arg2 = cause; } #else /* Returns the OSF/1 entMM failure indication, or -1 on success. */ From 1bcae46aac60ae0efbeb3957f7679da9e7e50f30 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 3 May 2024 09:20:06 +0200 Subject: [PATCH 2/9] target/alpha: Hoist branch shift to initial decode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20240503072014.24751-3-philmd@linaro.org> --- target/alpha/translate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/alpha/translate.c b/target/alpha/translate.c index a97cd54f0c..52c2e6248b 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -432,7 +432,7 @@ static bool use_goto_tb(DisasContext *ctx, uint64_t dest) static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) { - uint64_t dest = ctx->base.pc_next + (disp << 2); + uint64_t dest = ctx->base.pc_next + disp; if (ra != 31) { tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next); @@ -455,7 +455,7 @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, TCGv cmp, uint64_t imm, int32_t disp) { - uint64_t dest = ctx->base.pc_next + (disp << 2); + uint64_t dest = ctx->base.pc_next + disp; TCGLabel *lab_true = gen_new_label(); if (use_goto_tb(ctx, dest)) { @@ -1382,7 +1382,7 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) real_islit = islit = extract32(insn, 12, 1); lit = extract32(insn, 13, 8); - disp21 = sextract32(insn, 0, 21); + disp21 = sextract32(insn, 0, 21) * 4; disp16 = sextract32(insn, 0, 16); disp12 = sextract32(insn, 0, 12); From 0cda93c9b55b1f865f92a2a2e189dcbaab485bb2 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 3 May 2024 09:20:07 +0200 Subject: [PATCH 3/9] target/alpha: Use DISAS_NEXT definition instead of magic '0' value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Richard Henderson Message-Id: <20240424234436.995410-4-richard.henderson@linaro.org> [PMD: Split bigger patch, part 1/5] Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20240503072014.24751-4-philmd@linaro.org> --- target/alpha/translate.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/alpha/translate.c b/target/alpha/translate.c index 52c2e6248b..9ad7bf6e5f 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -440,8 +440,10 @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) /* Notice branch-to-next; used to initialize RA with the PC. */ if (disp == 0) { - return 0; - } else if (use_goto_tb(ctx, dest)) { + return DISAS_NEXT; + } + + if (use_goto_tb(ctx, dest)) { tcg_gen_goto_tb(0); tcg_gen_movi_i64(cpu_pc, dest); tcg_gen_exit_tb(ctx->base.tb, 0); From c0fcd5612e84810fbc62b17fb99a0a4dd847b251 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 3 May 2024 09:20:08 +0200 Subject: [PATCH 4/9] target/alpha: Inline DISAS_PC_UPDATED and return DISAS_NORETURN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inline DISAS_PC_UPDATED switch case from alpha_tr_tb_stop(): switch (ctx->base.is_jmp) { ... case DISAS_PC_UPDATED: tcg_gen_lookup_and_goto_ptr(); break; Signed-off-by: Richard Henderson Message-Id: <20240424234436.995410-4-richard.henderson@linaro.org> [PMD: Split bigger patch, part 2/5] Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20240503072014.24751-5-philmd@linaro.org> --- target/alpha/translate.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/alpha/translate.c b/target/alpha/translate.c index 9ad7bf6e5f..01914e7b56 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -450,7 +450,8 @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) return DISAS_NORETURN; } else { tcg_gen_movi_i64(cpu_pc, dest); - return DISAS_PC_UPDATED; + tcg_gen_lookup_and_goto_ptr(); + return DISAS_NORETURN; } } @@ -479,7 +480,8 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, TCGv_i64 p = tcg_constant_i64(ctx->base.pc_next); tcg_gen_movcond_i64(cond, cpu_pc, cmp, i, d, p); - return DISAS_PC_UPDATED; + tcg_gen_lookup_and_goto_ptr(); + return DISAS_NORETURN; } } From 9804ab26d0f25cb9c97e34f96bb0fb2be0a9f677 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 3 May 2024 09:20:09 +0200 Subject: [PATCH 5/9] target/alpha: Return DISAS_NORETURN once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trivial change to make next commits easier to understand. Signed-off-by: Richard Henderson Message-Id: <20240424234436.995410-4-richard.henderson@linaro.org> [PMD: Split bigger patch, part 3/5] Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20240503072014.24751-6-philmd@linaro.org> --- target/alpha/translate.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/target/alpha/translate.c b/target/alpha/translate.c index 01914e7b56..41151f002e 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -447,12 +447,12 @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) tcg_gen_goto_tb(0); tcg_gen_movi_i64(cpu_pc, dest); tcg_gen_exit_tb(ctx->base.tb, 0); - return DISAS_NORETURN; } else { tcg_gen_movi_i64(cpu_pc, dest); tcg_gen_lookup_and_goto_ptr(); - return DISAS_NORETURN; } + + return DISAS_NORETURN; } static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, @@ -472,8 +472,6 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, tcg_gen_goto_tb(1); tcg_gen_movi_i64(cpu_pc, dest); tcg_gen_exit_tb(ctx->base.tb, 1); - - return DISAS_NORETURN; } else { TCGv_i64 i = tcg_constant_i64(imm); TCGv_i64 d = tcg_constant_i64(dest); @@ -481,8 +479,9 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, tcg_gen_movcond_i64(cond, cpu_pc, cmp, i, d, p); tcg_gen_lookup_and_goto_ptr(); - return DISAS_NORETURN; } + + return DISAS_NORETURN; } static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra, From 39482c2edcc9864cf694b8ea525b49693443f90a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 3 May 2024 09:20:10 +0200 Subject: [PATCH 6/9] target/alpha: Simplify gen_bcond_internal() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Richard Henderson explained on IRC: bcond_internal() used to insist that both branch destination and branch fallthrough are use_goto_tb; if not, we'd use movcond to compute an indirect jump. But it's perfectly fine for e.g. the branch fallthrough to use_goto_tb, and the branch destination to use an indirect branch. Signed-off-by: Richard Henderson Message-Id: <20240424234436.995410-4-richard.henderson@linaro.org> [PMD: Split bigger patch, part 4/5] Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20240503072014.24751-7-philmd@linaro.org> --- target/alpha/translate.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/target/alpha/translate.c b/target/alpha/translate.c index 41151f002e..b7b94cc378 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -461,23 +461,22 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, uint64_t dest = ctx->base.pc_next + disp; TCGLabel *lab_true = gen_new_label(); - if (use_goto_tb(ctx, dest)) { - tcg_gen_brcondi_i64(cond, cmp, imm, lab_true); - + tcg_gen_brcondi_i64(cond, cmp, imm, lab_true); + if (use_goto_tb(ctx, ctx->base.pc_next)) { tcg_gen_goto_tb(0); tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); tcg_gen_exit_tb(ctx->base.tb, 0); - - gen_set_label(lab_true); + } else { + tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); + tcg_gen_lookup_and_goto_ptr(); + } + gen_set_label(lab_true); + if (use_goto_tb(ctx, dest)) { tcg_gen_goto_tb(1); tcg_gen_movi_i64(cpu_pc, dest); tcg_gen_exit_tb(ctx->base.tb, 1); } else { - TCGv_i64 i = tcg_constant_i64(imm); - TCGv_i64 d = tcg_constant_i64(dest); - TCGv_i64 p = tcg_constant_i64(ctx->base.pc_next); - - tcg_gen_movcond_i64(cond, cpu_pc, cmp, i, d, p); + tcg_gen_movi_i64(cpu_pc, dest); tcg_gen_lookup_and_goto_ptr(); } From 82b60d2509ddb9123c48ea773c58886b7dad22d7 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 3 May 2024 09:20:11 +0200 Subject: [PATCH 7/9] target/alpha: Split out gen_goto_tb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Richard Henderson Message-Id: <20240424234436.995410-4-richard.henderson@linaro.org> [PMD: Split bigger patch, part 5/5] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20240503072014.24751-8-philmd@linaro.org> --- target/alpha/translate.c | 53 ++++++++++++---------------------------- 1 file changed, 16 insertions(+), 37 deletions(-) diff --git a/target/alpha/translate.c b/target/alpha/translate.c index b7b94cc378..c1a55e5153 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -425,15 +425,22 @@ static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb, return DISAS_NEXT; } -static bool use_goto_tb(DisasContext *ctx, uint64_t dest) +static void gen_goto_tb(DisasContext *ctx, int idx, int32_t disp) { - return translator_use_goto_tb(&ctx->base, dest); + uint64_t dest = ctx->base.pc_next + disp; + + if (translator_use_goto_tb(&ctx->base, dest)) { + tcg_gen_goto_tb(idx); + tcg_gen_movi_i64(cpu_pc, dest); + tcg_gen_exit_tb(ctx->base.tb, idx); + } else { + tcg_gen_movi_i64(cpu_pc, dest); + tcg_gen_lookup_and_goto_ptr(); + } } static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) { - uint64_t dest = ctx->base.pc_next + disp; - if (ra != 31) { tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next); } @@ -442,43 +449,19 @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) if (disp == 0) { return DISAS_NEXT; } - - if (use_goto_tb(ctx, dest)) { - tcg_gen_goto_tb(0); - tcg_gen_movi_i64(cpu_pc, dest); - tcg_gen_exit_tb(ctx->base.tb, 0); - } else { - tcg_gen_movi_i64(cpu_pc, dest); - tcg_gen_lookup_and_goto_ptr(); - } - + gen_goto_tb(ctx, 0, disp); return DISAS_NORETURN; } static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, TCGv cmp, uint64_t imm, int32_t disp) { - uint64_t dest = ctx->base.pc_next + disp; TCGLabel *lab_true = gen_new_label(); tcg_gen_brcondi_i64(cond, cmp, imm, lab_true); - if (use_goto_tb(ctx, ctx->base.pc_next)) { - tcg_gen_goto_tb(0); - tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); - tcg_gen_exit_tb(ctx->base.tb, 0); - } else { - tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); - tcg_gen_lookup_and_goto_ptr(); - } + gen_goto_tb(ctx, 0, 0); gen_set_label(lab_true); - if (use_goto_tb(ctx, dest)) { - tcg_gen_goto_tb(1); - tcg_gen_movi_i64(cpu_pc, dest); - tcg_gen_exit_tb(ctx->base.tb, 1); - } else { - tcg_gen_movi_i64(cpu_pc, dest); - tcg_gen_lookup_and_goto_ptr(); - } + gen_goto_tb(ctx, 1, disp); return DISAS_NORETURN; } @@ -2922,12 +2905,8 @@ static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_NORETURN: break; case DISAS_TOO_MANY: - if (use_goto_tb(ctx, ctx->base.pc_next)) { - tcg_gen_goto_tb(0); - tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); - tcg_gen_exit_tb(ctx->base.tb, 0); - } - /* FALLTHRU */ + gen_goto_tb(ctx, 0, 0); + break; case DISAS_PC_STALE: tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); /* FALLTHRU */ From b1a3eacf314ba829506f65c227b57676db4ddbac Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 3 May 2024 09:20:12 +0200 Subject: [PATCH 8/9] target/alpha: Split out gen_pc_disp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepare for pcrel by not modifying cpu_pc before use, in the case of JSR. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20240503072014.24751-9-philmd@linaro.org> --- target/alpha/translate.c | 41 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/target/alpha/translate.c b/target/alpha/translate.c index c1a55e5153..86402d96d5 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -252,6 +252,11 @@ static void st_flag_byte(TCGv val, unsigned shift) tcg_gen_st8_i64(val, tcg_env, get_flag_ofs(shift)); } +static void gen_pc_disp(DisasContext *ctx, TCGv dest, int32_t disp) +{ + tcg_gen_movi_i64(dest, ctx->base.pc_next + disp); +} + static void gen_excp_1(int exception, int error_code) { TCGv_i32 tmp1, tmp2; @@ -263,7 +268,7 @@ static void gen_excp_1(int exception, int error_code) static DisasJumpType gen_excp(DisasContext *ctx, int exception, int error_code) { - tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); + gen_pc_disp(ctx, cpu_pc, 0); gen_excp_1(exception, error_code); return DISAS_NORETURN; } @@ -427,14 +432,12 @@ static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb, static void gen_goto_tb(DisasContext *ctx, int idx, int32_t disp) { - uint64_t dest = ctx->base.pc_next + disp; - - if (translator_use_goto_tb(&ctx->base, dest)) { + if (translator_use_goto_tb(&ctx->base, ctx->base.pc_next + disp)) { tcg_gen_goto_tb(idx); - tcg_gen_movi_i64(cpu_pc, dest); + gen_pc_disp(ctx, cpu_pc, disp); tcg_gen_exit_tb(ctx->base.tb, idx); } else { - tcg_gen_movi_i64(cpu_pc, dest); + gen_pc_disp(ctx, cpu_pc, disp); tcg_gen_lookup_and_goto_ptr(); } } @@ -442,7 +445,7 @@ static void gen_goto_tb(DisasContext *ctx, int idx, int32_t disp) static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) { if (ra != 31) { - tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next); + gen_pc_disp(ctx, ctx->ir[ra], 0); } /* Notice branch-to-next; used to initialize RA with the PC. */ @@ -1091,7 +1094,7 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode) } /* Allow interrupts to be recognized right away. */ - tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); + gen_pc_disp(ctx, cpu_pc, 0); return DISAS_PC_UPDATED_NOCHAIN; case 0x36: @@ -1138,19 +1141,17 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode) #else { TCGv tmp = tcg_temp_new(); - uint64_t exc_addr = ctx->base.pc_next; - uint64_t entry = ctx->palbr; + uint64_t entry; + gen_pc_disp(ctx, tmp, 0); if (ctx->tbflags & ENV_FLAG_PAL_MODE) { - exc_addr |= 1; + tcg_gen_ori_i64(tmp, tmp, 1); } else { - tcg_gen_movi_i64(tmp, 1); - st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT); + st_flag_byte(tcg_constant_i64(1), ENV_FLAG_PAL_SHIFT); } - - tcg_gen_movi_i64(tmp, exc_addr); tcg_gen_st_i64(tmp, tcg_env, offsetof(CPUAlphaState, exc_addr)); + entry = ctx->palbr; entry += (palcode & 0x80 ? 0x2000 + (palcode - 0x80) * 64 : 0x1000 + palcode * 64); @@ -2344,9 +2345,13 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) /* JMP, JSR, RET, JSR_COROUTINE. These only differ by the branch prediction stack action, which of course we don't implement. */ vb = load_gpr(ctx, rb); - tcg_gen_andi_i64(cpu_pc, vb, ~3); if (ra != 31) { - tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next); + tmp = tcg_temp_new(); + tcg_gen_andi_i64(tmp, vb, ~3); + gen_pc_disp(ctx, ctx->ir[ra], 0); + tcg_gen_mov_i64(cpu_pc, tmp); + } else { + tcg_gen_andi_i64(cpu_pc, vb, ~3); } ret = DISAS_PC_UPDATED; break; @@ -2908,7 +2913,7 @@ static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) gen_goto_tb(ctx, 0, 0); break; case DISAS_PC_STALE: - tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); + gen_pc_disp(ctx, cpu_pc, 0); /* FALLTHRU */ case DISAS_PC_UPDATED: tcg_gen_lookup_and_goto_ptr(); From 23bb086350c0de390f77dd034d775742314cabd7 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 3 May 2024 09:20:13 +0200 Subject: [PATCH 9/9] target/alpha: Implement CF_PCREL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20240503072014.24751-10-philmd@linaro.org> --- target/alpha/cpu.c | 23 ++++++++++++++++++++++- target/alpha/translate.c | 29 +++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index f98d022671..0e2fbcb397 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -38,12 +38,27 @@ static vaddr alpha_cpu_get_pc(CPUState *cs) return env->pc; } +static void alpha_cpu_synchronize_from_tb(CPUState *cs, + const TranslationBlock *tb) +{ + /* The program counter is always up to date with CF_PCREL. */ + if (!(tb_cflags(tb) & CF_PCREL)) { + CPUAlphaState *env = cpu_env(cs); + env->pc = tb->pc; + } +} + static void alpha_restore_state_to_opc(CPUState *cs, const TranslationBlock *tb, const uint64_t *data) { CPUAlphaState *env = cpu_env(cs); - env->pc = data[0]; + + if (tb_cflags(tb) & CF_PCREL) { + env->pc = (env->pc & TARGET_PAGE_MASK) | data[0]; + } else { + env->pc = data[0]; + } } static bool alpha_cpu_has_work(CPUState *cs) @@ -78,6 +93,11 @@ static void alpha_cpu_realizefn(DeviceState *dev, Error **errp) AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev); Error *local_err = NULL; +#ifndef CONFIG_USER_ONLY + /* Use pc-relative instructions in system-mode */ + cs->tcg_cflags |= CF_PCREL; +#endif + cpu_exec_realizefn(cs, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); @@ -190,6 +210,7 @@ static const struct SysemuCPUOps alpha_sysemu_ops = { static const TCGCPUOps alpha_tcg_ops = { .initialize = alpha_translate_init, + .synchronize_from_tb = alpha_cpu_synchronize_from_tb, .restore_state_to_opc = alpha_restore_state_to_opc, #ifdef CONFIG_USER_ONLY diff --git a/target/alpha/translate.c b/target/alpha/translate.c index 86402d96d5..db847e7a23 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -54,6 +54,9 @@ struct DisasContext { uint32_t tbflags; int mem_idx; + /* True if generating pc-relative code. */ + bool pcrel; + /* implver and amask values for this CPU. */ int implver; int amask; @@ -254,7 +257,12 @@ static void st_flag_byte(TCGv val, unsigned shift) static void gen_pc_disp(DisasContext *ctx, TCGv dest, int32_t disp) { - tcg_gen_movi_i64(dest, ctx->base.pc_next + disp); + uint64_t addr = ctx->base.pc_next + disp; + if (ctx->pcrel) { + tcg_gen_addi_i64(dest, cpu_pc, addr - ctx->base.pc_first); + } else { + tcg_gen_movi_i64(dest, addr); + } } static void gen_excp_1(int exception, int error_code) @@ -433,8 +441,14 @@ static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb, static void gen_goto_tb(DisasContext *ctx, int idx, int32_t disp) { if (translator_use_goto_tb(&ctx->base, ctx->base.pc_next + disp)) { - tcg_gen_goto_tb(idx); - gen_pc_disp(ctx, cpu_pc, disp); + /* With PCREL, PC must always be up-to-date. */ + if (ctx->pcrel) { + gen_pc_disp(ctx, cpu_pc, disp); + tcg_gen_goto_tb(idx); + } else { + tcg_gen_goto_tb(idx); + gen_pc_disp(ctx, cpu_pc, disp); + } tcg_gen_exit_tb(ctx->base.tb, idx); } else { gen_pc_disp(ctx, cpu_pc, disp); @@ -2852,6 +2866,7 @@ static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) ctx->tbflags = ctx->base.tb->flags; ctx->mem_idx = alpha_env_mmu_index(env); + ctx->pcrel = ctx->base.tb->cflags & CF_PCREL; ctx->implver = env->implver; ctx->amask = env->amask; @@ -2887,7 +2902,13 @@ static void alpha_tr_tb_start(DisasContextBase *db, CPUState *cpu) static void alpha_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) { - tcg_gen_insn_start(dcbase->pc_next); + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + if (ctx->pcrel) { + tcg_gen_insn_start(dcbase->pc_next & ~TARGET_PAGE_MASK); + } else { + tcg_gen_insn_start(dcbase->pc_next); + } } static void alpha_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)