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

target/arm: Split out FPSCR.QC to a vector field



Change the representation of this field such that it is easy
to set from vector code.

Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20190209033847.9014-11-richard.henderson@linaro.org
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 18aaa59c
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -577,11 +577,13 @@ typedef struct CPUARMState {
        ARMPredicateReg preg_tmp;
#endif

        uint32_t xregs[16];
        /* We store these fpcsr fields separately for convenience.  */
        uint32_t qc[4] QEMU_ALIGNED(16);
        int vec_len;
        int vec_stride;

        uint32_t xregs[16];

        /* Scratch space for aa32 neon expansion.  */
        uint32_t scratch[8];

@@ -1427,6 +1429,7 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
#define FPCR_FZ16   (1 << 19)   /* ARMv8.2+, FP16 flush-to-zero */
#define FPCR_FZ     (1 << 24)   /* Flush-to-zero enable bit */
#define FPCR_DN     (1 << 25)   /* Default NaN enable bit */
#define FPCR_QC     (1 << 27)   /* Cumulative saturation bit */

static inline uint32_t vfp_get_fpsr(CPUARMState *env)
{
+15 −4
Original line number Diff line number Diff line
@@ -12704,8 +12704,7 @@ static inline int vfp_exceptbits_from_host(int host_bits)

uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
{
    int i;
    uint32_t fpscr;
    uint32_t i, fpscr;

    fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
            | (env->vfp.vec_len << 16)
@@ -12716,8 +12715,11 @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
    /* FZ16 does not generate an input denormal exception.  */
    i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
          & ~float_flag_input_denormal);

    fpscr |= vfp_exceptbits_from_host(i);

    i = env->vfp.qc[0] | env->vfp.qc[1] | env->vfp.qc[2] | env->vfp.qc[3];
    fpscr |= i ? FPCR_QC : 0;

    return fpscr;
}

@@ -12764,10 +12766,19 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
     * (which are stored in fp_status), and the other RES0 bits
     * in between, then we clear all of the low 16 bits.
     */
    env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xffc80000;
    env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c80000;
    env->vfp.vec_len = (val >> 16) & 7;
    env->vfp.vec_stride = (val >> 20) & 3;

    /*
     * The bit we set within fpscr_q is arbitrary; the register as a
     * whole being zero/non-zero is what counts.
     */
    env->vfp.qc[0] = val & FPCR_QC;
    env->vfp.qc[1] = 0;
    env->vfp.qc[2] = 0;
    env->vfp.qc[3] = 0;

    changed ^= val;
    if (changed & (3 << 22)) {
        i = (val >> 22) & 3;
+1 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
#define SIGNBIT (uint32_t)0x80000000
#define SIGNBIT64 ((uint64_t)1 << 63)

#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q
#define SET_QC() env->vfp.qc[0] = 1

#define NEON_TYPE1(name, type) \
typedef struct \
+1 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@
#define H4(x)  (x)
#endif

#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q
#define SET_QC() env->vfp.qc[0] = 1

static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
{