[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 08/24] target/arm: Rename FPSR_MASK and FPCR_MASK and define them
From: |
Peter Maydell |
Subject: |
[PULL 08/24] target/arm: Rename FPSR_MASK and FPCR_MASK and define them symbolically |
Date: |
Thu, 11 Jul 2024 14:18:06 +0100 |
Now that we store FPSR and FPCR separately, the FPSR_MASK and
FPCR_MASK macros are slightly confusingly named and the comment
describing them is out of date. Rename them to FPSCR_FPSR_MASK and
FPSCR_FPCR_MASK, document that they are the mask of which FPSCR bits
are architecturally mapped to which AArch64 register, and define them
symbolically rather than as hex values. (This latter requires
defining some extra macros for bits which we haven't previously
defined.)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240628142347.1283015-9-peter.maydell@linaro.org
---
target/arm/cpu.h | 41 ++++++++++++++++++++++++++++++++++-------
target/arm/machine.c | 3 ++-
target/arm/vfp_helper.c | 7 ++++---
3 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c75b0a73aec..4c656bdbb76 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1687,15 +1687,19 @@ static inline void xpsr_write(CPUARMState *env,
uint32_t val, uint32_t mask)
uint32_t vfp_get_fpscr(CPUARMState *env);
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
-/* FPCR, Floating Point Control Register
- * FPSR, Floating Poiht Status Register
+/*
+ * FPCR, Floating Point Control Register
+ * FPSR, Floating Point Status Register
*
- * For A64 the FPSCR is split into two logically distinct registers,
- * FPCR and FPSR. However since they still use non-overlapping bits
- * we store the underlying state in fpscr and just mask on read/write.
+ * For A64 floating point control and status bits are stored in
+ * two logically distinct registers, FPCR and FPSR. We store these
+ * in QEMU in vfp.fpcr and vfp.fpsr.
+ * For A32 there was only one register, FPSCR. The bits are arranged
+ * such that FPSCR bits map to FPCR or FPSR bits in the same bit positions,
+ * so we can use appropriate masking to handle FPSCR reads and writes.
+ * Note that the FPCR has some bits which are not visible in the
+ * AArch32 view (for FEAT_AFP). Writing the FPSCR leaves these unchanged.
*/
-#define FPSR_MASK 0xf800009f
-#define FPCR_MASK 0x07ff9f00
/* FPCR bits */
#define FPCR_IOE (1 << 8) /* Invalid Operation exception trap enable */
@@ -1704,7 +1708,9 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
#define FPCR_UFE (1 << 11) /* Underflow exception trap enable */
#define FPCR_IXE (1 << 12) /* Inexact exception trap enable */
#define FPCR_IDE (1 << 15) /* Input Denormal exception trap enable */
+#define FPCR_LEN_MASK (7 << 16) /* LEN, A-profile only */
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
+#define FPCR_STRIDE_MASK (3 << 20) /* Stride */
#define FPCR_RMODE_MASK (3 << 22) /* Rounding mode */
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
#define FPCR_DN (1 << 25) /* Default NaN enable bit */
@@ -1714,16 +1720,37 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
#define FPCR_LTPSIZE_MASK (7 << FPCR_LTPSIZE_SHIFT)
#define FPCR_LTPSIZE_LENGTH 3
+/* Cumulative exception trap enable bits */
+#define FPCR_EEXC_MASK (FPCR_IOE | FPCR_DZE | FPCR_OFE | FPCR_UFE | FPCR_IXE |
FPCR_IDE)
+
/* FPSR bits */
+#define FPSR_IOC (1 << 0) /* Invalid Operation cumulative exception */
+#define FPSR_DZC (1 << 1) /* Divide by Zero cumulative exception */
+#define FPSR_OFC (1 << 2) /* Overflow cumulative exception */
+#define FPSR_UFC (1 << 3) /* Underflow cumulative exception */
+#define FPSR_IXC (1 << 4) /* Inexact cumulative exception */
+#define FPSR_IDC (1 << 7) /* Input Denormal cumulative exception */
#define FPSR_QC (1 << 27) /* Cumulative saturation bit */
#define FPSR_V (1 << 28) /* FP overflow flag */
#define FPSR_C (1 << 29) /* FP carry flag */
#define FPSR_Z (1 << 30) /* FP zero flag */
#define FPSR_N (1 << 31) /* FP negative flag */
+/* Cumulative exception status bits */
+#define FPSR_CEXC_MASK (FPSR_IOC | FPSR_DZC | FPSR_OFC | FPSR_UFC | FPSR_IXC |
FPSR_IDC)
+
#define FPSR_NZCV_MASK (FPSR_N | FPSR_Z | FPSR_C | FPSR_V)
#define FPSR_NZCVQC_MASK (FPSR_NZCV_MASK | FPSR_QC)
+/* A32 FPSCR bits which architecturally map to FPSR bits */
+#define FPSCR_FPSR_MASK (FPSR_NZCVQC_MASK | FPSR_CEXC_MASK)
+/* A32 FPSCR bits which architecturally map to FPCR bits */
+#define FPSCR_FPCR_MASK (FPCR_EEXC_MASK | FPCR_LEN_MASK | FPCR_FZ16 | \
+ FPCR_STRIDE_MASK | FPCR_RMODE_MASK | \
+ FPCR_FZ | FPCR_DN | FPCR_AHP)
+/* These masks don't overlap: each bit lives in only one place */
+QEMU_BUILD_BUG_ON(FPSCR_FPSR_MASK & FPSCR_FPCR_MASK);
+
/**
* vfp_get_fpsr: read the AArch64 FPSR
* @env: CPU context
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 8c820955d95..a3c1e05e65d 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -43,7 +43,8 @@ static bool vfp_fpcr_fpsr_needed(void *opaque)
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
- return (vfp_get_fpcr(env) & ~FPCR_MASK) || (vfp_get_fpsr(env) &
~FPSR_MASK);
+ return (vfp_get_fpcr(env) & ~FPSCR_FPCR_MASK) ||
+ (vfp_get_fpsr(env) & ~FPSCR_FPSR_MASK);
}
static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
index 85e50ede373..cbe69ae3fe3 100644
--- a/target/arm/vfp_helper.c
+++ b/target/arm/vfp_helper.c
@@ -202,7 +202,8 @@ uint32_t vfp_get_fpsr(CPUARMState *env)
uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
{
- return (vfp_get_fpcr(env) & FPCR_MASK) | (vfp_get_fpsr(env) & FPSR_MASK);
+ return (vfp_get_fpcr(env) & FPSCR_FPCR_MASK) |
+ (vfp_get_fpsr(env) & FPSCR_FPSR_MASK);
}
uint32_t vfp_get_fpscr(CPUARMState *env)
@@ -280,8 +281,8 @@ void vfp_set_fpcr(CPUARMState *env, uint32_t val)
void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
{
- vfp_set_fpcr(env, val & FPCR_MASK);
- vfp_set_fpsr(env, val & FPSR_MASK);
+ vfp_set_fpcr(env, val & FPSCR_FPCR_MASK);
+ vfp_set_fpsr(env, val & FPSCR_FPSR_MASK);
}
void vfp_set_fpscr(CPUARMState *env, uint32_t val)
--
2.34.1
- [PULL 07/24] target/arm: Rename FPCR_ QC, NZCV macros to FPSR_, (continued)
- [PULL 07/24] target/arm: Rename FPCR_ QC, NZCV macros to FPSR_, Peter Maydell, 2024/07/11
- [PULL 16/24] hw/misc: In STM32L4x5 EXTI, consolidate 2 constants, Peter Maydell, 2024/07/11
- [PULL 09/24] target/arm: Allow FPCR bits that aren't in FPSCR, Peter Maydell, 2024/07/11
- [PULL 15/24] accel/tcg: Make TCGCPUOps::cpu_exec_halt mandatory, Peter Maydell, 2024/07/11
- [PULL 23/24] target/arm: Convert ADDHN, SUBHN, RADDHN, RSUBHN to decodetree, Peter Maydell, 2024/07/11
- [PULL 12/24] target/arm: Use cpu_env in cpu_untagged_addr, Peter Maydell, 2024/07/11
- [PULL 18/24] hw/arm: In STM32L4x5 SOC, connect USART devices to EXTI, Peter Maydell, 2024/07/11
- [PULL 22/24] target/arm: Convert SADDW, SSUBW, UADDW, USUBW to decodetree, Peter Maydell, 2024/07/11
- [PULL 11/24] hw/misc/bcm2835_thermal: Fix access size handling in bcm2835_thermal_ops, Peter Maydell, 2024/07/11
- [PULL 20/24] target/arm: Convert SADDL, SSUBL, SABDL, SABAL, and unsigned to decodetree, Peter Maydell, 2024/07/11
- [PULL 08/24] target/arm: Rename FPSR_MASK and FPCR_MASK and define them symbolically,
Peter Maydell <=
- [PULL 14/24] target: Set TCGCPUOps::cpu_exec_halt to target's has_work implementation, Peter Maydell, 2024/07/11
- [PULL 21/24] target/arm: Convert SQDMULL, SQDMLAL, SQDMLSL to decodetree, Peter Maydell, 2024/07/11
- Re: [PULL 00/24] target-arm queue, Richard Henderson, 2024/07/11