mirror of
				https://github.com/yuzu-emu/unicorn.git
				synced 2025-11-04 10:24:53 +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