mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 16:15:36 +00:00
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. Backports commit a4d5846245c5e029e5aa3945a9bda1de1c3fedbf from qemu
This commit is contained in:
parent
356b70e931
commit
10d468f601
|
@ -568,11 +568,13 @@ typedef struct CPUARMState {
|
||||||
ARMPredicateReg preg_tmp;
|
ARMPredicateReg preg_tmp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t xregs[16];
|
|
||||||
/* We store these fpcsr fields separately for convenience. */
|
/* We store these fpcsr fields separately for convenience. */
|
||||||
|
uint32_t QEMU_ALIGNED(16, qc[4]);
|
||||||
int vec_len;
|
int vec_len;
|
||||||
int vec_stride;
|
int vec_stride;
|
||||||
|
|
||||||
|
uint32_t xregs[16];
|
||||||
|
|
||||||
/* Scratch space for aa32 neon expansion. */
|
/* Scratch space for aa32 neon expansion. */
|
||||||
uint32_t scratch[8];
|
uint32_t scratch[8];
|
||||||
|
|
||||||
|
@ -1369,6 +1371,7 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
|
||||||
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
|
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
|
||||||
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
|
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
|
||||||
#define FPCR_DN (1 << 25) /* Default NaN 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)
|
static inline uint32_t vfp_get_fpsr(CPUARMState *env)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11779,8 +11779,7 @@ static inline int vfp_exceptbits_from_host(int host_bits)
|
||||||
|
|
||||||
uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
|
uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
|
||||||
{
|
{
|
||||||
int i;
|
uint32_t i, fpscr;
|
||||||
uint32_t fpscr;
|
|
||||||
|
|
||||||
fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
|
fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
|
||||||
| (env->vfp.vec_len << 16)
|
| (env->vfp.vec_len << 16)
|
||||||
|
@ -11792,6 +11791,10 @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
|
||||||
i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
|
i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
|
||||||
& ~float_flag_input_denormal);
|
& ~float_flag_input_denormal);
|
||||||
fpscr |= vfp_exceptbits_from_host(i);
|
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;
|
return fpscr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11838,10 +11841,19 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
|
||||||
* (which are stored in fp_status), and the other RES0 bits
|
* (which are stored in fp_status), and the other RES0 bits
|
||||||
* in between, then we clear all of the low 16 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_len = (val >> 16) & 7;
|
||||||
env->vfp.vec_stride = (val >> 20) & 3;
|
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;
|
changed ^= val;
|
||||||
if (changed & (3 << 22)) {
|
if (changed & (3 << 22)) {
|
||||||
i = (val >> 22) & 3;
|
i = (val >> 22) & 3;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#define SIGNBIT (uint32_t)0x80000000
|
#define SIGNBIT (uint32_t)0x80000000
|
||||||
#define SIGNBIT64 ((uint64_t)1 << 63)
|
#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) \
|
#define NEON_TYPE1(name, type) \
|
||||||
typedef struct \
|
typedef struct \
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#define H4(x) (x)
|
#define H4(x) (x)
|
||||||
#endif
|
#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)
|
static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue