jit: LDM/STM keep proper stack alignment

This commit is contained in:
RSDuck 2019-07-15 20:34:08 +02:00 committed by RSDuck
parent dd04cef47e
commit 3167ddcde1
1 changed files with 13 additions and 3 deletions

View File

@ -480,11 +480,14 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
? NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2] ? NDS::ARM7MemTimings[CurInstr.CodeCycles][Thumb ? 0 : 2]
: (R15 & 0x2 ? 0 : CurInstr.CodeCycles); : (R15 & 0x2 ? 0 : CurInstr.CodeCycles);
// we need to make sure that the stack stays aligned to 16 bytes
u32 stackAlloc = ((regsCount + 1) & ~1) * 8;
MOV(32, R(ABI_PARAM4), Imm32(cycles)); MOV(32, R(ABI_PARAM4), Imm32(cycles));
if (!store) if (!store)
{ {
MOV(32, R(ABI_PARAM3), Imm32(regsCount)); MOV(32, R(ABI_PARAM3), Imm32(regsCount));
SUB(64, R(RSP), regsCount < 16 ? Imm8(regsCount * 8) : Imm32(regsCount * 8)); SUB(64, R(RSP), stackAlloc <= INT8_MAX ? Imm8(stackAlloc) : Imm32(stackAlloc));
MOV(64, R(ABI_PARAM2), R(RSP)); MOV(64, R(ABI_PARAM2), R(RSP));
CALL(Num == 0 CALL(Num == 0
@ -508,7 +511,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
POP(ABI_PARAM3); POP(ABI_PARAM3);
CALL(WriteBanked); CALL(WriteBanked);
FixupBranch sucessfulWritten = J_CC(CC_NC); FixupBranch sucessfulWritten = J_CC(CC_NC);
if (RegCache.Mapping[reg] != INVALID_REG && RegCache.DirtyRegs & (1 << reg)) if (RegCache.Mapping[reg] != INVALID_REG)
MOV(32, R(RegCache.Mapping[reg]), R(ABI_PARAM3)); MOV(32, R(RegCache.Mapping[reg]), R(ABI_PARAM3));
SaveReg(reg, ABI_PARAM3); SaveReg(reg, ABI_PARAM3);
SetJumpTarget(sucessfulWritten); SetJumpTarget(sucessfulWritten);
@ -529,6 +532,9 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
} }
} }
if (regsCount & 1)
POP(RSCRATCH);
if (regs[15]) if (regs[15])
{ {
if (Num == 1) if (Num == 1)
@ -543,6 +549,9 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
} }
else else
{ {
if (regsCount & 1)
PUSH(RSCRATCH);
bool firstUserMode = true; bool firstUserMode = true;
for (int reg : regs) for (int reg : regs)
{ {
@ -572,6 +581,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
PUSH(MapReg(reg).GetSimpleReg()); PUSH(MapReg(reg).GetSimpleReg());
} }
} }
MOV(64, R(ABI_PARAM2), R(RSP)); MOV(64, R(ABI_PARAM2), R(RSP));
MOV(32, R(ABI_PARAM3), Imm32(regsCount)); MOV(32, R(ABI_PARAM3), Imm32(regsCount));
@ -579,7 +589,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
? MemoryFuncsSeq9[1][preinc] ? MemoryFuncsSeq9[1][preinc]
: MemoryFuncsSeq7[1][preinc][CodeRegion == 0x02]); : MemoryFuncsSeq7[1][preinc][CodeRegion == 0x02]);
ADD(64, R(RSP), regsCount < 16 ? Imm8(regsCount * 8) : Imm32(regsCount * 8)); ADD(64, R(RSP), stackAlloc <= INT8_MAX ? Imm8(stackAlloc) : Imm32(stackAlloc));
} }
return offset; return offset;