On 5/13/24 09:46, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Helge Deller <deller@gmx.de>
> ---
> target/hppa/cpu.h | 43 ++-----------------------------------------
> target/hppa/cpu.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 44 insertions(+), 41 deletions(-)
>
> diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
> index fb2e4c4a98..61f1353133 100644
> --- a/target/hppa/cpu.h
> +++ b/target/hppa/cpu.h
> @@ -314,47 +314,8 @@ hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr);
> #define TB_FLAG_PRIV_SHIFT 8
> #define TB_FLAG_UNALIGN 0x400
>
> -static inline void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
> - uint64_t *cs_base, uint32_t *pflags)
> -{
> - uint32_t flags = env->psw_n * PSW_N;
> -
> - /* TB lookup assumes that PC contains the complete virtual address.
> - If we leave space+offset separate, we'll get ITLB misses to an
> - incomplete virtual address. This also means that we must separate
> - out current cpu privilege from the low bits of IAOQ_F. */
> -#ifdef CONFIG_USER_ONLY
> - *pc = env->iaoq_f & -4;
> - *cs_base = env->iaoq_b & -4;
> - flags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus;
> -#else
> - /* ??? E, T, H, L, B bits need to be here, when implemented. */
> - flags |= env->psw & (PSW_W | PSW_C | PSW_D | PSW_P);
> - flags |= (env->iaoq_f & 3) << TB_FLAG_PRIV_SHIFT;
> -
> - *pc = hppa_form_gva_psw(env->psw, (env->psw & PSW_C ? env->iasq_f : 0),
> - env->iaoq_f & -4);
> - *cs_base = env->iasq_f;
> -
> - /* Insert a difference between IAOQ_B and IAOQ_F within the otherwise zero
> - low 32-bits of CS_BASE. This will succeed for all direct branches,
> - which is the primary case we care about -- using goto_tb within a page.
> - Failure is indicated by a zero difference. */
> - if (env->iasq_f == env->iasq_b) {
> - target_long diff = env->iaoq_b - env->iaoq_f;
> - if (diff == (int32_t)diff) {
> - *cs_base |= (uint32_t)diff;
> - }
> - }
> - if ((env->sr[4] == env->sr[5])
> - & (env->sr[4] == env->sr[6])
> - & (env->sr[4] == env->sr[7])) {
> - flags |= TB_FLAG_SR_SAME;
> - }
> -#endif
> -
> - *pflags = flags;
> -}
> +void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
> + uint64_t *cs_base, uint32_t *pflags);
>
> target_ulong cpu_hppa_get_psw(CPUHPPAState *env);
> void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong);
> diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
> index 393a81988d..582036b31e 100644
> --- a/target/hppa/cpu.c
> +++ b/target/hppa/cpu.c
> @@ -43,6 +43,48 @@ static vaddr hppa_cpu_get_pc(CPUState *cs)
> return cpu->env.iaoq_f;
> }
>
> +void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
> + uint64_t *cs_base, uint32_t *pflags)
> +{
> + uint32_t flags = env->psw_n * PSW_N;
> +
> + /* TB lookup assumes that PC contains the complete virtual address.
> + If we leave space+offset separate, we'll get ITLB misses to an
> + incomplete virtual address. This also means that we must separate
> + out current cpu privilege from the low bits of IAOQ_F. */
> +#ifdef CONFIG_USER_ONLY
> + *pc = env->iaoq_f & -4;
> + *cs_base = env->iaoq_b & -4;
> + flags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus;
> +#else
> + /* ??? E, T, H, L, B bits need to be here, when implemented. */
> + flags |= env->psw & (PSW_W | PSW_C | PSW_D | PSW_P);
> + flags |= (env->iaoq_f & 3) << TB_FLAG_PRIV_SHIFT;
> +
> + *pc = hppa_form_gva_psw(env->psw, (env->psw & PSW_C ? env->iasq_f : 0),
> + env->iaoq_f & -4);
> + *cs_base = env->iasq_f;
> +
> + /* Insert a difference between IAOQ_B and IAOQ_F within the otherwise zero
> + low 32-bits of CS_BASE. This will succeed for all direct branches,
> + which is the primary case we care about -- using goto_tb within a page.
> + Failure is indicated by a zero difference. */
> + if (env->iasq_f == env->iasq_b) {
> + target_long diff = env->iaoq_b - env->iaoq_f;
> + if (diff == (int32_t)diff) {
> + *cs_base |= (uint32_t)diff;
> + }
> + }
> + if ((env->sr[4] == env->sr[5])
> + & (env->sr[4] == env->sr[6])
> + & (env->sr[4] == env->sr[7])) {
> + flags |= TB_FLAG_SR_SAME;
> + }
> +#endif
> +
> + *pflags = flags;
> +}
> +
> static void hppa_cpu_synchronize_from_tb(CPUState *cs,
> const TranslationBlock *tb)
> {