diff --git a/Source/Core/Common/Arm64Emitter.cpp b/Source/Core/Common/Arm64Emitter.cpp index 637f7d06c2..6453f29e05 100644 --- a/Source/Core/Common/Arm64Emitter.cpp +++ b/Source/Core/Common/Arm64Emitter.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -480,13 +481,13 @@ void ARM64XEmitter::EncodeCompareBranchInst(u32 op, ARM64Reg Rt, const void* ptr bool b64Bit = Is64Bit(Rt); s64 distance = (s64)ptr - (s64)m_code; - _assert_msg_(DYNA_REC, !(distance & 0x3), "%s: distance must be a multiple of 4: %lx", + _assert_msg_(DYNA_REC, !(distance & 0x3), "%s: distance must be a multiple of 4: %" PRIx64, __FUNCTION__, distance); distance >>= 2; _assert_msg_(DYNA_REC, distance >= -0x40000 && distance <= 0x3FFFF, - "%s: Received too large distance: %lx", __FUNCTION__, distance); + "%s: Received too large distance: %" PRIx64, __FUNCTION__, distance); Rt = DecodeReg(Rt); Write32((b64Bit << 31) | (0x34 << 24) | (op << 24) | (((u32)distance << 5) & 0xFFFFE0) | Rt); @@ -497,13 +498,13 @@ void ARM64XEmitter::EncodeTestBranchInst(u32 op, ARM64Reg Rt, u8 bits, const voi bool b64Bit = Is64Bit(Rt); s64 distance = (s64)ptr - (s64)m_code; - _assert_msg_(DYNA_REC, !(distance & 0x3), "%s: distance must be a multiple of 4: %lx", + _assert_msg_(DYNA_REC, !(distance & 0x3), "%s: distance must be a multiple of 4: %" PRIx64, __FUNCTION__, distance); distance >>= 2; _assert_msg_(DYNA_REC, distance >= -0x3FFF && distance < 0x3FFF, - "%s: Received too large distance: %lx", __FUNCTION__, distance); + "%s: Received too large distance: %" PRIx64, __FUNCTION__, distance); Rt = DecodeReg(Rt); Write32((b64Bit << 31) | (0x36 << 24) | (op << 24) | (bits << 19) | @@ -514,13 +515,13 @@ void ARM64XEmitter::EncodeUnconditionalBranchInst(u32 op, const void* ptr) { s64 distance = (s64)ptr - s64(m_code); - _assert_msg_(DYNA_REC, !(distance & 0x3), "%s: distance must be a multiple of 4: %lx", + _assert_msg_(DYNA_REC, !(distance & 0x3), "%s: distance must be a multiple of 4: %" PRIx64, __FUNCTION__, distance); distance >>= 2; _assert_msg_(DYNA_REC, distance >= -0x2000000LL && distance <= 0x1FFFFFFLL, - "%s: Received too large distance: %lx", __FUNCTION__, distance); + "%s: Received too large distance: %" PRIx64, __FUNCTION__, distance); Write32((op << 31) | (0x5 << 26) | (distance & 0x3FFFFFF)); } @@ -902,37 +903,42 @@ void ARM64XEmitter::SetJumpTarget(FixupBranch const& branch) Not = true; case 0: // CBZ { - _assert_msg_(DYNA_REC, IsInRangeImm19(distance), "%s(%d): Received too large distance: %lx", - __FUNCTION__, branch.type, distance); + _assert_msg_(DYNA_REC, IsInRangeImm19(distance), + "%s(%d): Received too large distance: %" PRIx64, __FUNCTION__, branch.type, + distance); bool b64Bit = Is64Bit(branch.reg); ARM64Reg reg = DecodeReg(branch.reg); inst = (b64Bit << 31) | (0x1A << 25) | (Not << 24) | (MaskImm19(distance) << 5) | reg; } break; case 2: // B (conditional) - _assert_msg_(DYNA_REC, IsInRangeImm19(distance), "%s(%d): Received too large distance: %lx", - __FUNCTION__, branch.type, distance); + _assert_msg_(DYNA_REC, IsInRangeImm19(distance), + "%s(%d): Received too large distance: %" PRIx64, __FUNCTION__, branch.type, + distance); inst = (0x2A << 25) | (MaskImm19(distance) << 5) | branch.cond; break; case 4: // TBNZ Not = true; case 3: // TBZ { - _assert_msg_(DYNA_REC, IsInRangeImm14(distance), "%s(%d): Received too large distance: %lx", - __FUNCTION__, branch.type, distance); + _assert_msg_(DYNA_REC, IsInRangeImm14(distance), + "%s(%d): Received too large distance: %" PRIx64, __FUNCTION__, branch.type, + distance); ARM64Reg reg = DecodeReg(branch.reg); inst = ((branch.bit & 0x20) << 26) | (0x1B << 25) | (Not << 24) | ((branch.bit & 0x1F) << 19) | (MaskImm14(distance) << 5) | reg; } break; case 5: // B (uncoditional) - _assert_msg_(DYNA_REC, IsInRangeImm26(distance), "%s(%d): Received too large distance: %lx", - __FUNCTION__, branch.type, distance); + _assert_msg_(DYNA_REC, IsInRangeImm26(distance), + "%s(%d): Received too large distance: %" PRIx64, __FUNCTION__, branch.type, + distance); inst = (0x5 << 26) | MaskImm26(distance); break; case 6: // BL (unconditional) - _assert_msg_(DYNA_REC, IsInRangeImm26(distance), "%s(%d): Received too large distance: %lx", - __FUNCTION__, branch.type, distance); + _assert_msg_(DYNA_REC, IsInRangeImm26(distance), + "%s(%d): Received too large distance: %" PRIx64, __FUNCTION__, branch.type, + distance); inst = (0x25 << 26) | MaskImm26(distance); break; } @@ -1021,8 +1027,8 @@ void ARM64XEmitter::B(CCFlags cond, const void* ptr) distance >>= 2; _assert_msg_(DYNA_REC, IsInRangeImm19(distance), - "%s: Received too large distance: %p->%p %ld %lx", __FUNCTION__, m_code, ptr, - distance, distance); + "%s: Received too large distance: %p->%p %" PRIi64 " %" PRIx64, __FUNCTION__, m_code, + ptr, distance, distance); Write32((0x54 << 24) | (MaskImm19(distance) << 5) | cond); } @@ -4102,27 +4108,29 @@ void ARM64XEmitter::ANDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) } } +void ARM64XEmitter::AddImmediate(ARM64Reg Rd, ARM64Reg Rn, u64 imm, bool shift, bool negative, + bool flags) +{ + switch ((negative << 1) | flags) + { + case 0: + ADD(Rd, Rn, imm, shift); + break; + case 1: + ADDS(Rd, Rn, imm, shift); + break; + case 2: + SUB(Rd, Rn, imm, shift); + break; + case 3: + SUBS(Rd, Rn, imm, shift); + break; + } +} + void ARM64XEmitter::ADDI2R_internal(ARM64Reg Rd, ARM64Reg Rn, u64 imm, bool negative, bool flags, ARM64Reg scratch) { - auto addi = [this](ARM64Reg Rd, ARM64Reg Rn, u64 imm, bool shift, bool negative, bool flags) { - switch ((negative << 1) | flags) - { - case 0: - ADD(Rd, Rn, imm, shift); - break; - case 1: - ADDS(Rd, Rn, imm, shift); - break; - case 2: - SUB(Rd, Rn, imm, shift); - break; - case 3: - SUBS(Rd, Rn, imm, shift); - break; - } - }; - bool has_scratch = scratch != INVALID_REG; u64 imm_neg = Is64Bit(Rd) ? -imm : -imm & 0xFFFFFFFFuLL; bool neg_neg = negative ? false : true; @@ -4131,22 +4139,22 @@ void ARM64XEmitter::ADDI2R_internal(ARM64Reg Rd, ARM64Reg Rn, u64 imm, bool nega // Try them all first if (imm <= 0xFFF) { - addi(Rd, Rn, imm, false, negative, flags); + AddImmediate(Rd, Rn, imm, false, negative, flags); return; } if (imm <= 0xFFFFFF && (imm & 0xFFF) == 0) { - addi(Rd, Rn, imm >> 12, true, negative, flags); + AddImmediate(Rd, Rn, imm >> 12, true, negative, flags); return; } if (imm_neg <= 0xFFF) { - addi(Rd, Rn, imm_neg, false, neg_neg, flags); + AddImmediate(Rd, Rn, imm_neg, false, neg_neg, flags); return; } if (imm_neg <= 0xFFFFFF && (imm_neg & 0xFFF) == 0) { - addi(Rd, Rn, imm_neg >> 12, true, neg_neg, flags); + AddImmediate(Rd, Rn, imm_neg >> 12, true, neg_neg, flags); return; } @@ -4155,14 +4163,14 @@ void ARM64XEmitter::ADDI2R_internal(ARM64Reg Rd, ARM64Reg Rn, u64 imm, bool nega // As this splits the addition in two parts, this must not be done on setting flags. if (!flags && (imm >= 0x10000u || !has_scratch) && imm < 0x1000000u) { - addi(Rd, Rn, imm & 0xFFF, false, negative, false); - addi(Rd, Rd, imm >> 12, true, negative, false); + AddImmediate(Rd, Rn, imm & 0xFFF, false, negative, false); + AddImmediate(Rd, Rd, imm >> 12, true, negative, false); return; } if (!flags && (imm_neg >= 0x10000u || !has_scratch) && imm_neg < 0x1000000u) { - addi(Rd, Rn, imm_neg & 0xFFF, false, neg_neg, false); - addi(Rd, Rd, imm_neg >> 12, true, neg_neg, false); + AddImmediate(Rd, Rn, imm_neg & 0xFFF, false, neg_neg, false); + AddImmediate(Rd, Rd, imm_neg >> 12, true, neg_neg, false); return; } diff --git a/Source/Core/Common/Arm64Emitter.h b/Source/Core/Common/Arm64Emitter.h index 07dc8bc9ba..143325f531 100644 --- a/Source/Core/Common/Arm64Emitter.h +++ b/Source/Core/Common/Arm64Emitter.h @@ -505,6 +505,7 @@ private: u8* m_code; u8* m_lastCacheFlushEnd; + void AddImmediate(ARM64Reg Rd, ARM64Reg Rn, u64 imm, bool shift, bool negative, bool flags); void EncodeCompareBranchInst(u32 op, ARM64Reg Rt, const void* ptr); void EncodeTestBranchInst(u32 op, ARM64Reg Rt, u8 bits, const void* ptr); void EncodeUnconditionalBranchInst(u32 op, const void* ptr); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp index 2606df9682..64906d7804 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include #include #include "Common/BitSet.h" @@ -38,7 +39,7 @@ void JitArm64::DoBacktrace(uintptr_t access_address, SContext* ctx) Common::swap32(*(u32*)(pc + 4)), Common::swap32(*(u32*)(pc + 8)), Common::swap32(*(u32*)(pc + 12))); - ERROR_LOG(DYNA_REC, "0x%016lx: %08x %08x %08x %08x", pc, *(u32*)pc, *(u32*)(pc + 4), + ERROR_LOG(DYNA_REC, "0x%016" PRIx64 ": %08x %08x %08x %08x", pc, *(u32*)pc, *(u32*)(pc + 4), *(u32*)(pc + 8), *(u32*)(pc + 12)); } diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 0d94d1ac30..bde2903917 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -115,6 +115,21 @@ void JitArm64::reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32), } } +static constexpr u32 BitOR(u32 a, u32 b) +{ + return a | b; +} + +static constexpr u32 BitAND(u32 a, u32 b) +{ + return a & b; +} + +static constexpr u32 BitXOR(u32 a, u32 b) +{ + return a ^ b; +} + void JitArm64::arith_imm(UGeckoInstruction inst) { INSTRUCTION_START @@ -129,23 +144,22 @@ void JitArm64::arith_imm(UGeckoInstruction inst) // NOP return; } - reg_imm(a, s, inst.UIMM, [](u32 a, u32 b) { return a | b; }, &ARM64XEmitter::ORRI2R); + reg_imm(a, s, inst.UIMM, BitOR, &ARM64XEmitter::ORRI2R); break; case 25: // oris - reg_imm(a, s, inst.UIMM << 16, [](u32 a, u32 b) { return a | b; }, &ARM64XEmitter::ORRI2R); + reg_imm(a, s, inst.UIMM << 16, BitOR, &ARM64XEmitter::ORRI2R); break; case 28: // andi - reg_imm(a, s, inst.UIMM, [](u32 a, u32 b) { return a & b; }, &ARM64XEmitter::ANDI2R, true); + reg_imm(a, s, inst.UIMM, BitAND, &ARM64XEmitter::ANDI2R, true); break; case 29: // andis - reg_imm(a, s, inst.UIMM << 16, [](u32 a, u32 b) { return a & b; }, &ARM64XEmitter::ANDI2R, - true); + reg_imm(a, s, inst.UIMM << 16, BitAND, &ARM64XEmitter::ANDI2R, true); break; case 26: // xori - reg_imm(a, s, inst.UIMM, [](u32 a, u32 b) { return a ^ b; }, &ARM64XEmitter::EORI2R); + reg_imm(a, s, inst.UIMM, BitXOR, &ARM64XEmitter::EORI2R); break; case 27: // xoris - reg_imm(a, s, inst.UIMM << 16, [](u32 a, u32 b) { return a ^ b; }, &ARM64XEmitter::EORI2R); + reg_imm(a, s, inst.UIMM << 16, BitXOR, &ARM64XEmitter::EORI2R); break; } } @@ -161,7 +175,6 @@ void JitArm64::addix(UGeckoInstruction inst) { imm <<= 16; } - u32 imm_neg = 0u - imm; if (a) { @@ -1136,7 +1149,7 @@ void JitArm64::divwx(UGeckoInstruction inst) if (inst.Rc) ComputeRC(imm_d); } - else if (gpr.IsImm(b) && gpr.GetImm(b) != 0 && gpr.GetImm(b) != -1) + else if (gpr.IsImm(b) && gpr.GetImm(b) != 0 && gpr.GetImm(b) != -1u) { ARM64Reg WA = gpr.GetReg(); MOVI2R(WA, gpr.GetImm(b));