mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-09-18 23:42:05 +00:00
Compile fixes for Windows-on-ARM64
This commit is contained in:
parent
6fcb1c6c46
commit
d744c5a148
13 changed files with 115 additions and 64 deletions
|
@ -33,6 +33,10 @@ typedef CONTEXT SContext;
|
|||
#define CTX_R14 R14
|
||||
#define CTX_R15 R15
|
||||
#define CTX_RIP Rip
|
||||
#elif _M_ARM64
|
||||
#define CTX_REG(x) X[x]
|
||||
#define CTX_SP Sp
|
||||
#define CTX_PC Pc
|
||||
#else
|
||||
#error No context definition for architecture
|
||||
#endif
|
||||
|
|
|
@ -754,9 +754,9 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(msr));
|
||||
FixupBranch b1 = TBNZ(WA, 13); // Test FP enabled bit
|
||||
|
||||
FixupBranch far = B();
|
||||
FixupBranch far_addr = B();
|
||||
SwitchToFarCode();
|
||||
SetJumpTarget(far);
|
||||
SetJumpTarget(far_addr);
|
||||
|
||||
gpr.Flush(FLUSH_MAINTAIN_STATE);
|
||||
fpr.Flush(FLUSH_MAINTAIN_STATE);
|
||||
|
|
|
@ -143,9 +143,9 @@ void JitArm64::bcx(UGeckoInstruction inst)
|
|||
JumpIfCRFieldBit(inst.BI >> 2, 3 - (inst.BI & 3), !(inst.BO_2 & BO_BRANCH_IF_TRUE));
|
||||
}
|
||||
|
||||
FixupBranch far = B();
|
||||
FixupBranch far_addr = B();
|
||||
SwitchToFarCode();
|
||||
SetJumpTarget(far);
|
||||
SetJumpTarget(far_addr);
|
||||
|
||||
if (inst.LK)
|
||||
{
|
||||
|
@ -160,12 +160,12 @@ void JitArm64::bcx(UGeckoInstruction inst)
|
|||
if (js.op->branchIsIdleLoop)
|
||||
{
|
||||
// make idle loops go faster
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
ARM64Reg XA = EncodeRegTo64(WA);
|
||||
ARM64Reg WA2 = gpr.GetReg();
|
||||
ARM64Reg XA2 = EncodeRegTo64(WA2);
|
||||
|
||||
MOVP2R(XA, &CoreTiming::Idle);
|
||||
BLR(XA);
|
||||
gpr.Unlock(WA);
|
||||
MOVP2R(XA2, &CoreTiming::Idle);
|
||||
BLR(XA2);
|
||||
gpr.Unlock(WA2);
|
||||
|
||||
WriteExceptionExit(js.op->branchTo);
|
||||
}
|
||||
|
@ -260,9 +260,9 @@ void JitArm64::bclrx(UGeckoInstruction inst)
|
|||
|
||||
if (conditional)
|
||||
{
|
||||
FixupBranch far = B();
|
||||
FixupBranch far_addr = B();
|
||||
SwitchToFarCode();
|
||||
SetJumpTarget(far);
|
||||
SetJumpTarget(far_addr);
|
||||
}
|
||||
|
||||
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(spr[SPR_LR]));
|
||||
|
|
|
@ -35,7 +35,7 @@ void JitArm64::fp_arith(UGeckoInstruction inst)
|
|||
bool inputs_are_singles = fpr.IsSingle(a, !packed) && (!use_b || fpr.IsSingle(b, !packed)) &&
|
||||
(!use_c || fpr.IsSingle(c, !packed));
|
||||
|
||||
ARM64Reg VA, VB, VC, VD;
|
||||
ARM64Reg VA{}, VB{}, VC{}, VD{};
|
||||
|
||||
if (packed)
|
||||
{
|
||||
|
|
|
@ -368,7 +368,11 @@ void JitArm64::cntlzwx(UGeckoInstruction inst)
|
|||
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
gpr.SetImmediate(a, _CountLeadingZeros(gpr.GetImm(s)));
|
||||
#else
|
||||
gpr.SetImmediate(a, __builtin_clz(gpr.GetImm(s)));
|
||||
#endif
|
||||
if (inst.Rc)
|
||||
ComputeRC0(gpr.GetImm(a));
|
||||
}
|
||||
|
@ -931,7 +935,7 @@ void JitArm64::subfex(UGeckoInstruction inst)
|
|||
|
||||
// d = ~a + b + carry;
|
||||
if (gpr.IsImm(a))
|
||||
MOVI2R(WA, ~gpr.GetImm(a));
|
||||
MOVI2R(WA, u32(~gpr.GetImm(a)));
|
||||
else
|
||||
MVN(WA, gpr.R(a));
|
||||
ADCS(gpr.R(d), WA, gpr.R(b));
|
||||
|
@ -1187,7 +1191,7 @@ void JitArm64::divwx(UGeckoInstruction inst)
|
|||
if (inst.Rc)
|
||||
ComputeRC0(imm_d);
|
||||
}
|
||||
else if (gpr.IsImm(b) && gpr.GetImm(b) != 0 && gpr.GetImm(b) != -1u)
|
||||
else if (gpr.IsImm(b) && gpr.GetImm(b) != 0 && gpr.GetImm(b) != UINT32_C(0xFFFFFFFF))
|
||||
{
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
MOVI2R(WA, gpr.GetImm(b));
|
||||
|
|
|
@ -408,7 +408,7 @@ void JitArm64::stX(UGeckoInstruction inst)
|
|||
gpr.BindToRegister(a, false);
|
||||
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
ARM64Reg RB;
|
||||
ARM64Reg RB = {};
|
||||
ARM64Reg RA = gpr.R(a);
|
||||
if (regOffset != -1)
|
||||
RB = gpr.R(regOffset);
|
||||
|
@ -549,9 +549,9 @@ void JitArm64::dcbx(UGeckoInstruction inst)
|
|||
LSR(value, value, addr); // move current bit to bit 0
|
||||
|
||||
FixupBranch bit_not_set = TBZ(value, 0);
|
||||
FixupBranch far = B();
|
||||
FixupBranch far_addr = B();
|
||||
SwitchToFarCode();
|
||||
SetJumpTarget(far);
|
||||
SetJumpTarget(far_addr);
|
||||
|
||||
BitSet32 gprs_to_push = gpr.GetCallerSavedUsed();
|
||||
BitSet32 fprs_to_push = fpr.GetCallerSavedUsed();
|
||||
|
@ -568,10 +568,10 @@ void JitArm64::dcbx(UGeckoInstruction inst)
|
|||
m_float_emit.ABI_PopRegisters(fprs_to_push, X30);
|
||||
ABI_PopRegisters(gprs_to_push);
|
||||
|
||||
FixupBranch near = B();
|
||||
FixupBranch near_addr = B();
|
||||
SwitchToNearCode();
|
||||
SetJumpTarget(bit_not_set);
|
||||
SetJumpTarget(near);
|
||||
SetJumpTarget(near_addr);
|
||||
|
||||
gpr.Unlock(addr, value, W30);
|
||||
}
|
||||
|
|
|
@ -149,6 +149,7 @@ Arm64GPRCache::GuestRegInfo Arm64GPRCache::GetGuestByIndex(size_t index)
|
|||
if (index >= GUEST_CR_OFFSET && index < GUEST_CR_OFFSET + GUEST_CR_COUNT)
|
||||
return GetGuestCR(index - GUEST_CR_OFFSET);
|
||||
ASSERT_MSG(DYNA_REC, false, "Invalid index for guest register");
|
||||
return GetGuestGPR(0);
|
||||
}
|
||||
|
||||
void Arm64GPRCache::FlushRegister(size_t index, bool maintain_state)
|
||||
|
@ -161,7 +162,7 @@ void Arm64GPRCache::FlushRegister(size_t index, bool maintain_state)
|
|||
{
|
||||
ARM64Reg host_reg = reg.GetReg();
|
||||
if (reg.IsDirty())
|
||||
m_emit->STR(INDEX_UNSIGNED, host_reg, PPC_REG, guest_reg.ppc_offset);
|
||||
m_emit->STR(INDEX_UNSIGNED, host_reg, PPC_REG, u32(guest_reg.ppc_offset));
|
||||
|
||||
if (!maintain_state)
|
||||
{
|
||||
|
@ -173,14 +174,14 @@ void Arm64GPRCache::FlushRegister(size_t index, bool maintain_state)
|
|||
{
|
||||
if (!reg.GetImm())
|
||||
{
|
||||
m_emit->STR(INDEX_UNSIGNED, bitsize == 64 ? ZR : WZR, PPC_REG, guest_reg.ppc_offset);
|
||||
m_emit->STR(INDEX_UNSIGNED, bitsize == 64 ? ZR : WZR, PPC_REG, u32(guest_reg.ppc_offset));
|
||||
}
|
||||
else
|
||||
{
|
||||
ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg());
|
||||
|
||||
m_emit->MOVI2R(host_reg, reg.GetImm());
|
||||
m_emit->STR(INDEX_UNSIGNED, host_reg, PPC_REG, guest_reg.ppc_offset);
|
||||
m_emit->STR(INDEX_UNSIGNED, host_reg, PPC_REG, u32(guest_reg.ppc_offset));
|
||||
|
||||
UnlockRegister(DecodeReg(host_reg));
|
||||
}
|
||||
|
@ -207,7 +208,7 @@ void Arm64GPRCache::FlushRegisters(BitSet32 regs, bool maintain_state)
|
|||
size_t ppc_offset = GetGuestByIndex(i).ppc_offset;
|
||||
ARM64Reg RX1 = R(GetGuestByIndex(i));
|
||||
ARM64Reg RX2 = R(GetGuestByIndex(i + 1));
|
||||
m_emit->STP(INDEX_SIGNED, RX1, RX2, PPC_REG, ppc_offset);
|
||||
m_emit->STP(INDEX_SIGNED, RX1, RX2, PPC_REG, u32(ppc_offset));
|
||||
if (!maintain_state)
|
||||
{
|
||||
UnlockRegister(DecodeReg(RX1));
|
||||
|
@ -285,7 +286,7 @@ ARM64Reg Arm64GPRCache::R(const GuestRegInfo& guest_reg)
|
|||
ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg());
|
||||
reg.Load(host_reg);
|
||||
reg.SetDirty(false);
|
||||
m_emit->LDR(INDEX_UNSIGNED, host_reg, PPC_REG, guest_reg.ppc_offset);
|
||||
m_emit->LDR(INDEX_UNSIGNED, host_reg, PPC_REG, u32(guest_reg.ppc_offset));
|
||||
return host_reg;
|
||||
}
|
||||
break;
|
||||
|
@ -318,7 +319,7 @@ void Arm64GPRCache::BindToRegister(const GuestRegInfo& guest_reg, bool do_load)
|
|||
ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg());
|
||||
reg.Load(host_reg);
|
||||
if (do_load)
|
||||
m_emit->LDR(INDEX_UNSIGNED, host_reg, PPC_REG, guest_reg.ppc_offset);
|
||||
m_emit->LDR(INDEX_UNSIGNED, host_reg, PPC_REG, u32(guest_reg.ppc_offset));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,7 +451,7 @@ ARM64Reg Arm64FPRCache::R(size_t preg, RegType type)
|
|||
// Load the high 64bits from the file and insert them in to the high 64bits of the host
|
||||
// register
|
||||
ARM64Reg tmp_reg = GetReg();
|
||||
m_float_emit->LDR(64, INDEX_UNSIGNED, tmp_reg, PPC_REG, PPCSTATE_OFF(ps[preg].ps1));
|
||||
m_float_emit->LDR(64, INDEX_UNSIGNED, tmp_reg, PPC_REG, u32(PPCSTATE_OFF(ps[preg].ps1)));
|
||||
m_float_emit->INS(64, host_reg, 1, tmp_reg, 0);
|
||||
UnlockRegister(tmp_reg);
|
||||
|
||||
|
@ -503,7 +504,8 @@ ARM64Reg Arm64FPRCache::R(size_t preg, RegType type)
|
|||
reg.Load(host_reg, REG_LOWER_PAIR);
|
||||
}
|
||||
reg.SetDirty(false);
|
||||
m_float_emit->LDR(load_size, INDEX_UNSIGNED, host_reg, PPC_REG, PPCSTATE_OFF(ps[preg].ps0));
|
||||
m_float_emit->LDR(load_size, INDEX_UNSIGNED, host_reg, PPC_REG,
|
||||
u32(PPCSTATE_OFF(ps[preg].ps0)));
|
||||
return host_reg;
|
||||
}
|
||||
default:
|
||||
|
@ -551,7 +553,7 @@ ARM64Reg Arm64FPRCache::RW(size_t preg, RegType type)
|
|||
// We are doing a full 128bit store because it takes 2 cycles on a Cortex-A57 to do a 128bit
|
||||
// store.
|
||||
// It would take longer to do an insert to a temporary and a 64bit store than to just do this.
|
||||
m_float_emit->STR(128, INDEX_UNSIGNED, flush_reg, PPC_REG, PPCSTATE_OFF(ps[preg].ps0));
|
||||
m_float_emit->STR(128, INDEX_UNSIGNED, flush_reg, PPC_REG, u32(PPCSTATE_OFF(ps[preg].ps0)));
|
||||
break;
|
||||
case REG_DUP_SINGLE:
|
||||
flush_reg = GetReg();
|
||||
|
@ -559,7 +561,7 @@ ARM64Reg Arm64FPRCache::RW(size_t preg, RegType type)
|
|||
[[fallthrough]];
|
||||
case REG_DUP:
|
||||
// Store PSR1 (which is equal to PSR0) in memory.
|
||||
m_float_emit->STR(64, INDEX_UNSIGNED, flush_reg, PPC_REG, PPCSTATE_OFF(ps[preg].ps1));
|
||||
m_float_emit->STR(64, INDEX_UNSIGNED, flush_reg, PPC_REG, u32(PPCSTATE_OFF(ps[preg].ps1)));
|
||||
break;
|
||||
default:
|
||||
// All other types doesn't store anything in PSR1.
|
||||
|
@ -684,7 +686,10 @@ void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state)
|
|||
store_size = 64;
|
||||
|
||||
if (dirty)
|
||||
m_float_emit->STR(store_size, INDEX_UNSIGNED, host_reg, PPC_REG, PPCSTATE_OFF(ps[preg].ps0));
|
||||
{
|
||||
m_float_emit->STR(store_size, INDEX_UNSIGNED, host_reg, PPC_REG,
|
||||
u32(PPCSTATE_OFF(ps[preg].ps0)));
|
||||
}
|
||||
|
||||
if (!maintain_state)
|
||||
{
|
||||
|
@ -700,8 +705,8 @@ void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state)
|
|||
// Too bad moving them would break savestate compatibility between x86_64 and AArch64
|
||||
// m_float_emit->STP(64, INDEX_SIGNED, host_reg, host_reg, PPC_REG,
|
||||
// PPCSTATE_OFF(ps[preg].ps0));
|
||||
m_float_emit->STR(64, INDEX_UNSIGNED, host_reg, PPC_REG, PPCSTATE_OFF(ps[preg].ps0));
|
||||
m_float_emit->STR(64, INDEX_UNSIGNED, host_reg, PPC_REG, PPCSTATE_OFF(ps[preg].ps1));
|
||||
m_float_emit->STR(64, INDEX_UNSIGNED, host_reg, PPC_REG, u32(PPCSTATE_OFF(ps[preg].ps0)));
|
||||
m_float_emit->STR(64, INDEX_UNSIGNED, host_reg, PPC_REG, u32(PPCSTATE_OFF(ps[preg].ps1)));
|
||||
}
|
||||
|
||||
if (!maintain_state)
|
||||
|
|
|
@ -32,6 +32,7 @@ FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
|
|||
return jump_if_set ? TBNZ(XA, 62) : TBZ(XA, 62);
|
||||
default:
|
||||
ASSERT_MSG(DYNA_REC, false, "Invalid CR bit");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,9 +197,9 @@ void JitArm64::twx(UGeckoInstruction inst)
|
|||
SetJumpTarget(fixup);
|
||||
}
|
||||
|
||||
FixupBranch far = B();
|
||||
FixupBranch far_addr = B();
|
||||
SwitchToFarCode();
|
||||
SetJumpTarget(far);
|
||||
SetJumpTarget(far_addr);
|
||||
|
||||
gpr.Flush(FlushMode::FLUSH_MAINTAIN_STATE);
|
||||
fpr.Flush(FlushMode::FLUSH_MAINTAIN_STATE);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue