diff options
author | Hendiadyoin1 <leon2002.la@gmail.com> | 2022-02-03 12:46:21 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-15 11:39:42 +0100 |
commit | 3f581c77d9710310f56b1d69ccd2b43de49efc4c (patch) | |
tree | 6fd061b0b651c9c4fbc83c1e1e78b2d051d4e2bb /Userland | |
parent | 60cb5b8dfaef207bf267bc968586ecee5e2dc1d8 (diff) | |
download | serenity-3f581c77d9710310f56b1d69ccd2b43de49efc4c.zip |
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.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/DevTools/UserspaceEmulator/SoftFPU.cpp | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp b/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp index 1cc48b66fd..7c8cd5ccf8 100644 --- a/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp +++ b/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp @@ -1054,32 +1054,34 @@ void SoftFPU::F2XM1(const X86::Instruction&) } void SoftFPU::FYL2X(const X86::Instruction&) { - // FIXME: raise precision and under/overflow - // FIXME: detect denormal operands - // FIXME: QNaN - auto f0 = fpu_get(0); - auto f1 = fpu_get(1); - - if (f0 < 0. || isnan(f0) || isnan(f1) - || (isinf(f0) && f1 == 0.) || (f0 == 1. && isinf(f1))) + // FIXME: Set C1 on when result was rounded up, cleared otherwise + // FIXME: Raise #IA #D #U #O #P + auto x = fpu_get(0); + auto y = fpu_get(1); + if (x < 0. && !isinf(x)) { fpu_set_exception(FPU_Exception::InvalidOperation); - if (f0 == 0.) + // FIXME: Spec does not say what to do here.... + // So lets just ask libm.... + fpu_set(1, y * log2l(x)); + } else if (x == 0.) { + if (y == 0) + fpu_set_exception(FPU_Exception::InvalidOperation); fpu_set_exception(FPU_Exception::ZeroDivide); - - fpu_set(1, f1 * log2l(f0)); + fpu_set(1, INFINITY * (signbit(y) ? 1 : -1)); + } else { + fpu_set(1, y * log2l(x)); + } fpu_pop(); } void SoftFPU::FYL2XP1(const X86::Instruction&) { - // FIXME: raise #O #U #P #D - // FIXME: QNaN - auto f0 = fpu_get(0); - auto f1 = fpu_get(1); - if (isnan(f0) || isnan(f1) - || (isinf(f1) && f0 == 0)) + // FIXME: Raise #IA #O #U #P #D + auto x = fpu_get(0); + auto y = fpu_get(1); + if (x == 0 && isinf(y)) fpu_set_exception(FPU_Exception::InvalidOperation); - fpu_set(1, (f1 * log2l(f0 + 1.0l))); + fpu_set(1, (y * log2l(x + 1.0l))); fpu_pop(); } |