mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Save regs before/after 3-arg func calls on x86.
This fixes bugs only on x64 when ABI_CallFunctionACC and etc. were used. This was breaking things since R8 was not being saved (arg 3.)
This commit is contained in:
1 parent
19f2b35679
commit
662ae77214
4 files changed
+49
-8
No files matched your search
@@ -559,6 +559,7 @@ void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
|
||||
PUSH(R14);
|
||||
PUSH(R15);
|
||||
PUSH(R15); //just to align stack. duped push/pop doesn't hurt.
|
||||
// TODO: XMM?
|
||||
}
|
||||
|
||||
void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
|
||||
|
||||
@@ -57,6 +57,14 @@ public:
|
||||
Shutdown();
|
||||
}
|
||||
void *ProtectFunction(void *function, int num_params);
|
||||
|
||||
const u8 *GetSaveRegsFunction() const {
|
||||
return save_regs;
|
||||
}
|
||||
const u8 *GetLoadRegsFunction() const {
|
||||
return load_regs;
|
||||
}
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void Shutdown();
|
||||
|
||||
+35
-8
@@ -418,13 +418,13 @@ void Jit::WriteExitDestInEAX()
|
||||
SetJumpTarget(tooLow);
|
||||
SetJumpTarget(tooHigh);
|
||||
|
||||
ABI_CallFunctionA(thunks.ProtectFunction((void *) Memory::GetPointer, 1), R(EAX));
|
||||
CallProtectedFunction((void *) Memory::GetPointer, R(EAX));
|
||||
CMP(32, R(EAX), Imm32(0));
|
||||
FixupBranch skip = J_CC(CC_NE);
|
||||
|
||||
// TODO: "Ignore" this so other threads can continue?
|
||||
if (g_Config.bIgnoreBadMemAccess)
|
||||
ABI_CallFunctionA(thunks.ProtectFunction((void *) Core_UpdateState, 1), Imm32(CORE_ERROR));
|
||||
CallProtectedFunction((void *) Core_UpdateState, Imm32(CORE_ERROR));
|
||||
|
||||
SUB(32, M(¤tMIPS->downcount), Imm32(0));
|
||||
JMP(asm_.dispatcherCheckCoreState, true);
|
||||
@@ -607,7 +607,6 @@ OpArg Jit::JitSafeMem::PrepareMemoryOpArg(ReadType type)
|
||||
jit_->SUB(32, R(xaddr_), Imm32(offset_));
|
||||
}
|
||||
|
||||
|
||||
#ifdef _M_IX86
|
||||
return MDisp(xaddr_, (u32) Memory::base + offset_);
|
||||
#else
|
||||
@@ -657,7 +656,7 @@ void Jit::JitSafeMem::DoSlowWrite(void *safeFunc, const OpArg src, int suboffset
|
||||
jit_->AND(32, R(EAX), Imm32(alignMask_));
|
||||
}
|
||||
|
||||
jit_->ABI_CallFunctionAA(jit_->thunks.ProtectFunction(safeFunc, 2), src, R(EAX));
|
||||
jit_->CallProtectedFunction(safeFunc, src, R(EAX));
|
||||
needsCheck_ = true;
|
||||
}
|
||||
|
||||
@@ -680,7 +679,7 @@ bool Jit::JitSafeMem::PrepareSlowRead(void *safeFunc)
|
||||
jit_->AND(32, R(EAX), Imm32(alignMask_));
|
||||
}
|
||||
|
||||
jit_->ABI_CallFunctionA(jit_->thunks.ProtectFunction(safeFunc, 1), R(EAX));
|
||||
jit_->CallProtectedFunction(safeFunc, R(EAX));
|
||||
needsCheck_ = true;
|
||||
return true;
|
||||
}
|
||||
@@ -710,7 +709,7 @@ void Jit::JitSafeMem::NextSlowRead(void *safeFunc, int suboffset)
|
||||
jit_->AND(32, R(EAX), Imm32(alignMask_));
|
||||
}
|
||||
|
||||
jit_->ABI_CallFunctionA(jit_->thunks.ProtectFunction(safeFunc, 1), R(EAX));
|
||||
jit_->CallProtectedFunction(safeFunc, R(EAX));
|
||||
}
|
||||
|
||||
bool Jit::JitSafeMem::ImmValid()
|
||||
@@ -755,7 +754,7 @@ void Jit::JitSafeMem::MemCheckImm(ReadType type)
|
||||
return;
|
||||
|
||||
jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC));
|
||||
jit_->ABI_CallFunctionCCC(jit_->thunks.ProtectFunction((void *)&JitMemCheck, 3), iaddr_, size_, type == MEM_WRITE ? 1 : 0);
|
||||
jit_->CallProtectedFunction((void *)&JitMemCheck, iaddr_, size_, type == MEM_WRITE ? 1 : 0);
|
||||
|
||||
jit_->CMP(32, M((void*)&coreState), Imm32(0));
|
||||
skipChecks_.push_back(jit_->J_CC(CC_NE, true));
|
||||
@@ -795,7 +794,7 @@ void Jit::JitSafeMem::MemCheckAsm(ReadType type)
|
||||
jit_->PUSH(xaddr_);
|
||||
jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC));
|
||||
jit_->ADD(32, R(xaddr_), Imm32(offset_));
|
||||
jit_->ABI_CallFunctionACC(jit_->thunks.ProtectFunction((void *)&JitMemCheck, 3), R(xaddr_), size_, type == MEM_WRITE ? 1 : 0);
|
||||
jit_->CallProtectedFunction((void *)&JitMemCheck, R(xaddr_), size_, type == MEM_WRITE ? 1 : 0);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
jit_->POP(xaddr_);
|
||||
|
||||
@@ -812,6 +811,34 @@ void Jit::JitSafeMem::MemCheckAsm(ReadType type)
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(void *func, const OpArg &arg1)
|
||||
{
|
||||
// We don't regcache RCX, so the below is safe (and also faster, maybe branch prediction?)
|
||||
ABI_CallFunctionA(thunks.ProtectFunction(func, 1), arg1);
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(void *func, const OpArg &arg1, const OpArg &arg2)
|
||||
{
|
||||
// We don't regcache RCX/RDX, so the below is safe (and also faster, maybe branch prediction?)
|
||||
ABI_CallFunctionAA(thunks.ProtectFunction(func, 2), arg1, arg2);
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(void *func, const u32 arg1, const u32 arg2, const u32 arg3)
|
||||
{
|
||||
// On x64, we need to save R8, which is caller saved.
|
||||
ABI_CallFunction((void *)thunks.GetSaveRegsFunction());
|
||||
ABI_CallFunctionCCC(func, arg1, arg2, arg3);
|
||||
ABI_CallFunction((void *)thunks.GetLoadRegsFunction());
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(void *func, const OpArg &arg1, const u32 arg2, const u32 arg3)
|
||||
{
|
||||
// On x64, we need to save R8, which is caller saved.
|
||||
ABI_CallFunction((void *)thunks.GetSaveRegsFunction());
|
||||
ABI_CallFunctionACC(func, arg1, arg2, arg3);
|
||||
ABI_CallFunction((void *)thunks.GetLoadRegsFunction());
|
||||
}
|
||||
|
||||
void Jit::Comp_DoNothing(u32 op) { }
|
||||
|
||||
} // namespace
|
||||
@@ -280,6 +280,11 @@ private:
|
||||
void CompFPTriArith(u32 op, void (XEmitter::*arith)(X64Reg reg, OpArg), bool orderMatters);
|
||||
void CompFPComp(int lhs, int rhs, u8 compare, bool allowNaN = false);
|
||||
|
||||
void CallProtectedFunction(void *func, const OpArg &arg1);
|
||||
void CallProtectedFunction(void *func, const OpArg &arg1, const OpArg &arg2);
|
||||
void CallProtectedFunction(void *func, const u32 arg1, const u32 arg2, const u32 arg3);
|
||||
void CallProtectedFunction(void *func, const OpArg &arg1, const u32 arg2, const u32 arg3);
|
||||
|
||||
JitBlockCache blocks;
|
||||
JitOptions jo;
|
||||
JitState js;
|
||||
|
||||
Reference in new issue
Block a user