Merge pull request #5159 from ligfx/arm64warnings
Arm64: a slew of warning fixes
This commit is contained in:
commit
fd7f7c5541
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cinttypes>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -480,13 +481,13 @@ void ARM64XEmitter::EncodeCompareBranchInst(u32 op, ARM64Reg Rt, const void* ptr
|
||||||
bool b64Bit = Is64Bit(Rt);
|
bool b64Bit = Is64Bit(Rt);
|
||||||
s64 distance = (s64)ptr - (s64)m_code;
|
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);
|
__FUNCTION__, distance);
|
||||||
|
|
||||||
distance >>= 2;
|
distance >>= 2;
|
||||||
|
|
||||||
_assert_msg_(DYNA_REC, distance >= -0x40000 && distance <= 0x3FFFF,
|
_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);
|
Rt = DecodeReg(Rt);
|
||||||
Write32((b64Bit << 31) | (0x34 << 24) | (op << 24) | (((u32)distance << 5) & 0xFFFFE0) | 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);
|
bool b64Bit = Is64Bit(Rt);
|
||||||
s64 distance = (s64)ptr - (s64)m_code;
|
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);
|
__FUNCTION__, distance);
|
||||||
|
|
||||||
distance >>= 2;
|
distance >>= 2;
|
||||||
|
|
||||||
_assert_msg_(DYNA_REC, distance >= -0x3FFF && distance < 0x3FFF,
|
_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);
|
Rt = DecodeReg(Rt);
|
||||||
Write32((b64Bit << 31) | (0x36 << 24) | (op << 24) | (bits << 19) |
|
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);
|
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);
|
__FUNCTION__, distance);
|
||||||
|
|
||||||
distance >>= 2;
|
distance >>= 2;
|
||||||
|
|
||||||
_assert_msg_(DYNA_REC, distance >= -0x2000000LL && distance <= 0x1FFFFFFLL,
|
_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));
|
Write32((op << 31) | (0x5 << 26) | (distance & 0x3FFFFFF));
|
||||||
}
|
}
|
||||||
|
@ -902,37 +903,42 @@ void ARM64XEmitter::SetJumpTarget(FixupBranch const& branch)
|
||||||
Not = true;
|
Not = true;
|
||||||
case 0: // CBZ
|
case 0: // CBZ
|
||||||
{
|
{
|
||||||
_assert_msg_(DYNA_REC, IsInRangeImm19(distance), "%s(%d): Received too large distance: %lx",
|
_assert_msg_(DYNA_REC, IsInRangeImm19(distance),
|
||||||
__FUNCTION__, branch.type, distance);
|
"%s(%d): Received too large distance: %" PRIx64, __FUNCTION__, branch.type,
|
||||||
|
distance);
|
||||||
bool b64Bit = Is64Bit(branch.reg);
|
bool b64Bit = Is64Bit(branch.reg);
|
||||||
ARM64Reg reg = DecodeReg(branch.reg);
|
ARM64Reg reg = DecodeReg(branch.reg);
|
||||||
inst = (b64Bit << 31) | (0x1A << 25) | (Not << 24) | (MaskImm19(distance) << 5) | reg;
|
inst = (b64Bit << 31) | (0x1A << 25) | (Not << 24) | (MaskImm19(distance) << 5) | reg;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // B (conditional)
|
case 2: // B (conditional)
|
||||||
_assert_msg_(DYNA_REC, IsInRangeImm19(distance), "%s(%d): Received too large distance: %lx",
|
_assert_msg_(DYNA_REC, IsInRangeImm19(distance),
|
||||||
__FUNCTION__, branch.type, distance);
|
"%s(%d): Received too large distance: %" PRIx64, __FUNCTION__, branch.type,
|
||||||
|
distance);
|
||||||
inst = (0x2A << 25) | (MaskImm19(distance) << 5) | branch.cond;
|
inst = (0x2A << 25) | (MaskImm19(distance) << 5) | branch.cond;
|
||||||
break;
|
break;
|
||||||
case 4: // TBNZ
|
case 4: // TBNZ
|
||||||
Not = true;
|
Not = true;
|
||||||
case 3: // TBZ
|
case 3: // TBZ
|
||||||
{
|
{
|
||||||
_assert_msg_(DYNA_REC, IsInRangeImm14(distance), "%s(%d): Received too large distance: %lx",
|
_assert_msg_(DYNA_REC, IsInRangeImm14(distance),
|
||||||
__FUNCTION__, branch.type, distance);
|
"%s(%d): Received too large distance: %" PRIx64, __FUNCTION__, branch.type,
|
||||||
|
distance);
|
||||||
ARM64Reg reg = DecodeReg(branch.reg);
|
ARM64Reg reg = DecodeReg(branch.reg);
|
||||||
inst = ((branch.bit & 0x20) << 26) | (0x1B << 25) | (Not << 24) | ((branch.bit & 0x1F) << 19) |
|
inst = ((branch.bit & 0x20) << 26) | (0x1B << 25) | (Not << 24) | ((branch.bit & 0x1F) << 19) |
|
||||||
(MaskImm14(distance) << 5) | reg;
|
(MaskImm14(distance) << 5) | reg;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // B (uncoditional)
|
case 5: // B (uncoditional)
|
||||||
_assert_msg_(DYNA_REC, IsInRangeImm26(distance), "%s(%d): Received too large distance: %lx",
|
_assert_msg_(DYNA_REC, IsInRangeImm26(distance),
|
||||||
__FUNCTION__, branch.type, distance);
|
"%s(%d): Received too large distance: %" PRIx64, __FUNCTION__, branch.type,
|
||||||
|
distance);
|
||||||
inst = (0x5 << 26) | MaskImm26(distance);
|
inst = (0x5 << 26) | MaskImm26(distance);
|
||||||
break;
|
break;
|
||||||
case 6: // BL (unconditional)
|
case 6: // BL (unconditional)
|
||||||
_assert_msg_(DYNA_REC, IsInRangeImm26(distance), "%s(%d): Received too large distance: %lx",
|
_assert_msg_(DYNA_REC, IsInRangeImm26(distance),
|
||||||
__FUNCTION__, branch.type, distance);
|
"%s(%d): Received too large distance: %" PRIx64, __FUNCTION__, branch.type,
|
||||||
|
distance);
|
||||||
inst = (0x25 << 26) | MaskImm26(distance);
|
inst = (0x25 << 26) | MaskImm26(distance);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1021,8 +1027,8 @@ void ARM64XEmitter::B(CCFlags cond, const void* ptr)
|
||||||
distance >>= 2;
|
distance >>= 2;
|
||||||
|
|
||||||
_assert_msg_(DYNA_REC, IsInRangeImm19(distance),
|
_assert_msg_(DYNA_REC, IsInRangeImm19(distance),
|
||||||
"%s: Received too large distance: %p->%p %ld %lx", __FUNCTION__, m_code, ptr,
|
"%s: Received too large distance: %p->%p %" PRIi64 " %" PRIx64, __FUNCTION__, m_code,
|
||||||
distance, distance);
|
ptr, distance, distance);
|
||||||
Write32((0x54 << 24) | (MaskImm19(distance) << 5) | cond);
|
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,
|
void ARM64XEmitter::ADDI2R_internal(ARM64Reg Rd, ARM64Reg Rn, u64 imm, bool negative, bool flags,
|
||||||
ARM64Reg scratch)
|
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;
|
bool has_scratch = scratch != INVALID_REG;
|
||||||
u64 imm_neg = Is64Bit(Rd) ? -imm : -imm & 0xFFFFFFFFuLL;
|
u64 imm_neg = Is64Bit(Rd) ? -imm : -imm & 0xFFFFFFFFuLL;
|
||||||
bool neg_neg = negative ? false : true;
|
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
|
// Try them all first
|
||||||
if (imm <= 0xFFF)
|
if (imm <= 0xFFF)
|
||||||
{
|
{
|
||||||
addi(Rd, Rn, imm, false, negative, flags);
|
AddImmediate(Rd, Rn, imm, false, negative, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (imm <= 0xFFFFFF && (imm & 0xFFF) == 0)
|
if (imm <= 0xFFFFFF && (imm & 0xFFF) == 0)
|
||||||
{
|
{
|
||||||
addi(Rd, Rn, imm >> 12, true, negative, flags);
|
AddImmediate(Rd, Rn, imm >> 12, true, negative, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (imm_neg <= 0xFFF)
|
if (imm_neg <= 0xFFF)
|
||||||
{
|
{
|
||||||
addi(Rd, Rn, imm_neg, false, neg_neg, flags);
|
AddImmediate(Rd, Rn, imm_neg, false, neg_neg, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (imm_neg <= 0xFFFFFF && (imm_neg & 0xFFF) == 0)
|
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;
|
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.
|
// As this splits the addition in two parts, this must not be done on setting flags.
|
||||||
if (!flags && (imm >= 0x10000u || !has_scratch) && imm < 0x1000000u)
|
if (!flags && (imm >= 0x10000u || !has_scratch) && imm < 0x1000000u)
|
||||||
{
|
{
|
||||||
addi(Rd, Rn, imm & 0xFFF, false, negative, false);
|
AddImmediate(Rd, Rn, imm & 0xFFF, false, negative, false);
|
||||||
addi(Rd, Rd, imm >> 12, true, negative, false);
|
AddImmediate(Rd, Rd, imm >> 12, true, negative, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!flags && (imm_neg >= 0x10000u || !has_scratch) && imm_neg < 0x1000000u)
|
if (!flags && (imm_neg >= 0x10000u || !has_scratch) && imm_neg < 0x1000000u)
|
||||||
{
|
{
|
||||||
addi(Rd, Rn, imm_neg & 0xFFF, false, neg_neg, false);
|
AddImmediate(Rd, Rn, imm_neg & 0xFFF, false, neg_neg, false);
|
||||||
addi(Rd, Rd, imm_neg >> 12, true, neg_neg, false);
|
AddImmediate(Rd, Rd, imm_neg >> 12, true, neg_neg, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -505,6 +505,7 @@ private:
|
||||||
u8* m_code;
|
u8* m_code;
|
||||||
u8* m_lastCacheFlushEnd;
|
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 EncodeCompareBranchInst(u32 op, ARM64Reg Rt, const void* ptr);
|
||||||
void EncodeTestBranchInst(u32 op, ARM64Reg Rt, u8 bits, const void* ptr);
|
void EncodeTestBranchInst(u32 op, ARM64Reg Rt, u8 bits, const void* ptr);
|
||||||
void EncodeUnconditionalBranchInst(u32 op, const void* ptr);
|
void EncodeUnconditionalBranchInst(u32 op, const void* ptr);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under GPLv2+
|
// Licensed under GPLv2+
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <cinttypes>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "Common/BitSet.h"
|
#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 + 4)), Common::swap32(*(u32*)(pc + 8)),
|
||||||
Common::swap32(*(u32*)(pc + 12)));
|
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));
|
*(u32*)(pc + 8), *(u32*)(pc + 12));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
void JitArm64::arith_imm(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
@ -129,23 +144,22 @@ void JitArm64::arith_imm(UGeckoInstruction inst)
|
||||||
// NOP
|
// NOP
|
||||||
return;
|
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;
|
break;
|
||||||
case 25: // oris
|
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;
|
break;
|
||||||
case 28: // andi
|
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;
|
break;
|
||||||
case 29: // andis
|
case 29: // andis
|
||||||
reg_imm(a, s, inst.UIMM << 16, [](u32 a, u32 b) { return a & b; }, &ARM64XEmitter::ANDI2R,
|
reg_imm(a, s, inst.UIMM << 16, BitAND, &ARM64XEmitter::ANDI2R, true);
|
||||||
true);
|
|
||||||
break;
|
break;
|
||||||
case 26: // xori
|
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;
|
break;
|
||||||
case 27: // xoris
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +175,6 @@ void JitArm64::addix(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
imm <<= 16;
|
imm <<= 16;
|
||||||
}
|
}
|
||||||
u32 imm_neg = 0u - imm;
|
|
||||||
|
|
||||||
if (a)
|
if (a)
|
||||||
{
|
{
|
||||||
|
@ -1136,7 +1149,7 @@ void JitArm64::divwx(UGeckoInstruction inst)
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
ComputeRC(imm_d);
|
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();
|
ARM64Reg WA = gpr.GetReg();
|
||||||
MOVI2R(WA, gpr.GetImm(b));
|
MOVI2R(WA, gpr.GetImm(b));
|
||||||
|
|
Loading…
Reference in New Issue