summary refs log tree commit diff stats
path: root/target/arm/helper.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2019-02-15 09:56:41 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-02-15 09:56:41 +0000
commita4d5846245c5e029e5aa3945a9bda1de1c3fedbf (patch)
tree0c2f1bfef43d253eec7def5ddea82c7d26a515a1 /target/arm/helper.c
parent18aaa59c622208743565307668a2100ab24f7de9 (diff)
downloadfocaccia-qemu-a4d5846245c5e029e5aa3945a9bda1de1c3fedbf.tar.gz
focaccia-qemu-a4d5846245c5e029e5aa3945a9bda1de1c3fedbf.zip
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: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190209033847.9014-11-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/helper.c')
-rw-r--r--target/arm/helper.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d4b7eca30a..55e9b77bb1 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -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;