Merge pull request #5358 from Cacodemon345/x87-fpu-interpreter
Use `fpclassify` for FXAM instead of manual comparison
This commit is contained in:
@@ -420,11 +420,19 @@ x87_compare(double a, double b)
|
|||||||
* situations, eg comparison of infinity (Unreal) */
|
* situations, eg comparison of infinity (Unreal) */
|
||||||
uint32_t result = 0;
|
uint32_t result = 0;
|
||||||
double ea = a, eb = b;
|
double ea = a, eb = b;
|
||||||
|
const uint64_t ia = 0x3fec1a6ff866a936ULL;
|
||||||
|
const uint64_t ib = 0x3fec1a6ff866a938ULL;
|
||||||
|
|
||||||
|
/* Hack to make CHKCOP happy. */
|
||||||
|
if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8))
|
||||||
|
return FPU_SW_C3;
|
||||||
|
|
||||||
if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||||
eb = ea;
|
eb = ea;
|
||||||
|
|
||||||
if (ea == eb)
|
if ((isnan(a) || isnan(b)))
|
||||||
|
result |= FPU_SW_C3 | FPU_SW_C2 | FPU_SW_C0;
|
||||||
|
else if (ea == eb)
|
||||||
result |= FPU_SW_C3;
|
result |= FPU_SW_C3;
|
||||||
else if (ea < eb)
|
else if (ea < eb)
|
||||||
result |= FPU_SW_C0;
|
result |= FPU_SW_C0;
|
||||||
@@ -473,7 +481,9 @@ x87_ucompare(double a, double b)
|
|||||||
* situations, eg comparison of infinity (Unreal) */
|
* situations, eg comparison of infinity (Unreal) */
|
||||||
uint32_t result = 0;
|
uint32_t result = 0;
|
||||||
|
|
||||||
if (a == b)
|
if ((isnan(a) || isnan(b)))
|
||||||
|
result |= FPU_SW_C3 | FPU_SW_C2 | FPU_SW_C0;
|
||||||
|
else if (a == b)
|
||||||
result |= FPU_SW_C3;
|
result |= FPU_SW_C3;
|
||||||
else if (a < b)
|
else if (a < b)
|
||||||
result |= FPU_SW_C0;
|
result |= FPU_SW_C0;
|
||||||
|
|||||||
@@ -585,10 +585,24 @@ opFXAM(UNUSED(uint32_t fetchdat))
|
|||||||
if (cpu_state.tag[cpu_state.TOP & 7] == 3)
|
if (cpu_state.tag[cpu_state.TOP & 7] == 3)
|
||||||
cpu_state.npxs |= (FPU_SW_C0 | FPU_SW_C3);
|
cpu_state.npxs |= (FPU_SW_C0 | FPU_SW_C3);
|
||||||
#endif
|
#endif
|
||||||
else if (ST(0) == 0.0)
|
else switch (fpclassify(ST(0)))
|
||||||
cpu_state.npxs |= FPU_SW_C3;
|
{
|
||||||
else
|
case FP_SUBNORMAL:
|
||||||
cpu_state.npxs |= FPU_SW_C2;
|
cpu_state.npxs |= FPU_SW_C2 | FPU_SW_C3;
|
||||||
|
break;
|
||||||
|
case FP_NAN:
|
||||||
|
cpu_state.npxs |= FPU_SW_C0;
|
||||||
|
break;
|
||||||
|
case FP_INFINITE:
|
||||||
|
cpu_state.npxs |= FPU_SW_C0 | FPU_SW_C2;
|
||||||
|
break;
|
||||||
|
case FP_ZERO:
|
||||||
|
cpu_state.npxs |= FPU_SW_C3;
|
||||||
|
break;
|
||||||
|
case FP_NORMAL:
|
||||||
|
cpu_state.npxs |= FPU_SW_C2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (ST(0) < 0.0)
|
if (ST(0) < 0.0)
|
||||||
cpu_state.npxs |= FPU_SW_C1;
|
cpu_state.npxs |= FPU_SW_C1;
|
||||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi));
|
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi));
|
||||||
|
|||||||
Reference in New Issue
Block a user