From 60ff27c63358ccf147c05c7cdfa6ca0d5d5a547c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 14 Nov 2020 15:15:41 +0100 Subject: [PATCH] UserspaceEmulator: Improve FCOMI/FCOMIP/FUCOMI/FUCOMIP These instructions now operate on the specified FPU stack entry instead of always using ST(0) and ST(1). FUCOMI and FUCOMIP also handle NaN values slightly better. --- DevTools/UserspaceEmulator/SoftCPU.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index 94de431e56..e86db38ea9 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -1709,24 +1709,32 @@ void SoftCPU::FNINIT(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::FNSETPM(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::FLD_RM80(const X86::Instruction&) { TODO_INSN(); } -void SoftCPU::FUCOMI(const X86::Instruction&) +void SoftCPU::FUCOMI(const X86::Instruction& insn) { + auto i = insn.rm() & 7; // FIXME: Unordered comparison checks. // FIXME: QNaN / exception handling. // FIXME: Set C0, C2, C3 in FPU status word. - set_zf(fpu_get(0) == fpu_get(1)); - set_pf(false); - set_cf(fpu_get(0) < fpu_get(1)); - set_of(false); + if (__builtin_isnan(fpu_get(0)) || __builtin_isnan(fpu_get(i))) { + set_zf(true); + set_pf(true); + set_cf(true); + } else { + set_zf(fpu_get(0) == fpu_get(i)); + set_pf(false); + set_cf(fpu_get(0) < fpu_get(i)); + set_of(false); + } } -void SoftCPU::FCOMI(const X86::Instruction&) +void SoftCPU::FCOMI(const X86::Instruction& insn) { + auto i = insn.rm() & 7; // FIXME: QNaN / exception handling. // FIXME: Set C0, C2, C3 in FPU status word. - set_zf(fpu_get(0) == fpu_get(1)); + set_zf(fpu_get(0) == fpu_get(i)); set_pf(false); - set_cf(fpu_get(0) < fpu_get(1)); + set_cf(fpu_get(0) < fpu_get(i)); set_of(false); }