mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #1568 from JayFoxRox/fix-printf
Fix ftoi and disable VFPv3
This commit is contained in:
		
						commit
						031a9c57bb
					
				
					 3 changed files with 61 additions and 26 deletions
				
			
		|  | @ -422,6 +422,10 @@ ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) { | |||
|         n = arm_instruction[i].attribute_value; | ||||
|         base = 0; | ||||
| 
 | ||||
|         // 3DS has no VFP3 support
 | ||||
|         if (arm_instruction[i].version == ARMVFP3) | ||||
|             continue; | ||||
| 
 | ||||
|         while (n) { | ||||
|             if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) { | ||||
|                 // clrex
 | ||||
|  |  | |||
|  | @ -568,7 +568,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 | |||
|     if (vdm.exponent >= 1023 + 32) { | ||||
|         d = vdm.sign ? 0 : 0xffffffff; | ||||
|         exceptions = FPSCR_IOC; | ||||
|     } else if (vdm.exponent >= 1023 - 1) { | ||||
|     } else if (vdm.exponent >= 1023) { | ||||
|         int shift = 1023 + 63 - vdm.exponent; | ||||
|         u64 rem, incr = 0; | ||||
| 
 | ||||
|  | @ -603,12 +603,20 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 | |||
|     } else { | ||||
|         d = 0; | ||||
|         if (vdm.exponent | vdm.significand) { | ||||
|             exceptions |= FPSCR_IXC; | ||||
|             if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) | ||||
|             if (rmode == FPSCR_ROUND_NEAREST) { | ||||
|                 if (vdm.exponent >= 1022) { | ||||
|                     d = vdm.sign ? 0 : 1; | ||||
|                     exceptions |= vdm.sign ? FPSCR_IOC : FPSCR_IXC; | ||||
|                 } else { | ||||
|                     exceptions |= FPSCR_IXC; | ||||
|                 } | ||||
|             } else if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) { | ||||
|                 d = 1; | ||||
|             else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) { | ||||
|                 d = 0; | ||||
|                 exceptions |= FPSCR_IOC; | ||||
|                 exceptions |= FPSCR_IXC; | ||||
|             } else if (rmode == FPSCR_ROUND_MINUSINF) { | ||||
|                 exceptions |= vdm.sign ? FPSCR_IOC : FPSCR_IXC; | ||||
|             } else { | ||||
|                 exceptions |= FPSCR_IXC; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -623,7 +631,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 | |||
| static u32 vfp_double_ftouiz(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) | ||||
| { | ||||
|     LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); | ||||
|     return vfp_double_ftoui(state, sd, unused, dm, FPSCR_ROUND_TOZERO); | ||||
|     return vfp_double_ftoui(state, sd, unused, dm, (fpscr & ~FPSCR_RMODE_MASK) | FPSCR_ROUND_TOZERO); | ||||
| } | ||||
| 
 | ||||
| static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) | ||||
|  | @ -647,12 +655,12 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 | |||
|     if (tm & VFP_NAN) { | ||||
|         d = 0; | ||||
|         exceptions |= FPSCR_IOC; | ||||
|     } else if (vdm.exponent >= 1023 + 32) { | ||||
|     } else if (vdm.exponent >= 1023 + 31) { | ||||
|         d = 0x7fffffff; | ||||
|         if (vdm.sign) | ||||
|             d = ~d; | ||||
|         exceptions |= FPSCR_IOC; | ||||
|     } else if (vdm.exponent >= 1023 - 1) { | ||||
|     } else if (vdm.exponent >= 1023) { | ||||
|         int shift = 1023 + 63 - vdm.exponent;	/* 58 */ | ||||
|         u64 rem, incr = 0; | ||||
| 
 | ||||
|  | @ -683,10 +691,17 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 | |||
|         d = 0; | ||||
|         if (vdm.exponent | vdm.significand) { | ||||
|             exceptions |= FPSCR_IXC; | ||||
|             if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) | ||||
|             if (rmode == FPSCR_ROUND_NEAREST) { | ||||
|                 if (vdm.exponent >= 1022) { | ||||
|                     d = vdm.sign ? 0xffffffff : 1; | ||||
|                 } else { | ||||
|                     d = 0; | ||||
|                 } | ||||
|             } else if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) { | ||||
|                 d = 1; | ||||
|             else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) | ||||
|                 d = -1; | ||||
|             } else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) { | ||||
|                 d = 0xffffffff; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -700,7 +715,7 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 | |||
| static u32 vfp_double_ftosiz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) | ||||
| { | ||||
|     LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); | ||||
|     return vfp_double_ftosi(state, dd, unused, dm, FPSCR_ROUND_TOZERO); | ||||
|     return vfp_double_ftosi(state, dd, unused, dm, (fpscr & ~FPSCR_RMODE_MASK) | FPSCR_ROUND_TOZERO); | ||||
| } | ||||
| 
 | ||||
