rewrite JIT memory emulation

This commit is contained in:
RSDuck
2020-05-09 00:45:05 +02:00
parent bcc4b5c8dd
commit 0f53a34551
14 changed files with 1494 additions and 843 deletions

View File

@ -579,7 +579,8 @@ void ARMv5::ExecuteJIT()
while (NDS::ARM9Timestamp < NDS::ARM9Target) while (NDS::ARM9Timestamp < NDS::ARM9Target)
{ {
u32 instrAddr = R[15] - ((CPSR&0x20)?2:4); u32 instrAddr = R[15] - ((CPSR&0x20)?2:4);
if (!ARMJIT::IsMapped<0>(instrAddr)) u32 translatedAddr = ARMJIT::TranslateAddr9(instrAddr);
if (!translatedAddr)
{ {
NDS::ARM9Timestamp = NDS::ARM9Target; NDS::ARM9Timestamp = NDS::ARM9Target;
printf("ARMv5 PC in non executable region %08X\n", R[15]); printf("ARMv5 PC in non executable region %08X\n", R[15]);
@ -589,7 +590,7 @@ void ARMv5::ExecuteJIT()
// hack so Cycles <= 0 becomes Cycles < 0 // hack so Cycles <= 0 becomes Cycles < 0
Cycles = NDS::ARM9Target - NDS::ARM9Timestamp - 1; Cycles = NDS::ARM9Target - NDS::ARM9Timestamp - 1;
ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlockEntry(ARMJIT::TranslateAddr<0>(instrAddr)); ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlockEntry<0>(translatedAddr);
if (block) if (block)
ARM_Dispatch(this, block); ARM_Dispatch(this, block);
else else
@ -722,7 +723,8 @@ void ARMv4::ExecuteJIT()
while (NDS::ARM7Timestamp < NDS::ARM7Target) while (NDS::ARM7Timestamp < NDS::ARM7Target)
{ {
u32 instrAddr = R[15] - ((CPSR&0x20)?2:4); u32 instrAddr = R[15] - ((CPSR&0x20)?2:4);
if (!ARMJIT::IsMapped<1>(instrAddr)) u32 translatedAddr = ARMJIT::TranslateAddr7(instrAddr);
if (!translatedAddr)
{ {
NDS::ARM7Timestamp = NDS::ARM7Target; NDS::ARM7Timestamp = NDS::ARM7Target;
printf("ARMv4 PC in non executable region %08X\n", R[15]); printf("ARMv4 PC in non executable region %08X\n", R[15]);
@ -731,7 +733,7 @@ void ARMv4::ExecuteJIT()
Cycles = NDS::ARM7Target - NDS::ARM7Timestamp - 1; Cycles = NDS::ARM7Target - NDS::ARM7Timestamp - 1;
ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlockEntry(ARMJIT::TranslateAddr<1>(instrAddr)); ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlockEntry<1>(translatedAddr);
if (block) if (block)
ARM_Dispatch(this, block); ARM_Dispatch(this, block);
else else

View File

@ -308,7 +308,7 @@ public:
void DataRead8(u32 addr, u32* val) void DataRead8(u32 addr, u32* val)
{ {
*val = NDS::ARM7Read8(addr); *val = NDS::ARM7Read8(addr);
DataRegion = addr >> 20; DataRegion = addr;
DataCycles = NDS::ARM7MemTimings[addr >> 15][0]; DataCycles = NDS::ARM7MemTimings[addr >> 15][0];
} }
@ -317,7 +317,7 @@ public:
addr &= ~1; addr &= ~1;
*val = NDS::ARM7Read16(addr); *val = NDS::ARM7Read16(addr);
DataRegion = addr >> 20; DataRegion = addr;
DataCycles = NDS::ARM7MemTimings[addr >> 15][0]; DataCycles = NDS::ARM7MemTimings[addr >> 15][0];
} }
@ -326,7 +326,7 @@ public:
addr &= ~3; addr &= ~3;
*val = NDS::ARM7Read32(addr); *val = NDS::ARM7Read32(addr);
DataRegion = addr >> 20; DataRegion = addr;
DataCycles = NDS::ARM7MemTimings[addr >> 15][2]; DataCycles = NDS::ARM7MemTimings[addr >> 15][2];
} }
@ -341,7 +341,7 @@ public:
void DataWrite8(u32 addr, u8 val) void DataWrite8(u32 addr, u8 val)
{ {
NDS::ARM7Write8(addr, val); NDS::ARM7Write8(addr, val);
DataRegion = addr >> 20; DataRegion = addr;
DataCycles = NDS::ARM7MemTimings[addr >> 15][0]; DataCycles = NDS::ARM7MemTimings[addr >> 15][0];
} }
@ -350,7 +350,7 @@ public:
addr &= ~1; addr &= ~1;
NDS::ARM7Write16(addr, val); NDS::ARM7Write16(addr, val);
DataRegion = addr >> 20; DataRegion = addr;
DataCycles = NDS::ARM7MemTimings[addr >> 15][0]; DataCycles = NDS::ARM7MemTimings[addr >> 15][0];
} }
@ -359,7 +359,7 @@ public:
addr &= ~3; addr &= ~3;
NDS::ARM7Write32(addr, val); NDS::ARM7Write32(addr, val);
DataRegion = addr >> 20; DataRegion = addr;
DataCycles = NDS::ARM7MemTimings[addr >> 15][2]; DataCycles = NDS::ARM7MemTimings[addr >> 15][2];
} }
@ -390,7 +390,7 @@ public:
s32 numC = NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2]; s32 numC = NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2];
s32 numD = DataCycles; s32 numD = DataCycles;
if ((DataRegion >> 4) == 0x02) // mainRAM if ((DataRegion >> 24) == 0x02) // mainRAM
{ {
if (CodeRegion == 0x02) if (CodeRegion == 0x02)
Cycles -= numC + numD; Cycles -= numC + numD;
@ -417,7 +417,7 @@ public:
s32 numC = NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2]; s32 numC = NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2];
s32 numD = DataCycles; s32 numD = DataCycles;
if ((DataRegion >> 4) == 0x02) if ((DataRegion >> 24) == 0x02)
{ {
if (CodeRegion == 0x02) if (CodeRegion == 0x02)
Cycles -= numC + numD; Cycles -= numC + numD;
@ -443,4 +443,12 @@ void T_UNK(ARM* cpu);
} }
namespace NDS
{
extern ARMv5* ARM9;
extern ARMv4* ARM7;
}
#endif // ARM_H #endif // ARM_H

