diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 14da56ec7c..472162332c 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -31,8 +31,8 @@ void JitArm64::ComputeRC(u32 imm, int crf) ARM64Reg WA = gpr.GetReg(); ARM64Reg XA = EncodeRegTo64(WA); - MOVI2R(WA, imm); - if (!(imm & 0x80000000)) + MOVI2R(XA, imm); + if (imm & 0x80000000) SXTW(XA, WA); STR(INDEX_UNSIGNED, XA, X29, PPCSTATE_OFF(cr_val[crf])); @@ -405,7 +405,11 @@ void JitArm64::cmpl(UGeckoInstruction inst) return; } - FALLBACK_IF(true); + ARM64Reg WA = gpr.GetReg(); + ARM64Reg XA = EncodeRegTo64(WA); + SUB(XA, EncodeRegTo64(gpr.R(a)), EncodeRegTo64(gpr.R(b))); + STR(INDEX_UNSIGNED, XA, X29, PPCSTATE_OFF(cr_val[0]) + (sizeof(PowerPC::ppcState.cr_val[0]) * crf)); + gpr.Unlock(WA); } void JitArm64::cmpi(UGeckoInstruction inst) @@ -457,7 +461,21 @@ void JitArm64::cmpli(UGeckoInstruction inst) return; } - FALLBACK_IF(true); + ARM64Reg WA = gpr.GetReg(); + ARM64Reg XA = EncodeRegTo64(WA); + + if (inst.UIMM < 4096) + { + SUB(XA, EncodeRegTo64(gpr.R(a)), inst.UIMM); + } + else + { + MOVI2R(WA, inst.UIMM); + SUB(XA, EncodeRegTo64(gpr.R(a)), XA); + } + + STR(INDEX_UNSIGNED, XA, X29, PPCSTATE_OFF(cr_val[0]) + (sizeof(PowerPC::ppcState.cr_val[0]) * crf)); + gpr.Unlock(WA); } void JitArm64::rlwinmx(UGeckoInstruction inst) 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;