From 6d41f15f0d5fe931bfaf07c35f054db08b5a5091 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 17 Sep 2023 22:01:25 -0700 Subject: [PATCH] x86jit: Implement FSign. --- Core/MIPS/x86/X64IRCompFPU.cpp | 25 ++++++++++++++++++++++++- Core/MIPS/x86/X64IRJit.h | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Core/MIPS/x86/X64IRCompFPU.cpp b/Core/MIPS/x86/X64IRCompFPU.cpp index 0ef0dea6b9..ae104aa6a4 100644 --- a/Core/MIPS/x86/X64IRCompFPU.cpp +++ b/Core/MIPS/x86/X64IRCompFPU.cpp @@ -43,6 +43,7 @@ using namespace X64IRJitConstants; void X64JitBackend::EmitFPUConstants() { EmitConst4x32(&constants.noSignMask, 0x7FFFFFFF); EmitConst4x32(&constants.signBitAll, 0x80000000); + EmitConst4x32(&constants.positiveZeroes, 0x00000000); EmitConst4x32(&constants.positiveInfinity, 0x7F800000); EmitConst4x32(&constants.qNAN, 0x7FC00000); EmitConst4x32(&constants.positiveOnes, 0x3F800000); @@ -233,8 +234,30 @@ void X64JitBackend::CompIR_FAssign(IRInst inst) { break; case IROp::FSign: - CompIR_Generic(inst); + { + X64Reg tempReg = regs_.MapWithFPRTemp(inst); + + // Set tempReg to +1.0 or -1.0 per sign bit. + if (cpu_info.bAVX) { + VANDPS(128, tempReg, regs_.FX(inst.src1), M(constants.signBitAll)); // rip accessible + } else { + MOVAPS(tempReg, regs_.F(inst.src1)); + ANDPS(tempReg, M(constants.signBitAll)); // rip accessible + } + ORPS(tempReg, M(constants.positiveOnes)); // rip accessible + + // Set dest = 0xFFFFFFFF if +0.0 or -0.0. + if (inst.dest != inst.src1) { + XORPS(regs_.FX(inst.dest), regs_.F(inst.dest)); + CMPPS(regs_.FX(inst.dest), regs_.F(inst.src1), CMP_EQ); + } else { + CMPPS(regs_.FX(inst.dest), M(constants.positiveZeroes), CMP_EQ); // rip accessible + } + + // Now not the mask to keep zero if it was zero. + ANDNPS(regs_.FX(inst.dest), R(tempReg)); break; + } default: INVALIDOP; diff --git a/Core/MIPS/x86/X64IRJit.h b/Core/MIPS/x86/X64IRJit.h index 6a2c09aef5..2fb72b9269 100644 --- a/Core/MIPS/x86/X64IRJit.h +++ b/Core/MIPS/x86/X64IRJit.h @@ -144,6 +144,7 @@ private: struct Constants { const void *noSignMask; const void *signBitAll; + const void *positiveZeroes; const void *positiveInfinity; const void *positiveOnes; const void *negativeOnes;