File diff suppressed because it is too large Load Diff

View File

@ -28,45 +28,60 @@ extern const u32 ExeMemRegionSizes[];
typedef u32 (*JitBlockEntry)(); typedef u32 (*JitBlockEntry)();
extern u32 AddrTranslate9[0x2000];
extern u32 AddrTranslate7[0x4000];
const u32 ExeMemSpaceSize = 0x518000; // I hate you C++, sometimes I really hate you... const u32 ExeMemSpaceSize = 0x518000; // I hate you C++, sometimes I really hate you...
template <u32 num> u32 TranslateAddr9(u32 addr);
inline bool IsMapped(u32 addr) u32 TranslateAddr7(u32 addr);
{
if (num == 0)
return AddrTranslate9[(addr & 0xFFFFFFF) >> 15] >= ExeMemRegionSizes[exeMem_Unmapped];
else
return AddrTranslate7[(addr & 0xFFFFFFF) >> 14] >= ExeMemRegionSizes[exeMem_Unmapped];
}
template <u32 num>
inline u32 TranslateAddr(u32 addr)
{
if (num == 0)
return AddrTranslate9[(addr & 0xFFFFFFF) >> 15] + (addr & 0x7FFF);
else
return AddrTranslate7[(addr & 0xFFFFFFF) >> 14] + (addr & 0x3FFF);
}
template <u32 Num>
JitBlockEntry LookUpBlockEntry(u32 addr); JitBlockEntry LookUpBlockEntry(u32 addr);
void Init(); void Init();
void DeInit(); void DeInit();
void InvalidateByAddr(u32 pseudoPhysical, bool mayRestore = true); void Reset();
void InvalidateAll();
void InvalidateITCM(u32 addr); void InvalidateByAddr(u32 pseudoPhysical);
void InvalidateByAddr7(u32 addr);
void InvalidateRegionIfNecessary(u32 addr);
inline void InvalidateMainRAMIfNecessary(u32 addr)
{
InvalidateRegionIfNecessary(ExeMemRegionOffsets[exeMem_MainRAM] + (addr & (MAIN_RAM_SIZE - 1)));
}
inline void InvalidateITCMIfNecessary(u32 addr)
{
InvalidateRegionIfNecessary(ExeMemRegionOffsets[exeMem_ITCM] + (addr & 0x7FFF));
}
inline void InvalidateLCDCIfNecessary(u32 addr)
{
if (addr < 0x68A3FFF)
InvalidateRegionIfNecessary(ExeMemRegionOffsets[exeMem_LCDC] + (addr - 0x6800000));
}
inline void InvalidateSWRAM7IfNecessary(u32 addr)
{
InvalidateRegionIfNecessary(ExeMemRegionOffsets[exeMem_SWRAM] + (NDS::SWRAM_ARM7 - NDS::SharedWRAM) + (addr & NDS::SWRAM_ARM7Mask));
}
inline void InvalidateSWRAM9IfNecessary(u32 addr)
{
InvalidateRegionIfNecessary(ExeMemRegionOffsets[exeMem_SWRAM] + (NDS::SWRAM_ARM9 - NDS::SharedWRAM) + (addr & NDS::SWRAM_ARM9Mask));
}
inline void InvalidateARM7WRAMIfNecessary(u32 addr)
{
InvalidateRegionIfNecessary(ExeMemRegionOffsets[exeMem_ARM7_WRAM] + (addr & 0xFFFF));
}
inline void InvalidateARM7WVRAMIfNecessary(u32 addr)
{
InvalidateRegionIfNecessary(ExeMemRegionOffsets[exeMem_ARM7_WVRAM] + (addr & 0x1FFFF));
}
void CompileBlock(ARM* cpu); void CompileBlock(ARM* cpu);
void ResetBlockCache(); void ResetBlockCache();
void UpdateMemoryStatus9(u32 start, u32 end);
void UpdateMemoryStatus7(u32 start, u32 end);
} }
extern "C" void ARM_Dispatch(ARM* cpu, ARMJIT::JitBlockEntry entry); extern "C" void ARM_Dispatch(ARM* cpu, ARMJIT::JitBlockEntry entry);

View File

@ -650,7 +650,7 @@ void Compiler::Comp_AddCycles_CDI()
s32 numC = NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]; s32 numC = NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2];
s32 numD = CurInstr.DataCycles; s32 numD = CurInstr.DataCycles;
if ((CurInstr.DataRegion >> 4) == 0x02) // mainRAM if ((CurInstr.DataRegion >> 24) == 0x02) // mainRAM
{ {
if (CodeRegion == 0x02) if (CodeRegion == 0x02)
cycles = numC + numD; cycles = numC + numD;
@ -695,7 +695,7 @@ void Compiler::Comp_AddCycles_CD()
s32 numC = NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]; s32 numC = NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2];
s32 numD = CurInstr.DataCycles; s32 numD = CurInstr.DataCycles;
if ((CurInstr.DataRegion >> 4) == 0x02) if ((CurInstr.DataRegion >> 24) == 0x02)
{ {
if (CodeRegion == 0x02) if (CodeRegion == 0x02)
cycles += numC + numD; cycles += numC + numD;

View File

@ -152,30 +152,34 @@ struct __attribute__((packed)) TinyVector
class JitBlock class JitBlock
{ {
public: public:
JitBlock(u32 numInstrs, u32 numAddresses) JitBlock(u32 num, u32 literalHash, u32 numAddresses, u32 numLiterals)
{ {
NumInstrs = numInstrs; Num = num;
NumAddresses = numAddresses; NumAddresses = numAddresses;
Data.SetLength(numInstrs + numAddresses); NumLiterals = numLiterals;
Data.SetLength(numAddresses * 2 + numLiterals);
} }
u32 StartAddr;
u32 PseudoPhysicalAddr; u32 PseudoPhysicalAddr;
u32 NumInstrs; u32 InstrHash, LiteralHash;
u32 NumAddresses; u8 Num;
u16 NumAddresses;
u16 NumLiterals;
JitBlockEntry EntryPoint; JitBlockEntry EntryPoint;
u32* Instrs()
{ return &Data[0]; }
u32* AddressRanges() u32* AddressRanges()
{ return &Data[NumInstrs]; } { return &Data[0]; }
u32* AddressMasks()
{ return &Data[NumAddresses]; }
u32* Literals()
{ return &Data[NumAddresses * 2]; }
u32* Links() u32* Links()
{ return &Data[NumInstrs + NumAddresses]; } { return &Data[NumAddresses * 2 + NumLiterals]; }
u32 NumLinks() u32 NumLinks()
{ return Data.Length - NumInstrs - NumAddresses; } { return Data.Length - NumAddresses * 2 - NumLiterals; }
void AddLink(u32 link) void AddLink(u32 link)
{ {
@ -184,7 +188,7 @@ public:
void ResetLinks() void ResetLinks()
{ {
Data.SetLength(NumInstrs + NumAddresses); Data.SetLength(NumAddresses * 2 + NumLiterals);
} }
private: private:
@ -200,8 +204,7 @@ private:
struct __attribute__((packed)) AddressRange struct __attribute__((packed)) AddressRange
{ {
TinyVector<JitBlock*> Blocks; TinyVector<JitBlock*> Blocks;
u16 InvalidLiterals; u32 Code;
u16 TimesInvalidated;
}; };
extern AddressRange CodeRanges[ExeMemSpaceSize / 512]; extern AddressRange CodeRanges[ExeMemSpaceSize / 512];
@ -210,14 +213,45 @@ typedef void (*InterpreterFunc)(ARM* cpu);
extern InterpreterFunc InterpretARM[]; extern InterpreterFunc InterpretARM[];
extern InterpreterFunc InterpretTHUMB[]; extern InterpreterFunc InterpretTHUMB[];
extern u8 MemRegion9[0x80000]; extern u8 MemoryStatus9[0x800000];
extern u8 MemRegion7[0x80000]; extern u8 MemoryStatus7[0x800000];
extern TinyVector<u32> InvalidLiterals;
void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size); void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size);
template <u32 Num> template <u32 Num>
void LinkBlock(ARM* cpu, u32 codeOffset); void LinkBlock(ARM* cpu, u32 codeOffset);
enum
{
memregion_Other = 0,
memregion_ITCM,
memregion_DTCM,
memregion_BIOS9,
memregion_MainRAM,
memregion_SWRAM9,
memregion_SWRAM7,
memregion_IO9,
memregion_VRAM,
memregion_BIOS7,
memregion_WRAM7,
memregion_IO7,
memregion_Wifi,
memregion_VWRAM,
};
int ClassifyAddress9(u32 addr);
int ClassifyAddress7(u32 addr);
template <typename T> T SlowRead9(ARMv5* cpu, u32 addr);
template <typename T> void SlowWrite9(ARMv5* cpu, u32 addr, T val);
template <typename T> T SlowRead7(u32 addr);
template <typename T> void SlowWrite7(u32 addr, T val);
template <bool PreInc, bool Write> void SlowBlockTransfer9(u32 addr, u64* data, u32 num, ARMv5* cpu);
template <bool PreInc, bool Write> void SlowBlockTransfer7(u32 addr, u64* data, u32 num);
} }
#endif #endif

View File

@ -95,20 +95,6 @@ public:
LiteralsLoaded = 0; LiteralsLoaded = 0;
} }
BitSet32 GetPushRegs()
{
BitSet16 used;
for (int i = 0; i < InstrsCount; i++)
used |= BitSet16(Instrs[i].Info.SrcRegs | Instrs[i].Info.DstRegs);
BitSet32 res;
u32 registersMax = std::min((int)used.Count(), NativeRegsAvailable);
for (int i = 0; i < registersMax; i++)
res |= BitSet32(1 << (int)NativeRegAllocOrder[i]);
return res;
}
void Prepare(bool thumb, int i) void Prepare(bool thumb, int i)
{ {
FetchedInstr instr = Instrs[i]; FetchedInstr instr = Instrs[i];
@ -139,7 +125,6 @@ public:
UnloadRegister(reg); UnloadRegister(reg);
u16 necessaryRegs = ((instr.Info.SrcRegs & PCAllocatableAsSrc) | instr.Info.DstRegs) & ~instr.Info.NotStrictlyNeeded; u16 necessaryRegs = ((instr.Info.SrcRegs & PCAllocatableAsSrc) | instr.Info.DstRegs) & ~instr.Info.NotStrictlyNeeded;
u16 writeRegs = instr.Info.DstRegs & ~instr.Info.NotStrictlyNeeded;
BitSet16 needToBeLoaded(necessaryRegs & ~LoadedRegs); BitSet16 needToBeLoaded(necessaryRegs & ~LoadedRegs);
if (needToBeLoaded != BitSet16(0)) if (needToBeLoaded != BitSet16(0))
{ {
@ -182,13 +167,12 @@ public:
if (left-- == 0) if (left-- == 0)
break; break;
writeRegs |= (1 << reg) & instr.Info.DstRegs;
LoadRegister(reg, !(thumb || instr.Cond() >= 0xE) || (1 << reg) & instr.Info.SrcRegs); LoadRegister(reg, !(thumb || instr.Cond() >= 0xE) || (1 << reg) & instr.Info.SrcRegs);
} }
} }
} }
DirtyRegs |= writeRegs & ~(1 << 15); DirtyRegs |= (LoadedRegs & instr.Info.DstRegs) & ~(1 << 15);
} }
static const Reg NativeRegAllocOrder[]; static const Reg NativeRegAllocOrder[];

View File

@ -195,26 +195,6 @@ Compiler::Compiler()
Reset(); Reset();
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
MemoryFuncs9[i][j] = Gen_MemoryRoutine9(j, 8 << i);
}
MemoryFuncs7[0][0] = (void*)NDS::ARM7Read8;
MemoryFuncs7[0][1] = (void*)NDS::ARM7Write8;
MemoryFuncs7[1][0] = (void*)NDS::ARM7Read16;
MemoryFuncs7[1][1] = (void*)NDS::ARM7Write16;
MemoryFuncs7[2][0] = (void*)NDS::ARM7Read32;
MemoryFuncs7[2][1] = (void*)NDS::ARM7Write32;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
{
MemoryFuncsSeq9[i][j] = Gen_MemoryRoutineSeq9(i, j);
MemoryFuncsSeq7[i][j][0] = Gen_MemoryRoutineSeq7(i, j, false);
MemoryFuncsSeq7[i][j][1] = Gen_MemoryRoutineSeq7(i, j, true);
}
{ {
// RSCRATCH mode // RSCRATCH mode
// RSCRATCH2 reg number // RSCRATCH2 reg number
@ -317,6 +297,12 @@ Compiler::Compiler()
// move the region forward to prevent overwriting the generated functions // move the region forward to prevent overwriting the generated functions
CodeMemSize -= GetWritableCodePtr() - ResetStart; CodeMemSize -= GetWritableCodePtr() - ResetStart;
ResetStart = GetWritableCodePtr(); ResetStart = GetWritableCodePtr();
NearStart = ResetStart;
FarStart = ResetStart + 1024*1024*24;
NearSize = FarStart - ResetStart;
FarSize = (ResetStart + CodeMemSize) - FarStart;
} }
void Compiler::LoadCPSR() void Compiler::LoadCPSR()
@ -504,6 +490,9 @@ void Compiler::Reset()
{ {
memset(ResetStart, 0xcc, CodeMemSize); memset(ResetStart, 0xcc, CodeMemSize);
SetCodePtr(ResetStart); SetCodePtr(ResetStart);
NearCode = NearStart;
FarCode = FarStart;
} }
void Compiler::Comp_SpecialBranchBehaviour(bool taken) void Compiler::Comp_SpecialBranchBehaviour(bool taken)
@ -544,8 +533,16 @@ void Compiler::Comp_SpecialBranchBehaviour(bool taken)
JitBlockEntry Compiler::CompileBlock(u32 translatedAddr, ARM* cpu, bool thumb, FetchedInstr instrs[], int instrsCount) JitBlockEntry Compiler::CompileBlock(u32 translatedAddr, ARM* cpu, bool thumb, FetchedInstr instrs[], int instrsCount)
{ {
if (CodeMemSize - (GetWritableCodePtr() - ResetStart) < 1024 * 32) // guess... if (NearSize - (NearCode - NearStart) < 1024 * 32) // guess...
{
printf("near reset\n");
ResetBlockCache(); ResetBlockCache();
}
if (FarSize - (FarCode - FarStart) < 1024 * 32) // guess...
{
printf("far reset\n");
ResetBlockCache();
}
ConstantCycles = 0; ConstantCycles = 0;
Thumb = thumb; Thumb = thumb;
@ -762,12 +759,14 @@ void Compiler::Comp_AddCycles_CDI()
Comp_AddCycles_CD(); Comp_AddCycles_CD();
else else
{ {
IrregularCycles = true;
s32 cycles; s32 cycles;
s32 numC = NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]; s32 numC = NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2];
s32 numD = CurInstr.DataCycles; s32 numD = CurInstr.DataCycles;
if ((CurInstr.DataRegion >> 4) == 0x02) // mainRAM if ((CurInstr.DataRegion >> 24) == 0x02) // mainRAM
{ {
if (CodeRegion == 0x02) if (CodeRegion == 0x02)
cycles = numC + numD; cycles = numC + numD;

View File

@ -140,7 +140,7 @@ public:
}; };
void Comp_MemAccess(int rd, int rn, const ComplexOperand& op2, int size, int flags); void Comp_MemAccess(int rd, int rn, const ComplexOperand& op2, int size, int flags);
s32 Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode); s32 Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode);
void Comp_MemLoadLiteral(int size, int rd, u32 addr); bool Comp_MemLoadLiteral(int size, int rd, u32 addr);
void Comp_ArithTriOp(void (Compiler::*op)(int, const Gen::OpArg&, const Gen::OpArg&), void Comp_ArithTriOp(void (Compiler::*op)(int, const Gen::OpArg&, const Gen::OpArg&),
Gen::OpArg rd, Gen::OpArg rn, Gen::OpArg op2, bool carryUsed, int opFlags); Gen::OpArg rd, Gen::OpArg rn, Gen::OpArg op2, bool carryUsed, int opFlags);
@ -154,12 +154,6 @@ public:
void Comp_SpecialBranchBehaviour(bool taken); void Comp_SpecialBranchBehaviour(bool taken);
void* Gen_MemoryRoutine9(bool store, int size);
void* Gen_MemoryRoutineSeq9(bool store, bool preinc);
void* Gen_MemoryRoutineSeq7(bool store, bool preinc, bool codeMainRAM);
void* Gen_ChangeCPSRRoutine();
Gen::OpArg Comp_RegShiftImm(int op, int amount, Gen::OpArg rm, bool S, bool& carryUsed); Gen::OpArg Comp_RegShiftImm(int op, int amount, Gen::OpArg rm, bool S, bool& carryUsed);
Gen::OpArg Comp_RegShiftReg(int op, Gen::OpArg rs, Gen::OpArg rm, bool S, bool& carryUsed); Gen::OpArg Comp_RegShiftReg(int op, Gen::OpArg rs, Gen::OpArg rm, bool S, bool& carryUsed);
@ -193,6 +187,26 @@ public:
return (u8*)entry - ResetStart; return (u8*)entry - ResetStart;
} }
void SwitchToNearCode()
{
FarCode = GetWritableCodePtr();
SetCodePtr(NearCode);
}
void SwitchToFarCode()
{
NearCode = GetWritableCodePtr();
SetCodePtr(FarCode);
}
u8* FarCode;
u8* NearCode;
u32 FarSize;
u32 NearSize;
u8* NearStart;
u8* FarStart;
u8* ResetStart; u8* ResetStart;
u32 CodeMemSize; u32 CodeMemSize;
@ -201,12 +215,6 @@ public:
void* BranchStub[2]; void* BranchStub[2];
void* MemoryFuncs9[3][2];
void* MemoryFuncs7[3][2];
void* MemoryFuncsSeq9[2][2];
void* MemoryFuncsSeq7[2][2][2];
void* ReadBanked; void* ReadBanked;
void* WriteBanked; void* WriteBanked;

