Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- 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 a072d0bb63..01dc8781a5 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -320,47 +320,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 3831cb6db2..1d5f5086bf 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) { -- 2.34.1