mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-23 14:19:55 -06:00
JIT: handle STR post with rd == rn
fixes Zelda Four Swords
This commit is contained in:
@ -174,10 +174,13 @@ void Compiler::PopRegs(bool saveHiRegs)
|
|||||||
{
|
{
|
||||||
if (saveHiRegs)
|
if (saveHiRegs)
|
||||||
{
|
{
|
||||||
BitSet16 hiRegsLoaded(RegCache.LoadedRegs & 0x7F00);
|
if (!Thumb && CurInstr.Cond() != 0xE)
|
||||||
|
{
|
||||||
|
BitSet16 hiRegsLoaded(RegCache.LoadedRegs & 0x7F00);
|
||||||
|
|
||||||
for (int reg : hiRegsLoaded)
|
for (int reg : hiRegsLoaded)
|
||||||
LoadReg(reg, RegCache.Mapping[reg]);
|
LoadReg(reg, RegCache.Mapping[reg]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,9 +329,10 @@ Compiler::Compiler()
|
|||||||
{
|
{
|
||||||
for (int size = 0; size < 3; size++)
|
for (int size = 0; size < 3; size++)
|
||||||
{
|
{
|
||||||
for (int reg = 0; reg < 8; reg++)
|
for (int reg = 0; reg < 32; reg++)
|
||||||
{
|
{
|
||||||
ARM64Reg rdMapped = (ARM64Reg)(W19 + reg);
|
if (!(reg == W4 || (reg >= W19 && reg <= W26)))
|
||||||
|
continue;
|
||||||
PatchedStoreFuncs[consoleType][num][size][reg] = GetRXPtr();
|
PatchedStoreFuncs[consoleType][num][size][reg] = GetRXPtr();
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
{
|
{
|
||||||
@ -711,7 +715,9 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
|
|||||||
QuickCallFunction(X1, InterpretTHUMB[CurInstr.Info.Kind]);
|
QuickCallFunction(X1, InterpretTHUMB[CurInstr.Info.Kind]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
(this->*comp)();
|
(this->*comp)();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -727,10 +733,12 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cond == 0xF)
|
else if (cond == 0xF)
|
||||||
|
{
|
||||||
Comp_AddCycles_C();
|
Comp_AddCycles_C();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IrregularCycles = false;
|
IrregularCycles = comp == NULL;
|
||||||
|
|
||||||
FixupBranch skipExecute;
|
FixupBranch skipExecute;
|
||||||
if (cond < 0xE)
|
if (cond < 0xE)
|
||||||
@ -763,7 +771,9 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
|
|||||||
SetJumpTarget(skipNop);
|
SetJumpTarget(skipNop);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
SetJumpTarget(skipExecute);
|
SetJumpTarget(skipExecute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -241,17 +241,8 @@ public:
|
|||||||
u32 JitMemSecondarySize;
|
u32 JitMemSecondarySize;
|
||||||
u32 JitMemMainSize;
|
u32 JitMemMainSize;
|
||||||
|
|
||||||
void* ReadBanked, *WriteBanked;
|
|
||||||
|
|
||||||
void* JumpToFuncs9[3];
|
|
||||||
void* JumpToFuncs7[3];
|
|
||||||
|
|
||||||
std::unordered_map<ptrdiff_t, LoadStorePatch> LoadStorePatches;
|
std::unordered_map<ptrdiff_t, LoadStorePatch> LoadStorePatches;
|
||||||
|
|
||||||
// [Console Type][Num][Size][Sign Extend][Output register]
|
|
||||||
void* PatchedLoadFuncs[2][2][3][2][8];
|
|
||||||
void* PatchedStoreFuncs[2][2][3][8];
|
|
||||||
|
|
||||||
RegisterCache<Compiler, Arm64Gen::ARM64Reg> RegCache;
|
RegisterCache<Compiler, Arm64Gen::ARM64Reg> RegCache;
|
||||||
|
|
||||||
bool CPSRDirty = false;
|
bool CPSRDirty = false;
|
||||||
@ -263,6 +254,15 @@ public:
|
|||||||
void* JitRWStart;
|
void* JitRWStart;
|
||||||
void* JitRXStart;
|
void* JitRXStart;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void* ReadBanked, *WriteBanked;
|
||||||
|
|
||||||
|
void* JumpToFuncs9[3];
|
||||||
|
void* JumpToFuncs7[3];
|
||||||
|
|
||||||
|
// [Console Type][Num][Size][Sign Extend][Output register]
|
||||||
|
void* PatchedLoadFuncs[2][2][3][2][32];
|
||||||
|
void* PatchedStoreFuncs[2][2][3][32];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,12 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)
|
|||||||
rnMapped = W3;
|
rnMapped = W3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & memop_Store && flags & (memop_Post|memop_Writeback) && rd == rn)
|
||||||
|
{
|
||||||
|
MOV(W4, rdMapped);
|
||||||
|
rdMapped = W4;
|
||||||
|
}
|
||||||
|
|
||||||
ARM64Reg finalAddr = W0;
|
ARM64Reg finalAddr = W0;
|
||||||
if (flags & memop_Post)
|
if (flags & memop_Post)
|
||||||
{
|
{
|
||||||
@ -170,10 +176,10 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)
|
|||||||
ptrdiff_t memopStart = GetCodeOffset();
|
ptrdiff_t memopStart = GetCodeOffset();
|
||||||
LoadStorePatch patch;
|
LoadStorePatch patch;
|
||||||
|
|
||||||
|
assert((rdMapped >= W19 && rdMapped <= W26) || rdMapped == W4);
|
||||||
patch.PatchFunc = flags & memop_Store
|
patch.PatchFunc = flags & memop_Store
|
||||||
? PatchedStoreFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][rdMapped - W19]
|
? PatchedStoreFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][rdMapped]
|
||||||
: PatchedLoadFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][!!(flags & memop_SignExtend)][rdMapped - W19];
|
: PatchedLoadFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][!!(flags & memop_SignExtend)][rdMapped];
|
||||||
assert(rdMapped - W19 >= 0 && rdMapped - W19 < 8);
|
|
||||||
|
|
||||||
MOVP2R(X7, Num == 0 ? ARMJIT_Memory::FastMem9Start : ARMJIT_Memory::FastMem7Start);
|
MOVP2R(X7, Num == 0 ? ARMJIT_Memory::FastMem9Start : ARMJIT_Memory::FastMem7Start);
|
||||||
|
|
||||||
|
@ -98,7 +98,9 @@ void Compiler::A_Comp_MRS()
|
|||||||
MOV(32, rd, R(RSCRATCH3));
|
MOV(32, rd, R(RSCRATCH3));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
MOV(32, rd, R(RCPSR));
|
MOV(32, rd, R(RCPSR));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateModeTrampoline(ARM* arm, u32 oldmode, u32 newmode)
|
void UpdateModeTrampoline(ARM* arm, u32 oldmode, u32 newmode)
|
||||||
@ -703,7 +705,9 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
|
|||||||
ABI_CallFunction(InterpretTHUMB[CurInstr.Info.Kind]);
|
ABI_CallFunction(InterpretTHUMB[CurInstr.Info.Kind]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
(this->*comp)();
|
(this->*comp)();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -724,7 +728,7 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IrregularCycles = false;
|
IrregularCycles = comp == NULL;
|
||||||
|
|
||||||
FixupBranch skipExecute;
|
FixupBranch skipExecute;
|
||||||
if (cond < 0xE)
|
if (cond < 0xE)
|
||||||
@ -737,7 +741,9 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
|
|||||||
ABI_CallFunction(InterpretARM[CurInstr.Info.Kind]);
|
ABI_CallFunction(InterpretARM[CurInstr.Info.Kind]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
(this->*comp)();
|
(this->*comp)();
|
||||||
|
}
|
||||||
|
|
||||||
Comp_SpecialBranchBehaviour(true);
|
Comp_SpecialBranchBehaviour(true);
|
||||||
|
|
||||||
@ -755,7 +761,9 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
|
|||||||
SetJumpTarget(skipFailed);
|
SetJumpTarget(skipFailed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
SetJumpTarget(skipExecute);
|
SetJumpTarget(skipExecute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -130,6 +130,12 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag
|
|||||||
if (Thumb && rn == 15)
|
if (Thumb && rn == 15)
|
||||||
rnMapped = Imm32(R15 & ~0x2);
|
rnMapped = Imm32(R15 & ~0x2);
|
||||||
|
|
||||||
|
if (flags & memop_Store && flags & (memop_Post|memop_Writeback) && rd == rn)
|
||||||
|
{
|
||||||
|
MOV(32, R(RSCRATCH4), rdMapped);
|
||||||
|
rdMapped = R(RSCRATCH4);
|
||||||
|
}
|
||||||
|
|
||||||
X64Reg finalAddr = RSCRATCH3;
|
X64Reg finalAddr = RSCRATCH3;
|
||||||
if (flags & memop_Post)
|
if (flags & memop_Post)
|
||||||
{
|
{
|
||||||
@ -282,13 +288,15 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag
|
|||||||
{
|
{
|
||||||
if (Num == 0)
|
if (Num == 0)
|
||||||
{
|
{
|
||||||
|
// on Windows param 3 is R8 which is also scratch 4 which can be used for rd
|
||||||
|
if (flags & memop_Store)
|
||||||
|
MOV(32, R(ABI_PARAM3), rdMapped);
|
||||||
|
|
||||||
MOV(64, R(ABI_PARAM2), R(RCPU));
|
MOV(64, R(ABI_PARAM2), R(RCPU));
|
||||||
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_PARAM3), rdMapped);
|
|
||||||
|
|
||||||
switch (size | NDS::ConsoleType)
|
switch (size | NDS::ConsoleType)
|
||||||
{
|
{
|
||||||
case 32: CALL((void*)&SlowWrite9<u32, 0>); break;
|
case 32: CALL((void*)&SlowWrite9<u32, 0>); break;
|
||||||
|
Reference in New Issue
Block a user