diff options
Diffstat (limited to 'target/arm/cpu.h')
| -rw-r--r-- | target/arm/cpu.h | 113 |
1 files changed, 79 insertions, 34 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index d8eb986a04..a12859fc53 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -619,6 +619,13 @@ typedef struct CPUArchState { int vec_len; int vec_stride; + /* + * Floating point status and control registers. Some bits are + * stored separately in other fields or in the float_status below. + */ + uint64_t fpsr; + uint64_t fpcr; + uint32_t xregs[16]; /* Scratch space for aa32 neon expansion. */ @@ -1680,61 +1687,99 @@ 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 */ #define FPCR_DZE (1 << 9) /* Divide by Zero exception trap enable */ #define FPCR_OFE (1 << 10) /* Overflow exception trap enable */ #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 */ #define FPCR_AHP (1 << 26) /* Alternative half-precision */ -#define FPCR_QC (1 << 27) /* Cumulative saturation bit */ -#define FPCR_V (1 << 28) /* FP overflow flag */ -#define FPCR_C (1 << 29) /* FP carry flag */ -#define FPCR_Z (1 << 30) /* FP zero flag */ -#define FPCR_N (1 << 31) /* FP negative flag */ #define FPCR_LTPSIZE_SHIFT 16 /* LTPSIZE, M-profile only */ #define FPCR_LTPSIZE_MASK (7 << FPCR_LTPSIZE_SHIFT) #define FPCR_LTPSIZE_LENGTH 3 -#define FPCR_NZCV_MASK (FPCR_N | FPCR_Z | FPCR_C | FPCR_V) -#define FPCR_NZCVQC_MASK (FPCR_NZCV_MASK | FPCR_QC) +/* 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); -static inline uint32_t vfp_get_fpsr(CPUARMState *env) -{ - return vfp_get_fpscr(env) & FPSR_MASK; -} +/** + * vfp_get_fpsr: read the AArch64 FPSR + * @env: CPU context + * + * Return the current AArch64 FPSR value + */ +uint32_t vfp_get_fpsr(CPUARMState *env); -static inline void vfp_set_fpsr(CPUARMState *env, uint32_t val) -{ - uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPSR_MASK) | (val & FPSR_MASK); - vfp_set_fpscr(env, new_fpscr); -} +/** + * vfp_get_fpcr: read the AArch64 FPCR + * @env: CPU context + * + * Return the current AArch64 FPCR value + */ +uint32_t vfp_get_fpcr(CPUARMState *env); -static inline uint32_t vfp_get_fpcr(CPUARMState *env) -{ - return vfp_get_fpscr(env) & FPCR_MASK; -} +/** + * vfp_set_fpsr: write the AArch64 FPSR + * @env: CPU context + * @value: new value + */ +void vfp_set_fpsr(CPUARMState *env, uint32_t value); -static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val) -{ - uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPCR_MASK) | (val & FPCR_MASK); - vfp_set_fpscr(env, new_fpscr); -} +/** + * vfp_set_fpcr: write the AArch64 FPCR + * @env: CPU context + * @value: new value + */ +void vfp_set_fpcr(CPUARMState *env, uint32_t value); enum arm_cpu_mode { ARM_CPU_MODE_USR = 0x10, @@ -3309,8 +3354,8 @@ extern const uint64_t pred_esz_masks[5]; */ static inline target_ulong cpu_untagged_addr(CPUState *cs, target_ulong x) { - ARMCPU *cpu = ARM_CPU(cs); - if (cpu->env.tagged_addr_enable) { + CPUARMState *env = cpu_env(cs); + if (env->tagged_addr_enable) { /* * TBI is enabled for userspace but not kernelspace addresses. * Only clear the tag if bit 55 is clear. |