From 5305017fc3a5356f9611475fe8ed8fea70a2a90d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 19 Jan 2013 10:49:19 -0800 Subject: [PATCH] Properly save registers before the slowmem call. --- Common/ABI.cpp | 30 ++++++++++++------------- Common/x64Emitter.h | 2 +- Core/MIPS/x86/CompLoadStore.cpp | 40 +++++++-------------------------- Core/MIPS/x86/Jit.h | 2 ++ 4 files changed, 26 insertions(+), 48 deletions(-) diff --git a/Common/ABI.cpp b/Common/ABI.cpp index 4a79b64434..3d0d792984 100644 --- a/Common/ABI.cpp +++ b/Common/ABI.cpp @@ -170,16 +170,6 @@ void XEmitter::ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param ABI_RestoreStack(3 * 4); } -void XEmitter::ABI_CallFunctionAAC(void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2, u32 param3) -{ - ABI_AlignStack(3 * 4); - PUSH(32, Imm32(param3)); - PUSH(32, arg2); - PUSH(32, arg1); - CALL(func); - ABI_RestoreStack(3 * 4); -} - void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1) { ABI_AlignStack(1 * 4); @@ -188,6 +178,15 @@ void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1) ABI_RestoreStack(1 * 4); } +void XEmitter::ABI_CallFunctionAA(void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2) +{ + ABI_AlignStack(2 * 4); + PUSH(32, arg2); + PUSH(32, arg1); + CALL(func); + ABI_RestoreStack(2 * 4); +} + void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() { // Note: 4 * 4 = 16 bytes, so alignment is preserved. PUSH(EBP); @@ -440,11 +439,10 @@ void XEmitter::ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param } } -void XEmitter::ABI_CallFunctionAAC(void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2, u32 param3) +void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1) { - MOV(32, R(ABI_PARAM1), arg1); - MOV(32, R(ABI_PARAM2), arg2); - MOV(64, R(ABI_PARAM3), Imm64(param3)); + if (!arg1.IsSimpleReg(ABI_PARAM1)) + MOV(32, R(ABI_PARAM1), arg1); u64 distance = u64(func) - (u64(code) + 5); if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { @@ -456,10 +454,12 @@ void XEmitter::ABI_CallFunctionAAC(void *func, const Gen::OpArg &arg1, const Gen } } -void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1) +void XEmitter::ABI_CallFunctionAA(void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2) { if (!arg1.IsSimpleReg(ABI_PARAM1)) MOV(32, R(ABI_PARAM1), arg1); + if (!arg2.IsSimpleReg(ABI_PARAM2)) + MOV(32, R(ABI_PARAM2), arg2); u64 distance = u64(func) - (u64(code) + 5); if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { diff --git a/Common/x64Emitter.h b/Common/x64Emitter.h index fb8ec8694b..cb690593a3 100644 --- a/Common/x64Emitter.h +++ b/Common/x64Emitter.h @@ -657,8 +657,8 @@ public: void ABI_CallFunctionPPC(void *func, void *param1, void *param2,u32 param3); void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2); void ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param2, u32 param3); - void ABI_CallFunctionAAC(void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2, u32 param3); void ABI_CallFunctionA(void *func, const Gen::OpArg &arg1); + void ABI_CallFunctionAA(void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2); // Pass a register as a paremeter. void ABI_CallFunctionR(void *func, Gen::X64Reg reg1); diff --git a/Core/MIPS/x86/CompLoadStore.cpp b/Core/MIPS/x86/CompLoadStore.cpp index 1b9695612b..4110a60b1b 100644 --- a/Core/MIPS/x86/CompLoadStore.cpp +++ b/Core/MIPS/x86/CompLoadStore.cpp @@ -41,26 +41,6 @@ namespace MIPSComp { - static u32 ReadMemSafe32(u32 addr, u32 offset) - { - return Memory::Read_U32(addr + offset); - } - - static u32 ReadMemSafe16(u32 addr, u32 offset) - { - return Memory::Read_U16(addr + offset); - } - - static void WriteMemSafe32(u32 addr, u32 value, u32 offset) - { - Memory::Write_U32(value, addr + offset); - } - - static void WriteMemSafe16(u32 addr, u32 value, u32 offset) - { - Memory::Write_U16(value, addr + offset); - } - void Jit::Comp_ITypeMem(u32 op) { int offset = (signed short)(op&0xFFFF); @@ -77,8 +57,6 @@ namespace MIPSComp case 37: //R(rt) = ReadMem16(addr); break; //lhu if (!g_Config.bFastMemory) { - FlushAll(); - gpr.Lock(rt, rs); gpr.BindToRegister(rt, rt == rs, true); @@ -97,7 +75,8 @@ namespace MIPSComp SetJumpTarget(tooLow); SetJumpTarget(tooHigh); - ABI_CallFunctionAC((void *) &ReadMemSafe16, R(EAX), offset); + ADD(32, R(EAX), Imm32(offset)); + ABI_CallFunctionA(thunks.ProtectFunction((void *) &Memory::Read_U16, 1), R(EAX)); MOVZX(32, 16, gpr.RX(rt), R(EAX)); SetJumpTarget(skip); @@ -126,8 +105,6 @@ namespace MIPSComp case 35: //R(rt) = ReadMem32(addr); break; //lw if (!g_Config.bFastMemory) { - FlushAll(); - gpr.Lock(rt, rs); gpr.BindToRegister(rt, rt == rs, true); @@ -146,7 +123,8 @@ namespace MIPSComp SetJumpTarget(tooLow); SetJumpTarget(tooHigh); - ABI_CallFunctionAC((void *) &ReadMemSafe32, R(EAX), offset); + ADD(32, R(EAX), Imm32(offset)); + ABI_CallFunctionA(thunks.ProtectFunction((void *) &Memory::Read_U32, 1), R(EAX)); MOV(32, gpr.R(rt), R(EAX)); SetJumpTarget(skip); @@ -178,8 +156,6 @@ namespace MIPSComp case 41: //WriteMem16(addr, R(rt)); break; //sh if (!g_Config.bFastMemory) { - FlushAll(); - gpr.Lock(rt, rs); gpr.BindToRegister(rt, true, false); @@ -198,7 +174,8 @@ namespace MIPSComp SetJumpTarget(tooLow); SetJumpTarget(tooHigh); - ABI_CallFunctionAAC((void *) &WriteMemSafe16, R(EAX), gpr.R(rt), offset); + ADD(32, R(EAX), Imm32(offset)); + ABI_CallFunctionAA(thunks.ProtectFunction((void *) &Memory::Write_U16, 2), gpr.R(rt), R(EAX)); SetJumpTarget(skip); gpr.UnlockAll(); @@ -222,8 +199,6 @@ namespace MIPSComp case 43: //WriteMem32(addr, R(rt)); break; //sw if (!g_Config.bFastMemory) { - FlushAll(); - gpr.Lock(rt, rs); gpr.BindToRegister(rt, true, false); @@ -242,7 +217,8 @@ namespace MIPSComp SetJumpTarget(tooLow); SetJumpTarget(tooHigh); - ABI_CallFunctionAAC((void *) &WriteMemSafe32, R(EAX), gpr.R(rt), offset); + ADD(32, R(EAX), Imm32(offset)); + ABI_CallFunctionAA(thunks.ProtectFunction((void *) &Memory::Write_U32, 2), gpr.R(rt), R(EAX)); SetJumpTarget(skip); gpr.UnlockAll(); diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index 6d895b697c..34f18c86ef 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -18,6 +18,7 @@ #pragma once #include "../../../Globals.h" +#include "../../../Common/Thunk.h" #include "Asm.h" #if defined(ARM) @@ -131,6 +132,7 @@ private: FPURegCache fpr; AsmRoutineManager asm_; + ThunkManager thunks; MIPSState *mips_; };