[AArch64] Optimize cases when an FPR is only used for non-paired ops.
This commit is contained in:
parent
90e05f7bea
commit
7ce4c3138e
|
@ -26,12 +26,18 @@ void JitArm64::fabsx(UGeckoInstruction inst)
|
||||||
fpr.BindToRegister(d, true);
|
fpr.BindToRegister(d, true);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FABS(EncodeRegToDouble(V0), EncodeRegToDouble(VB));
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
{
|
||||||
|
m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||||
fpr.Unlock(V0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FABS(EncodeRegToDouble(V0), EncodeRegToDouble(VB));
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::faddsx(UGeckoInstruction inst)
|
void JitArm64::faddsx(UGeckoInstruction inst)
|
||||||
|
@ -41,11 +47,11 @@ void JitArm64::faddsx(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b);
|
fpr.BindToRegister(d, d == a || d == b, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||||
m_float_emit.INS(64, VD, 1, VD, 0);
|
m_float_emit.INS(64, VD, 1, VD, 0);
|
||||||
|
@ -63,12 +69,18 @@ void JitArm64::faddx(UGeckoInstruction inst)
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FADD(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
{
|
||||||
|
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||||
fpr.Unlock(V0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FADD(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::fmaddsx(UGeckoInstruction inst)
|
void JitArm64::fmaddsx(UGeckoInstruction inst)
|
||||||
|
@ -78,12 +90,12 @@ void JitArm64::fmaddsx(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
||||||
|
@ -105,12 +117,18 @@ void JitArm64::fmaddx(UGeckoInstruction inst)
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.FADD(EncodeRegToDouble(V0), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
|
{
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
m_float_emit.FMADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||||
fpr.Unlock(V0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FMADD(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::fmrx(UGeckoInstruction inst)
|
void JitArm64::fmrx(UGeckoInstruction inst)
|
||||||
|
@ -135,12 +153,12 @@ void JitArm64::fmsubsx(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
||||||
|
@ -162,12 +180,18 @@ void JitArm64::fmsubx(UGeckoInstruction inst)
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.FSUB(EncodeRegToDouble(V0), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
|
{
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
m_float_emit.FNMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||||
fpr.Unlock(V0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FNMSUB(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::fmulsx(UGeckoInstruction inst)
|
void JitArm64::fmulsx(UGeckoInstruction inst)
|
||||||
|
@ -177,11 +201,11 @@ void JitArm64::fmulsx(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == c);
|
fpr.BindToRegister(d, d == a || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
||||||
m_float_emit.INS(64, VD, 1, VD, 0);
|
m_float_emit.INS(64, VD, 1, VD, 0);
|
||||||
|
@ -199,12 +223,18 @@ void JitArm64::fmulx(UGeckoInstruction inst)
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
{
|
||||||
|
m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
||||||
fpr.Unlock(V0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::fnabsx(UGeckoInstruction inst)
|
void JitArm64::fnabsx(UGeckoInstruction inst)
|
||||||
|
@ -218,13 +248,20 @@ void JitArm64::fnabsx(UGeckoInstruction inst)
|
||||||
|
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FABS(EncodeRegToDouble(V0), EncodeRegToDouble(VB));
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.FNEG(EncodeRegToDouble(V0), EncodeRegToDouble(V0));
|
{
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||||
|
m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VD));
|
||||||
fpr.Unlock(V0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FABS(EncodeRegToDouble(V0), EncodeRegToDouble(VB));
|
||||||
|
m_float_emit.FNEG(EncodeRegToDouble(V0), EncodeRegToDouble(V0));
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::fnegx(UGeckoInstruction inst)
|
void JitArm64::fnegx(UGeckoInstruction inst)
|
||||||
|
@ -238,12 +275,18 @@ void JitArm64::fnegx(UGeckoInstruction inst)
|
||||||
|
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FNEG(EncodeRegToDouble(V0), EncodeRegToDouble(VB));
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
{
|
||||||
|
m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||||
fpr.Unlock(V0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FNEG(EncodeRegToDouble(V0), EncodeRegToDouble(VB));
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::fnmaddsx(UGeckoInstruction inst)
|
void JitArm64::fnmaddsx(UGeckoInstruction inst)
|
||||||
|
@ -253,12 +296,12 @@ void JitArm64::fnmaddsx(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
||||||
|
@ -281,13 +324,18 @@ void JitArm64::fnmaddx(UGeckoInstruction inst)
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.FADD(EncodeRegToDouble(V0), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
|
{
|
||||||
m_float_emit.FNEG(EncodeRegToDouble(V0), EncodeRegToDouble(V0));
|
m_float_emit.FNMADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
}
|
||||||
fpr.Unlock(V0);
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FNMADD(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::fnmsubsx(UGeckoInstruction inst)
|
void JitArm64::fnmsubsx(UGeckoInstruction inst)
|
||||||
|
@ -297,12 +345,12 @@ void JitArm64::fnmsubsx(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
||||||
|
@ -325,13 +373,18 @@ void JitArm64::fnmsubx(UGeckoInstruction inst)
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.FSUB(EncodeRegToDouble(V0), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
|
{
|
||||||
m_float_emit.FNEG(EncodeRegToDouble(V0), EncodeRegToDouble(V0));
|
m_float_emit.FMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
}
|
||||||
fpr.Unlock(V0);
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FMSUB(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::fselx(UGeckoInstruction inst)
|
void JitArm64::fselx(UGeckoInstruction inst)
|
||||||
|
@ -347,13 +400,19 @@ void JitArm64::fselx(UGeckoInstruction inst)
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FCMPE(EncodeRegToDouble(VA));
|
m_float_emit.FCMPE(EncodeRegToDouble(VA));
|
||||||
m_float_emit.FCSEL(EncodeRegToDouble(V0), EncodeRegToDouble(VC), EncodeRegToDouble(VB), CC_GE);
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
{
|
||||||
|
m_float_emit.FCSEL(EncodeRegToDouble(VD), EncodeRegToDouble(VC), EncodeRegToDouble(VB), CC_GE);
|
||||||
fpr.Unlock(V0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FCSEL(EncodeRegToDouble(V0), EncodeRegToDouble(VC), EncodeRegToDouble(VB), CC_GE);
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::fsubsx(UGeckoInstruction inst)
|
void JitArm64::fsubsx(UGeckoInstruction inst)
|
||||||
|
@ -363,11 +422,11 @@ void JitArm64::fsubsx(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b);
|
fpr.BindToRegister(d, d == a || d == b, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||||
m_float_emit.INS(64, VD, 1, VD, 0);
|
m_float_emit.INS(64, VD, 1, VD, 0);
|
||||||
|
@ -385,10 +444,16 @@ void JitArm64::fsubx(UGeckoInstruction inst)
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
|
||||||
|
|
||||||
m_float_emit.FSUB(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
if (fpr.IsLower(d))
|
||||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
{
|
||||||
|
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||||
fpr.Unlock(V0);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
m_float_emit.FSUB(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||||
|
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||||
|
fpr.Unlock(V0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,9 +72,9 @@ void JitArm64::lfXX(UGeckoInstruction inst)
|
||||||
bool is_immediate = false;
|
bool is_immediate = false;
|
||||||
|
|
||||||
// 64 bit loads only load PSR0
|
// 64 bit loads only load PSR0
|
||||||
fpr.BindToRegister(inst.FD, flags & BackPatchInfo::FLAG_SIZE_F64);
|
fpr.BindToRegister(inst.FD, flags & BackPatchInfo::FLAG_SIZE_F64, flags & BackPatchInfo::FLAG_SIZE_F64);
|
||||||
|
|
||||||
ARM64Reg VD = fpr.R(inst.FD);
|
ARM64Reg VD = fpr.R(inst.FD, flags & BackPatchInfo::FLAG_SIZE_F64);
|
||||||
ARM64Reg addr_reg = W0;
|
ARM64Reg addr_reg = W0;
|
||||||
|
|
||||||
gpr.Lock(W0, W30);
|
gpr.Lock(W0, W30);
|
||||||
|
|
|
@ -66,8 +66,8 @@ void JitArm64::psq_l(UGeckoInstruction inst)
|
||||||
LDR(X30, X30, ArithOption(EncodeRegTo64(type_reg), true));
|
LDR(X30, X30, ArithOption(EncodeRegTo64(type_reg), true));
|
||||||
BLR(X30);
|
BLR(X30);
|
||||||
|
|
||||||
fpr.BindToRegister(inst.RS, false);
|
fpr.BindToRegister(inst.RS, false, false);
|
||||||
ARM64Reg VS = fpr.R(inst.RS);
|
ARM64Reg VS = fpr.R(inst.RS, false);
|
||||||
m_float_emit.FCVTL(64, VS, D0);
|
m_float_emit.FCVTL(64, VS, D0);
|
||||||
if (inst.W)
|
if (inst.W)
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,7 @@ void JitArm64::psq_st(UGeckoInstruction inst)
|
||||||
fpr.Lock(Q0, Q1);
|
fpr.Lock(Q0, Q1);
|
||||||
|
|
||||||
ARM64Reg arm_addr = gpr.R(inst.RA);
|
ARM64Reg arm_addr = gpr.R(inst.RA);
|
||||||
ARM64Reg VS = fpr.R(inst.RS);
|
ARM64Reg VS = fpr.R(inst.RS, false);
|
||||||
|
|
||||||
ARM64Reg scale_reg = W0;
|
ARM64Reg scale_reg = W0;
|
||||||
ARM64Reg addr_reg = W1;
|
ARM64Reg addr_reg = W1;
|
||||||
|
|
|
@ -23,10 +23,10 @@ void JitArm64::ps_abs(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 b = inst.FB, d = inst.FD;
|
u32 b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == b);
|
fpr.BindToRegister(d, d == b, false);
|
||||||
|
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FABS(64, VD, VB);
|
m_float_emit.FABS(64, VD, VB);
|
||||||
}
|
}
|
||||||
|
@ -38,11 +38,11 @@ void JitArm64::ps_add(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b);
|
fpr.BindToRegister(d, d == a || d == b, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FADD(64, VD, VA, VB);
|
m_float_emit.FADD(64, VD, VA, VB);
|
||||||
}
|
}
|
||||||
|
@ -54,11 +54,11 @@ void JitArm64::ps_div(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b);
|
fpr.BindToRegister(d, d == a || d == b, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FDIV(64, VD, VA, VB);
|
m_float_emit.FDIV(64, VD, VA, VB);
|
||||||
}
|
}
|
||||||
|
@ -70,12 +70,12 @@ void JitArm64::ps_madd(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.FMUL(64, V0, VA, VC);
|
m_float_emit.FMUL(64, V0, VA, VC);
|
||||||
|
@ -91,12 +91,12 @@ void JitArm64::ps_madds0(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.DUP(64, V0, VC, 0);
|
m_float_emit.DUP(64, V0, VC, 0);
|
||||||
|
@ -113,12 +113,12 @@ void JitArm64::ps_madds1(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.DUP(64, V0, VC, 1);
|
m_float_emit.DUP(64, V0, VC, 1);
|
||||||
|
@ -135,11 +135,11 @@ void JitArm64::ps_merge00(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b);
|
fpr.BindToRegister(d, d == a || d == b, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.TRN1(64, VD, VA, VB);
|
m_float_emit.TRN1(64, VD, VA, VB);
|
||||||
}
|
}
|
||||||
|
@ -151,11 +151,11 @@ void JitArm64::ps_merge01(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b);
|
fpr.BindToRegister(d, d == a || d == b, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.INS(64, VD, 0, VA, 0);
|
m_float_emit.INS(64, VD, 0, VA, 0);
|
||||||
m_float_emit.INS(64, VD, 1, VB, 1);
|
m_float_emit.INS(64, VD, 1, VB, 1);
|
||||||
|
@ -168,11 +168,11 @@ void JitArm64::ps_merge10(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b);
|
fpr.BindToRegister(d, d == a || d == b, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
if (d != a && d != b)
|
if (d != a && d != b)
|
||||||
{
|
{
|
||||||
|
@ -196,11 +196,11 @@ void JitArm64::ps_merge11(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b);
|
fpr.BindToRegister(d, d == a || d == b, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.TRN2(64, VD, VA, VB);
|
m_float_emit.TRN2(64, VD, VA, VB);
|
||||||
}
|
}
|
||||||
|
@ -216,10 +216,10 @@ void JitArm64::ps_mr(UGeckoInstruction inst)
|
||||||
if (d == b)
|
if (d == b)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fpr.BindToRegister(d, false);
|
fpr.BindToRegister(d, false, false);
|
||||||
|
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.ORR(VD, VB, VB);
|
m_float_emit.ORR(VD, VB, VB);
|
||||||
}
|
}
|
||||||
|
@ -231,11 +231,11 @@ void JitArm64::ps_mul(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == c);
|
fpr.BindToRegister(d, d == a || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FMUL(64, VD, VA, VC);
|
m_float_emit.FMUL(64, VD, VA, VC);
|
||||||
}
|
}
|
||||||
|
@ -247,11 +247,11 @@ void JitArm64::ps_muls0(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == c);
|
fpr.BindToRegister(d, d == a || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.DUP(64, V0, VC, 0);
|
m_float_emit.DUP(64, V0, VC, 0);
|
||||||
|
@ -266,11 +266,11 @@ void JitArm64::ps_muls1(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == c);
|
fpr.BindToRegister(d, d == a || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.DUP(64, V0, VC, 1);
|
m_float_emit.DUP(64, V0, VC, 1);
|
||||||
|
@ -285,12 +285,12 @@ void JitArm64::ps_msub(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.FMUL(64, V0, VA, VC);
|
m_float_emit.FMUL(64, V0, VA, VC);
|
||||||
|
@ -306,10 +306,10 @@ void JitArm64::ps_nabs(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 b = inst.FB, d = inst.FD;
|
u32 b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == b);
|
fpr.BindToRegister(d, d == b, false);
|
||||||
|
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FABS(64, VD, VB);
|
m_float_emit.FABS(64, VD, VB);
|
||||||
m_float_emit.FNEG(64, VD, VD);
|
m_float_emit.FNEG(64, VD, VD);
|
||||||
|
@ -322,10 +322,10 @@ void JitArm64::ps_neg(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 b = inst.FB, d = inst.FD;
|
u32 b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == b);
|
fpr.BindToRegister(d, d == b, false);
|
||||||
|
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FNEG(64, VD, VB);
|
m_float_emit.FNEG(64, VD, VB);
|
||||||
}
|
}
|
||||||
|
@ -337,12 +337,12 @@ void JitArm64::ps_nmadd(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.FMUL(64, V0, VA, VC);
|
m_float_emit.FMUL(64, V0, VA, VC);
|
||||||
|
@ -359,12 +359,12 @@ void JitArm64::ps_nmsub(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.FMUL(64, V0, VA, VC);
|
m_float_emit.FMUL(64, V0, VA, VC);
|
||||||
|
@ -381,10 +381,10 @@ void JitArm64::ps_res(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 b = inst.FB, d = inst.FD;
|
u32 b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == b);
|
fpr.BindToRegister(d, d == b, false);
|
||||||
|
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FRSQRTE(64, VD, VB);
|
m_float_emit.FRSQRTE(64, VD, VB);
|
||||||
}
|
}
|
||||||
|
@ -396,12 +396,12 @@ void JitArm64::ps_sel(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
if (d != a && d != b && d != c)
|
if (d != a && d != b && d != c)
|
||||||
{
|
{
|
||||||
|
@ -425,11 +425,11 @@ void JitArm64::ps_sub(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b);
|
fpr.BindToRegister(d, d == a || d == b, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
|
|
||||||
m_float_emit.FSUB(64, VD, VA, VB);
|
m_float_emit.FSUB(64, VD, VA, VB);
|
||||||
}
|
}
|
||||||
|
@ -441,12 +441,12 @@ void JitArm64::ps_sum0(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.DUP(64, V0, VB, 1);
|
m_float_emit.DUP(64, V0, VB, 1);
|
||||||
|
@ -471,12 +471,12 @@ void JitArm64::ps_sum1(UGeckoInstruction inst)
|
||||||
FALLBACK_IF(inst.Rc);
|
FALLBACK_IF(inst.Rc);
|
||||||
|
|
||||||
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
|
||||||
fpr.BindToRegister(d, d == a || d == b || d == c);
|
fpr.BindToRegister(d, d == a || d == b || d == c, false);
|
||||||
|
|
||||||
ARM64Reg VA = fpr.R(a);
|
ARM64Reg VA = fpr.R(a, false);
|
||||||
ARM64Reg VB = fpr.R(b);
|
ARM64Reg VB = fpr.R(b, false);
|
||||||
ARM64Reg VC = fpr.R(c);
|
ARM64Reg VC = fpr.R(c, false);
|
||||||
ARM64Reg VD = fpr.R(d);
|
ARM64Reg VD = fpr.R(d, false);
|
||||||
ARM64Reg V0 = fpr.GetReg();
|
ARM64Reg V0 = fpr.GetReg();
|
||||||
|
|
||||||
m_float_emit.DUP(64, V0, VA, 0);
|
m_float_emit.DUP(64, V0, VA, 0);
|
||||||
|
|
|
@ -65,7 +65,8 @@ void Arm64RegCache::FlushMostStaleRegister()
|
||||||
{
|
{
|
||||||
u32 last_used = m_guest_registers[i].GetLastUsed();
|
u32 last_used = m_guest_registers[i].GetLastUsed();
|
||||||
if (last_used > most_stale_amount &&
|
if (last_used > most_stale_amount &&
|
||||||
m_guest_registers[i].GetType() == REG_REG)
|
(m_guest_registers[i].GetType() != REG_NOTLOADED &&
|
||||||
|
m_guest_registers[i].GetType() != REG_IMM))
|
||||||
{
|
{
|
||||||
most_stale_preg = i;
|
most_stale_preg = i;
|
||||||
most_stale_amount = last_used;
|
most_stale_amount = last_used;
|
||||||
|
@ -261,7 +262,8 @@ void Arm64FPRCache::Flush(FlushMode mode, PPCAnalyst::CodeOp* op)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 32; ++i)
|
for (int i = 0; i < 32; ++i)
|
||||||
{
|
{
|
||||||
if (m_guest_registers[i].GetType() == REG_REG)
|
if (m_guest_registers[i].GetType() != REG_NOTLOADED &&
|
||||||
|
m_guest_registers[i].GetType() != REG_IMM)
|
||||||
{
|
{
|
||||||
// XXX: Determine if we can keep a register in the lower 64bits
|
// XXX: Determine if we can keep a register in the lower 64bits
|
||||||
// Which will allow it to be callee saved.
|
// Which will allow it to be callee saved.
|
||||||
|
@ -270,7 +272,7 @@ void Arm64FPRCache::Flush(FlushMode mode, PPCAnalyst::CodeOp* op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ARM64Reg Arm64FPRCache::R(u32 preg)
|
ARM64Reg Arm64FPRCache::R(u32 preg, bool only_lower)
|
||||||
{
|
{
|
||||||
OpArg& reg = m_guest_registers[preg];
|
OpArg& reg = m_guest_registers[preg];
|
||||||
IncrementAllUsed();
|
IncrementAllUsed();
|
||||||
|
@ -279,14 +281,25 @@ ARM64Reg Arm64FPRCache::R(u32 preg)
|
||||||
switch (reg.GetType())
|
switch (reg.GetType())
|
||||||
{
|
{
|
||||||
case REG_REG: // already in a reg
|
case REG_REG: // already in a reg
|
||||||
|
case REG_LOWER_PAIR:
|
||||||
return reg.GetReg();
|
return reg.GetReg();
|
||||||
break;
|
break;
|
||||||
case REG_NOTLOADED: // Register isn't loaded at /all/
|
case REG_NOTLOADED: // Register isn't loaded at /all/
|
||||||
{
|
{
|
||||||
ARM64Reg host_reg = GetReg();
|
ARM64Reg host_reg = GetReg();
|
||||||
reg.LoadToReg(host_reg);
|
u32 load_size;
|
||||||
|
if (only_lower)
|
||||||
|
{
|
||||||
|
load_size = 64;
|
||||||
|
reg.LoadLowerReg(host_reg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
load_size = 128;
|
||||||
|
reg.LoadToReg(host_reg);
|
||||||
|
}
|
||||||
reg.SetDirty(false);
|
reg.SetDirty(false);
|
||||||
m_float_emit->LDR(128, INDEX_UNSIGNED, host_reg, X29, PPCSTATE_OFF(ps[preg][0]));
|
m_float_emit->LDR(load_size, INDEX_UNSIGNED, host_reg, X29, PPCSTATE_OFF(ps[preg][0]));
|
||||||
return host_reg;
|
return host_reg;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -298,17 +311,55 @@ ARM64Reg Arm64FPRCache::R(u32 preg)
|
||||||
return INVALID_REG;
|
return INVALID_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Arm64FPRCache::BindToRegister(u32 preg, bool do_load)
|
void Arm64FPRCache::BindToRegister(u32 preg, bool do_load, bool only_lower)
|
||||||
{
|
{
|
||||||
OpArg& reg = m_guest_registers[preg];
|
OpArg& reg = m_guest_registers[preg];
|
||||||
|
|
||||||
reg.SetDirty(true);
|
reg.SetDirty(true);
|
||||||
if (reg.GetType() == REG_NOTLOADED)
|
switch (reg.GetType())
|
||||||
|
{
|
||||||
|
case REG_NOTLOADED:
|
||||||
{
|
{
|
||||||
ARM64Reg host_reg = GetReg();
|
ARM64Reg host_reg = GetReg();
|
||||||
reg.LoadToReg(host_reg);
|
u32 load_size;
|
||||||
|
if (only_lower)
|
||||||
|
{
|
||||||
|
// We only want the lower 64bits
|
||||||
|
load_size = 64;
|
||||||
|
reg.LoadLowerReg(host_reg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We want the full 128bit register
|
||||||
|
load_size = 128;
|
||||||
|
reg.LoadToReg(host_reg);
|
||||||
|
}
|
||||||
if (do_load)
|
if (do_load)
|
||||||
m_float_emit->LDR(128, INDEX_UNSIGNED, host_reg, X29, PPCSTATE_OFF(ps[preg][0]));
|
m_float_emit->LDR(load_size, INDEX_UNSIGNED, host_reg, X29, PPCSTATE_OFF(ps[preg][0]));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REG_LOWER_PAIR:
|
||||||
|
{
|
||||||
|
if (!only_lower)
|
||||||
|
{
|
||||||
|
// Okay, we've got the lower reg loaded and we really wanted the full register
|
||||||
|
if (do_load)
|
||||||
|
{
|
||||||
|
// Load the high 64bits from the file and insert them in to the high 64bits of the host register
|
||||||
|
ARM64Reg tmp_reg = GetReg();
|
||||||
|
m_float_emit->LDR(64, INDEX_UNSIGNED, tmp_reg, X29, PPCSTATE_OFF(ps[preg][1]));
|
||||||
|
m_float_emit->INS(64, reg.GetReg(), 1, tmp_reg, 0);
|
||||||
|
UnlockRegister(tmp_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change it over to a full 128bit register
|
||||||
|
reg.LoadToReg(reg.GetReg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +385,7 @@ void Arm64FPRCache::FlushByHost(ARM64Reg host_reg)
|
||||||
for (int i = 0; i < 32; ++i)
|
for (int i = 0; i < 32; ++i)
|
||||||
{
|
{
|
||||||
OpArg& reg = m_guest_registers[i];
|
OpArg& reg = m_guest_registers[i];
|
||||||
if (reg.GetType() == REG_REG && reg.GetReg() == host_reg)
|
if ((reg.GetType() != REG_NOTLOADED && reg.GetType() != REG_IMM) && reg.GetReg() == host_reg)
|
||||||
{
|
{
|
||||||
FlushRegister(i, false);
|
FlushRegister(i, false);
|
||||||
return;
|
return;
|
||||||
|
@ -355,12 +406,18 @@ bool Arm64FPRCache::IsCalleeSaved(ARM64Reg reg)
|
||||||
void Arm64FPRCache::FlushRegister(u32 preg, bool maintain_state)
|
void Arm64FPRCache::FlushRegister(u32 preg, bool maintain_state)
|
||||||
{
|
{
|
||||||
OpArg& reg = m_guest_registers[preg];
|
OpArg& reg = m_guest_registers[preg];
|
||||||
if (reg.GetType() == REG_REG)
|
if (reg.GetType() == REG_REG ||
|
||||||
|
reg.GetType() == REG_LOWER_PAIR)
|
||||||
{
|
{
|
||||||
ARM64Reg host_reg = reg.GetReg();
|
ARM64Reg host_reg = reg.GetReg();
|
||||||
|
u32 store_size;
|
||||||
|
if (reg.GetType() == REG_REG)
|
||||||
|
store_size = 128;
|
||||||
|
else
|
||||||
|
store_size = 64;
|
||||||
|
|
||||||
if (reg.IsDirty())
|
if (reg.IsDirty())
|
||||||
m_float_emit->STR(128, INDEX_UNSIGNED, host_reg, X29, PPCSTATE_OFF(ps[preg][0]));
|
m_float_emit->STR(store_size, INDEX_UNSIGNED, host_reg, X29, PPCSTATE_OFF(ps[preg][0]));
|
||||||
|
|
||||||
if (!maintain_state)
|
if (!maintain_state)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,11 +19,7 @@ enum RegType
|
||||||
REG_NOTLOADED = 0,
|
REG_NOTLOADED = 0,
|
||||||
REG_REG, // Reg type is register
|
REG_REG, // Reg type is register
|
||||||
REG_IMM, // Reg is really a IMM
|
REG_IMM, // Reg is really a IMM
|
||||||
};
|
REG_LOWER_PAIR, // Only the lower pair of a paired register
|
||||||
enum RegLocation
|
|
||||||
{
|
|
||||||
REG_LOW = 0,
|
|
||||||
REG_HIGH,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FlushMode
|
enum FlushMode
|
||||||
|
@ -64,6 +60,11 @@ public:
|
||||||
m_type = REG_REG;
|
m_type = REG_REG;
|
||||||
m_reg = reg;
|
m_reg = reg;
|
||||||
}
|
}
|
||||||
|
void LoadLowerReg(ARM64Reg reg)
|
||||||
|
{
|
||||||
|
m_type = REG_LOWER_PAIR;
|
||||||
|
m_reg = reg;
|
||||||
|
}
|
||||||
void LoadToImm(u32 imm)
|
void LoadToImm(u32 imm)
|
||||||
{
|
{
|
||||||
m_type = REG_IMM;
|
m_type = REG_IMM;
|
||||||
|
@ -134,10 +135,6 @@ public:
|
||||||
// Flushes the register cache in different ways depending on the mode
|
// Flushes the register cache in different ways depending on the mode
|
||||||
virtual void Flush(FlushMode mode, PPCAnalyst::CodeOp* op) = 0;
|
virtual void Flush(FlushMode mode, PPCAnalyst::CodeOp* op) = 0;
|
||||||
|
|
||||||
// Returns a guest register inside of a host register
|
|
||||||
// Will dump an immediate to the host register as well
|
|
||||||
virtual ARM64Reg R(u32 reg) = 0;
|
|
||||||
|
|
||||||
virtual BitSet32 GetCallerSavedUsed() = 0;
|
virtual BitSet32 GetCallerSavedUsed() = 0;
|
||||||
|
|
||||||
// Returns a temporary register for use
|
// Returns a temporary register for use
|
||||||
|
@ -265,9 +262,12 @@ public:
|
||||||
|
|
||||||
// Returns a guest register inside of a host register
|
// Returns a guest register inside of a host register
|
||||||
// Will dump an immediate to the host register as well
|
// Will dump an immediate to the host register as well
|
||||||
ARM64Reg R(u32 preg);
|
ARM64Reg R(u32 preg, bool only_lower = true);
|
||||||
|
|
||||||
void BindToRegister(u32 preg, bool do_load);
|
void BindToRegister(u32 preg, bool do_load, bool only_lower = true);
|
||||||
|
|
||||||
|
// Returns if the register is only the lower 64bit register
|
||||||
|
bool IsLower(u32 preg) const { return m_guest_registers[preg].GetType() == REG_LOWER_PAIR; }
|
||||||
|
|
||||||
BitSet32 GetCallerSavedUsed() override;
|
BitSet32 GetCallerSavedUsed() override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue