misc JIT changes

This commit is contained in:
RSDuck
2020-07-08 23:08:25 +02:00
parent 778623a8b7
commit 3786660099
6 changed files with 141 additions and 93 deletions

View File

@ -474,19 +474,17 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
ANDI2R(W0, MapReg(rn), ~3); ANDI2R(W0, MapReg(rn), ~3);
} }
LoadStorePatch patch;
if (compileFastPath) if (compileFastPath)
{ {
ptrdiff_t fastPathStart = GetCodeOffset(); ptrdiff_t fastPathStart = GetCodeOffset();
ptrdiff_t firstLoadStoreOffset; ptrdiff_t loadStoreOffsets[16];
bool firstLoadStore = true;
MOVP2R(X1, Num == 0 ? ARMJIT_Memory::FastMem9Start : ARMJIT_Memory::FastMem7Start); MOVP2R(X1, Num == 0 ? ARMJIT_Memory::FastMem9Start : ARMJIT_Memory::FastMem7Start);
ADD(X1, X1, X0); ADD(X1, X1, X0);
u32 offset = preinc ? 4 : 0; u32 offset = preinc ? 4 : 0;
BitSet16::Iterator it = regs.begin(); BitSet16::Iterator it = regs.begin();
u32 i = 0;
if (regsCount & 1) if (regsCount & 1)
{ {
@ -499,11 +497,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
else if (store) else if (store)
LoadReg(reg, first); LoadReg(reg, first);
if (firstLoadStore) loadStoreOffsets[i++] = GetCodeOffset();
{
firstLoadStoreOffset = GetCodeOffset();
firstLoadStore = false;
}
if (store) if (store)
STR(INDEX_UNSIGNED, first, X1, offset); STR(INDEX_UNSIGNED, first, X1, offset);
@ -533,11 +527,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
else if (store) else if (store)
LoadReg(nextReg, second); LoadReg(nextReg, second);
if (firstLoadStore) loadStoreOffsets[i++] = GetCodeOffset();
{
firstLoadStoreOffset = GetCodeOffset();
firstLoadStore = false;
}
if (store) if (store)
STP(INDEX_SIGNED, first, second, X1, offset); STP(INDEX_SIGNED, first, second, X1, offset);
@ -552,12 +542,15 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
offset += 8; offset += 8;
} }
LoadStorePatch patch;
patch.PatchSize = GetCodeOffset() - fastPathStart; patch.PatchSize = GetCodeOffset() - fastPathStart;
patch.PatchOffset = fastPathStart - firstLoadStoreOffset;
SwapCodeRegion(); SwapCodeRegion();
patch.PatchFunc = GetRXPtr(); patch.PatchFunc = GetRXPtr();
for (i = 0; i < regsCount; i++)
LoadStorePatches[firstLoadStoreOffset] = patch; {
patch.PatchOffset = fastPathStart - loadStoreOffsets[i];
LoadStorePatches[loadStoreOffsets[i]] = patch;
}
ABI_PushRegisters({30}); ABI_PushRegisters({30});
} }

View File

