aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRSDuck <rsduck@users.noreply.github.com>2021-01-19 23:49:32 +0100
committerRSDuck <rsduck@users.noreply.github.com>2021-01-19 23:50:08 +0100
commit771dfaca2e3851217287aa73423eb6ec6d6b4360 (patch)
treee2917b8770e6cf9354bff9d89f3ae0455f4a15d4
parent31c9d116bd9a1e16fccc2e7a974d4a7410f7da90 (diff)
JIT: handle STR post with rd == rn
fixes Zelda Four Swords
-rw-r--r--src/ARMJIT_A64/ARMJIT_Compiler.cpp22
-rw-r--r--src/ARMJIT_A64/ARMJIT_Compiler.h18
-rw-r--r--src/ARMJIT_A64/ARMJIT_LoadStore.cpp12
-rw-r--r--src/ARMJIT_x64/ARMJIT_Compiler.cpp10
-rw-r--r--src/ARMJIT_x64/ARMJIT_LoadStore.cpp12
5 files changed, 53 insertions, 21 deletions
diff --git a/src/ARMJIT_A64/ARMJIT_Compiler.cpp b/src/ARMJIT_A64/ARMJIT_Compiler.cpp
index 880a6fc..b5702bf 100644
--- a/src/ARMJIT_A64/ARMJIT_Compiler.cpp
+++ b/src/ARMJIT_A64/ARMJIT_Compiler.cpp
@@ -174,10 +174,13 @@ void Compiler::PopRegs(bool saveHiRegs)
{
if (saveHiRegs)
{
- BitSet16 hiRegsLoaded(RegCache.LoadedRegs & 0x7F00);
+ if (!Thumb && CurInstr.Cond() != 0xE)
+ {
+ BitSet16 hiRegsLoaded(RegCache.LoadedRegs & 0x7F00);
- for (int reg : hiRegsLoaded)
- LoadReg(reg, RegCache.Mapping[reg]);
+ for (int reg : hiRegsLoaded)
+ LoadReg(reg, RegCache.Mapping[reg]);
+ }
}
}
@@ -326,9 +329,10 @@ Compiler::Compiler()
{
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();
if (num == 0)
{
@@ -711,7 +715,9 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
QuickCallFunction(X1, InterpretTHUMB[CurInstr.Info.Kind]);
}
else
+ {
(this->*comp)();
+ }
}
else
{
@@ -727,10 +733,12 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
}
}
else if (cond == 0xF)
+ {
Comp_AddCycles_C();
+ }
else
{
- IrregularCycles = false;
+ IrregularCycles = comp == NULL;
FixupBranch skipExecute;
if (cond < 0xE)
@@ -763,7 +771,9 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
SetJumpTarget(skipNop);
}
else
+ {
SetJumpTarget(skipExecute);
+ }
}
}
diff --git a/src/ARMJIT_A64/ARMJIT_Compiler.h b/src/ARMJIT_A64/ARMJIT_Compiler.h
index a79e9da..0154175 100644
--- a/src/ARMJIT_A64/ARMJIT_Compiler.h
+++ b/src/ARMJIT_A64/ARMJIT_Compiler.h
@@ -241,17 +241,8 @@ public:
u32 JitMemSecondarySize;
u32 JitMemMainSize;
- void* ReadBanked, *WriteBanked;
-
- void* JumpToFuncs9[3];
- void* JumpToFuncs7[3];
-
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;
bool CPSRDirty = false;
@@ -263,6 +254,15 @@ public:
void* JitRWStart;
void* JitRXStart;
#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];
};
}
diff --git a/src/ARMJIT_A64/ARMJIT_LoadStore.cpp b/src/ARMJIT_A64/ARMJIT_LoadStore.cpp
index 3d30759..a622a92 100644
--- a/src/ARMJIT_A64/ARMJIT_LoadStore.cpp
+++ b/src/ARMJIT_A64/ARMJIT_LoadStore.cpp
@@ -116,6 +116,12 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)
rnMapped = W3;
}
+ if (flags & memop_Store && flags & (memop_Post|memop_Writeback) && rd == rn)
+ {
+ MOV(W4, rdMapped);
+ rdMapped = W4;
+ }
+
ARM64Reg finalAddr = W0;
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();
LoadStorePatch patch;
+ assert((rdMapped >= W19 && rdMapped <= W26) || rdMapped == W4);
patch.PatchFunc = flags & memop_Store
- ? PatchedStoreFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][rdMapped - W19]
- : PatchedLoadFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][!!(flags & memop_SignExtend)][rdMapped - W19];
- assert(rdMapped - W19 >= 0 && rdMapped - W19 < 8);
+ ? PatchedStoreFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][rdMapped]
+ : PatchedLoadFuncs[NDS::ConsoleType][Num][__builtin_ctz(size) - 3][!!(flags & memop_SignExtend)][rdMapped];
MOVP2R(X7, Num == 0 ? ARMJIT_Memory::FastMem9Start : ARMJIT_Memory::FastMem7Start);
diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.cpp b/src/ARMJIT_x64/ARMJIT_Compiler.cpp
index cc4ad80..1eb5a2a 100644
--- a/src/ARMJIT_x64/ARMJIT_Compiler.cpp
+++ b/src/ARMJIT_x64/ARMJIT_Compiler.cpp
@@ -98,7 +98,9 @@ void Compiler::A_Comp_MRS()
MOV(32, rd, R(RSCRATCH3));
}
else
+ {
MOV(32, rd, R(RCPSR));
+ }
}
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]);
}
else
+ {
(this->*comp)();
+ }
}
else
{
@@ -724,7 +728,7 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
}
else
{
- IrregularCycles = false;
+ IrregularCycles = comp == NULL;
FixupBranch skipExecute;
if (cond < 0xE)
@@ -737,7 +741,9 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
ABI_CallFunction(InterpretARM[CurInstr.Info.Kind]);
}
else
+ {
(this->*comp)();
+ }
Comp_SpecialBranchBehaviour(true);
@@ -755,7 +761,9 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
SetJumpTarget(skipFailed);
}
else
+ {
SetJumpTarget(skipExecute);
+ }
}
}
diff --git a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp
index d80b25b..c044e69 100644
--- a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp
+++ b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp
@@ -130,6 +130,12 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag
if (Thumb && rn == 15)
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;
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)
{
+ // 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));
if (ABI_PARAM1 != RSCRATCH3)
MOV(32, R(ABI_PARAM1), R(RSCRATCH3));
if (flags & memop_Store)
{
- MOV(32, R(ABI_PARAM3), rdMapped);
-
switch (size | NDS::ConsoleType)
{
case 32: CALL((void*)&SlowWrite9<u32, 0>); break;