Fix ftoi behaviour
This commit is contained in:
parent
6fe0cb671d
commit
501d0bc5ed
2 changed files with 53 additions and 22 deletions
|
@ -560,7 +560,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32
|
||||||
if (vdm.exponent >= 1023 + 32) {
|
if (vdm.exponent >= 1023 + 32) {
|
||||||
d = vdm.sign ? 0 : 0xffffffff;
|
d = vdm.sign ? 0 : 0xffffffff;
|
||||||
exceptions = FPSCR_IOC;
|
exceptions = FPSCR_IOC;
|
||||||
} else if (vdm.exponent >= 1023 - 1) {
|
} else if (vdm.exponent >= 1023) {
|
||||||
int shift = 1023 + 63 - vdm.exponent;
|
int shift = 1023 + 63 - vdm.exponent;
|
||||||
u64 rem, incr = 0;
|
u64 rem, incr = 0;
|
||||||
|
|
||||||
|
@ -595,12 +595,20 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32
|
||||||
} else {
|
} else {
|
||||||
d = 0;
|
d = 0;
|
||||||
if (vdm.exponent | vdm.significand) {
|
if (vdm.exponent | vdm.significand) {
|
||||||
|
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;
|
exceptions |= FPSCR_IXC;
|
||||||
if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0)
|
}
|
||||||
|
} else if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) {
|
||||||
d = 1;
|
d = 1;
|
||||||
else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) {
|
exceptions |= FPSCR_IXC;
|
||||||
d = 0;
|
} else if (rmode == FPSCR_ROUND_MINUSINF) {
|
||||||
exceptions |= FPSCR_IOC;
|
exceptions |= vdm.sign ? FPSCR_IOC : FPSCR_IXC;
|
||||||
|
} else {
|
||||||
|
exceptions |= FPSCR_IXC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -639,12 +647,12 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32
|
||||||
if (tm & VFP_NAN) {
|
if (tm & VFP_NAN) {
|
||||||
d = 0;
|
d = 0;
|
||||||
exceptions |= FPSCR_IOC;
|
exceptions |= FPSCR_IOC;
|
||||||
} else if (vdm.exponent >= 1023 + 32) {
|
} else if (vdm.exponent >= 1023 + 31) {
|
||||||
d = 0x7fffffff;
|
d = 0x7fffffff;
|
||||||
if (vdm.sign)
|
if (vdm.sign)
|
||||||
d = ~d;
|
d = ~d;
|
||||||
exceptions |= FPSCR_IOC;
|
exceptions |= FPSCR_IOC;
|
||||||
} else if (vdm.exponent >= 1023 - 1) {
|
} else if (vdm.exponent >= 1023) {
|
||||||
int shift = 1023 + 63 - vdm.exponent; /* 58 */
|
int shift = 1023 + 63 - vdm.exponent; /* 58 */
|
||||||
u64 rem, incr = 0;
|
u64 rem, incr = 0;
|
||||||
|
|
||||||
|
@ -675,10 +683,17 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32
|
||||||
d = 0;
|
d = 0;
|
||||||
if (vdm.exponent | vdm.significand) {
|
if (vdm.exponent | vdm.significand) {
|
||||||
exceptions |= FPSCR_IXC;
|
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;
|
d = 1;
|
||||||
else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign)
|
} else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) {
|
||||||
d = -1;
|
d = 0xffffffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -592,7 +592,11 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f
|
||||||
* 2^0 <= m < 2^32-2^8
|
* 2^0 <= m < 2^32-2^8
|
||||||
*/
|
*/
|
||||||
d = (vsm.significand << 1) >> shift;
|
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) {
|
if (rmode == FPSCR_ROUND_NEAREST) {
|
||||||
incr = 0x80000000;
|
incr = 0x80000000;
|
||||||
|
@ -619,12 +623,20 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f
|
||||||
} else {
|
} else {
|
||||||
d = 0;
|
d = 0;
|
||||||
if (vsm.exponent | vsm.significand) {
|
if (vsm.exponent | vsm.significand) {
|
||||||
|
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;
|
exceptions |= FPSCR_IXC;
|
||||||
if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0)
|
}
|
||||||
|
} else if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) {
|
||||||
d = 1;
|
d = 1;
|
||||||
else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) {
|
exceptions |= FPSCR_IXC;
|
||||||
d = 0;
|
} else if (rmode == FPSCR_ROUND_MINUSINF) {
|
||||||
exceptions |= FPSCR_IOC;
|
exceptions |= vsm.sign ? FPSCR_IOC : FPSCR_IXC;
|
||||||
|
} else {
|
||||||
|
exceptions |= FPSCR_IXC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -661,7 +673,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f
|
||||||
if (tm & VFP_NAN) {
|
if (tm & VFP_NAN) {
|
||||||
d = 0;
|
d = 0;
|
||||||
exceptions |= FPSCR_IOC;
|
exceptions |= FPSCR_IOC;
|
||||||
} else if (vsm.exponent >= 127 + 32) {
|
} else if (vsm.exponent >= 127 + 31) {
|
||||||
/*
|
/*
|
||||||
* m >= 2^31-2^7: invalid
|
* m >= 2^31-2^7: invalid
|
||||||
*/
|
*/
|
||||||
|
@ -675,7 +687,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f
|
||||||
|
|
||||||
/* 2^0 <= m <= 2^31-2^7 */
|
/* 2^0 <= m <= 2^31-2^7 */
|
||||||
d = (vsm.significand << 1) >> shift;
|
d = (vsm.significand << 1) >> shift;
|
||||||
rem = vsm.significand << (33 - shift);
|
rem = (vsm.significand << 1) << (32 - shift);
|
||||||
|
|
||||||
if (rmode == FPSCR_ROUND_NEAREST) {
|
if (rmode == FPSCR_ROUND_NEAREST) {
|
||||||
incr = 0x80000000;
|
incr = 0x80000000;
|
||||||
|
@ -701,10 +713,14 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f
|
||||||
d = 0;
|
d = 0;
|
||||||
if (vsm.exponent | vsm.significand) {
|
if (vsm.exponent | vsm.significand) {
|
||||||
exceptions |= FPSCR_IXC;
|
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;
|
d = 1;
|
||||||
else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign)
|
} else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) {
|
||||||
d = -1;
|
d = 0xffffffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue