Merge pull request #2911 from Sonicadvance1/aarch64_regcache_optimization
[AArch64] Optimize paired registers being used in double operations.
This commit is contained in:
commit
a36b135473
|
@ -27,17 +27,7 @@ void JitArm64::fabsx(UGeckoInstruction inst)
|
|||
ARM64Reg VB = fpr.R(b);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||
}
|
||||
|
||||
void JitArm64::faddsx(UGeckoInstruction inst)
|
||||
|
@ -70,17 +60,7 @@ void JitArm64::faddx(UGeckoInstruction inst)
|
|||
ARM64Reg VB = fpr.R(b);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||
}
|
||||
|
||||
void JitArm64::fmaddsx(UGeckoInstruction inst)
|
||||
|
@ -118,17 +98,7 @@ void JitArm64::fmaddx(UGeckoInstruction inst)
|
|||
ARM64Reg VC = fpr.R(c);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FMADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FMADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||
}
|
||||
|
||||
void JitArm64::fmrx(UGeckoInstruction inst)
|
||||
|
@ -181,17 +151,7 @@ void JitArm64::fmsubx(UGeckoInstruction inst)
|
|||
ARM64Reg VC = fpr.R(c);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FNMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FNMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||
}
|
||||
|
||||
void JitArm64::fmulsx(UGeckoInstruction inst)
|
||||
|
@ -224,17 +184,7 @@ void JitArm64::fmulx(UGeckoInstruction inst)
|
|||
ARM64Reg VC = fpr.R(c);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
|
||||
}
|
||||
|
||||
void JitArm64::fnabsx(UGeckoInstruction inst)
|
||||
|
@ -249,19 +199,8 @@ void JitArm64::fnabsx(UGeckoInstruction inst)
|
|||
ARM64Reg VB = fpr.R(b);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||
m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VD));
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||
m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VD));
|
||||
}
|
||||
|
||||
void JitArm64::fnegx(UGeckoInstruction inst)
|
||||
|
@ -276,17 +215,7 @@ void JitArm64::fnegx(UGeckoInstruction inst)
|
|||
ARM64Reg VB = fpr.R(b);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||
}
|
||||
|
||||
void JitArm64::fnmaddsx(UGeckoInstruction inst)
|
||||
|
@ -325,17 +254,7 @@ void JitArm64::fnmaddx(UGeckoInstruction inst)
|
|||
ARM64Reg VC = fpr.R(c);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FNMADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FNMADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||
}
|
||||
|
||||
void JitArm64::fnmsubsx(UGeckoInstruction inst)
|
||||
|
@ -374,17 +293,7 @@ void JitArm64::fnmsubx(UGeckoInstruction inst)
|
|||
ARM64Reg VC = fpr.R(c);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
|
||||
}
|
||||
|
||||
void JitArm64::fselx(UGeckoInstruction inst)
|
||||
|
@ -402,17 +311,7 @@ void JitArm64::fselx(UGeckoInstruction inst)
|
|||
ARM64Reg VC = fpr.R(c);
|
||||
|
||||
m_float_emit.FCMPE(EncodeRegToDouble(VA));
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FCSEL(EncodeRegToDouble(VD), EncodeRegToDouble(VC), EncodeRegToDouble(VB), CC_GE);
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FCSEL(EncodeRegToDouble(VD), EncodeRegToDouble(VC), EncodeRegToDouble(VB), CC_GE);
|
||||
}
|
||||
|
||||
void JitArm64::fsubsx(UGeckoInstruction inst)
|
||||
|
@ -445,17 +344,7 @@ void JitArm64::fsubx(UGeckoInstruction inst)
|
|||
ARM64Reg VB = fpr.R(b);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||
}
|
||||
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);
|
||||
}
|
||||
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||
}
|
||||
|
||||
void JitArm64::frspx(UGeckoInstruction inst)
|
||||
|
@ -576,21 +465,10 @@ void JitArm64::fctiwzx(UGeckoInstruction inst)
|
|||
// Generate 0xFFF8000000000000ULL
|
||||
m_float_emit.MOVI(64, EncodeRegToDouble(V0), 0xFFFF000000000000ULL);
|
||||
m_float_emit.BIC(16, EncodeRegToDouble(V0), 0x7);
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FCVTN(32, EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||
m_float_emit.FCVTS(EncodeRegToSingle(VD), EncodeRegToSingle(VD), ROUND_Z);
|
||||
m_float_emit.ORR(EncodeRegToDouble(VD), EncodeRegToDouble(VD), EncodeRegToDouble(V0));
|
||||
}
|
||||
else
|
||||
{
|
||||
ARM64Reg V1 = fpr.GetReg();
|
||||
m_float_emit.FCVTN(32, EncodeRegToDouble(V1), EncodeRegToDouble(VB));
|
||||
m_float_emit.FCVTS(EncodeRegToSingle(V1), EncodeRegToSingle(V1), ROUND_Z);
|
||||
m_float_emit.ORR(EncodeRegToDouble(V1), EncodeRegToDouble(V1), EncodeRegToDouble(V0));
|
||||
m_float_emit.INS(64, VD, 0, V1, 0);
|
||||
fpr.Unlock(V1);
|
||||
}
|
||||
|
||||
m_float_emit.FCVTN(32, EncodeRegToDouble(VD), EncodeRegToDouble(VB));
|
||||
m_float_emit.FCVTS(EncodeRegToSingle(VD), EncodeRegToSingle(VD), ROUND_Z);
|
||||
m_float_emit.ORR(EncodeRegToDouble(VD), EncodeRegToDouble(VD), EncodeRegToDouble(V0));
|
||||
fpr.Unlock(V0);
|
||||
}
|
||||
|
||||
|
@ -607,17 +485,7 @@ void JitArm64::fdivx(UGeckoInstruction inst)
|
|||
ARM64Reg VB = fpr.R(b);
|
||||
ARM64Reg VD = fpr.R(d);
|
||||
|
||||
if (fpr.IsLower(d))
|
||||
{
|
||||
m_float_emit.FDIV(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||
}
|
||||
else
|
||||
{
|
||||
ARM64Reg V0 = fpr.GetReg();
|
||||
m_float_emit.FDIV(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||
m_float_emit.INS(64, VD, 0, V0, 0);
|
||||
fpr.Unlock(V0);
|
||||
}
|
||||
m_float_emit.FDIV(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
|
||||
}
|
||||
|
||||
void JitArm64::fdivsx(UGeckoInstruction inst)
|
||||
|
|
|
@ -330,6 +330,7 @@ void Arm64FPRCache::BindToRegister(u32 preg, bool do_load, bool only_lower)
|
|||
{
|
||||
OpArg& reg = m_guest_registers[preg];
|
||||
|
||||
bool was_dirty = reg.IsDirty();
|
||||
reg.SetDirty(true);
|
||||
switch (reg.GetType())
|
||||
{
|
||||
|
@ -372,6 +373,20 @@ void Arm64FPRCache::BindToRegister(u32 preg, bool do_load, bool only_lower)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case REG_REG:
|
||||
{
|
||||
if (only_lower)
|
||||
{
|
||||
// If we only want the lower bits, let's store away the high bits and drop to a lower only register
|
||||
// We are doing a full 128bit store because it takes 2 cycles on a Cortex-A57 to do a 128bit store.
|
||||
// It would take longer to do an insert to a temporary and a 64bit store than to just do this.
|
||||
ARM64Reg host_reg = reg.GetReg();
|
||||
if (was_dirty)
|
||||
m_float_emit->STR(128, INDEX_UNSIGNED, host_reg, X29, PPCSTATE_OFF(ps[preg][0]));
|
||||
reg.LoadLowerReg(host_reg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue