Merge pull request #12427 from JosJuice/jitarm64-msr-updated-logical-imm

JitArm64: Fix MSRUpdated(ARM64Reg) with FEATURE_FLAG_PERFMON set
This commit is contained in:
Admiral H. Curtiss 2023-12-16 17:22:23 +01:00 committed by GitHub
commit 190c4e8cda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 100 additions and 94 deletions

View File

@ -1932,13 +1932,13 @@ void ARM64XEmitter::MOVI2RImpl(ARM64Reg Rd, T imm)
(imm & 0xFFFF'FFFF'0000'0000) | (imm >> 32), (imm & 0xFFFF'FFFF'0000'0000) | (imm >> 32),
(imm << 48) | (imm & 0x0000'FFFF'FFFF'0000) | (imm >> 48)}) (imm << 48) | (imm & 0x0000'FFFF'FFFF'0000) | (imm >> 48)})
{ {
if (LogicalImm(orr_imm, 64)) if (LogicalImm(orr_imm, GPRSize::B64))
try_base(orr_imm, Approach::ORRBase, false); try_base(orr_imm, Approach::ORRBase, false);
} }
} }
else else
{ {
if (LogicalImm(imm, 32)) if (LogicalImm(imm, GPRSize::B32))
try_base(imm, Approach::ORRBase, false); try_base(imm, Approach::ORRBase, false);
} }
} }
@ -4041,7 +4041,7 @@ void ARM64XEmitter::ANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
if (!Is64Bit(Rn)) if (!Is64Bit(Rn))
imm &= 0xFFFFFFFF; imm &= 0xFFFFFFFF;
if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? 64 : 32)) if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
{ {
AND(Rd, Rn, result); AND(Rd, Rn, result);
} }
@ -4057,7 +4057,7 @@ void ARM64XEmitter::ANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
void ARM64XEmitter::ORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) void ARM64XEmitter::ORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
{ {
if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? 64 : 32)) if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
{ {
ORR(Rd, Rn, result); ORR(Rd, Rn, result);
} }
@ -4073,7 +4073,7 @@ void ARM64XEmitter::ORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
void ARM64XEmitter::EORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) void ARM64XEmitter::EORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
{ {
if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? 64 : 32)) if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
{ {
EOR(Rd, Rn, result); EOR(Rd, Rn, result);
} }
@ -4089,7 +4089,7 @@ void ARM64XEmitter::EORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
void ARM64XEmitter::ANDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) void ARM64XEmitter::ANDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
{ {
if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? 64 : 32)) if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
{ {
ANDS(Rd, Rn, result); ANDS(Rd, Rn, result);
} }
@ -4265,7 +4265,7 @@ bool ARM64XEmitter::TryCMPI2R(ARM64Reg Rn, u64 imm)
bool ARM64XEmitter::TryANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm) bool ARM64XEmitter::TryANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm)
{ {
if (const auto result = LogicalImm(imm, Is64Bit(Rd) ? 64 : 32)) if (const auto result = LogicalImm(imm, Is64Bit(Rd) ? GPRSize::B64 : GPRSize::B32))
{ {
AND(Rd, Rn, result); AND(Rd, Rn, result);
return true; return true;
@ -4276,7 +4276,7 @@ bool ARM64XEmitter::TryANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm)
bool ARM64XEmitter::TryORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm) bool ARM64XEmitter::TryORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm)
{ {
if (const auto result = LogicalImm(imm, Is64Bit(Rd) ? 64 : 32)) if (const auto result = LogicalImm(imm, Is64Bit(Rd) ? GPRSize::B64 : GPRSize::B32))
{ {
ORR(Rd, Rn, result); ORR(Rd, Rn, result);
return true; return true;
@ -4287,7 +4287,7 @@ bool ARM64XEmitter::TryORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm)
bool ARM64XEmitter::TryEORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm) bool ARM64XEmitter::TryEORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm)
{ {
if (const auto result = LogicalImm(imm, Is64Bit(Rd) ? 64 : 32)) if (const auto result = LogicalImm(imm, Is64Bit(Rd) ? GPRSize::B64 : GPRSize::B32))
{ {
EOR(Rd, Rn, result); EOR(Rd, Rn, result);
return true; return true;

View File

@ -350,6 +350,12 @@ enum class RoundingMode
Z, // round towards zero Z, // round towards zero
}; };
enum class GPRSize
{
B32,
B64,
};
struct FixupBranch struct FixupBranch
{ {
enum class Type : u32 enum class Type : u32
@ -522,7 +528,7 @@ struct LogicalImm
constexpr LogicalImm(u8 r_, u8 s_, bool n_) : r(r_), s(s_), n(n_), valid(true) {} constexpr LogicalImm(u8 r_, u8 s_, bool n_) : r(r_), s(s_), n(n_), valid(true) {}
constexpr LogicalImm(u64 value, u32 width) constexpr LogicalImm(u64 value, GPRSize size)
{ {
// Logical immediates are encoded using parameters n, imm_s and imm_r using // Logical immediates are encoded using parameters n, imm_s and imm_r using
// the following table: // the following table:
@ -540,17 +546,14 @@ struct LogicalImm
// are set. The pattern is rotated right by R, and repeated across a 32 or // are set. The pattern is rotated right by R, and repeated across a 32 or
// 64-bit value, depending on destination register width. // 64-bit value, depending on destination register width.
constexpr int kWRegSizeInBits = 32; if (size == GPRSize::B32)
if (width == kWRegSizeInBits)
{ {
// To handle 32-bit logical immediates, the very easiest thing is to repeat // To handle 32-bit logical immediates, the very easiest thing is to repeat
// the input value twice to make a 64-bit word. The correct encoding of that // the input value twice to make a 64-bit word. The correct encoding of that
// as a logical immediate will also be the correct encoding of the 32-bit // as a logical immediate will also be the correct encoding of the 32-bit
// value. // value.
value <<= kWRegSizeInBits; value = (value << 32) | (value & 0xFFFFFFFF);
value |= value >> kWRegSizeInBits;
} }
if (value == 0 || (~value) == 0) if (value == 0 || (~value) == 0)

View File

@ -386,7 +386,7 @@ void JitArm64::MSRUpdated(ARM64Reg msr)
auto& memory = m_system.GetMemory(); auto& memory = m_system.GetMemory();
MOVP2R(MEM_REG, jo.fastmem ? memory.GetLogicalBase() : memory.GetLogicalPageMappingsBase()); MOVP2R(MEM_REG, jo.fastmem ? memory.GetLogicalBase() : memory.GetLogicalPageMappingsBase());
MOVP2R(XA, jo.fastmem ? memory.GetPhysicalBase() : memory.GetPhysicalPageMappingsBase()); MOVP2R(XA, jo.fastmem ? memory.GetPhysicalBase() : memory.GetPhysicalPageMappingsBase());
TST(msr, LogicalImm(1 << (31 - 27), 32)); TST(msr, LogicalImm(1 << (31 - 27), GPRSize::B32));
CSEL(MEM_REG, MEM_REG, XA, CCFlags::CC_NEQ); CSEL(MEM_REG, MEM_REG, XA, CCFlags::CC_NEQ);
STR(IndexType::Unsigned, MEM_REG, PPC_REG, PPCSTATE_OFF(mem_ptr)); STR(IndexType::Unsigned, MEM_REG, PPC_REG, PPCSTATE_OFF(mem_ptr));
@ -398,7 +398,7 @@ void JitArm64::MSRUpdated(ARM64Reg msr)
const u32 other_feature_flags = m_ppc_state.feature_flags & ~0x3; const u32 other_feature_flags = m_ppc_state.feature_flags & ~0x3;
UBFX(WA, msr, 4, 2); UBFX(WA, msr, 4, 2);
if (other_feature_flags != 0) if (other_feature_flags != 0)
ORR(WA, WA, LogicalImm(32, other_feature_flags)); ORR(WA, WA, LogicalImm(other_feature_flags, GPRSize::B32));
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(feature_flags)); STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(feature_flags));
gpr.Unlock(WA); gpr.Unlock(WA);
@ -1164,7 +1164,7 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
constexpr u32 cause_mask = ProcessorInterface::INT_CAUSE_CP | constexpr u32 cause_mask = ProcessorInterface::INT_CAUSE_CP |
ProcessorInterface::INT_CAUSE_PE_TOKEN | ProcessorInterface::INT_CAUSE_PE_TOKEN |
ProcessorInterface::INT_CAUSE_PE_FINISH; ProcessorInterface::INT_CAUSE_PE_FINISH;
TST(WA, LogicalImm(cause_mask, 32)); TST(WA, LogicalImm(cause_mask, GPRSize::B32));
B(CC_EQ, done_here); B(CC_EQ, done_here);
gpr.Flush(FlushMode::MaintainState, WA); gpr.Flush(FlushMode::MaintainState, WA);
@ -1198,7 +1198,7 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
fpr.Flush(FlushMode::MaintainState, ARM64Reg::INVALID_REG); fpr.Flush(FlushMode::MaintainState, ARM64Reg::INVALID_REG);
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
ORR(WA, WA, LogicalImm(EXCEPTION_FPU_UNAVAILABLE, 32)); ORR(WA, WA, LogicalImm(EXCEPTION_FPU_UNAVAILABLE, GPRSize::B32));
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
gpr.Unlock(WA); gpr.Unlock(WA);

View File

@ -91,7 +91,7 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, MemAccessMode mode, ARM64Reg RS,
SetJumpTarget(pass); SetJumpTarget(pass);
} }
AND(memory_offset, addr, LogicalImm(PowerPC::BAT_PAGE_SIZE - 1, 64)); AND(memory_offset, addr, LogicalImm(PowerPC::BAT_PAGE_SIZE - 1, GPRSize::B64));
} }
else if (emit_slow_access && emitting_routine) else if (emit_slow_access && emitting_routine)
{ {

View File

@ -26,7 +26,7 @@ void JitArm64::sc(UGeckoInstruction inst)
ARM64Reg WA = gpr.GetReg(); ARM64Reg WA = gpr.GetReg();
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
ORR(WA, WA, LogicalImm(EXCEPTION_SYSCALL, 32)); ORR(WA, WA, LogicalImm(EXCEPTION_SYSCALL, GPRSize::B32));
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
gpr.Unlock(WA); gpr.Unlock(WA);
@ -229,7 +229,7 @@ void JitArm64::bcctrx(UGeckoInstruction inst)
ARM64Reg WA = gpr.GetReg(); ARM64Reg WA = gpr.GetReg();
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF_SPR(SPR_CTR)); LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF_SPR(SPR_CTR));
AND(WA, WA, LogicalImm(~0x3, 32)); AND(WA, WA, LogicalImm(~0x3, GPRSize::B32));
WriteExit(WA, inst.LK_3, js.compilerPC + 4, inst.LK_3 ? WB : ARM64Reg::INVALID_REG); WriteExit(WA, inst.LK_3, js.compilerPC + 4, inst.LK_3 ? WB : ARM64Reg::INVALID_REG);
@ -270,7 +270,7 @@ void JitArm64::bclrx(UGeckoInstruction inst)
} }
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF_SPR(SPR_LR)); LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF_SPR(SPR_LR));
AND(WA, WA, LogicalImm(~0x3, 32)); AND(WA, WA, LogicalImm(~0x3, GPRSize::B32));
if (inst.LK) if (inst.LK)
{ {

View File

@ -458,7 +458,7 @@ void JitArm64::FloatCompare(UGeckoInstruction inst, bool upper)
{ {
fpscr_reg = gpr.GetReg(); fpscr_reg = gpr.GetReg();
LDR(IndexType::Unsigned, fpscr_reg, PPC_REG, PPCSTATE_OFF(fpscr)); LDR(IndexType::Unsigned, fpscr_reg, PPC_REG, PPCSTATE_OFF(fpscr));
AND(fpscr_reg, fpscr_reg, LogicalImm(~FPCC_MASK, 32)); AND(fpscr_reg, fpscr_reg, LogicalImm(~FPCC_MASK, GPRSize::B32));
} }
ARM64Reg V0Q = ARM64Reg::INVALID_REG; ARM64Reg V0Q = ARM64Reg::INVALID_REG;
@ -506,14 +506,14 @@ void JitArm64::FloatCompare(UGeckoInstruction inst, bool upper)
// A == B // A == B
MOVI2R(XA, 0); MOVI2R(XA, 0);
if (fprf) if (fprf)
ORR(fpscr_reg, fpscr_reg, LogicalImm(PowerPC::CR_EQ << FPRF_SHIFT, 32)); ORR(fpscr_reg, fpscr_reg, LogicalImm(PowerPC::CR_EQ << FPRF_SHIFT, GPRSize::B32));
continue1 = B(); continue1 = B();
SetJumpTarget(pNaN); SetJumpTarget(pNaN);
MOVI2R(XA, ~(1ULL << PowerPC::CR_EMU_LT_BIT)); MOVI2R(XA, ~(1ULL << PowerPC::CR_EMU_LT_BIT));
if (fprf) if (fprf)
ORR(fpscr_reg, fpscr_reg, LogicalImm(PowerPC::CR_SO << FPRF_SHIFT, 32)); ORR(fpscr_reg, fpscr_reg, LogicalImm(PowerPC::CR_SO << FPRF_SHIFT, GPRSize::B32));
if (a != b) if (a != b)
{ {
@ -522,14 +522,14 @@ void JitArm64::FloatCompare(UGeckoInstruction inst, bool upper)
SetJumpTarget(pGreater); SetJumpTarget(pGreater);
MOVI2R(XA, 1); MOVI2R(XA, 1);
if (fprf) if (fprf)
ORR(fpscr_reg, fpscr_reg, LogicalImm(PowerPC::CR_GT << FPRF_SHIFT, 32)); ORR(fpscr_reg, fpscr_reg, LogicalImm(PowerPC::CR_GT << FPRF_SHIFT, GPRSize::B32));
continue3 = B(); continue3 = B();
SetJumpTarget(pLesser); SetJumpTarget(pLesser);
MOVI2R(XA, ~(1ULL << PowerPC::CR_EMU_SO_BIT)); MOVI2R(XA, ~(1ULL << PowerPC::CR_EMU_SO_BIT));
if (fprf) if (fprf)
ORR(fpscr_reg, fpscr_reg, LogicalImm(PowerPC::CR_LT << FPRF_SHIFT, 32)); ORR(fpscr_reg, fpscr_reg, LogicalImm(PowerPC::CR_LT << FPRF_SHIFT, GPRSize::B32));
SetJumpTarget(continue2); SetJumpTarget(continue2);
SetJumpTarget(continue3); SetJumpTarget(continue3);
@ -610,7 +610,7 @@ void JitArm64::fctiwx(UGeckoInstruction inst)
m_float_emit.FCVTS(WA, EncodeRegToDouble(VD), RoundingMode::Z); m_float_emit.FCVTS(WA, EncodeRegToDouble(VD), RoundingMode::Z);
} }
ORR(EncodeRegTo64(WA), EncodeRegTo64(WA), LogicalImm(0xFFF8'0000'0000'0000ULL, 64)); ORR(EncodeRegTo64(WA), EncodeRegTo64(WA), LogicalImm(0xFFF8'0000'0000'0000ULL, GPRSize::B64));
m_float_emit.FMOV(EncodeRegToDouble(VD), EncodeRegTo64(WA)); m_float_emit.FMOV(EncodeRegToDouble(VD), EncodeRegTo64(WA));
gpr.Unlock(WA); gpr.Unlock(WA);

View File

@ -323,10 +323,10 @@ void JitArm64::boolX(UGeckoInstruction inst)
PanicAlertFmt("WTF!"); PanicAlertFmt("WTF!");
} }
} }
else if ((gpr.IsImm(s) && else if ((gpr.IsImm(s) && (gpr.GetImm(s) == 0 || gpr.GetImm(s) == 0xFFFFFFFF ||
(gpr.GetImm(s) == 0 || gpr.GetImm(s) == 0xFFFFFFFF || LogicalImm(gpr.GetImm(s), 32))) || LogicalImm(gpr.GetImm(s), GPRSize::B32))) ||
(gpr.IsImm(b) && (gpr.IsImm(b) && (gpr.GetImm(b) == 0 || gpr.GetImm(b) == 0xFFFFFFFF ||
(gpr.GetImm(b) == 0 || gpr.GetImm(b) == 0xFFFFFFFF || LogicalImm(gpr.GetImm(b), 32)))) LogicalImm(gpr.GetImm(b), GPRSize::B32))))
{ {
int i, j; int i, j;
if (gpr.IsImm(s)) if (gpr.IsImm(s))
@ -358,7 +358,7 @@ void JitArm64::boolX(UGeckoInstruction inst)
const bool is_zero = imm == 0; const bool is_zero = imm == 0;
const bool is_ones = imm == 0xFFFFFFFF; const bool is_ones = imm == 0xFFFFFFFF;
// If imm can be represented as LogicalImm, so can ~imm. // If imm can be represented as LogicalImm, so can ~imm.
const auto log_imm = LogicalImm(imm, 32); const auto log_imm = LogicalImm(imm, GPRSize::B32);
if (is_xor) if (is_xor)
{ {
@ -782,7 +782,7 @@ void JitArm64::rlwinmx(UGeckoInstruction inst)
else if (!inst.SH) else if (!inst.SH)
{ {
// Immediate mask // Immediate mask
AND(gpr.R(a), gpr.R(s), LogicalImm(mask, 32)); AND(gpr.R(a), gpr.R(s), LogicalImm(mask, GPRSize::B32));
} }
else if (inst.ME == 31 && 31 < inst.SH + inst.MB) else if (inst.ME == 31 && 31 < inst.SH + inst.MB)
{ {

View File

@ -988,14 +988,14 @@ void JitArm64::dcbz(UGeckoInstruction inst)
u32 imm_offset = is_imm_a ? gpr.GetImm(a) : gpr.GetImm(b); u32 imm_offset = is_imm_a ? gpr.GetImm(a) : gpr.GetImm(b);
ADDI2R(addr_reg, base, imm_offset, addr_reg); ADDI2R(addr_reg, base, imm_offset, addr_reg);
emit_low_dcbz_hack(addr_reg); emit_low_dcbz_hack(addr_reg);
AND(addr_reg, addr_reg, LogicalImm(~31, 32)); AND(addr_reg, addr_reg, LogicalImm(~31, GPRSize::B32));
} }
else else
{ {
// Both are registers // Both are registers
ADD(addr_reg, gpr.R(a), gpr.R(b)); ADD(addr_reg, gpr.R(a), gpr.R(b));
emit_low_dcbz_hack(addr_reg); emit_low_dcbz_hack(addr_reg);
AND(addr_reg, addr_reg, LogicalImm(~31, 32)); AND(addr_reg, addr_reg, LogicalImm(~31, GPRSize::B32));
} }
} }
else else
@ -1011,7 +1011,7 @@ void JitArm64::dcbz(UGeckoInstruction inst)
else else
{ {
emit_low_dcbz_hack(gpr.R(b)); emit_low_dcbz_hack(gpr.R(b));
AND(addr_reg, gpr.R(b), LogicalImm(~31, 32)); AND(addr_reg, gpr.R(b), LogicalImm(~31, GPRSize::B32));
} }
} }