| static struct op fops_ext[] = { | ||||
|  |  | |||
|  | @ -600,7 +600,11 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
|          * 2^0 <= m < 2^32-2^8 | ||||
|          */ | ||||
|         d = (vsm.significand << 1) >> shift; | ||||
|         rem = vsm.significand << (33 - shift); | ||||
|         if (shift > 0) { | ||||
|             rem = (vsm.significand << 1) << (32 - shift); | ||||
|         } else { | ||||
|             rem = 0; | ||||
|         } | ||||
| 
 | ||||
|         if (rmode == FPSCR_ROUND_NEAREST) { | ||||
|             incr = 0x80000000; | ||||
|  | @ -627,12 +631,20 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
|     } else { | ||||
|         d = 0; | ||||
|         if (vsm.exponent | vsm.significand) { | ||||
|             exceptions |= FPSCR_IXC; | ||||
|             if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) | ||||
|             if (rmode == FPSCR_ROUND_NEAREST) { | ||||
|                 if (vsm.exponent >= 126) { | ||||
|                     d = vsm.sign ? 0 : 1; | ||||
|                     exceptions |= vsm.sign ? FPSCR_IOC : FPSCR_IXC; | ||||
|                 } else { | ||||
|                     exceptions |= FPSCR_IXC; | ||||
|                 } | ||||
|             } else if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) { | ||||
|                 d = 1; | ||||
|             else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) { | ||||
|                 d = 0; | ||||
|                 exceptions |= FPSCR_IOC; | ||||
|                 exceptions |= FPSCR_IXC; | ||||
|             } else if (rmode == FPSCR_ROUND_MINUSINF) { | ||||
|                 exceptions |= vsm.sign ? FPSCR_IOC : FPSCR_IXC; | ||||
|             } else { | ||||
|                 exceptions |= FPSCR_IXC; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -646,7 +658,7 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
| 
 | ||||
| static u32 vfp_single_ftouiz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) | ||||
| { | ||||
|     return vfp_single_ftoui(state, sd, unused, m, FPSCR_ROUND_TOZERO); | ||||
|     return vfp_single_ftoui(state, sd, unused, m, (fpscr & ~FPSCR_RMODE_MASK) | FPSCR_ROUND_TOZERO); | ||||
| } | ||||
| 
 | ||||
| static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) | ||||
|  | @ -669,7 +681,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
|     if (tm & VFP_NAN) { | ||||
|         d = 0; | ||||
|         exceptions |= FPSCR_IOC; | ||||
|     } else if (vsm.exponent >= 127 + 32) { | ||||
|     } else if (vsm.exponent >= 127 + 31) { | ||||
|         /*
 | ||||
|          * m >= 2^31-2^7: invalid | ||||
|          */ | ||||
|  | @ -683,7 +695,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
| 
 | ||||
|         /* 2^0 <= m <= 2^31-2^7 */ | ||||
|         d = (vsm.significand << 1) >> shift; | ||||
|         rem = vsm.significand << (33 - shift); | ||||
|         rem = (vsm.significand << 1) << (32 - shift); | ||||
| 
 | ||||
|         if (rmode == FPSCR_ROUND_NEAREST) { | ||||
|             incr = 0x80000000; | ||||
|  | @ -709,10 +721,14 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
|         d = 0; | ||||
|         if (vsm.exponent | vsm.significand) { | ||||
|             exceptions |= FPSCR_IXC; | ||||
|             if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) | ||||
|             if (rmode == FPSCR_ROUND_NEAREST) { | ||||
|                 if (vsm.exponent >= 126) | ||||
|                     d = vsm.sign ? 0xffffffff : 1; | ||||
|             } else if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) { | ||||
|                 d = 1; | ||||
|             else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) | ||||
|                 d = -1; | ||||
|             } else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) { | ||||
|                 d = 0xffffffff; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -725,7 +741,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
| 
 | ||||
| static u32 vfp_single_ftosiz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) | ||||
| { | ||||
|     return vfp_single_ftosi(state, sd, unused, m, FPSCR_ROUND_TOZERO); | ||||
|     return vfp_single_ftosi(state, sd, unused, m, (fpscr & ~FPSCR_RMODE_MASK) | FPSCR_ROUND_TOZERO); | ||||
| } | ||||
| 
 | ||||
| static struct op fops_ext[] = { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue