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:
Unknown W. Brackets committed 2013-07-06 00:54:53 -07:00
1 parent 19f2b35679
commit 662ae77214
4 files changed
+49 -8

No files matched your search

+1
View File
@@ -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() {
+8
View File
@@ -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
View File
@@ -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(&currentMIPS->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
+5
View File
@@ -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;