diff --git a/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp b/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp index 98383a2991..62a975d8f5 100644 --- a/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -1613,14 +1613,49 @@ void SoftCPU::FLDZ(const X86::Instruction&) } void SoftCPU::FNSTENV(const X86::Instruction&) { TODO_INSN(); } -void SoftCPU::F2XM1(const X86::Instruction&) { TODO_INSN(); } -void SoftCPU::FYL2X(const X86::Instruction&) { TODO_INSN(); } + +void SoftCPU::F2XM1(const X86::Instruction&) +{ + // FIXME: validate ST(0) is in range –1.0 to +1.0 + auto f32 = fpu_get(0); + // FIXME: Set C0, C2, C3 in FPU status word. + fpu_set(0, powf(2, f32) - 1.0f); +} + +void SoftCPU::FYL2X(const X86::Instruction&) +{ + // FIXME: Raise IA on +-infinity, +-0, raise Z on +-0 + auto f32 = fpu_get(0); + // FIXME: Set C0, C2, C3 in FPU status word. + fpu_set(1, fpu_get(1) * log2f(f32)); + fpu_pop(); +} + +void SoftCPU::FYL2XP1(const X86::Instruction&) +{ + // FIXME: validate ST(0) range + auto f32 = fpu_get(0); + // FIXME: Set C0, C2, C3 in FPU status word. + fpu_set(1, (fpu_get(1) * log2f(f32 + 1.0f))); + fpu_pop(); +} + void SoftCPU::FPTAN(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::FPATAN(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::FXTRACT(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::FPREM1(const X86::Instruction&) { TODO_INSN(); } -void SoftCPU::FDECSTP(const X86::Instruction&) { TODO_INSN(); } -void SoftCPU::FINCSTP(const X86::Instruction&) { TODO_INSN(); } + +void SoftCPU::FDECSTP(const X86::Instruction&) +{ + m_fpu_top = (m_fpu_top == 0) ? 7 : m_fpu_top - 1; + set_cf(0); +} + +void SoftCPU::FINCSTP(const X86::Instruction&) +{ + m_fpu_top = (m_fpu_top == 7) ? 0 : m_fpu_top + 1; + set_cf(0); +} void SoftCPU::FNSTCW(const X86::Instruction& insn) { @@ -1628,7 +1663,6 @@ void SoftCPU::FNSTCW(const X86::Instruction& insn) } void SoftCPU::FPREM(const X86::Instruction&) { TODO_INSN(); } -void SoftCPU::FYL2XP1(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::FSQRT(const X86::Instruction&) { @@ -1643,7 +1677,11 @@ void SoftCPU::FRNDINT(const X86::Instruction&) fpu_set(0, round(fpu_get(0))); } -void SoftCPU::FSCALE(const X86::Instruction&) { TODO_INSN(); } +void SoftCPU::FSCALE(const X86::Instruction&) +{ + // FIXME: set C1 upon stack overflow or if result was rounded + fpu_set(0, fpu_get(0) * powf(2, floorf(fpu_get(1)))); +} void SoftCPU::FSIN(const X86::Instruction&) { @@ -1701,8 +1739,6 @@ void SoftCPU::FISUBR_RM32(const X86::Instruction& insn) fpu_set(0, (long double)m32int - fpu_get(0)); } -void SoftCPU::FUCOMPP(const X86::Instruction&) { TODO_INSN(); } - void SoftCPU::FIDIV_RM32(const X86::Instruction& insn) { VERIFY(!insn.modrm().is_register()); @@ -1912,6 +1948,7 @@ void SoftCPU::FSTP_RM64(const X86::Instruction& insn) void SoftCPU::FRSTOR(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::FUCOM(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::FUCOMP(const X86::Instruction&) { TODO_INSN(); } +void SoftCPU::FUCOMPP(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::FNSAVE(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::FNSTSW(const X86::Instruction&) { TODO_INSN(); }