@ -73,7 +73,8 @@ u64 __nx_exception_stack_size = 0x8000;
void __libnx_exception_handler(ThreadExceptionDump* ctx) void __libnx_exception_handler(ThreadExceptionDump* ctx)
{ {
ARMJIT_Memory::FaultDescription desc; ARMJIT_Memory::FaultDescription desc;
desc.EmulatedFaultAddr = ctx->cpu_gprs[0].w; u8* curArea = (u8*)(NDS::CurCPU == 0 ? ARMJIT_Memory::FastMem9Start : ARMJIT_Memory::FastMem7Start);
desc.EmulatedFaultAddr = (u8*)ctx->far.x - curArea;
desc.FaultPC = ctx->pc.x; desc.FaultPC = ctx->pc.x;
u64 integerRegisters[33]; u64 integerRegisters[33];
@ -109,10 +110,14 @@ void __libnx_exception_handler(ThreadExceptionDump* ctx)
static LONG ExceptionHandler(EXCEPTION_POINTERS* exceptionInfo) static LONG ExceptionHandler(EXCEPTION_POINTERS* exceptionInfo)
{ {
if (exceptionInfo->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) if (exceptionInfo->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
{
printf("narg\n");
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
}
ARMJIT_Memory::FaultDescription desc; ARMJIT_Memory::FaultDescription desc;
desc.EmulatedFaultAddr = exceptionInfo->ContextRecord->Rcx; u8* curArea = (u8*)(NDS::CurCPU == 0 ? ARMJIT_Memory::FastMem9Start : ARMJIT_Memory::FastMem7Start);
desc.EmulatedFaultAddr = (u8*)exceptionInfo->ExceptionRecord->ExceptionInformation[1] - curArea;
desc.FaultPC = exceptionInfo->ContextRecord->Rip; desc.FaultPC = exceptionInfo->ContextRecord->Rip;
s32 offset = 0; s32 offset = 0;
@ -122,6 +127,7 @@ static LONG ExceptionHandler(EXCEPTION_POINTERS* exceptionInfo)
return EXCEPTION_CONTINUE_EXECUTION; return EXCEPTION_CONTINUE_EXECUTION;
} }
printf("miauz\n");
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }
@ -277,7 +283,8 @@ void SetCodeProtectionRange(u32 addr, u32 size, u32 num, int protection)
winProtection = PAGE_READONLY; winProtection = PAGE_READONLY;
else else
winProtection = PAGE_READWRITE; winProtection = PAGE_READWRITE;
VirtualProtect(dst, size, winProtection, &oldProtection); bool success = VirtualProtect(dst, size, winProtection, &oldProtection);
assert(success);
#else #else
int posixProt; int posixProt;
if (protection == 0) if (protection == 0)
@ -348,9 +355,10 @@ void SetCodeProtection(int region, u32 offset, bool protect)
{ {
Mapping& mapping = Mappings[region][i]; Mapping& mapping = Mappings[region][i];
// if (offset < mapping.LocalOffset || offset >= mapping.LocalOffset + mapping.Size)
// continue;
u32 effectiveAddr = mapping.Addr + (offset - mapping.LocalOffset); u32 effectiveAddr = mapping.Addr + (offset - mapping.LocalOffset);
if (offset < mapping.LocalOffset || offset >= mapping.LocalOffset + mapping.Size)
continue;
if (mapping.Num == 0 if (mapping.Num == 0
&& region != memregion_DTCM && region != memregion_DTCM
&& effectiveAddr >= NDS::ARM9->DTCMBase && effectiveAddr >= NDS::ARM9->DTCMBase
@ -401,8 +409,8 @@ void RemapDTCM(u32 newBase, u32 newSize)
printf("mapping %d %x %x %x %x\n", region, mapping.Addr, mapping.Size, mapping.Num, mapping.LocalOffset); printf("mapping %d %x %x %x %x\n", region, mapping.Addr, mapping.Size, mapping.Num, mapping.LocalOffset);
bool oldOverlap = NDS::ARM9->DTCMSize > 0 && !(oldDTCMBase >= end || oldDTCBEnd < start); bool oldOverlap = NDS::ARM9->DTCMSize > 0 && !(oldDTCMBase >= end || oldDTCBEnd <= start);
bool newOverlap = newSize > 0 && !(newBase >= end || newEnd < start); bool newOverlap = newSize > 0 && !(newBase >= end || newEnd <= start);
if (mapping.Num == 0 && (oldOverlap || newOverlap)) if (mapping.Num == 0 && (oldOverlap || newOverlap))
{ {
@ -449,24 +457,22 @@ void RemapNWRAM(int num)
void RemapSWRAM() void RemapSWRAM()
{ {
printf("remapping SWRAM\n"); printf("remapping SWRAM\n");
for (int i = 0; i < Mappings[memregion_WRAM7].Length;)
{
Mapping& mapping = Mappings[memregion_WRAM7][i];
if (mapping.Addr + mapping.Size < 0x03800000)
{
mapping.Unmap(memregion_WRAM7);
Mappings[memregion_WRAM7].Remove(i);
}
else
i++;
}
for (int i = 0; i < Mappings[memregion_SharedWRAM].Length; i++) for (int i = 0; i < Mappings[memregion_SharedWRAM].Length; i++)
{ {
Mappings[memregion_SharedWRAM][i].Unmap(memregion_SharedWRAM); Mappings[memregion_SharedWRAM][i].Unmap(memregion_SharedWRAM);
} }
Mappings[memregion_SharedWRAM].Clear(); Mappings[memregion_SharedWRAM].Clear();
for (int i = 0; i < Mappings[memregion_WRAM7].Length; i++)
{
Mappings[memregion_WRAM7][i].Unmap(memregion_WRAM7);
}
Mappings[memregion_WRAM7].Clear();
for (int j = 0; j < 3; j++)
{
for (int i = 0; i < Mappings[memregion_NewSharedWRAM_A + j].Length; i++)
{
Mappings[memregion_NewSharedWRAM_A + j][i].Unmap(memregion_NewSharedWRAM_A + j);
}
Mappings[memregion_NewSharedWRAM_A + j].Clear();
}
} }
bool MapAtAddress(u32 addr) bool MapAtAddress(u32 addr)
@ -687,8 +693,6 @@ bool IsFastmemCompatible(int region)
|| region == memregion_NewSharedWRAM_C) || region == memregion_NewSharedWRAM_C)
return false; return false;
#endif #endif
if (region == memregion_DTCM)
return false;
return OffsetsPerRegion[region] != UINT32_MAX; return OffsetsPerRegion[region] != UINT32_MAX;
} }

View File

@ -633,7 +633,7 @@ void Compiler::Comp_SpecialBranchBehaviour(bool taken)
JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[], int instrsCount) JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[], int instrsCount)
{ {
if (NearSize - (NearCode - NearStart) < 1024 * 32) // guess... if (NearSize - (GetCodePtr() - NearStart) < 1024 * 32) // guess...
{ {
printf("near reset\n"); printf("near reset\n");
ResetBlockCache(); ResetBlockCache();

View File

@ -216,9 +216,17 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag
if (size == 32) if (size == 32)
{ {
AND(32, R(RSCRATCH3), Imm8(0x3)); if (addrIsStatic)
SHL(32, R(RSCRATCH3), Imm8(3)); {
ROR_(32, rdMapped, R(RSCRATCH3)); if (staticAddress & 0x3)
ROR_(32, rdMapped, Imm8((staticAddress & 0x3) * 8));
}
else
{
AND(32, R(RSCRATCH3), Imm8(0x3));
SHL(32, R(RSCRATCH3), Imm8(3));
ROR_(32, rdMapped, R(RSCRATCH3));
}
} }
} }
@ -233,78 +241,115 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag
{ {
PushRegs(false); PushRegs(false);
if (Num == 0) void* func = NULL;
if (addrIsStatic)
func = ARMJIT_Memory::GetFuncForAddr(CurCPU, staticAddress, flags & memop_Store, size);
if (func)
{ {
MOV(64, R(ABI_PARAM2), R(RCPU)); AND(32, R(RSCRATCH3), Imm8(addressMask));
if (ABI_PARAM1 != RSCRATCH3) if (ABI_PARAM1 != RSCRATCH3)
MOV(32, R(ABI_PARAM1), R(RSCRATCH3)); MOV(32, R(ABI_PARAM1), R(RSCRATCH3));
if (flags & memop_Store) if (flags & memop_Store)
{ MOV(32, R(ABI_PARAM2), rdMapped);
MOV(32, R(ABI_PARAM3), rdMapped);
switch (size | NDS::ConsoleType) ABI_CallFunction((void (*)())func);
{
case 32: CALL((void*)&SlowWrite9<u32, 0>); break; PopRegs(false);
case 16: CALL((void*)&SlowWrite9<u16, 0>); break;
case 8: CALL((void*)&SlowWrite9<u8, 0>); break; if (!(flags & memop_Store))
case 33: CALL((void*)&SlowWrite9<u32, 1>); break;
case 17: CALL((void*)&SlowWrite9<u16, 1>); break;
case 9: CALL((void*)&SlowWrite9<u8, 1>); break;
}
}
else
{ {
switch (size | NDS::ConsoleType) if (size == 32)
{ {
case 32: CALL((void*)&SlowRead9<u32, 0>); break; MOV(32, rdMapped, R(RSCRATCH));
case 16: CALL((void*)&SlowRead9<u16, 0>); break; if (staticAddress & 0x3)
case 8: CALL((void*)&SlowRead9<u8, 0>); break; ROR_(32, rdMapped, Imm8((staticAddress & 0x3) * 8));
case 33: CALL((void*)&SlowRead9<u32, 1>); break; }
case 17: CALL((void*)&SlowRead9<u16, 1>); break; else
case 9: CALL((void*)&SlowRead9<u8, 1>); break; {
if (flags & memop_SignExtend)
MOVSX(32, size, rdMapped.GetSimpleReg(), R(RSCRATCH));
else
MOVZX(32, size, rdMapped.GetSimpleReg(), R(RSCRATCH));
} }
} }
} }
else else
{ {
if (ABI_PARAM1 != RSCRATCH3) if (Num == 0)
MOV(32, R(ABI_PARAM1), R(RSCRATCH3));
if (flags & memop_Store)
{ {
MOV(32, R(ABI_PARAM2), rdMapped); MOV(64, R(ABI_PARAM2), R(RCPU));
if (ABI_PARAM1 != RSCRATCH3)
switch (size | NDS::ConsoleType) MOV(32, R(ABI_PARAM1), R(RSCRATCH3));
if (flags & memop_Store)
{ {
case 32: CALL((void*)&SlowWrite7<u32, 0>); break; MOV(32, R(ABI_PARAM3), rdMapped);
case 16: CALL((void*)&SlowWrite7<u16, 0>); break;
case 8: CALL((void*)&SlowWrite7<u8, 0>); break; switch (size | NDS::ConsoleType)
case 33: CALL((void*)&SlowWrite7<u32, 1>); break; {
case 17: CALL((void*)&SlowWrite7<u16, 1>); break; case 32: CALL((void*)&SlowWrite9<u32, 0>); break;
case 9: CALL((void*)&SlowWrite7<u8, 1>); break; case 16: CALL((void*)&SlowWrite9<u16, 0>); break;
case 8: CALL((void*)&SlowWrite9<u8, 0>); break;
case 33: CALL((void*)&SlowWrite9<u32, 1>); break;
case 17: CALL((void*)&SlowWrite9<u16, 1>); break;
case 9: CALL((void*)&SlowWrite9<u8, 1>); break;
}
}
else
{
switch (size | NDS::ConsoleType)
{
case 32: CALL((void*)&SlowRead9<u32, 0>); break;
case 16: CALL((void*)&SlowRead9<u16, 0>); break;
case 8: CALL((void*)&SlowRead9<u8, 0>); break;
case 33: CALL((void*)&SlowRead9<u32, 1>); break;
case 17: CALL((void*)&SlowRead9<u16, 1>); break;
case 9: CALL((void*)&SlowRead9<u8, 1>); break;
}
} }
} }
else else
{ {
switch (size | NDS::ConsoleType) if (ABI_PARAM1 != RSCRATCH3)
MOV(32, R(ABI_PARAM1), R(RSCRATCH3));
if (flags & memop_Store)
{ {
case 32: CALL((void*)&SlowRead7<u32, 0>); break; MOV(32, R(ABI_PARAM2), rdMapped);
case 16: CALL((void*)&SlowRead7<u16, 0>); break;
case 8: CALL((void*)&SlowRead7<u8, 0>); break; switch (size | NDS::ConsoleType)
case 33: CALL((void*)&SlowRead7<u32, 1>); break; {
case 17: CALL((void*)&SlowRead7<u16, 1>); break; case 32: CALL((void*)&SlowWrite7<u32, 0>); break;
case 9: CALL((void*)&SlowRead7<u8, 1>); break; case 16: CALL((void*)&SlowWrite7<u16, 0>); break;
case 8: CALL((void*)&SlowWrite7<u8, 0>); break;
case 33: CALL((void*)&SlowWrite7<u32, 1>); break;
case 17: CALL((void*)&SlowWrite7<u16, 1>); break;
case 9: CALL((void*)&SlowWrite7<u8, 1>); break;
}
}
else
{
switch (size | NDS::ConsoleType)
{
case 32: CALL((void*)&SlowRead7<u32, 0>); break;
case 16: CALL((void*)&SlowRead7<u16, 0>); break;
case 8: CALL((void*)&SlowRead7<u8, 0>); break;
case 33: CALL((void*)&SlowRead7<u32, 1>); break;
case 17: CALL((void*)&SlowRead7<u16, 1>); break;
case 9: CALL((void*)&SlowRead7<u8, 1>); break;
}
} }
} }
}
PopRegs(false); PopRegs(false);
if (!(flags & memop_Store)) if (!(flags & memop_Store))
{ {
if (flags & memop_SignExtend) if (flags & memop_SignExtend)
MOVSX(32, size, rdMapped.GetSimpleReg(), R(RSCRATCH)); MOVSX(32, size, rdMapped.GetSimpleReg(), R(RSCRATCH));
else else
MOVZX(32, size, rdMapped.GetSimpleReg(), R(RSCRATCH)); MOVZX(32, size, rdMapped.GetSimpleReg(), R(RSCRATCH));
}
} }
} }

View File

@ -340,6 +340,11 @@ void* ARM64XEmitter::GetRXPtr()
return m_rxbase + m_code; return m_rxbase + m_code;
} }
u8* ARM64XEmitter::GetRXBase()
{
return m_rxbase;
}
void ARM64XEmitter::ReserveCodeSpace(u32 bytes) void ARM64XEmitter::ReserveCodeSpace(u32 bytes)
{ {
for (u32 i = 0; i < bytes / 4; i++) for (u32 i = 0; i < bytes / 4; i++)

View File

@ -556,6 +556,7 @@ public:
const u8* GetRWPtr(); const u8* GetRWPtr();
u8* GetWriteableRWPtr(); u8* GetWriteableRWPtr();
void* GetRXPtr(); void* GetRXPtr();
u8* GetRXBase();
void FlushIcache(); void FlushIcache();
void FlushIcacheSection(u8* start, u8* end); void FlushIcacheSection(u8* start, u8* end);