File diff suppressed because it is too large Load Diff

View File

@ -373,16 +373,16 @@ Info Decode(bool thumb, u32 num, u32 instr)
if (res.Kind == tk_LDMIA || res.Kind == tk_POP) if (res.Kind == tk_LDMIA || res.Kind == tk_POP)
{ {
u32 set = (instr & 0xFF) & ~(res.DstRegs|res.SrcRegs); u32 set = (instr & 0xFF);
res.NotStrictlyNeeded |= set; res.NotStrictlyNeeded |= set & ~(res.DstRegs|res.SrcRegs);
res.DstRegs |= set; res.DstRegs |= set;
} }
if (res.Kind == tk_STMIA || res.Kind == tk_PUSH) if (res.Kind == tk_STMIA || res.Kind == tk_PUSH)
{ {
u32 set = (instr & 0xFF) & ~(res.DstRegs|res.SrcRegs); u32 set = (instr & 0xFF);
if (res.Kind == tk_PUSH && instr & (1 << 8)) if (res.Kind == tk_PUSH && instr & (1 << 8))
set |= (1 << 14); set |= (1 << 14);
res.NotStrictlyNeeded |= set; res.NotStrictlyNeeded |= set & ~(res.DstRegs|res.SrcRegs);
res.SrcRegs |= set; res.SrcRegs |= set;
} }
@ -495,15 +495,15 @@ Info Decode(bool thumb, u32 num, u32 instr)
if (res.Kind == ak_LDM) if (res.Kind == ak_LDM)
{ {
u16 set = (instr & 0xFFFF) & ~(res.SrcRegs|res.DstRegs|(1<<15)); u16 set = (instr & 0xFFFF);
res.NotStrictlyNeeded |= set & ~(res.SrcRegs|res.DstRegs|(1<<15));
res.DstRegs |= set; res.DstRegs |= set;
res.NotStrictlyNeeded |= set;
} }
if (res.Kind == ak_STM) if (res.Kind == ak_STM)
{ {
u16 set = (instr & 0xFFFF) & ~(res.SrcRegs|res.DstRegs|(1<<15)); u16 set = (instr & 0xFFFF);
res.NotStrictlyNeeded |= set & ~(res.SrcRegs|res.DstRegs|(1<<15));
res.SrcRegs |= set; res.SrcRegs |= set;
res.NotStrictlyNeeded |= set;
} }
if ((instr >> 28) < 0xE) if ((instr >> 28) < 0xE)

View File

