Pass the register number (rd) to the wfit helper and report it in the
syndrome ISS. This also includes the correction of the TI bits for
WFIT traps to 0b10.
TODO: split the helper flags
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
target/arm/syndrome.h | 4 +++-
target/arm/tcg/helper-defs.h | 2 +-
target/arm/tcg/op_helper.c | 7 ++++---
target/arm/tcg/translate-a64.c | 2 +-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index 1887467b719..f303c41d71a 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -670,7 +670,7 @@ FIELD(WFX_ISS, RN, 5, 5)
FIELD(WFX_ISS, COND, 20, 4)
FIELD(WFX_ISS, CV, 24, 1)
-static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
+static inline uint32_t syn_wfx(int cv, int cond, int rn, int rv, int ti, bool is_16bit)
{
uint32_t res = syn_set_ec(0, EC_WFX_TRAP);
res = FIELD_DP32(res, SYNDROME, IL, is_16bit ? 0 : 1);
@@ -678,6 +678,8 @@ static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
res = FIELD_DP32(res, WFX_ISS, CV, cv);
res = FIELD_DP32(res, WFX_ISS, COND, cond);
res = FIELD_DP32(res, WFX_ISS, TI, ti);
+ res = FIELD_DP32(res, WFX_ISS, RN, rn);
+ res = FIELD_DP32(res, WFX_ISS, RV, rv);
return res;
}
diff --git a/target/arm/tcg/helper-defs.h b/target/arm/tcg/helper-defs.h
index 5a10a9fba3b..a05f2258f29 100644
--- a/target/arm/tcg/helper-defs.h
+++ b/target/arm/tcg/helper-defs.h
@@ -55,7 +55,7 @@ DEF_HELPER_2(exception_pc_alignment, noreturn, env, vaddr)
DEF_HELPER_1(setend, void, env)
DEF_HELPER_2(wfi, void, env, i32)
DEF_HELPER_1(wfe, void, env)
-DEF_HELPER_2(wfit, void, env, i64)
+DEF_HELPER_2(wfit, void, env, i32)
DEF_HELPER_1(yield, void, env)
DEF_HELPER_1(pre_hvc, void, env)
DEF_HELPER_2(pre_smc, void, env, i32)
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
index aa14f15eb62..635c538ed4b 100644
--- a/target/arm/tcg/op_helper.c
+++ b/target/arm/tcg/op_helper.c
@@ -399,7 +399,7 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
env->regs[15] -= insn_len;
}
- raise_exception(env, excp, syn_wfx(1, 0xe, 0, insn_len == 2),
+ raise_exception(env, excp, syn_wfx(1, 0xe, 0, 0, 0, insn_len == 2),
target_el);
}
@@ -409,7 +409,7 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
#endif
}
-void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
+void HELPER(wfit)(CPUARMState *env, uint32_t rd)
{
#ifdef CONFIG_USER_ONLY
/*
@@ -428,6 +428,7 @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
int target_el = check_wfx_trap(env, false, &excp);
/* The WFIT should time out when CNTVCT_EL0 >= the specified value. */
uint64_t cntval = gt_get_countervalue(env);
+ uint64_t timeout = env->xregs[rd];
/*
* We want the value that we would get if we read CNTVCT_EL0 from
* the current exception level, so the direct_access offset, not
@@ -448,7 +449,7 @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
if (target_el) {
env->pc -= 4;
- raise_exception(env, excp, syn_wfx(1, 0xe, 2, false), target_el);
+ raise_exception(env, excp, syn_wfx(1, 0xe, rd, 1, 2, false), target_el);
}
if (uadd64_overflow(timeout, offset, &nexttick)) {
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 5d261a5e32b..073454b9195 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -2064,7 +2064,7 @@ static bool trans_WFIT(DisasContext *s, arg_WFIT *a)
}
gen_a64_update_pc(s, 4);
- gen_helper_wfit(tcg_env, cpu_reg(s, a->rd));
+ gen_helper_wfit(tcg_env, tcg_constant_i32(a->rd));
/* Go back to the main loop to check for interrupts */
s->base.is_jmp = DISAS_EXIT;
return true;
--
2.47.3