Commit 9a2b5256 authored by Richard Henderson's avatar Richard Henderson Committed by Peter Maydell
Browse files

target/arm: Add aa{32, 64}_vfp_{dreg, qreg} helpers



Helpers that return a pointer into env->vfp.regs so that we isolate
the logic of how to index the regs array for different cpu modes.

Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20180119045438.28582-7-richard.henderson@linaro.org
Reviewed-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 3f68b8a5
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -1487,12 +1487,13 @@ static int target_setup_sigframe(struct target_rt_sigframe *sf,
    }

    for (i = 0; i < 32; i++) {
        uint64_t *q = aa64_vfp_qreg(env, i);
#ifdef TARGET_WORDS_BIGENDIAN
        __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
        __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
        __put_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
        __put_user(q[1], &aux->fpsimd.vregs[i * 2]);
#else
        __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
        __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
        __put_user(q[0], &aux->fpsimd.vregs[i * 2]);
        __put_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
#endif
    }
    __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
@@ -1539,12 +1540,13 @@ static int target_restore_sigframe(CPUARMState *env,
    }

    for (i = 0; i < 32; i++) {
        uint64_t *q = aa64_vfp_qreg(env, i);
#ifdef TARGET_WORDS_BIGENDIAN
        __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
        __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
        __get_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
        __get_user(q[1], &aux->fpsimd.vregs[i * 2]);
#else
        __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
        __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
        __get_user(q[0], &aux->fpsimd.vregs[i * 2]);
        __get_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
#endif
    }
    __get_user(fpsr, &aux->fpsimd.fpsr);
@@ -1903,7 +1905,7 @@ static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
    __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
    __put_user(sizeof(*vfpframe), &vfpframe->size);
    for (i = 0; i < 32; i++) {
        __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
        __put_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]);
    }
    __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
    __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
@@ -2210,7 +2212,7 @@ static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
        return 0;
    }
    for (i = 0; i < 32; i++) {
        __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
        __get_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]);
    }
    __get_user(fpscr, &vfpframe->ufp.fpscr);
    vfp_set_fpscr(env, fpscr);
+5 −3
Original line number Diff line number Diff line
@@ -99,8 +99,10 @@ static int aarch64_write_elf64_prfpreg(WriteCoreDumpFunction f,

    aarch64_note_init(&note, s, "CORE", 5, NT_PRFPREG, sizeof(note.vfp));

    for (i = 0; i < 64; ++i) {
        note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
    for (i = 0; i < 32; ++i) {
        uint64_t *q = aa64_vfp_qreg(env, i);
        note.vfp.vregs[2*i + 0] = cpu_to_dump64(s, q[0]);
        note.vfp.vregs[2*i + 1] = cpu_to_dump64(s, q[1]);
    }

    if (s->dump_info.d_endian == ELFDATA2MSB) {
@@ -229,7 +231,7 @@ static int arm_write_elf32_vfp(WriteCoreDumpFunction f, CPUARMState *env,
    arm_note_init(&note, s, "LINUX", 6, NT_ARM_VFP, sizeof(note.vfp));

    for (i = 0; i < 32; ++i) {
        note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
        note.vfp.vregs[i] = cpu_to_dump64(s, *aa32_vfp_dreg(env, i));
    }

    note.vfp.fpscr = cpu_to_dump32(s, vfp_get_fpscr(env));
+27 −0
Original line number Diff line number Diff line
@@ -2885,4 +2885,31 @@ static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
    return cpu->el_change_hook_opaque;
}

/**
 * aa32_vfp_dreg:
 * Return a pointer to the Dn register within env in 32-bit mode.
 */
static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
{
    return &env->vfp.regs[regno];
}

/**
 * aa32_vfp_qreg:
 * Return a pointer to the Qn register within env in 32-bit mode.
 */
static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
{
    return &env->vfp.regs[2 * regno];
}

/**
 * aa64_vfp_qreg:
 * Return a pointer to the Qn register within env in 64-bit mode.
 */
static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
{
    return &env->vfp.regs[2 * regno];
}

#endif
+3 −2
Original line number Diff line number Diff line
@@ -153,13 +153,14 @@ uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
        if (index < 16 * numregs) {
            /* Convert index (a byte offset into the virtual table
             * which is a series of 128-bit vectors concatenated)
             * into the correct vfp.regs[] element plus a bit offset
             * into the correct register element plus a bit offset
             * into that element, bearing in mind that the table
             * can wrap around from V31 to V0.
             */
            int elt = (rn * 2 + (index >> 3)) % 64;
            int bitidx = (index & 7) * 8;
            uint64_t val = extract64(env->vfp.regs[elt], bitidx, 8);
            uint64_t *q = aa64_vfp_qreg(env, elt >> 1);
            uint64_t val = extract64(q[elt & 1], bitidx, 8);

            result = deposit64(result, shift, 8, val);
        }
+20 −12
Original line number Diff line number Diff line
@@ -64,15 +64,16 @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
    /* VFP data registers are always little-endian.  */
    nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
    if (reg < nregs) {
        stq_le_p(buf, env->vfp.regs[reg]);
        stq_le_p(buf, *aa32_vfp_dreg(env, reg));
        return 8;
    }
    if (arm_feature(env, ARM_FEATURE_NEON)) {
        /* Aliases for Q regs.  */
        nregs += 16;
        if (reg < nregs) {
            stq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
            stq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
            uint64_t *q = aa32_vfp_qreg(env, reg - 32);
            stq_le_p(buf, q[0]);
            stq_le_p(buf + 8, q[1]);
            return 16;
        }
    }
@@ -90,14 +91,15 @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)

    nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
    if (reg < nregs) {
        env->vfp.regs[reg] = ldq_le_p(buf);
        *aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
        return 8;
    }
    if (arm_feature(env, ARM_FEATURE_NEON)) {
        nregs += 16;
        if (reg < nregs) {
            env->vfp.regs[(reg - 32) * 2] = ldq_le_p(buf);
            env->vfp.regs[(reg - 32) * 2 + 1] = ldq_le_p(buf + 8);
            uint64_t *q = aa32_vfp_qreg(env, reg - 32);
            q[0] = ldq_le_p(buf);
            q[1] = ldq_le_p(buf + 8);
            return 16;
        }
    }
@@ -114,9 +116,12 @@ static int aarch64_fpu_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
    switch (reg) {
    case 0 ... 31:
        /* 128 bit FP register */
        stq_le_p(buf, env->vfp.regs[reg * 2]);
        stq_le_p(buf + 8, env->vfp.regs[reg * 2 + 1]);
        {
            uint64_t *q = aa64_vfp_qreg(env, reg);
            stq_le_p(buf, q[0]);
            stq_le_p(buf + 8, q[1]);
            return 16;
        }
    case 32:
        /* FPSR */
        stl_p(buf, vfp_get_fpsr(env));
@@ -135,9 +140,12 @@ static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
    switch (reg) {
    case 0 ... 31:
        /* 128 bit FP register */
        env->vfp.regs[reg * 2] = ldq_le_p(buf);
        env->vfp.regs[reg * 2 + 1] = ldq_le_p(buf + 8);
        {
            uint64_t *q = aa64_vfp_qreg(env, reg);
            q[0] = ldq_le_p(buf);
            q[1] = ldq_le_p(buf + 8);
            return 16;
        }
    case 32:
        /* FPSR */
        vfp_set_fpsr(env, ldl_p(buf));
Loading