From 98d99a9eefc74957a3c6542870a344b601f1ddf5 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 18 Jan 2015 16:45:42 -0600 Subject: [PATCH] [AArch64] Optimize loadstores address calculation. For offsets that fit in the instruction encoding then we should just put it in the instruction encoding. Saves an instruction in a large amount of loadstores. --- .../PowerPC/JitArm64/JitArm64_LoadStore.cpp | 78 ++++++++++++++++--- .../JitArm64/JitArm64_LoadStoreFloating.cpp | 63 ++++++++++++--- 2 files changed, 118 insertions(+), 23 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp index c0a3176307..ed92483e58 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp @@ -62,8 +62,19 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o } else { - MOVI2R(addr_reg, offset); - ADD(addr_reg, addr_reg, up_reg); + if (offset >= 0 && offset < 4096) + { + ADD(addr_reg, up_reg, offset); + } + else if (offset < 0 && offset > -4096) + { + SUB(addr_reg, up_reg, std::abs(offset)); + } + else + { + MOVI2R(addr_reg, offset); + ADD(addr_reg, addr_reg, up_reg); + } } } else @@ -83,13 +94,29 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o } else if (gpr.IsImm(addr) && !gpr.IsImm(offsetReg)) { - MOVI2R(addr_reg, gpr.GetImm(addr)); - ADD(addr_reg, addr_reg, off_reg); + u32 reg_offset = gpr.GetImm(addr); + if (reg_offset < 4096) + { + ADD(addr_reg, off_reg, reg_offset); + } + else + { + MOVI2R(addr_reg, gpr.GetImm(addr)); + ADD(addr_reg, addr_reg, off_reg); + } } else if (!gpr.IsImm(addr) && gpr.IsImm(offsetReg)) { - MOVI2R(addr_reg, gpr.GetImm(offsetReg)); - ADD(addr_reg, addr_reg, up_reg); + u32 reg_offset = gpr.GetImm(offsetReg); + if (reg_offset < 4096) + { + ADD(addr_reg, up_reg, reg_offset); + } + else + { + MOVI2R(addr_reg, gpr.GetImm(offsetReg)); + ADD(addr_reg, addr_reg, up_reg); + } } else { @@ -176,8 +203,19 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s } else { - MOVI2R(addr_reg, offset); - ADD(addr_reg, addr_reg, reg_dest); + if (offset >= 0 && offset < 4096) + { + ADD(addr_reg, reg_dest, offset); + } + else if (offset < 0 && offset > -4096) + { + SUB(addr_reg, reg_dest, std::abs(offset)); + } + else + { + MOVI2R(addr_reg, offset); + ADD(addr_reg, addr_reg, reg_dest); + } } } else @@ -197,13 +235,29 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s } else if (gpr.IsImm(dest) && !gpr.IsImm(regOffset)) { - MOVI2R(addr_reg, gpr.GetImm(dest)); - ADD(addr_reg, addr_reg, reg_off); + u32 reg_offset = gpr.GetImm(dest); + if (reg_offset < 4096) + { + ADD(addr_reg, reg_off, reg_offset); + } + else + { + MOVI2R(addr_reg, reg_offset); + ADD(addr_reg, addr_reg, reg_off); + } } else if (!gpr.IsImm(dest) && gpr.IsImm(regOffset)) { - MOVI2R(addr_reg, gpr.GetImm(regOffset)); - ADD(addr_reg, addr_reg, reg_dest); + u32 reg_offset = gpr.GetImm(regOffset); + if (reg_offset < 4096) + { + ADD(addr_reg, reg_dest, reg_offset); + } + else + { + MOVI2R(addr_reg, gpr.GetImm(regOffset)); + ADD(addr_reg, addr_reg, reg_dest); + } } else { diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp index 49c40a905a..38d3b4b8fe 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp @@ -94,9 +94,19 @@ void JitArm64::lfXX(UGeckoInstruction inst) { if (offset_reg == -1) { - MOVI2R(addr_reg, offset); - ADD(addr_reg, addr_reg, gpr.R(a)); - } + if (offset >= 0 && offset < 4096) + { + ADD(addr_reg, gpr.R(a), offset); + } + else if (offset < 0 && offset > -4096) + { + SUB(addr_reg, gpr.R(a), std::abs(offset)); + } + else + { + MOVI2R(addr_reg, offset); + ADD(addr_reg, addr_reg, gpr.R(a)); + } } else { ADD(addr_reg, gpr.R(offset_reg), gpr.R(a)); @@ -114,9 +124,19 @@ void JitArm64::lfXX(UGeckoInstruction inst) } else if (a) { - MOVI2R(addr_reg, offset); - ADD(addr_reg, addr_reg, gpr.R(a)); - } + if (offset >= 0 && offset < 4096) + { + ADD(addr_reg, gpr.R(a), offset); + } + else if (offset < 0 && offset > -4096) + { + SUB(addr_reg, gpr.R(a), std::abs(offset)); + } + else + { + MOVI2R(addr_reg, offset); + ADD(addr_reg, addr_reg, gpr.R(a)); + } } else { is_immediate = true; @@ -266,8 +286,19 @@ void JitArm64::stfXX(UGeckoInstruction inst) { if (offset_reg == -1) { - MOVI2R(addr_reg, offset); - ADD(addr_reg, addr_reg, gpr.R(a)); + if (offset >= 0 && offset < 4096) + { + ADD(addr_reg, gpr.R(a), offset); + } + else if (offset < 0 && offset > -4096) + { + SUB(addr_reg, gpr.R(a), std::abs(offset)); + } + else + { + MOVI2R(addr_reg, offset); + ADD(addr_reg, addr_reg, gpr.R(a)); + } } else { @@ -286,9 +317,19 @@ void JitArm64::stfXX(UGeckoInstruction inst) } else if (a) { - MOVI2R(addr_reg, offset); - ADD(addr_reg, addr_reg, gpr.R(a)); - } + if (offset >= 0 && offset < 4096) + { + ADD(addr_reg, gpr.R(a), offset); + } + else if (offset < 0 && offset > -4096) + { + SUB(addr_reg, gpr.R(a), std::abs(offset)); + } + else + { + MOVI2R(addr_reg, offset); + ADD(addr_reg, addr_reg, gpr.R(a)); + } } else { is_immediate = true;