View File

@ -49,7 +49,7 @@ void JitArm64::FixGTBeforeSettingCRFieldBit(Arm64Gen::ARM64Reg reg)
// intending to. This can break actual games, so fix it up. // intending to. This can break actual games, so fix it up.
ARM64Reg WA = gpr.GetReg(); ARM64Reg WA = gpr.GetReg();
ARM64Reg XA = EncodeRegTo64(WA); ARM64Reg XA = EncodeRegTo64(WA);
ORR(XA, reg, LogicalImm(1ULL << 63, 64)); ORR(XA, reg, LogicalImm(1ULL << 63, GPRSize::B64));
CMP(reg, ARM64Reg::ZR); CMP(reg, ARM64Reg::ZR);
CSEL(reg, reg, XA, CC_NEQ); CSEL(reg, reg, XA, CC_NEQ);
gpr.Unlock(WA); gpr.Unlock(WA);
@ -66,7 +66,7 @@ void JitArm64::UpdateFPExceptionSummary(ARM64Reg fpscr)
BFI(fpscr, WA, MathUtil::IntLog2(FPSCR_VX), 1); BFI(fpscr, WA, MathUtil::IntLog2(FPSCR_VX), 1);
// fpscr.FEX = ((fpscr >> 22) & (fpscr & FPSCR_ANY_E)) != 0 // fpscr.FEX = ((fpscr >> 22) & (fpscr & FPSCR_ANY_E)) != 0
AND(WA, fpscr, LogicalImm(FPSCR_ANY_E, 32)); AND(WA, fpscr, LogicalImm(FPSCR_ANY_E, GPRSize::B32));
TST(WA, fpscr, ArithOption(fpscr, ShiftType::LSR, 22)); TST(WA, fpscr, ArithOption(fpscr, ShiftType::LSR, 22));
CSET(WA, CCFlags::CC_NEQ); CSET(WA, CCFlags::CC_NEQ);
BFI(fpscr, WA, MathUtil::IntLog2(FPSCR_FEX), 1); BFI(fpscr, WA, MathUtil::IntLog2(FPSCR_FEX), 1);
@ -259,7 +259,7 @@ void JitArm64::twx(UGeckoInstruction inst)
fpr.Flush(FlushMode::MaintainState, ARM64Reg::INVALID_REG); fpr.Flush(FlushMode::MaintainState, ARM64Reg::INVALID_REG);
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
ORR(WA, WA, LogicalImm(EXCEPTION_PROGRAM, 32)); ORR(WA, WA, LogicalImm(EXCEPTION_PROGRAM, GPRSize::B32));
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
MOVI2R(WA, static_cast<u32>(ProgramExceptionCause::Trap)); MOVI2R(WA, static_cast<u32>(ProgramExceptionCause::Trap));
@ -337,7 +337,7 @@ void JitArm64::mfspr(UGeckoInstruction inst)
SUB(Xresult, Xresult, XB); SUB(Xresult, Xresult, XB);
// a / 12 = (a * 0xAAAAAAAAAAAAAAAB) >> 67 // a / 12 = (a * 0xAAAAAAAAAAAAAAAB) >> 67
ORR(XB, ARM64Reg::ZR, LogicalImm(0xAAAAAAAAAAAAAAAA, 64)); ORR(XB, ARM64Reg::ZR, LogicalImm(0xAAAAAAAAAAAAAAAA, GPRSize::B64));
ADD(XB, XB, 1); ADD(XB, XB, 1);
UMULH(Xresult, Xresult, XB); UMULH(Xresult, Xresult, XB);
@ -462,7 +462,7 @@ void JitArm64::mtspr(UGeckoInstruction inst)
{ {
ARM64Reg RD = gpr.R(inst.RD); ARM64Reg RD = gpr.R(inst.RD);
ARM64Reg WA = gpr.GetReg(); ARM64Reg WA = gpr.GetReg();
AND(WA, RD, LogicalImm(0xFFFFFF7F, 32)); AND(WA, RD, LogicalImm(0xFFFFFF7F, GPRSize::B32));
STRH(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_stringctrl)); STRH(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_stringctrl));
UBFM(WA, RD, XER_CA_SHIFT, XER_CA_SHIFT + 1); UBFM(WA, RD, XER_CA_SHIFT, XER_CA_SHIFT + 1);
STRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca)); STRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
@ -497,20 +497,20 @@ void JitArm64::crXXX(UGeckoInstruction inst)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: case PowerPC::CR_SO_BIT:
AND(XA, XA, LogicalImm(~(u64(1) << PowerPC::CR_EMU_SO_BIT), 64)); AND(XA, XA, LogicalImm(~(u64(1) << PowerPC::CR_EMU_SO_BIT), GPRSize::B64));
break; break;
case PowerPC::CR_EQ_BIT: case PowerPC::CR_EQ_BIT:
FixGTBeforeSettingCRFieldBit(XA); FixGTBeforeSettingCRFieldBit(XA);
ORR(XA, XA, LogicalImm(1, 64)); ORR(XA, XA, LogicalImm(1, GPRSize::B64));
break; break;
case PowerPC::CR_GT_BIT: case PowerPC::CR_GT_BIT:
ORR(XA, XA, LogicalImm(u64(1) << 63, 64)); ORR(XA, XA, LogicalImm(u64(1) << 63, GPRSize::B64));
break; break;
case PowerPC::CR_LT_BIT: case PowerPC::CR_LT_BIT:
AND(XA, XA, LogicalImm(~(u64(1) << PowerPC::CR_EMU_LT_BIT), 64)); AND(XA, XA, LogicalImm(~(u64(1) << PowerPC::CR_EMU_LT_BIT), GPRSize::B64));
break; break;
} }
return; return;
@ -532,23 +532,23 @@ void JitArm64::crXXX(UGeckoInstruction inst)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: case PowerPC::CR_SO_BIT:
ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_SO_BIT, 64)); ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_SO_BIT, GPRSize::B64));
break; break;
case PowerPC::CR_EQ_BIT: case PowerPC::CR_EQ_BIT:
AND(XA, XA, LogicalImm(0xFFFF'FFFF'0000'0000, 64)); AND(XA, XA, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
break; break;
case PowerPC::CR_GT_BIT: case PowerPC::CR_GT_BIT:
AND(XA, XA, LogicalImm(~(u64(1) << 63), 64)); AND(XA, XA, LogicalImm(~(u64(1) << 63), GPRSize::B64));
break; break;
case PowerPC::CR_LT_BIT: case PowerPC::CR_LT_BIT:
ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_LT_BIT, 64)); ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_LT_BIT, GPRSize::B64));
break; break;
} }
ORR(XA, XA, LogicalImm(u64(1) << 32, 64)); ORR(XA, XA, LogicalImm(u64(1) << 32, GPRSize::B64));
return; return;
} }
@ -578,7 +578,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
case PowerPC::CR_SO_BIT: // check bit 59 set case PowerPC::CR_SO_BIT: // check bit 59 set
UBFX(out, XC, PowerPC::CR_EMU_SO_BIT, 1); UBFX(out, XC, PowerPC::CR_EMU_SO_BIT, 1);
if (negate) if (negate)
EOR(out, out, LogicalImm(1, 64)); EOR(out, out, LogicalImm(1, GPRSize::B64));
break; break;
case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0 case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0
@ -594,7 +594,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
case PowerPC::CR_LT_BIT: // check bit 62 set case PowerPC::CR_LT_BIT: // check bit 62 set
UBFX(out, XC, PowerPC::CR_EMU_LT_BIT, 1); UBFX(out, XC, PowerPC::CR_EMU_LT_BIT, 1);
if (negate) if (negate)
EOR(out, out, LogicalImm(1, 64)); EOR(out, out, LogicalImm(1, GPRSize::B64));
break; break;
default: default:
@ -642,13 +642,13 @@ void JitArm64::crXXX(UGeckoInstruction inst)
break; break;
case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input
AND(XB, XB, LogicalImm(0xFFFF'FFFF'0000'0000, 64)); AND(XB, XB, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
EOR(XA, XA, LogicalImm(1, 64)); EOR(XA, XA, LogicalImm(1, GPRSize::B64));
ORR(XB, XB, XA); ORR(XB, XB, XA);
break; break;
case PowerPC::CR_GT_BIT: // set bit 63 to !input case PowerPC::CR_GT_BIT: // set bit 63 to !input
EOR(XA, XA, LogicalImm(1, 64)); EOR(XA, XA, LogicalImm(1, GPRSize::B64));
BFI(XB, XA, 63, 1); BFI(XB, XA, 63, 1);
break; break;
@ -657,7 +657,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
break; break;
} }
ORR(XB, XB, LogicalImm(1ULL << 32, 64)); ORR(XB, XB, LogicalImm(1ULL << 32, GPRSize::B64));
gpr.Unlock(WA); gpr.Unlock(WA);
} }
@ -696,12 +696,12 @@ void JitArm64::mfcr(UGeckoInstruction inst)
} }
// EQ // EQ
ORR(WC, WA, LogicalImm(1 << PowerPC::CR_EQ_BIT, 32)); ORR(WC, WA, LogicalImm(1 << PowerPC::CR_EQ_BIT, GPRSize::B32));
CMP(WCR, ARM64Reg::WZR); CMP(WCR, ARM64Reg::WZR);
CSEL(WA, WC, WA, CC_EQ); CSEL(WA, WC, WA, CC_EQ);
// GT // GT
ORR(WC, WA, LogicalImm(1 << PowerPC::CR_GT_BIT, 32)); ORR(WC, WA, LogicalImm(1 << PowerPC::CR_GT_BIT, GPRSize::B32));
CMP(CR, ARM64Reg::ZR); CMP(CR, ARM64Reg::ZR);
CSEL(WA, WC, WA, CC_GT); CSEL(WA, WC, WA, CC_GT);
@ -780,7 +780,7 @@ void JitArm64::mcrfs(UGeckoInstruction inst)
if (mask != 0) if (mask != 0)
{ {
const u32 inverted_mask = ~mask; const u32 inverted_mask = ~mask;
AND(WA, WA, LogicalImm(inverted_mask, 32)); AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
UpdateFPExceptionSummary(WA); UpdateFPExceptionSummary(WA);
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr)); STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
@ -805,7 +805,7 @@ void JitArm64::mffsx(UGeckoInstruction inst)
ARM64Reg VD = fpr.RW(inst.FD, RegType::LowerPair); ARM64Reg VD = fpr.RW(inst.FD, RegType::LowerPair);
ORR(XA, XA, LogicalImm(0xFFF8'0000'0000'0000, 64)); ORR(XA, XA, LogicalImm(0xFFF8'0000'0000'0000, GPRSize::B64));
m_float_emit.FMOV(EncodeRegToDouble(VD), XA); m_float_emit.FMOV(EncodeRegToDouble(VD), XA);
gpr.Unlock(WA); gpr.Unlock(WA);
@ -827,7 +827,7 @@ void JitArm64::mtfsb0x(UGeckoInstruction inst)
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr)); LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
AND(WA, WA, LogicalImm(inverted_mask, 32)); AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
if ((mask & (FPSCR_ANY_X | FPSCR_ANY_E)) != 0) if ((mask & (FPSCR_ANY_X | FPSCR_ANY_E)) != 0)
UpdateFPExceptionSummary(WA); UpdateFPExceptionSummary(WA);
@ -858,12 +858,12 @@ void JitArm64::mtfsb1x(UGeckoInstruction inst)
if ((mask & FPSCR_ANY_X) != 0) if ((mask & FPSCR_ANY_X) != 0)
{ {
ARM64Reg WB = gpr.GetReg(); ARM64Reg WB = gpr.GetReg();
TST(WA, LogicalImm(mask, 32)); TST(WA, LogicalImm(mask, GPRSize::B32));
ORR(WB, WA, LogicalImm(1 << 31, 32)); ORR(WB, WA, LogicalImm(1 << 31, GPRSize::B32));
CSEL(WA, WA, WB, CCFlags::CC_NEQ); CSEL(WA, WA, WB, CCFlags::CC_NEQ);
gpr.Unlock(WB); gpr.Unlock(WB);
} }
ORR(WA, WA, LogicalImm(mask, 32)); ORR(WA, WA, LogicalImm(mask, GPRSize::B32));
if ((mask & (FPSCR_ANY_X | FPSCR_ANY_E)) != 0) if ((mask & (FPSCR_ANY_X | FPSCR_ANY_E)) != 0)
UpdateFPExceptionSummary(WA); UpdateFPExceptionSummary(WA);
@ -892,7 +892,7 @@ void JitArm64::mtfsfix(UGeckoInstruction inst)
if (imm == 0xF) if (imm == 0xF)
{ {
ORR(WA, WA, LogicalImm(mask, 32)); ORR(WA, WA, LogicalImm(mask, GPRSize::B32));
} }
else if (imm == 0x0) else if (imm == 0x0)
{ {
@ -952,10 +952,10 @@ void JitArm64::mtfsfx(UGeckoInstruction inst)
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr)); LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(fpscr));
m_float_emit.FMOV(WB, EncodeRegToSingle(VB)); m_float_emit.FMOV(WB, EncodeRegToSingle(VB));
if (LogicalImm imm = LogicalImm(mask, 32)) if (LogicalImm imm = LogicalImm(mask, GPRSize::B32))
{ {
const u32 inverted_mask = ~mask; const u32 inverted_mask = ~mask;
AND(WA, WA, LogicalImm(inverted_mask, 32)); AND(WA, WA, LogicalImm(inverted_mask, GPRSize::B32));
AND(WB, WB, imm); AND(WB, WB, imm);
} }
else else

