Skip to content

Commit

Permalink
target/arm: Implement VLLDM for v7M CPUs with an FPU
Browse files Browse the repository at this point in the history
Implement the VLLDM instruction for v7M for the FPU present cas.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190416125744.27770-26-peter.maydell@linaro.org
  • Loading branch information
pm215 committed Apr 29, 2019
1 parent 019076b commit 956fe14
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
54 changes: 54 additions & 0 deletions target/arm/helper.c
Expand Up @@ -7390,6 +7390,12 @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
g_assert_not_reached();
}

void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
{
/* translate.c should never generate calls here in user-only mode */
g_assert_not_reached();
}

uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
{
/* The TT instructions can be used by unprivileged code, but in
Expand Down Expand Up @@ -8474,6 +8480,54 @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
}

void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
{
/* fptr is the value of Rn, the frame pointer we load the FP regs from */
assert(env->v7m.secure);

if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
return;
}

/* Check access to the coprocessor is permitted */
if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
}

if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
/* State in FP is still valid */
env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK;
} else {
bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
int i;
uint32_t fpscr;

if (fptr & 7) {
raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
}

for (i = 0; i < (ts ? 32 : 16); i += 2) {
uint32_t slo, shi;
uint64_t dn;
uint32_t faddr = fptr + 4 * i;

if (i >= 16) {
faddr += 8; /* skip the slot for the FPSCR */
}

slo = cpu_ldl_data(env, faddr);
shi = cpu_ldl_data(env, faddr + 4);

dn = (uint64_t) shi << 32 | slo;
*aa32_vfp_dreg(env, i / 2) = dn;
}
fpscr = cpu_ldl_data(env, fptr + 0x40);
vfp_set_fpscr(env, fpscr);
}

env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
}

static bool v7m_push_stack(ARMCPU *cpu)
{
/* Do the "set up stack frame" part of exception entry,
Expand Down
1 change: 1 addition & 0 deletions target/arm/helper.h
Expand Up @@ -72,6 +72,7 @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
DEF_HELPER_1(v7m_preserve_fp_state, void, env)

DEF_HELPER_2(v7m_vlstm, void, env, i32)
DEF_HELPER_2(v7m_vlldm, void, env, i32)

DEF_HELPER_2(v8m_stackcheck, void, env, i32)

Expand Down
2 changes: 1 addition & 1 deletion target/arm/translate.c
Expand Up @@ -11823,7 +11823,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
TCGv_i32 fptr = load_reg(s, rn);

if (extract32(insn, 20, 1)) {
/* VLLDM */
gen_helper_v7m_vlldm(cpu_env, fptr);
} else {
gen_helper_v7m_vlstm(cpu_env, fptr);
}
Expand Down

0 comments on commit 956fe14

Please sign in to comment.