@ -97,6 +97,10 @@ void ARMv5::CP15DoSavestate(Savestate* file)
void ARMv5::UpdateDTCMSetting() void ARMv5::UpdateDTCMSetting()
{ {
#ifdef JIT_ENABLED
u32 oldDTCMBase = DTCMBase;
u32 oldDTCMSize = DTCMSize;
#endif
if (CP15Control & (1<<16)) if (CP15Control & (1<<16))
{ {
DTCMBase = DTCMSetting & 0xFFFFF000; DTCMBase = DTCMSetting & 0xFFFFF000;
@ -109,10 +113,20 @@ void ARMv5::UpdateDTCMSetting()
DTCMSize = 0; DTCMSize = 0;
//printf("DTCM disabled\n"); //printf("DTCM disabled\n");
} }
#ifdef JIT_ENABLED
if (oldDTCMBase != DTCMBase || oldDTCMSize != DTCMSize)
{
ARMJIT::UpdateMemoryStatus9(oldDTCMBase, oldDTCMBase + oldDTCMSize);
ARMJIT::UpdateMemoryStatus9(DTCMBase, DTCMBase + DTCMSize);
}
#endif
} }
void ARMv5::UpdateITCMSetting() void ARMv5::UpdateITCMSetting()
{ {
#ifdef JIT_ENABLED
u32 oldITCMSize = ITCMSize;
#endif
if (CP15Control & (1<<18)) if (CP15Control & (1<<18))
{ {
ITCMSize = 0x200 << ((ITCMSetting >> 1) & 0x1F); ITCMSize = 0x200 << ((ITCMSetting >> 1) & 0x1F);
@ -123,6 +137,10 @@ void ARMv5::UpdateITCMSetting()
ITCMSize = 0; ITCMSize = 0;
//printf("ITCM disabled\n"); //printf("ITCM disabled\n");
} }
#ifdef JIT_ENABLED
if (oldITCMSize != ITCMSize)
ARMJIT::UpdateMemoryStatus9(0, std::max(oldITCMSize, ITCMSize));
#endif
} }
@ -561,15 +579,9 @@ void ARMv5::CP15Write(u32 id, u32 val)
case 0x750: case 0x750:
#ifdef JIT_ENABLED
ARMJIT::InvalidateAll();
#endif
ICacheInvalidateAll(); ICacheInvalidateAll();
return; return;
case 0x751: case 0x751:
#ifdef JIT_ENABLED
ARMJIT::InvalidateByAddr(ARMJIT::TranslateAddr<0>(val));
#endif
ICacheInvalidateByAddr(val); ICacheInvalidateByAddr(val);
return; return;
case 0x752: case 0x752:
@ -732,7 +744,7 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch)
void ARMv5::DataRead8(u32 addr, u32* val) void ARMv5::DataRead8(u32 addr, u32* val)
{ {
DataRegion = addr >> 12; DataRegion = addr;
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
@ -753,7 +765,7 @@ void ARMv5::DataRead8(u32 addr, u32* val)
void ARMv5::DataRead16(u32 addr, u32* val) void ARMv5::DataRead16(u32 addr, u32* val)
{ {
DataRegion = addr >> 12; DataRegion = addr;
addr &= ~1; addr &= ~1;
@ -776,7 +788,7 @@ void ARMv5::DataRead16(u32 addr, u32* val)
void ARMv5::DataRead32(u32 addr, u32* val) void ARMv5::DataRead32(u32 addr, u32* val)
{ {
DataRegion = addr >> 12; DataRegion = addr;
addr &= ~3; addr &= ~3;
@ -820,14 +832,14 @@ void ARMv5::DataRead32S(u32 addr, u32* val)
void ARMv5::DataWrite8(u32 addr, u8 val) void ARMv5::DataWrite8(u32 addr, u8 val)
{ {
DataRegion = addr >> 12; DataRegion = addr;
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
DataCycles = 1; DataCycles = 1;
*(u8*)&ITCM[addr & 0x7FFF] = val; *(u8*)&ITCM[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
ARMJIT::InvalidateITCM(addr & 0x7FFF); ARMJIT::InvalidateITCMIfNecessary(addr);
#endif #endif
return; return;
} }
@ -844,7 +856,7 @@ void ARMv5::DataWrite8(u32 addr, u8 val)
void ARMv5::DataWrite16(u32 addr, u16 val) void ARMv5::DataWrite16(u32 addr, u16 val)
{ {
DataRegion = addr >> 12; DataRegion = addr;
addr &= ~1; addr &= ~1;
@ -853,7 +865,7 @@ void ARMv5::DataWrite16(u32 addr, u16 val)
DataCycles = 1; DataCycles = 1;
*(u16*)&ITCM[addr & 0x7FFF] = val; *(u16*)&ITCM[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
ARMJIT::InvalidateITCM(addr & 0x7FFF); ARMJIT::InvalidateITCMIfNecessary(addr);
#endif #endif
return; return;
} }
@ -870,7 +882,7 @@ void ARMv5::DataWrite16(u32 addr, u16 val)
void ARMv5::DataWrite32(u32 addr, u32 val) void ARMv5::DataWrite32(u32 addr, u32 val)
{ {
DataRegion = addr >> 12; DataRegion = addr;
addr &= ~3; addr &= ~3;
@ -879,7 +891,7 @@ void ARMv5::DataWrite32(u32 addr, u32 val)
DataCycles = 1; DataCycles = 1;
*(u32*)&ITCM[addr & 0x7FFF] = val; *(u32*)&ITCM[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
ARMJIT::InvalidateITCM(addr & 0x7FFF); ARMJIT::InvalidateITCMIfNecessary(addr);
#endif #endif
return; return;
} }
@ -903,7 +915,7 @@ void ARMv5::DataWrite32S(u32 addr, u32 val)
DataCycles += 1; DataCycles += 1;
*(u32*)&ITCM[addr & 0x7FFF] = val; *(u32*)&ITCM[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
ARMJIT::InvalidateITCM(addr & 0x7FFF); ARMJIT::InvalidateITCMIfNecessary(addr);
#endif #endif
return; return;
} }

View File

@ -535,10 +535,6 @@ void Reset()
KeyCnt = 0; KeyCnt = 0;
RCnt = 0; RCnt = 0;
#ifdef JIT_ENABLED
ARMJIT::ResetBlockCache();
#endif
NDSCart::Reset(); NDSCart::Reset();
GBACart::Reset(); GBACart::Reset();
GPU::Reset(); GPU::Reset();
@ -548,6 +544,10 @@ void Reset()
Wifi::Reset(); Wifi::Reset();
AREngine::Reset(); AREngine::Reset();
#ifdef JIT_ENABLED
ARMJIT::Reset();
#endif
} }
void Stop() void Stop()
@ -1058,6 +1058,9 @@ void Halt()
void MapSharedWRAM(u8 val) void MapSharedWRAM(u8 val)
{ {
if (val == WRAMCnt)
return;
WRAMCnt = val; WRAMCnt = val;
switch (WRAMCnt & 0x3) switch (WRAMCnt & 0x3)
@ -1090,6 +1093,11 @@ void MapSharedWRAM(u8 val)
SWRAM_ARM7Mask = 0x7FFF; SWRAM_ARM7Mask = 0x7FFF;
break; break;
} }
#ifdef JIT_ENABLED
ARMJIT::UpdateMemoryStatus9(0x3000000, 0x3000000 + 0x1000000);
ARMJIT::UpdateMemoryStatus7(0x3000000, 0x3000000 + 0x1000000);
#endif
} }
@ -1873,12 +1881,18 @@ void ARM9Write8(u32 addr, u8 val)
switch (addr & 0xFF000000) switch (addr & 0xFF000000)
{ {
case 0x02000000: case 0x02000000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
*(u8*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; *(u8*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
return; return;
case 0x03000000: case 0x03000000:
if (SWRAM_ARM9) if (SWRAM_ARM9)
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateSWRAM9IfNecessary(addr);
#endif
*(u8*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask] = val; *(u8*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask] = val;
} }
return; return;
@ -1923,12 +1937,18 @@ void ARM9Write16(u32 addr, u16 val)
switch (addr & 0xFF000000) switch (addr & 0xFF000000)
{ {
case 0x02000000: case 0x02000000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
*(u16*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; *(u16*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
return; return;
case 0x03000000: case 0x03000000:
if (SWRAM_ARM9) if (SWRAM_ARM9)
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateSWRAM9IfNecessary(addr);
#endif
*(u16*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask] = val; *(u16*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask] = val;
} }
return; return;
@ -1949,7 +1969,12 @@ void ARM9Write16(u32 addr, u16 val)
case 0x00200000: GPU::WriteVRAM_BBG<u16>(addr, val); return; case 0x00200000: GPU::WriteVRAM_BBG<u16>(addr, val); return;
case 0x00400000: GPU::WriteVRAM_AOBJ<u16>(addr, val); return; case 0x00400000: GPU::WriteVRAM_AOBJ<u16>(addr, val); return;
case 0x00600000: GPU::WriteVRAM_BOBJ<u16>(addr, val); return; case 0x00600000: GPU::WriteVRAM_BOBJ<u16>(addr, val); return;
default: GPU::WriteVRAM_LCDC<u16>(addr, val); return; default:
#ifdef JIT_ENABLED
ARMJIT::InvalidateLCDCIfNecessary(addr);
#endif
GPU::WriteVRAM_LCDC<u16>(addr, val);
return;
} }
case 0x07000000: case 0x07000000:
@ -1989,12 +2014,18 @@ void ARM9Write32(u32 addr, u32 val)
switch (addr & 0xFF000000) switch (addr & 0xFF000000)
{ {
case 0x02000000: case 0x02000000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
*(u32*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; *(u32*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
return ; return ;
case 0x03000000: case 0x03000000:
if (SWRAM_ARM9) if (SWRAM_ARM9)
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateSWRAM9IfNecessary(addr);
#endif
*(u32*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask] = val; *(u32*)&SWRAM_ARM9[addr & SWRAM_ARM9Mask] = val;
} }
return; return;
@ -2015,7 +2046,12 @@ void ARM9Write32(u32 addr, u32 val)
case 0x00200000: GPU::WriteVRAM_BBG<u32>(addr, val); return; case 0x00200000: GPU::WriteVRAM_BBG<u32>(addr, val); return;
case 0x00400000: GPU::WriteVRAM_AOBJ<u32>(addr, val); return; case 0x00400000: GPU::WriteVRAM_AOBJ<u32>(addr, val); return;
case 0x00600000: GPU::WriteVRAM_BOBJ<u32>(addr, val); return; case 0x00600000: GPU::WriteVRAM_BOBJ<u32>(addr, val); return;
default: GPU::WriteVRAM_LCDC<u32>(addr, val); return; default:
#ifdef JIT_ENABLED
ARMJIT::InvalidateLCDCIfNecessary(addr);
#endif
GPU::WriteVRAM_LCDC<u32>(addr, val);
return;
} }
case 0x07000000: case 0x07000000:
@ -2279,30 +2315,38 @@ u32 ARM7Read32(u32 addr)
void ARM7Write8(u32 addr, u8 val) void ARM7Write8(u32 addr, u8 val)
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateByAddr7(addr);
#endif
switch (addr & 0xFF800000) switch (addr & 0xFF800000)
{ {
case 0x02000000: case 0x02000000:
case 0x02800000: case 0x02800000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
*(u8*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; *(u8*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
return; return;
case 0x03000000: case 0x03000000:
if (SWRAM_ARM7) if (SWRAM_ARM7)
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateSWRAM7IfNecessary(addr);
#endif
*(u8*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask] = val; *(u8*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask] = val;
return; return;
} }
else else
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateARM7WRAMIfNecessary(addr);
#endif
*(u8*)&ARM7WRAM[addr & 0xFFFF] = val; *(u8*)&ARM7WRAM[addr & 0xFFFF] = val;
return; return;
} }
case 0x03800000: case 0x03800000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateARM7WRAMIfNecessary(addr);
#endif
*(u8*)&ARM7WRAM[addr & 0xFFFF] = val; *(u8*)&ARM7WRAM[addr & 0xFFFF] = val;
return; return;
@ -2312,6 +2356,9 @@ void ARM7Write8(u32 addr, u8 val)
case 0x06000000: case 0x06000000:
case 0x06800000: case 0x06800000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateARM7WVRAMIfNecessary(addr);
#endif
GPU::WriteVRAM_ARM7<u8>(addr, val); GPU::WriteVRAM_ARM7<u8>(addr, val);
return; return;
@ -2342,30 +2389,38 @@ void ARM7Write8(u32 addr, u8 val)
void ARM7Write16(u32 addr, u16 val) void ARM7Write16(u32 addr, u16 val)
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateByAddr7(addr);
#endif
switch (addr & 0xFF800000) switch (addr & 0xFF800000)
{ {
case 0x02000000: case 0x02000000:
case 0x02800000: case 0x02800000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
*(u16*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; *(u16*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
return; return;
case 0x03000000: case 0x03000000:
if (SWRAM_ARM7) if (SWRAM_ARM7)
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateSWRAM7IfNecessary(addr);
#endif
*(u16*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask] = val; *(u16*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask] = val;
return; return;
} }
else else
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateARM7WRAMIfNecessary(addr);
#endif
*(u16*)&ARM7WRAM[addr & 0xFFFF] = val; *(u16*)&ARM7WRAM[addr & 0xFFFF] = val;
return; return;
} }
case 0x03800000: case 0x03800000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateARM7WRAMIfNecessary(addr);
#endif
*(u16*)&ARM7WRAM[addr & 0xFFFF] = val; *(u16*)&ARM7WRAM[addr & 0xFFFF] = val;
return; return;
@ -2383,6 +2438,9 @@ void ARM7Write16(u32 addr, u16 val)
case 0x06000000: case 0x06000000:
case 0x06800000: case 0x06800000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateARM7WVRAMIfNecessary(addr);
#endif
GPU::WriteVRAM_ARM7<u16>(addr, val); GPU::WriteVRAM_ARM7<u16>(addr, val);
return; return;
@ -2415,30 +2473,38 @@ void ARM7Write16(u32 addr, u16 val)
void ARM7Write32(u32 addr, u32 val) void ARM7Write32(u32 addr, u32 val)
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateByAddr7(addr);
#endif
switch (addr & 0xFF800000) switch (addr & 0xFF800000)
{ {
case 0x02000000: case 0x02000000:
case 0x02800000: case 0x02800000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
*(u32*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; *(u32*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
return; return;
case 0x03000000: case 0x03000000:
if (SWRAM_ARM7) if (SWRAM_ARM7)
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateSWRAM7IfNecessary(addr);
#endif
*(u32*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask] = val; *(u32*)&SWRAM_ARM7[addr & SWRAM_ARM7Mask] = val;
return; return;
} }
else else
{ {
#ifdef JIT_ENABLED
ARMJIT::InvalidateARM7WRAMIfNecessary(addr);
#endif
*(u32*)&ARM7WRAM[addr & 0xFFFF] = val; *(u32*)&ARM7WRAM[addr & 0xFFFF] = val;
return; return;
} }
case 0x03800000: case 0x03800000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateARM7WRAMIfNecessary(addr);
#endif
*(u32*)&ARM7WRAM[addr & 0xFFFF] = val; *(u32*)&ARM7WRAM[addr & 0xFFFF] = val;
return; return;
@ -2457,6 +2523,9 @@ void ARM7Write32(u32 addr, u32 val)
case 0x06000000: case 0x06000000:
case 0x06800000: case 0x06800000:
#ifdef JIT_ENABLED
ARMJIT::InvalidateARM7WVRAMIfNecessary(addr);
#endif
GPU::WriteVRAM_ARM7<u32>(addr, val); GPU::WriteVRAM_ARM7<u32>(addr, val);
return; return;

View File

@ -120,6 +120,14 @@ extern u8 ROMSeed1[2*8];
extern u8 ARM9BIOS[0x1000]; extern u8 ARM9BIOS[0x1000];
extern u8 ARM7BIOS[0x4000]; extern u8 ARM7BIOS[0x4000];
extern u8 SharedWRAM[0x8000];
extern u8* SWRAM_ARM9;
extern u8* SWRAM_ARM7;
extern u32 SWRAM_ARM9Mask;
extern u32 SWRAM_ARM7Mask;
extern u8 ARM7WRAM[0x10000];
#define MAIN_RAM_SIZE 0x400000 #define MAIN_RAM_SIZE 0x400000
extern u8 MainRAM[MAIN_RAM_SIZE]; extern u8 MainRAM[MAIN_RAM_SIZE];