View File

@ -272,7 +272,7 @@ void JitArm64::GenerateFres()
UBFX(ARM64Reg::X2, ARM64Reg::X1, 52, 11); // Grab the exponent UBFX(ARM64Reg::X2, ARM64Reg::X1, 52, 11); // Grab the exponent
m_float_emit.FMOV(ARM64Reg::X0, ARM64Reg::D0); m_float_emit.FMOV(ARM64Reg::X0, ARM64Reg::D0);
AND(ARM64Reg::X3, ARM64Reg::X1, LogicalImm(Common::DOUBLE_SIGN, 64)); AND(ARM64Reg::X3, ARM64Reg::X1, LogicalImm(Common::DOUBLE_SIGN, GPRSize::B64));
CMP(ARM64Reg::X2, 895); CMP(ARM64Reg::X2, 895);
FixupBranch small_exponent = B(CCFlags::CC_LO); FixupBranch small_exponent = B(CCFlags::CC_LO);
@ -287,12 +287,13 @@ void JitArm64::GenerateFres()
MOVI2R(ARM64Reg::W4, 1); MOVI2R(ARM64Reg::W4, 1);
MADD(ARM64Reg::W1, ARM64Reg::W3, ARM64Reg::W1, ARM64Reg::W4); MADD(ARM64Reg::W1, ARM64Reg::W3, ARM64Reg::W1, ARM64Reg::W4);
SUB(ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::W1, ArithOption(ARM64Reg::W1, ShiftType::LSR, 1)); SUB(ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::W1, ArithOption(ARM64Reg::W1, ShiftType::LSR, 1));
AND(ARM64Reg::X0, ARM64Reg::X0, LogicalImm(Common::DOUBLE_SIGN | Common::DOUBLE_EXP, 64)); AND(ARM64Reg::X0, ARM64Reg::X0,
LogicalImm(Common::DOUBLE_SIGN | Common::DOUBLE_EXP, GPRSize::B64));
ORR(ARM64Reg::X0, ARM64Reg::X0, ARM64Reg::X1, ArithOption(ARM64Reg::X1, ShiftType::LSL, 29)); ORR(ARM64Reg::X0, ARM64Reg::X0, ARM64Reg::X1, ArithOption(ARM64Reg::X1, ShiftType::LSL, 29));
RET(); RET();
SetJumpTarget(small_exponent); SetJumpTarget(small_exponent);
TST(ARM64Reg::X1, LogicalImm(Common::DOUBLE_EXP | Common::DOUBLE_FRAC, 64)); TST(ARM64Reg::X1, LogicalImm(Common::DOUBLE_EXP | Common::DOUBLE_FRAC, GPRSize::B64));
FixupBranch zero = B(CCFlags::CC_EQ); FixupBranch zero = B(CCFlags::CC_EQ);
MOVI2R(ARM64Reg::X4, MOVI2R(ARM64Reg::X4,
Common::BitCast<u64>(static_cast<double>(std::numeric_limits<float>::max()))); Common::BitCast<u64>(static_cast<double>(std::numeric_limits<float>::max())));
@ -325,7 +326,7 @@ void JitArm64::GenerateFrsqrte()
LSL(ARM64Reg::X2, ARM64Reg::X1, 1); LSL(ARM64Reg::X2, ARM64Reg::X1, 1);
m_float_emit.FMOV(ARM64Reg::X0, ARM64Reg::D0); m_float_emit.FMOV(ARM64Reg::X0, ARM64Reg::D0);
CLS(ARM64Reg::X3, ARM64Reg::X2); CLS(ARM64Reg::X3, ARM64Reg::X2);
TST(ARM64Reg::X1, LogicalImm(Common::DOUBLE_SIGN, 64)); TST(ARM64Reg::X1, LogicalImm(Common::DOUBLE_SIGN, GPRSize::B64));
CCMP(ARM64Reg::X3, Common::DOUBLE_EXP_WIDTH - 1, 0b0010, CCFlags::CC_EQ); CCMP(ARM64Reg::X3, Common::DOUBLE_EXP_WIDTH - 1, 0b0010, CCFlags::CC_EQ);
FixupBranch not_positive_normal = B(CCFlags::CC_HS); FixupBranch not_positive_normal = B(CCFlags::CC_HS);
@ -335,7 +336,8 @@ void JitArm64::GenerateFrsqrte()
ADD(ARM64Reg::X2, ARM64Reg::X3, ARM64Reg::X2, ArithOption(ARM64Reg::X2, ShiftType::LSL, 3)); ADD(ARM64Reg::X2, ARM64Reg::X3, ARM64Reg::X2, ArithOption(ARM64Reg::X2, ShiftType::LSL, 3));
LDP(IndexType::Signed, ARM64Reg::W3, ARM64Reg::W2, ARM64Reg::X2, 0); LDP(IndexType::Signed, ARM64Reg::W3, ARM64Reg::W2, ARM64Reg::X2, 0);
UBFX(ARM64Reg::X1, ARM64Reg::X1, 37, 11); UBFX(ARM64Reg::X1, ARM64Reg::X1, 37, 11);
AND(ARM64Reg::X0, ARM64Reg::X0, LogicalImm(Common::DOUBLE_SIGN | Common::DOUBLE_EXP, 64)); AND(ARM64Reg::X0, ARM64Reg::X0,
LogicalImm(Common::DOUBLE_SIGN | Common::DOUBLE_EXP, GPRSize::B64));
MADD(ARM64Reg::W1, ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::W3); MADD(ARM64Reg::W1, ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::W3);
ORR(ARM64Reg::X0, ARM64Reg::X0, ARM64Reg::X1, ArithOption(ARM64Reg::X1, ShiftType::LSL, 26)); ORR(ARM64Reg::X0, ARM64Reg::X0, ARM64Reg::X1, ArithOption(ARM64Reg::X1, ShiftType::LSL, 26));
RET(); RET();
@ -392,10 +394,10 @@ void JitArm64::GenerateConvertDoubleToSingle()
SetJumpTarget(denormal); SetJumpTarget(denormal);
LSR(ARM64Reg::X3, ARM64Reg::X0, 21); LSR(ARM64Reg::X3, ARM64Reg::X0, 21);
MOVZ(ARM64Reg::X0, 905); MOVZ(ARM64Reg::X0, 905);
ORR(ARM64Reg::W3, ARM64Reg::W3, LogicalImm(0x80000000, 32)); ORR(ARM64Reg::W3, ARM64Reg::W3, LogicalImm(0x80000000, GPRSize::B32));
SUB(ARM64Reg::W2, ARM64Reg::W0, ARM64Reg::W2); SUB(ARM64Reg::W2, ARM64Reg::W0, ARM64Reg::W2);
LSRV(ARM64Reg::W2, ARM64Reg::W3, ARM64Reg::W2); LSRV(ARM64Reg::W2, ARM64Reg::W3, ARM64Reg::W2);
AND(ARM64Reg::X3, ARM64Reg::X1, LogicalImm(0x80000000, 64)); AND(ARM64Reg::X3, ARM64Reg::X1, LogicalImm(0x80000000, GPRSize::B64));
ORR(ARM64Reg::X1, ARM64Reg::X3, ARM64Reg::X2); ORR(ARM64Reg::X1, ARM64Reg::X3, ARM64Reg::X2);
RET(); RET();
} }
@ -406,7 +408,7 @@ void JitArm64::GenerateConvertSingleToDouble()
UBFX(ARM64Reg::W1, ARM64Reg::W0, 23, 8); UBFX(ARM64Reg::W1, ARM64Reg::W0, 23, 8);
FixupBranch normal_or_nan = CBNZ(ARM64Reg::W1); FixupBranch normal_or_nan = CBNZ(ARM64Reg::W1);
AND(ARM64Reg::W1, ARM64Reg::W0, LogicalImm(0x007fffff, 32)); AND(ARM64Reg::W1, ARM64Reg::W0, LogicalImm(0x007fffff, GPRSize::B32));
FixupBranch denormal = CBNZ(ARM64Reg::W1); FixupBranch denormal = CBNZ(ARM64Reg::W1);
// Zero // Zero
@ -414,10 +416,10 @@ void JitArm64::GenerateConvertSingleToDouble()
RET(); RET();
SetJumpTarget(denormal); SetJumpTarget(denormal);
AND(ARM64Reg::W2, ARM64Reg::W0, LogicalImm(0x80000000, 32)); AND(ARM64Reg::W2, ARM64Reg::W0, LogicalImm(0x80000000, GPRSize::B32));
CLZ(ARM64Reg::X3, ARM64Reg::X1); CLZ(ARM64Reg::X3, ARM64Reg::X1);
LSL(ARM64Reg::X2, ARM64Reg::X2, 32); LSL(ARM64Reg::X2, ARM64Reg::X2, 32);
ORR(ARM64Reg::X4, ARM64Reg::X3, LogicalImm(0xffffffffffffffc0, 64)); ORR(ARM64Reg::X4, ARM64Reg::X3, LogicalImm(0xffffffffffffffc0, GPRSize::B64));
SUB(ARM64Reg::X2, ARM64Reg::X2, ARM64Reg::X3, ArithOption(ARM64Reg::X3, ShiftType::LSL, 52)); SUB(ARM64Reg::X2, ARM64Reg::X2, ARM64Reg::X3, ArithOption(ARM64Reg::X3, ShiftType::LSL, 52));
ADD(ARM64Reg::X3, ARM64Reg::X4, 23); ADD(ARM64Reg::X3, ARM64Reg::X4, 23);
LSLV(ARM64Reg::X1, ARM64Reg::X1, ARM64Reg::X3); LSLV(ARM64Reg::X1, ARM64Reg::X1, ARM64Reg::X3);
@ -427,13 +429,13 @@ void JitArm64::GenerateConvertSingleToDouble()
RET(); RET();
SetJumpTarget(normal_or_nan); SetJumpTarget(normal_or_nan);
AND(ARM64Reg::W2, ARM64Reg::W0, LogicalImm(0x40000000, 32)); AND(ARM64Reg::W2, ARM64Reg::W0, LogicalImm(0x40000000, GPRSize::B32));
CMP(ARM64Reg::W1, 0xff); CMP(ARM64Reg::W1, 0xff);
CSET(ARM64Reg::W4, CCFlags::CC_NEQ); CSET(ARM64Reg::W4, CCFlags::CC_NEQ);
AND(ARM64Reg::W3, ARM64Reg::W0, LogicalImm(0xc0000000, 32)); AND(ARM64Reg::W3, ARM64Reg::W0, LogicalImm(0xc0000000, GPRSize::B32));
EOR(ARM64Reg::W2, ARM64Reg::W4, ARM64Reg::W2, ArithOption(ARM64Reg::W2, ShiftType::LSR, 30)); EOR(ARM64Reg::W2, ARM64Reg::W4, ARM64Reg::W2, ArithOption(ARM64Reg::W2, ShiftType::LSR, 30));
MOVI2R(ARM64Reg::X1, 0x3800000000000000); MOVI2R(ARM64Reg::X1, 0x3800000000000000);
AND(ARM64Reg::W4, ARM64Reg::W0, LogicalImm(0x3fffffff, 32)); AND(ARM64Reg::W4, ARM64Reg::W0, LogicalImm(0x3fffffff, GPRSize::B32));
LSL(ARM64Reg::X3, ARM64Reg::X3, 32); LSL(ARM64Reg::X3, ARM64Reg::X3, 32);
CMP(ARM64Reg::W2, 0); CMP(ARM64Reg::W2, 0);
CSEL(ARM64Reg::X1, ARM64Reg::X1, ARM64Reg::ZR, CCFlags::CC_NEQ); CSEL(ARM64Reg::X1, ARM64Reg::X1, ARM64Reg::ZR, CCFlags::CC_NEQ);
@ -492,14 +494,15 @@ void JitArm64::GenerateFPRF(bool single)
FixupBranch nan_or_inf = TBNZ(input_reg, input_size - 2); FixupBranch nan_or_inf = TBNZ(input_reg, input_size - 2);
// exp == 0 && frac != 0 // exp == 0 && frac != 0
ORR(fprf_reg, fprf_reg, LogicalImm(Common::PPC_FPCLASS_PD & ~output_sign_mask, 32)); ORR(fprf_reg, fprf_reg, LogicalImm(Common::PPC_FPCLASS_PD & ~output_sign_mask, GPRSize::B32));
B(write_fprf_and_ret); B(write_fprf_and_ret);
// exp == EXP_MASK // exp == EXP_MASK
SetJumpTarget(nan_or_inf); SetJumpTarget(nan_or_inf);
MOVI2R(ARM64Reg::W2, Common::PPC_FPCLASS_QNAN); MOVI2R(ARM64Reg::W2, Common::PPC_FPCLASS_QNAN);
ORR(ARM64Reg::W1, fprf_reg, LogicalImm(Common::PPC_FPCLASS_PINF & ~output_sign_mask, 32)); ORR(ARM64Reg::W1, fprf_reg,
TST(input_reg, LogicalImm(input_frac_mask, input_size)); LogicalImm(Common::PPC_FPCLASS_PINF & ~output_sign_mask, GPRSize::B32));
TST(input_reg, LogicalImm(input_frac_mask, single ? GPRSize::B32 : GPRSize::B64));
CSEL(fprf_reg, ARM64Reg::W1, ARM64Reg::W2, CCFlags::CC_EQ); CSEL(fprf_reg, ARM64Reg::W1, ARM64Reg::W2, CCFlags::CC_EQ);
B(write_fprf_and_ret); B(write_fprf_and_ret);
} }

