mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 13:27:45 -07:00
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:
commit
190c4e8cda
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user