summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMerryMage <MerryMage@users.noreply.github.com>2018-10-04 21:47:07 +0100
committerMerryMage <MerryMage@users.noreply.github.com>2018-10-12 20:46:02 +0100
commitd60345f15ea98629eff5dccfa2c7ca37102c3eb4 (patch)
tree8f3617bfb88cc57aade0b986e29c53d6a99ababb
parent94f07e7fa9d300204c01b40a2cac963eb951f10a (diff)
Jit_FloatingPoint: Make fp_tri_op a local lambda
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.h4
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp82
2 files changed, 39 insertions, 47 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h
index bf5c947f50..068d42290c 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.h
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.h
@@ -119,10 +119,6 @@ public:
void regimmop(int d, int a, bool binary, u32 value, Operation doop,
void (Gen::XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&),
bool Rc = false, bool carry = false);
- Gen::X64Reg fp_tri_op(int d, int a, int b, bool reversible, bool single,
- void (Gen::XEmitter::*avxOp)(Gen::X64Reg, Gen::X64Reg, const Gen::OpArg&),
- void (Gen::XEmitter::*sseOp)(Gen::X64Reg, const Gen::OpArg&), bool packed,
- bool preserve_inputs, bool roundRHS = false);
void FloatCompare(UGeckoInstruction inst, bool upper = false);
void UpdateMXCSR();
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp
index 77ed9196ce..15a3588ff7 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp
@@ -26,34 +26,6 @@ alignas(16) static const u64 psAbsMask2[2] = {0x7FFFFFFFFFFFFFFFULL, 0x7FFFFFFFF
alignas(16) static const u64 psGeneratedQNaN[2] = {0x7FF8000000000000ULL, 0x7FF8000000000000ULL};
alignas(16) static const double half_qnan_and_s32_max[2] = {0x7FFFFFFF, -0x80000};
-X64Reg Jit64::fp_tri_op(int d, int a, int b, bool reversible, bool single,
- void (XEmitter::*avxOp)(X64Reg, X64Reg, const OpArg&),
- void (XEmitter::*sseOp)(X64Reg, const OpArg&), bool packed,
- bool preserve_inputs, bool roundRHS)
-{
- fpr.Lock(d, a, b);
- fpr.BindToRegister(d, d == a || d == b || !single);
- X64Reg dest = preserve_inputs ? XMM1 : fpr.RX(d);
- if (roundRHS)
- {
- if (d == a && !preserve_inputs)
- {
- Force25BitPrecision(XMM0, fpr.R(b), XMM1);
- (this->*sseOp)(fpr.RX(d), R(XMM0));
- }
- else
- {
- Force25BitPrecision(dest, fpr.R(b), XMM0);
- (this->*sseOp)(dest, fpr.R(a));
- }
- }
- else
- {
- avx_op(avxOp, sseOp, dest, fpr.R(a), fpr.R(b), packed, reversible);
- }
- return dest;
-}
-
// We can avoid calculating FPRF if it's not needed; every float operation resets it, so
// if it's going to be clobbered in a future instruction before being read, we can just
// not calculate it.
@@ -200,34 +172,58 @@ void Jit64::fp_arith(UGeckoInstruction inst)
bool round_input = single && !js.op->fprIsSingle[inst.FC];
bool preserve_inputs = SConfig::GetInstance().bAccurateNaNs;
- X64Reg dest = INVALID_REG;
+ const auto fp_tri_op = [&](int d, int a, int b, bool reversible,
+ void (XEmitter::*avxOp)(X64Reg, X64Reg, const OpArg&),
+ void (XEmitter::*sseOp)(X64Reg, const OpArg&), bool roundRHS = false) {
+ fpr.Lock(d, a, b);
+ fpr.BindToRegister(d, d == a || d == b || !single);
+ X64Reg dest = preserve_inputs ? XMM1 : fpr.RX(d);
+ if (roundRHS)
+ {
+ if (d == a && !preserve_inputs)
+ {
+ Force25BitPrecision(XMM0, fpr.R(b), XMM1);
+ (this->*sseOp)(fpr.RX(d), R(XMM0));
+ }
+ else
+ {
+ Force25BitPrecision(dest, fpr.R(b), XMM0);
+ (this->*sseOp)(dest, fpr.R(a));
+ }
+ }
+ else
+ {
+ avx_op(avxOp, sseOp, dest, fpr.R(a), fpr.R(b), packed, reversible);
+ }
+
+ HandleNaNs(inst, fpr.RX(d), dest);
+ if (single)
+ ForceSinglePrecision(fpr.RX(d), fpr.R(d), packed, true);
+ SetFPRFIfNeeded(fpr.RX(d));
+ fpr.UnlockAll();
+ };
+
switch (inst.SUBOP5)
{
case 18:
- dest = fp_tri_op(d, a, b, false, single, packed ? &XEmitter::VDIVPD : &XEmitter::VDIVSD,
- packed ? &XEmitter::DIVPD : &XEmitter::DIVSD, packed, preserve_inputs);
+ fp_tri_op(d, a, b, false, packed ? &XEmitter::VDIVPD : &XEmitter::VDIVSD,
+ packed ? &XEmitter::DIVPD : &XEmitter::DIVSD);
break;
case 20:
- dest = fp_tri_op(d, a, b, false, single, packed ? &XEmitter::VSUBPD : &XEmitter::VSUBSD,
- packed ? &XEmitter::SUBPD : &XEmitter::SUBSD, packed, preserve_inputs);
+ fp_tri_op(d, a, b, false, packed ? &XEmitter::VSUBPD : &XEmitter::VSUBSD,
+ packed ? &XEmitter::SUBPD : &XEmitter::SUBSD);
break;
case 21:
- dest = fp_tri_op(d, a, b, true, single, packed ? &XEmitter::VADDPD : &XEmitter::VADDSD,
- packed ? &XEmitter::ADDPD : &XEmitter::ADDSD, packed, preserve_inputs);
+ fp_tri_op(d, a, b, true, packed ? &XEmitter::VADDPD : &XEmitter::VADDSD,
+ packed ? &XEmitter::ADDPD : &XEmitter::ADDSD);
break;
case 25:
- dest = fp_tri_op(d, a, c, true, single, packed ? &XEmitter::VMULPD : &XEmitter::VMULSD,
- packed ? &XEmitter::MULPD : &XEmitter::MULSD, packed, preserve_inputs,
- round_input);
+ fp_tri_op(d, a, c, true, packed ? &XEmitter::VMULPD : &XEmitter::VMULSD,
+ packed ? &XEmitter::MULPD : &XEmitter::MULSD, round_input);
break;
default:
ASSERT_MSG(DYNA_REC, 0, "fp_arith WTF!!!");
}
- HandleNaNs(inst, fpr.RX(d), dest);
- if (single)
- ForceSinglePrecision(fpr.RX(d), fpr.R(d), packed, true);
- SetFPRFIfNeeded(fpr.RX(d));
- fpr.UnlockAll();
}
void Jit64::fmaddXX(UGeckoInstruction inst)