summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorMarkus Wick <markus@selfnet.de>2015-08-26 13:10:04 +0200
committerMarkus Wick <markus@selfnet.de>2015-08-26 13:10:04 +0200
commita36b1354737f92ae7148527fbd438ff13afbb9a8 (patch)
tree1716a42dea37839866e22540e2b1d1b458c5e8c5 /Source/Core
parent5716d18d107da0e6885594562cef6aedd288b478 (diff)
parentca51f1a4f67445a69632c3f53d1b62f074cb7414 (diff)
Merge pull request #2911 from Sonicadvance1/aarch64_regcache_optimization
[AArch64] Optimize paired registers being used in double operations.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp166
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp15
2 files changed, 32 insertions, 149 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp
index a02948534a..4ee267f55c 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp
@@ -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)
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp
index a2e16ef88a..27b021cf8a 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp
@@ -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;