JitArm64: Use a register as PC argument for the dispatcher.
This commit is contained in:
parent
050932ed23
commit
7b017c6a65
|
@ -193,31 +193,28 @@ void JitArm64::WriteExit(u32 destination)
|
|||
linkData.exitAddress = destination;
|
||||
linkData.exitPtrs = GetWritableCodePtr();
|
||||
linkData.linkStatus = false;
|
||||
b->linkData.push_back(linkData);
|
||||
|
||||
// the code generated in JitArm64BlockCache::WriteDestroyBlock must fit in this block
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
ARM64Reg XA = EncodeRegTo64(WA);
|
||||
MOVI2R(WA, destination);
|
||||
STR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(pc));
|
||||
MOVI2R(XA, (u64)asm_routines.dispatcher);
|
||||
BR(XA);
|
||||
gpr.Unlock(WA);
|
||||
|
||||
b->linkData.push_back(linkData);
|
||||
MOVI2R(X30, (u64)asm_routines.dispatcher);
|
||||
MOVI2R(DISPATCHER_PC, destination);
|
||||
BR(X30);
|
||||
}
|
||||
|
||||
void JitArm64::WriteExit(ARM64Reg Reg)
|
||||
{
|
||||
STR(INDEX_UNSIGNED, Reg, X29, PPCSTATE_OFF(pc));
|
||||
Cleanup();
|
||||
DoDownCount();
|
||||
|
||||
if (Reg != DISPATCHER_PC)
|
||||
MOV(DISPATCHER_PC, Reg);
|
||||
gpr.Unlock(Reg);
|
||||
|
||||
if (Profiler::g_ProfileBlocks)
|
||||
EndTimeProfile(js.curBlock);
|
||||
|
||||
MOVI2R(EncodeRegTo64(Reg), (u64)asm_routines.dispatcher);
|
||||
BR(EncodeRegTo64(Reg));
|
||||
gpr.Unlock(Reg);
|
||||
MOVI2R(X30, (u64)asm_routines.dispatcher);
|
||||
BR(X30);
|
||||
}
|
||||
|
||||
void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external)
|
||||
|
@ -227,10 +224,10 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external)
|
|||
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(pc));
|
||||
FixupBranch no_exceptions = CBZ(WA);
|
||||
gpr.Unlock(WA);
|
||||
|
||||
STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(pc));
|
||||
STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(npc));
|
||||
if (only_external)
|
||||
MOVI2R(EncodeRegTo64(dest), (u64)&PowerPC::CheckExternalExceptions);
|
||||
|
@ -238,17 +235,18 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external)
|
|||
MOVI2R(EncodeRegTo64(dest), (u64)&PowerPC::CheckExceptions);
|
||||
BLR(EncodeRegTo64(dest));
|
||||
LDR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(npc));
|
||||
STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(pc));
|
||||
|
||||
SetJumpTarget(no_exceptions);
|
||||
|
||||
if (dest != DISPATCHER_PC)
|
||||
MOV(DISPATCHER_PC, dest);
|
||||
gpr.Unlock(dest);
|
||||
|
||||
if (Profiler::g_ProfileBlocks)
|
||||
EndTimeProfile(js.curBlock);
|
||||
|
||||
MOVI2R(EncodeRegTo64(dest), (u64)asm_routines.dispatcher);
|
||||
BR(EncodeRegTo64(dest));
|
||||
|
||||
gpr.Unlock(dest);
|
||||
MOVI2R(X30, (u64)asm_routines.dispatcher);
|
||||
BR(X30);
|
||||
}
|
||||
|
||||
void JitArm64::DumpCode(const u8* start, const u8* end)
|
||||
|
@ -389,8 +387,7 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
|
|||
FixupBranch bail = B(CC_PL);
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
ARM64Reg XA = EncodeRegTo64(WA);
|
||||
MOVI2R(WA, js.blockStart);
|
||||
STR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(pc));
|
||||
MOVI2R(DISPATCHER_PC, js.blockStart);
|
||||
MOVI2R(XA, (u64)asm_routines.doTiming);
|
||||
BR(XA);
|
||||
gpr.Unlock(WA);
|
||||
|
@ -423,8 +420,8 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
|
|||
FixupBranch fail = B();
|
||||
SwitchToFarCode();
|
||||
SetJumpTarget(fail);
|
||||
MOVI2R(W0, js.blockStart);
|
||||
STR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(pc));
|
||||
MOVI2R(DISPATCHER_PC, js.blockStart);
|
||||
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||
MOVI2R(W0, (u32)JitInterface::ExceptionType::EXCEPTIONS_PAIRED_QUANTIZE);
|
||||
MOVI2R(X1, (u64)&JitInterface::CompileExceptionCheck);
|
||||
BLR(X1);
|
||||
|
|
|
@ -29,9 +29,8 @@ void JitArm64BlockCache::WriteDestroyBlock(const u8* location, u32 address)
|
|||
{
|
||||
// must fit within the code generated in JitArm64::WriteExit
|
||||
ARM64XEmitter emit((u8 *)location);
|
||||
emit.MOVI2R(W0, address);
|
||||
emit.MOVI2R(X30, (u64)jit->GetAsmRoutines()->dispatcher);
|
||||
emit.STR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(pc));
|
||||
emit.MOVI2R(DISPATCHER_PC, address);
|
||||
emit.BR(X30);
|
||||
emit.FlushIcache();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ using namespace Arm64Gen;
|
|||
// Dedicated host registers
|
||||
static const ARM64Reg MEM_REG = X28; // memory base register
|
||||
static const ARM64Reg PPC_REG = X29; // ppcState pointer
|
||||
static const ARM64Reg DISPATCHER_PC = W26; // register for PC when calling the dispatcher
|
||||
|
||||
#define PPCSTATE_OFF(elem) (offsetof(PowerPC::PowerPCState, elem))
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ void JitArm64AsmRoutineManager::Generate()
|
|||
MOVI2R(PPC_REG, (u64)&PowerPC::ppcState);
|
||||
MOVI2R(MEM_REG, (u64)Memory::logical_base);
|
||||
|
||||
// Load the current PC into DISPATCHER_PC
|
||||
LDR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||
|
||||
FixupBranch to_dispatcher = B();
|
||||
|
||||
// If we align the dispatcher to a page then we can load its location with one ADRP instruction
|
||||
|
@ -46,11 +49,10 @@ void JitArm64AsmRoutineManager::Generate()
|
|||
|
||||
// This block of code gets the address of the compiled block of code
|
||||
// It runs though to the compiling portion if it isn't found
|
||||
LDR(INDEX_UNSIGNED, W26, PPC_REG, PPCSTATE_OFF(pc)); // Load the current PC into W26
|
||||
BFM(W26, WSP, 3, 2); // Wipe the top 3 bits. Same as PC & JIT_ICACHE_MASK
|
||||
BFM(DISPATCHER_PC, WSP, 3, 2); // Wipe the top 3 bits. Same as PC & JIT_ICACHE_MASK
|
||||
|
||||
MOVI2R(X27, (u64)jit->GetBlockCache()->iCache.data());
|
||||
LDR(W27, X27, X26);
|
||||
LDR(W27, X27, EncodeRegTo64(DISPATCHER_PC));
|
||||
|
||||
FixupBranch JitBlock = TBNZ(W27, 7); // Test the 7th bit
|
||||
// Success, it is our Jitblock.
|
||||
|
@ -62,6 +64,8 @@ void JitArm64AsmRoutineManager::Generate()
|
|||
|
||||
SetJumpTarget(JitBlock);
|
||||
|
||||
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||
|
||||
MOVI2R(X30, (u64)&Jit);
|
||||
BLR(X30);
|
||||
|
||||
|
@ -75,12 +79,11 @@ void JitArm64AsmRoutineManager::Generate()
|
|||
// Does exception checking
|
||||
LDR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
FixupBranch no_exceptions = CBZ(W0);
|
||||
LDR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(pc));
|
||||
STR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(npc));
|
||||
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
|
||||
MOVI2R(X30, (u64)&PowerPC::CheckExceptions);
|
||||
BLR(X30);
|
||||
LDR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(npc));
|
||||
STR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(pc));
|
||||
LDR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
|
||||
SetJumpTarget(no_exceptions);
|
||||
|
||||
// Check the state pointer to see if we are exiting
|
||||
|
@ -94,6 +97,7 @@ void JitArm64AsmRoutineManager::Generate()
|
|||
B(dispatcher);
|
||||
|
||||
SetJumpTarget(Exit);
|
||||
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||
|
||||
// Let the waiting thread know we are done leaving
|
||||
MOVI2R(X0, (u64)&PowerPC::FinishStateMove);
|
||||
|
|
Loading…
Reference in New Issue