View File

@ -82,8 +82,8 @@ std::pair<Arm64Gen::ARM64Reg, u32> VertexLoaderARM64::GetVertexAddr(CPArray arra
if (array == CPArray::Position) if (array == CPArray::Position)
{ {
EOR(scratch2_reg, scratch1_reg, EOR(scratch2_reg, scratch1_reg,
attribute == VertexComponentFormat::Index8 ? LogicalImm(0xFF, 32) : attribute == VertexComponentFormat::Index8 ? LogicalImm(0xFF, GPRSize::B32) :
LogicalImm(0xFFFF, 32)); LogicalImm(0xFFFF, GPRSize::B32));
m_skip_vertex = CBZ(scratch2_reg); m_skip_vertex = CBZ(scratch2_reg);
} }
@ -202,7 +202,7 @@ void VertexLoaderARM64::ReadColor(VertexComponentFormat attribute, ColorFormat f
LDUR(scratch2_reg, reg, offset); LDUR(scratch2_reg, reg, offset);
if (format != ColorFormat::RGBA8888) if (format != ColorFormat::RGBA8888)
ORR(scratch2_reg, scratch2_reg, LogicalImm(0xFF000000, 32)); ORR(scratch2_reg, scratch2_reg, LogicalImm(0xFF000000, GPRSize::B32));
STR(IndexType::Unsigned, scratch2_reg, dst_reg, m_dst_ofs); STR(IndexType::Unsigned, scratch2_reg, dst_reg, m_dst_ofs);
load_bytes = format == ColorFormat::RGB888 ? 3 : 4; load_bytes = format == ColorFormat::RGB888 ? 3 : 4;
break; break;
@ -215,7 +215,7 @@ void VertexLoaderARM64::ReadColor(VertexComponentFormat attribute, ColorFormat f
REV16(scratch3_reg, scratch3_reg); REV16(scratch3_reg, scratch3_reg);
// B // B
AND(scratch2_reg, scratch3_reg, LogicalImm(0x1F, 32)); AND(scratch2_reg, scratch3_reg, LogicalImm(0x1F, GPRSize::B32));
ORR(scratch2_reg, ARM64Reg::WSP, scratch2_reg, ArithOption(scratch2_reg, ShiftType::LSL, 3)); ORR(scratch2_reg, ARM64Reg::WSP, scratch2_reg, ArithOption(scratch2_reg, ShiftType::LSL, 3));
ORR(scratch2_reg, scratch2_reg, scratch2_reg, ArithOption(scratch2_reg, ShiftType::LSR, 5)); ORR(scratch2_reg, scratch2_reg, scratch2_reg, ArithOption(scratch2_reg, ShiftType::LSR, 5));
ORR(scratch1_reg, ARM64Reg::WSP, scratch2_reg, ArithOption(scratch2_reg, ShiftType::LSL, 16)); ORR(scratch1_reg, ARM64Reg::WSP, scratch2_reg, ArithOption(scratch2_reg, ShiftType::LSL, 16));
@ -232,7 +232,7 @@ void VertexLoaderARM64::ReadColor(VertexComponentFormat attribute, ColorFormat f
ORR(scratch1_reg, scratch1_reg, scratch2_reg, ArithOption(scratch2_reg, ShiftType::LSR, 2)); ORR(scratch1_reg, scratch1_reg, scratch2_reg, ArithOption(scratch2_reg, ShiftType::LSR, 2));
// A // A
ORR(scratch1_reg, scratch1_reg, LogicalImm(0xFF000000, 32)); ORR(scratch1_reg, scratch1_reg, LogicalImm(0xFF000000, GPRSize::B32));
STR(IndexType::Unsigned, scratch1_reg, dst_reg, m_dst_ofs); STR(IndexType::Unsigned, scratch1_reg, dst_reg, m_dst_ofs);
load_bytes = 2; load_bytes = 2;
@ -248,7 +248,7 @@ void VertexLoaderARM64::ReadColor(VertexComponentFormat attribute, ColorFormat f
UBFM(scratch1_reg, scratch3_reg, 4, 7); UBFM(scratch1_reg, scratch3_reg, 4, 7);
// G // G
AND(scratch2_reg, scratch3_reg, LogicalImm(0xF, 32)); AND(scratch2_reg, scratch3_reg, LogicalImm(0xF, GPRSize::B32));
ORR(scratch1_reg, scratch1_reg, scratch2_reg, ArithOption(scratch2_reg, ShiftType::LSL, 8)); ORR(scratch1_reg, scratch1_reg, scratch2_reg, ArithOption(scratch2_reg, ShiftType::LSL, 8));
// B // B
@ -356,7 +356,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
if (m_VtxDesc.low.PosMatIdx) if (m_VtxDesc.low.PosMatIdx)
{ {
LDRB(IndexType::Unsigned, scratch1_reg, src_reg, m_src_ofs); LDRB(IndexType::Unsigned, scratch1_reg, src_reg, m_src_ofs);
AND(scratch1_reg, scratch1_reg, LogicalImm(0x3F, 32)); AND(scratch1_reg, scratch1_reg, LogicalImm(0x3F, GPRSize::B32));
STR(IndexType::Unsigned, scratch1_reg, dst_reg, m_dst_ofs); STR(IndexType::Unsigned, scratch1_reg, dst_reg, m_dst_ofs);
// Z-Freeze // Z-Freeze

View File

@ -98,12 +98,12 @@ TEST(JitArm64, MovI2R_LogImm)
for (unsigned rotation = 0; rotation < size; ++rotation) for (unsigned rotation = 0; rotation < size; ++rotation)
{ {
test.Check64(imm); test.Check64(imm);
EXPECT_EQ(static_cast<bool>(LogicalImm(imm, 64)), true); EXPECT_EQ(static_cast<bool>(LogicalImm(imm, GPRSize::B64)), true);
if (size < 64) if (size < 64)
{ {
test.Check32(imm); test.Check32(imm);
EXPECT_EQ(static_cast<bool>(LogicalImm(static_cast<u32>(imm), 32)), true); EXPECT_EQ(static_cast<bool>(LogicalImm(static_cast<u32>(imm), GPRSize::B32)), true);
} }
imm = (imm >> 63) | (imm << 1); imm = (imm >> 63) | (imm << 1);