mirror of
https://github.com/qemu/qemu.git
synced 2024-12-12 05:03:42 +08:00
target/hppa: Implement rfi
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
7f221b0706
commit
f49b3537cb
@ -178,6 +178,7 @@ struct CPUHPPAState {
|
||||
|
||||
target_ureg cr[32]; /* control registers */
|
||||
target_ureg cr_back[2]; /* back of cr17/cr18 */
|
||||
target_ureg shadow[7]; /* shadow registers */
|
||||
|
||||
/* Those resources are used only in QEMU core */
|
||||
CPU_COMMON
|
||||
|
@ -78,5 +78,7 @@ DEF_HELPER_FLAGS_4(fmpyfadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
|
||||
DEF_HELPER_FLAGS_4(fmpynfadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
DEF_HELPER_1(rfi, void, env)
|
||||
DEF_HELPER_1(rfi_r, void, env)
|
||||
DEF_HELPER_FLAGS_2(swap_system_mask, TCG_CALL_NO_RWG, tr, env, tr)
|
||||
#endif
|
||||
|
@ -614,4 +614,28 @@ target_ureg HELPER(swap_system_mask)(CPUHPPAState *env, target_ureg nsm)
|
||||
env->psw = (psw & ~PSW_SM) | (nsm & PSW_SM);
|
||||
return psw & PSW_SM;
|
||||
}
|
||||
|
||||
void HELPER(rfi)(CPUHPPAState *env)
|
||||
{
|
||||
/* ??? On second reading this condition simply seems
|
||||
to be undefined rather than a diagnosed trap. */
|
||||
if (env->psw & (PSW_I | PSW_R | PSW_Q)) {
|
||||
helper_excp(env, EXCP_ILL);
|
||||
}
|
||||
env->iaoq_f = env->cr[CR_IIAOQ];
|
||||
env->iaoq_b = env->cr_back[1];
|
||||
cpu_hppa_put_psw(env, env->cr[CR_IPSW]);
|
||||
}
|
||||
|
||||
void HELPER(rfi_r)(CPUHPPAState *env)
|
||||
{
|
||||
env->gr[1] = env->shadow[0];
|
||||
env->gr[8] = env->shadow[1];
|
||||
env->gr[9] = env->shadow[2];
|
||||
env->gr[16] = env->shadow[3];
|
||||
env->gr[17] = env->shadow[4];
|
||||
env->gr[24] = env->shadow[5];
|
||||
env->gr[25] = env->shadow[6];
|
||||
helper_rfi(env);
|
||||
}
|
||||
#endif
|
||||
|
@ -655,6 +655,10 @@ static DisasJumpType nullify_end(DisasContext *ctx, DisasJumpType status)
|
||||
{
|
||||
TCGLabel *null_lab = ctx->null_lab;
|
||||
|
||||
/* For NEXT, NORETURN, STALE, we can easily continue (or exit).
|
||||
For UPDATED, we cannot update on the nullified path. */
|
||||
assert(status != DISAS_IAQ_N_UPDATED);
|
||||
|
||||
if (likely(null_lab == NULL)) {
|
||||
/* The current insn wasn't conditional or handled the condition
|
||||
applied to it without a branch, so the (new) setting of
|
||||
@ -676,8 +680,6 @@ static DisasJumpType nullify_end(DisasContext *ctx, DisasJumpType status)
|
||||
gen_set_label(null_lab);
|
||||
ctx->null_cond = cond_make_n();
|
||||
}
|
||||
|
||||
assert(status != DISAS_NORETURN && status != DISAS_IAQ_N_UPDATED);
|
||||
if (status == DISAS_NORETURN) {
|
||||
status = DISAS_NEXT;
|
||||
}
|
||||
@ -2153,6 +2155,29 @@ static DisasJumpType trans_mtsm(DisasContext *ctx, uint32_t insn,
|
||||
/* Exit the TB to recognize new interrupts. */
|
||||
return nullify_end(ctx, DISAS_IAQ_N_STALE_EXIT);
|
||||
}
|
||||
|
||||
static DisasJumpType trans_rfi(DisasContext *ctx, uint32_t insn,
|
||||
const DisasInsn *di)
|
||||
{
|
||||
unsigned comp = extract32(insn, 5, 4);
|
||||
|
||||
CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
|
||||
nullify_over(ctx);
|
||||
|
||||
if (comp == 5) {
|
||||
gen_helper_rfi_r(cpu_env);
|
||||
} else {
|
||||
gen_helper_rfi(cpu_env);
|
||||
}
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
gen_excp_1(EXCP_DEBUG);
|
||||
} else {
|
||||
tcg_gen_exit_tb(0);
|
||||
}
|
||||
|
||||
/* Exit the TB to recognize new interrupts. */
|
||||
return nullify_end(ctx, DISAS_NORETURN);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
static const DisasInsn table_system[] = {
|
||||
@ -2169,6 +2194,7 @@ static const DisasInsn table_system[] = {
|
||||
{ 0x00000e60u, 0xfc00ffe0u, trans_rsm },
|
||||
{ 0x00000d60u, 0xfc00ffe0u, trans_ssm },
|
||||
{ 0x00001860u, 0xffe0ffffu, trans_mtsm },
|
||||
{ 0x00000c00u, 0xfffffe1fu, trans_rfi },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user