x86 JIT: Join adjacent vrot calls together to avoid redundant sin/cos calls. Add a prototype, fix minor issues.

This commit is contained in:
Henrik Rydgard committed 2014-11-30 11:04:13 +01:00
1 parent 7deb8055ee
commit ac772f25ff
11 files changed
+86 -30

No files matched your search

+4
View File
@@ -2111,4 +2111,8 @@ namespace MIPSComp
fpr.ReleaseSpillLocksAndDiscardTemps();
}
void Jit::Comp_ColorConv(MIPSOpcode op) {
DISABLE;
}
}
+4
View File
@@ -177,5 +177,9 @@ void Jit::CompNEON_Vocp(MIPSOpcode op) {
DISABLE;
}
void Jit::CompNEON_ColorConv(MIPSOpcode op) {
DISABLE;
}
}
// namespace MIPSComp
+2
View File
@@ -138,6 +138,7 @@ public:
void Comp_VCrossQuat(MIPSOpcode op);
void Comp_Vsgn(MIPSOpcode op);
void Comp_Vocp(MIPSOpcode op);
void Comp_ColorConv(MIPSOpcode op);
// Non-NEON: VPFX
@@ -176,6 +177,7 @@ public:
void CompNEON_VCrossQuat(MIPSOpcode op);
void CompNEON_Vsgn(MIPSOpcode op);
void CompNEON_Vocp(MIPSOpcode op);
void CompNEON_ColorConv(MIPSOpcode op);
int Replace_fabsf();
+1 -1
View File
@@ -131,7 +131,7 @@ public:
void Comp_VCrossQuat(MIPSOpcode op) {}
void Comp_Vsgn(MIPSOpcode op) {}
void Comp_Vocp(MIPSOpcode op) {}
void Comp_ColorConv(MIPSOpcode op) {}
int Replace_fabsf() { return 0; }
JitBlockCache *GetBlockCache() { return &blocks; }
+4
View File
@@ -46,6 +46,10 @@
#define MIPS_GET_FT(op) ((op>>16) & 0x1F)
#define MIPS_GET_FD(op) ((op>>6 ) & 0x1F)
#define MIPS_GET_VD(op) (op & 0x7F)
#define MIPS_GET_VS(op) ((op>>8) & 0x7F)
#define MIPS_GET_VT(op) ((op>>16) & 0x7F)
namespace MIPSCodeUtils
{
+3 -3
View File
@@ -771,9 +771,9 @@ const MIPSInstruction tableVFPU9[32] = // 110100 00010 xxxxx . ....... . .......
INVALID, INVALID, INVALID, INVALID,
//24
INVALID,
INSTR("vt4444", &Jit::Comp_Generic, Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vt5551", &Jit::Comp_Generic, Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vt5650", &Jit::Comp_Generic, Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vt4444", &Jit::Comp_ColorConv, Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vt5551", &Jit::Comp_ColorConv, Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
INSTR("vt5650", &Jit::Comp_ColorConv, Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
//28
INVALID, INVALID, INVALID, INVALID,
+3
View File
@@ -1209,5 +1209,8 @@ namespace MIPSComp
void Jit::Comp_Vocp(MIPSOpcode op) {
DISABLE;
}
void Jit::Comp_ColorConv(MIPSOpcode op) {
DISABLE;
}
}
+1
View File
@@ -131,6 +131,7 @@ public:
void Comp_VCrossQuat(MIPSOpcode op) {}
void Comp_Vsgn(MIPSOpcode op) {}
void Comp_Vocp(MIPSOpcode op) {}
void Comp_ColorConv(MIPSOpcode op) {}
int Replace_fabsf() { return 0; }
+60 -26
View File
@@ -2986,6 +2986,39 @@ void Jit::Comp_Vfim(MIPSOpcode op) {
fpr.ReleaseSpillLocks();
}
void Jit::CompVrotShuffle(u8 *dregs, int imm, int n, bool negSin) {
char what[4] = { '0', '0', '0', '0' };
if (((imm >> 2) & 3) == (imm & 3)) {
for (int i = 0; i < 4; i++)
what[i] = 'S';
}
what[(imm >> 2) & 3] = 'S';
what[imm & 3] = 'C';
// TODO: shufps SIMD version
for (int i = 0; i < n; i++) {
fpr.MapRegV(dregs[i], MAP_DIRTY | MAP_NOINIT);
switch (what[i]) {
case 'C': MOVSS(fpr.V(dregs[i]), XMM1); break;
case 'S':
MOVSS(fpr.V(dregs[i]), XMM0);
if (negSin) {
XORPS(fpr.VX(dregs[i]), M(&signBitLower));
}
break;
case '0':
{
XORPS(fpr.VX(dregs[i]), fpr.V(dregs[i]));
break;
}
default:
ERROR_LOG(JIT, "Bad what in vrot");
break;
}
}
}
// Very heavily used by FF:CC
void Jit::Comp_VRot(MIPSOpcode op) {
CONDITIONAL_DISABLE;
@@ -2997,8 +3030,22 @@ void Jit::Comp_VRot(MIPSOpcode op) {
int n = GetNumVectorElements(sz);
u8 dregs[4];
u8 dregs2[4];
u32 nextOp = Memory::Read_Opcode_JIT(js.compilerPC + 4).encoding;
int vd2 = -1;
int imm2 = -1;
if (false && (nextOp >> 26) == 60 && ((nextOp >> 21) & 0x1F) == 29 && _VS == MIPS_GET_VS(nextOp)) {
// Pair of vrot. Let's join them.
vd2 = MIPS_GET_VD(nextOp);
imm2 = (nextOp >> 16) & 0x1f;
NOTICE_LOG(JIT, "Joint VFPU at %08x", js.blockStart);
}
u8 sreg;
GetVectorRegs(dregs, sz, vd);
if (vd2 >= 0)
GetVectorRegs(dregs2, sz, vd2);
GetVectorRegs(&sreg, V_Single, vs);
// Flush SIMD.
@@ -3009,44 +3056,31 @@ void Jit::Comp_VRot(MIPSOpcode op) {
gpr.FlushBeforeCall();
fpr.Flush();
bool negSin = (imm & 0x10) ? true : false;
bool negSin1 = (imm & 0x10) ? true : false;
#ifdef _M_X64
MOVSS(XMM0, fpr.V(sreg));
ABI_CallFunction(negSin ? (const void *)&SinCosNegSin : (const void *)&SinCos);
ABI_CallFunction(negSin1 ? (const void *)&SinCosNegSin : (const void *)&SinCos);
#else
// Sigh, passing floats with cdecl isn't pretty, ends up on the stack.
ABI_CallFunctionA(negSin ? (const void *)&SinCosNegSin : (const void *)&SinCos, fpr.V(sreg));
ABI_CallFunctionA(negSin2 ? (const void *)&SinCosNegSin : (const void *)&SinCos, fpr.V(sreg));
#endif
MOVSS(XMM0, M(&sincostemp[0]));
MOVSS(XMM1, M(&sincostemp[1]));
char what[4] = {'0', '0', '0', '0'};
if (((imm >> 2) & 3) == (imm & 3)) {
for (int i = 0; i < 4; i++)
what[i] = 'S';
}
what[(imm >> 2) & 3] = 'S';
what[imm & 3] = 'C';
for (int i = 0; i < n; i++) {
fpr.MapRegV(dregs[i], MAP_DIRTY | MAP_NOINIT);
switch (what[i]) {
case 'C': MOVSS(fpr.V(dregs[i]), XMM1); break;
case 'S': MOVSS(fpr.V(dregs[i]), XMM0); break;
case '0':
{
XORPS(fpr.VX(dregs[i]), fpr.V(dregs[i]));
break;
}
default:
ERROR_LOG(JIT, "Bad what in vrot");
break;
}
CompVrotShuffle(dregs, imm, n, false);
if (vd2 != -1) {
// If the negsin setting differs between the two joint invocations, we need to flip the second one.
bool negSin2 = (imm2 & 0x10) ? true : false;
CompVrotShuffle(dregs2, imm2, n, negSin1 != negSin2);
js.compilerPC += 4;
}
fpr.ReleaseSpillLocks();
}
void Jit::Comp_ColorConv(MIPSOpcode op) {
DISABLE;
}
}
+2
View File
@@ -145,6 +145,7 @@ public:
void Comp_VCrossQuat(MIPSOpcode op);
void Comp_Vsgn(MIPSOpcode op);
void Comp_Vocp(MIPSOpcode op);
void Comp_ColorConv(MIPSOpcode op);
void Comp_DoNothing(MIPSOpcode op);
@@ -236,6 +237,7 @@ private:
void CompFPTriArith(MIPSOpcode op, void (XEmitter::*arith)(X64Reg reg, OpArg), bool orderMatters);
void CompFPComp(int lhs, int rhs, u8 compare, bool allowNaN = false);
void CompVrotShuffle(u8 *dregs, int imm, int n, bool negSin);
void CallProtectedFunction(const void *func, const OpArg &arg1);
void CallProtectedFunction(const void *func, const OpArg &arg1, const OpArg &arg2);
+2
View File
@@ -758,6 +758,8 @@ int FPURegCache::GetTempVS(u8 *v, VectorSize vsz) {
for (int i = 0; i < n; ++i) {
regs[v[i] + 32].tempLocked = true;
}
return 0; // ??
}
void FPURegCache::Flush() {