Fixes for the AArch64 JIT

Custom dispatcher isn't fully working yet, but fixes a few other bugs.
This commit is contained in:
Ryan Houdek 2019-11-12 00:03:15 -08:00 committed by Stefanos Kornilios Mitsis Poiitidis
parent cb81d0a1af
commit 6e72a365d9

View File

@ -35,6 +35,24 @@ using namespace vixl::aarch64;
#define VTMP2 v2
#define VTMP3 v3
const std::array<aarch64::Register, 13> RA64 = {
x4, x5, x6, x7, x8, x9,
x10, x11, x12, x13, x14, x15,
/*x16, x17,*/ // We can't use these until we move away from the MacroAssembler
x18};
const std::array<aarch64::Register, 13> RA32 = {
w4, w5, w6, w7, w8, w9,
w10, w11, w12, w13, w14, w15,
/*w16, w17,*/
w18};
// v8..v15 = (lower 64bits) Callee saved
const std::array<aarch64::VRegister, 22> RAFPR = {
v3, v4, v5, v6, v7, v8, v16,
v17, v18, v19, v20, v21, v22,
v23, v24, v25, v26, v27, v28,
v29, v30, v31};
static uint64_t SyscallThunk(FEXCore::SyscallHandler *Handler, FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args) {
return Handler->HandleSyscall(Thread, Args);
}
@ -76,7 +94,7 @@ public:
void ExecuteCustomDispatch(FEXCore::Core::ThreadState *Thread) override;
#else
void ExecuteCustomDispatch(FEXCore::Core::ThreadState *Thread) override {
DispatchPtr(reinterpret_cast<FEXCore::Core::InternalThreadState*>(Thread->InternalState));
DispatchPtr(reinterpret_cast<FEXCore::Core::InternalThreadState*>(Thread));
}
#endif
@ -90,8 +108,8 @@ private:
/**
* @name Register Allocation
* @{ */
constexpr static uint32_t NumGPRs = 15;
constexpr static uint32_t NumFPRs = 22;
constexpr static uint32_t NumGPRs = RA64.size();
constexpr static uint32_t NumFPRs = RAFPR.size();
constexpr static uint32_t RegisterCount = NumGPRs + NumFPRs;
constexpr static uint32_t RegisterClasses = 2;
@ -230,22 +248,6 @@ void JITCore::LoadConstant(vixl::aarch64::Register Reg, uint64_t Constant) {
}
}
const std::array<aarch64::Register, 15> RA64 = {
x4, x5, x6, x7, x8, x9,
x10, x11, x12, x13, x14, x15,
x16, x17, x18};
const std::array<aarch64::Register, 15> RA32 = {
w4, w5, w6, w7, w8, w9,
w10, w11, w12, w13, w14, w15,
w16, w17, w18};
// v8..v15 = (lower 64bits) Callee saved
const std::array<aarch64::VRegister, 22> RAFPR = {
v3, v4, v5, v6, v7, v8, v16,
v17, v18, v19, v20, v21, v22,
v23, v24, v25, v26, v27, v28,
v29, v30, v31};
uint32_t JITCore::GetPhys(uint32_t Node) {
uint32_t Reg = RAPass->GetNodeRegister(Node);
@ -696,8 +698,16 @@ void *JITCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const
switch (Op->Reason) {
case 0: // Hard fault
case 5: // Guest ud2
case 4: // HLT
hlt(4);
break;
case 4: // HLT
LoadConstant(TMP1, 1);
stlrb(TMP1, MemOperand(STATE, offsetof(FEXCore::Core::ThreadState, RunningEvents.ShouldStop)));
if (SpillSlots) {
add(sp, sp, SpillSlots * 16);
}
ret();
break;
default: LogMan::Msg::A("Unknown Break reason: %d", Op->Reason);
}
@ -1596,28 +1606,30 @@ void JITCore::CreateCustomDispatch(FEXCore::Core::InternalThreadState *Thread) {
bind(&LoopTop);
// Load in our RIP
ldr(x2, MemOperand(STATE, offsetof(FEXCore::Core::ThreadState, State.rip)));
// Don't modify x2 since it contains our RIP once the block doesn't exist
ldr(x2, MemOperand(STATE, offsetof(FEXCore::Core::CPUState, rip)));
LoadConstant(x0, Thread->BlockCache->GetPagePointer());
// Steal the page offset
and_(x1, x2, 0x0FFF);
// Offset the address and add to our page pointer
add(x3, x0, Operand(x2, LSR, 12));
// Load the pointer from the offset
ldr(x3, MemOperand(x3));
ldr(x0, MemOperand(x0, x1, Shift::LSL, 3));
aarch64::Label NoBlock;
// If page pointer is zero then we have no block
cbz(x3, &NoBlock);
cbz(x0, &NoBlock);
// Offset the address and add to our page pointer
lsr(x1, x2, 12);
// Now load from that pointer offset by the page offset to get our real block
ldr(x3, MemOperand(x3, x1));
cbz(x3, &NoBlock);
ldr(x0, MemOperand(x0, x1, Shift::LSL, 3));
cbz(x0, &NoBlock);
// If we've made it here then we have a real compiled block
{
blr(x3);
blr(x0);
}
aarch64::Label ExitCheck;
@ -1656,8 +1668,10 @@ void JITCore::CreateCustomDispatch(FEXCore::Core::InternalThreadState *Thread) {
Ptr.ClassPtr = &FEXCore::Context::Context::CompileBlock;
LoadConstant(x3, Ptr.Data);
stp(STATE, MEM_BASE, MemOperand(sp, -16, PreIndex));
// X2 contains our guest RIP
blr(x3); // { ThreadState, RIP}
blr(x3); // { CTX, ThreadState, RIP}
ldp(STATE, MEM_BASE, MemOperand(sp, 16, PostIndex));
#endif
// X0 now contains either nullptr or block pointer
cbz(x0, &FallbackCore);
@ -1689,8 +1703,10 @@ void JITCore::CreateCustomDispatch(FEXCore::Core::InternalThreadState *Thread) {
Ptr.ClassPtr = &FEXCore::Context::Context::CompileFallbackBlock;
LoadConstant(x3, Ptr.Data);
stp(STATE, MEM_BASE, MemOperand(sp, -16, PreIndex));
// X2 contains our guest RIP
blr(x3); // {ThreadState, RIP}
ldp(STATE, MEM_BASE, MemOperand(sp, 16, PostIndex));
#endif
// X0 now contains either nullptr or block pointer
cbz(x0, &ExitError);