Skip to content

Commit 3f581c7

Browse files
Hendiadyoin1awesomekling
authored andcommitted
UserspaceEmulator: Make error checks in FYL2XP1 and FYL2X a bit closer
...to the manual This removes the non complete NaN checks and fixes a bounds check in FYL2X.
1 parent 60cb5b8 commit 3f581c7

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

Userland/DevTools/UserspaceEmulator/SoftFPU.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,32 +1054,34 @@ void SoftFPU::F2XM1(const X86::Instruction&)
10541054
}
10551055
void SoftFPU::FYL2X(const X86::Instruction&)
10561056
{
1057-
// FIXME: raise precision and under/overflow
1058-
// FIXME: detect denormal operands
1059-
// FIXME: QNaN
1060-
auto f0 = fpu_get(0);
1061-
auto f1 = fpu_get(1);
1062-
1063-
if (f0 < 0. || isnan(f0) || isnan(f1)
1064-
|| (isinf(f0) && f1 == 0.) || (f0 == 1. && isinf(f1)))
1057+
// FIXME: Set C1 on when result was rounded up, cleared otherwise
1058+
// FIXME: Raise #IA #D #U #O #P
1059+
auto x = fpu_get(0);
1060+
auto y = fpu_get(1);
1061+
if (x < 0. && !isinf(x)) {
10651062
fpu_set_exception(FPU_Exception::InvalidOperation);
1066-
if (f0 == 0.)
1063+
// FIXME: Spec does not say what to do here....
1064+
// So lets just ask libm....
1065+
fpu_set(1, y * log2l(x));
1066+
} else if (x == 0.) {
1067+
if (y == 0)
1068+
fpu_set_exception(FPU_Exception::InvalidOperation);
10671069
fpu_set_exception(FPU_Exception::ZeroDivide);
1068-
1069-
fpu_set(1, f1 * log2l(f0));
1070+
fpu_set(1, INFINITY * (signbit(y) ? 1 : -1));
1071+
} else {
1072+
fpu_set(1, y * log2l(x));
1073+
}
10701074
fpu_pop();
10711075
}
10721076
void SoftFPU::FYL2XP1(const X86::Instruction&)
10731077
{
1074-
// FIXME: raise #O #U #P #D
1075-
// FIXME: QNaN
1076-
auto f0 = fpu_get(0);
1077-
auto f1 = fpu_get(1);
1078-
if (isnan(f0) || isnan(f1)
1079-
|| (isinf(f1) && f0 == 0))
1078+
// FIXME: Raise #IA #O #U #P #D
1079+
auto x = fpu_get(0);
1080+
auto y = fpu_get(1);
1081+
if (x == 0 && isinf(y))
10801082
fpu_set_exception(FPU_Exception::InvalidOperation);
10811083

1082-
fpu_set(1, (f1 * log2l(f0 + 1.0l)));
1084+
fpu_set(1, (y * log2l(x + 1.0l)));
10831085
fpu_pop();
10841086
}
10851087

0 commit comments

Comments
 (0)