From 7e38df077fc347f4b5ecb7370ebc8ec15b266d5c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 10 Apr 2015 19:57:13 -0700 Subject: [PATCH] x86jit: Prefer MOVAPS over MOVSS for reg->reg. --- Core/MIPS/x86/CompFPU.cpp | 53 ++++++++++++++++++++++++++------------- Core/MIPS/x86/Jit.h | 1 + 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/Core/MIPS/x86/CompFPU.cpp b/Core/MIPS/x86/CompFPU.cpp index d19fb1f5d8..c0f2fc25a4 100644 --- a/Core/MIPS/x86/CompFPU.cpp +++ b/Core/MIPS/x86/CompFPU.cpp @@ -47,6 +47,14 @@ namespace MIPSComp { using namespace Gen; using namespace X64JitConstants; +void Jit::CopyFPReg(X64Reg dst, OpArg src) { + if (src.IsSimpleReg()) { + MOVAPS(dst, src); + } else { + MOVSS(dst, src); + } +} + void Jit::CompFPTriArith(MIPSOpcode op, void (XEmitter::*arith)(X64Reg reg, OpArg), bool orderMatters) { int ft = _FT; int fs = _FS; @@ -62,14 +70,14 @@ void Jit::CompFPTriArith(MIPSOpcode op, void (XEmitter::*arith)(X64Reg reg, OpAr } else if (ft != fd) { // fs can't be fd (handled above.) fpr.MapReg(fd, false, true); - MOVSS(fpr.RX(fd), fpr.R(fs)); + CopyFPReg(fpr.RX(fd), fpr.R(fs)); (this->*arith)(fpr.RX(fd), fpr.R(ft)); } else { - // fd must be ft. + // fd must be ft, and order must matter. fpr.MapReg(fd, true, true); - MOVSS(XMM0, fpr.R(fs)); + CopyFPReg(XMM0, fpr.R(fs)); (this->*arith)(XMM0, fpr.R(ft)); - MOVSS(fpr.RX(fd), R(XMM0)); + MOVAPS(fpr.RX(fd), R(XMM0)); } fpr.ReleaseSpillLocks(); } @@ -151,14 +159,14 @@ void Jit::CompFPComp(int lhs, int rhs, u8 compare, bool allowNaN) { // This means that NaN also means true, e.g. !<> or !>, etc. if (allowNaN) { - MOVSS(XMM0, fpr.R(lhs)); - MOVSS(XMM1, fpr.R(lhs)); + CopyFPReg(XMM0, fpr.R(lhs)); + CopyFPReg(XMM1, fpr.R(lhs)); CMPSS(XMM0, fpr.R(rhs), compare); CMPUNORDSS(XMM1, fpr.R(rhs)); POR(XMM0, R(XMM1)); } else { - MOVSS(XMM0, fpr.R(lhs)); + CopyFPReg(XMM0, fpr.R(lhs)); CMPSS(XMM0, fpr.R(rhs), compare); } @@ -226,7 +234,8 @@ void Jit::Comp_FPU2op(MIPSOpcode op) { int fd = _FD; auto execRounding = [&](void (XEmitter::*conv)(X64Reg, OpArg), int setMXCSR) { - fpr.SpillLock(fs); + fpr.SpillLock(fd, fs); + fpr.MapReg(fd, fs == fd, true); // Small optimization: 0 is our default mode anyway. if (setMXCSR == 0 && !js.hasSetRounding) { @@ -268,32 +277,42 @@ void Jit::Comp_FPU2op(MIPSOpcode op) { case 5: //F(fd) = fabsf(F(fs)); break; //abs fpr.SpillLock(fd, fs); fpr.MapReg(fd, fd == fs, true); - if (fd != fs) { - MOVSS(fpr.RX(fd), fpr.R(fs)); + if (fd != fs && fpr.IsMapped(fs)) { + MOVAPS(fpr.RX(fd), M(ssNoSignMask)); + ANDPS(fpr.RX(fd), fpr.R(fs)); + } else { + if (fd != fs) { + MOVSS(fpr.RX(fd), fpr.R(fs)); + } + ANDPS(fpr.RX(fd), M(ssNoSignMask)); } - ANDPS(fpr.RX(fd), M(ssNoSignMask)); break; case 6: //F(fd) = F(fs); break; //mov if (fd != fs) { fpr.SpillLock(fd, fs); fpr.MapReg(fd, fd == fs, true); - MOVSS(fpr.RX(fd), fpr.R(fs)); + CopyFPReg(fpr.RX(fd), fpr.R(fs)); } break; case 7: //F(fd) = -F(fs); break; //neg fpr.SpillLock(fd, fs); fpr.MapReg(fd, fd == fs, true); - if (fd != fs) { - MOVSS(fpr.RX(fd), fpr.R(fs)); + if (fd != fs && fpr.IsMapped(fs)) { + MOVAPS(fpr.RX(fd), M(ssSignBits2)); + XORPS(fpr.RX(fd), fpr.R(fs)); + } else { + if (fd != fs) { + MOVSS(fpr.RX(fd), fpr.R(fs)); + } + XORPS(fpr.RX(fd), M(ssSignBits2)); } - XORPS(fpr.RX(fd), M(ssSignBits2)); break; case 4: //F(fd) = sqrtf(F(fs)); break; //sqrt - fpr.SpillLock(fd, fs); // this probably works, just badly tested + fpr.SpillLock(fd, fs); fpr.MapReg(fd, fd == fs, true); SQRTSS(fpr.RX(fd), fpr.R(fs)); break; @@ -305,7 +324,7 @@ void Jit::Comp_FPU2op(MIPSOpcode op) { case 32: //F(fd) = (float)FsI(fs); break; //cvt.s.w fpr.SpillLock(fd, fs); fpr.MapReg(fd, fs == fd, true); - if (fpr.R(fs).IsSimpleReg()) { + if (fpr.IsMapped(fs)) { CVTDQ2PS(fpr.RX(fd), fpr.R(fs)); } else { // If fs was fd, we'd be in the case above since we mapped fd. diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index 3e3b20b6ec..d062b9123b 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -238,6 +238,7 @@ private: static Gen::CCFlags FlipCCFlag(Gen::CCFlags flag); static Gen::CCFlags SwapCCFlag(Gen::CCFlags flag); + void CopyFPReg(Gen::X64Reg dst, Gen::OpArg src); void CompFPTriArith(MIPSOpcode op, void (XEmitter::*arith)(Gen::X64Reg reg, Gen::OpArg), bool orderMatters); void CompFPComp(int lhs, int rhs, u8 compare, bool allowNaN = false); void CompVrotShuffle(u8 *dregs, int imm, int n, bool negSin);