mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Properly save registers before the slowmem call.
This commit is contained in:
parent
f1295f6262
commit
5305017fc3
4 changed files with 26 additions and 48 deletions
|
@ -170,16 +170,6 @@ void XEmitter::ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param
|
||||||
ABI_RestoreStack(3 * 4);
|
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)
|
void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1)
|
||||||
{
|
{
|
||||||
ABI_AlignStack(1 * 4);
|
ABI_AlignStack(1 * 4);
|
||||||
|
@ -188,6 +178,15 @@ void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1)
|
||||||
ABI_RestoreStack(1 * 4);
|
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() {
|
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
|
||||||
// Note: 4 * 4 = 16 bytes, so alignment is preserved.
|
// Note: 4 * 4 = 16 bytes, so alignment is preserved.
|
||||||
PUSH(EBP);
|
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);
|
if (!arg1.IsSimpleReg(ABI_PARAM1))
|
||||||
MOV(32, R(ABI_PARAM2), arg2);
|
MOV(32, R(ABI_PARAM1), arg1);
|
||||||
MOV(64, R(ABI_PARAM3), Imm64(param3));
|
|
||||||
u64 distance = u64(func) - (u64(code) + 5);
|
u64 distance = u64(func) - (u64(code) + 5);
|
||||||
if (distance >= 0x0000000080000000ULL
|
if (distance >= 0x0000000080000000ULL
|
||||||
&& distance < 0xFFFFFFFF80000000ULL) {
|
&& 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))
|
if (!arg1.IsSimpleReg(ABI_PARAM1))
|
||||||
MOV(32, R(ABI_PARAM1), arg1);
|
MOV(32, R(ABI_PARAM1), arg1);
|
||||||
|
if (!arg2.IsSimpleReg(ABI_PARAM2))
|
||||||
|
MOV(32, R(ABI_PARAM2), arg2);
|
||||||
u64 distance = u64(func) - (u64(code) + 5);
|
u64 distance = u64(func) - (u64(code) + 5);
|
||||||
if (distance >= 0x0000000080000000ULL
|
if (distance >= 0x0000000080000000ULL
|
||||||
&& distance < 0xFFFFFFFF80000000ULL) {
|
&& distance < 0xFFFFFFFF80000000ULL) {
|
||||||
|
|
|
@ -657,8 +657,8 @@ public:
|
||||||
void ABI_CallFunctionPPC(void *func, void *param1, void *param2,u32 param3);
|
void ABI_CallFunctionPPC(void *func, void *param1, void *param2,u32 param3);
|
||||||
void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2);
|
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_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_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.
|
// Pass a register as a paremeter.
|
||||||
void ABI_CallFunctionR(void *func, Gen::X64Reg reg1);
|
void ABI_CallFunctionR(void *func, Gen::X64Reg reg1);
|
||||||
|
|
|
@ -41,26 +41,6 @@
|
||||||
|
|
||||||
namespace MIPSComp
|
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)
|
void Jit::Comp_ITypeMem(u32 op)
|
||||||
{
|
{
|
||||||
int offset = (signed short)(op&0xFFFF);
|
int offset = (signed short)(op&0xFFFF);
|
||||||
|
@ -77,8 +57,6 @@ namespace MIPSComp
|
||||||
case 37: //R(rt) = ReadMem16(addr); break; //lhu
|
case 37: //R(rt) = ReadMem16(addr); break; //lhu
|
||||||
if (!g_Config.bFastMemory)
|
if (!g_Config.bFastMemory)
|
||||||
{
|
{
|
||||||
FlushAll();
|
|
||||||
|
|
||||||
gpr.Lock(rt, rs);
|
gpr.Lock(rt, rs);
|
||||||
gpr.BindToRegister(rt, rt == rs, true);
|
gpr.BindToRegister(rt, rt == rs, true);
|
||||||
|
|
||||||
|
@ -97,7 +75,8 @@ namespace MIPSComp
|
||||||
SetJumpTarget(tooLow);
|
SetJumpTarget(tooLow);
|
||||||
SetJumpTarget(tooHigh);
|
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));
|
MOVZX(32, 16, gpr.RX(rt), R(EAX));
|
||||||
|
|
||||||
SetJumpTarget(skip);
|
SetJumpTarget(skip);
|
||||||
|
@ -126,8 +105,6 @@ namespace MIPSComp
|
||||||
case 35: //R(rt) = ReadMem32(addr); break; //lw
|
case 35: //R(rt) = ReadMem32(addr); break; //lw
|
||||||
if (!g_Config.bFastMemory)
|
if (!g_Config.bFastMemory)
|
||||||
{
|
{
|
||||||
FlushAll();
|
|
||||||
|
|
||||||
gpr.Lock(rt, rs);
|
gpr.Lock(rt, rs);
|
||||||
gpr.BindToRegister(rt, rt == rs, true);
|
gpr.BindToRegister(rt, rt == rs, true);
|
||||||
|
|
||||||
|
@ -146,7 +123,8 @@ namespace MIPSComp
|
||||||
SetJumpTarget(tooLow);
|
SetJumpTarget(tooLow);
|
||||||
SetJumpTarget(tooHigh);
|
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));
|
MOV(32, gpr.R(rt), R(EAX));
|
||||||
|
|
||||||
SetJumpTarget(skip);
|
SetJumpTarget(skip);
|
||||||
|
@ -178,8 +156,6 @@ namespace MIPSComp
|
||||||
case 41: //WriteMem16(addr, R(rt)); break; //sh
|
case 41: //WriteMem16(addr, R(rt)); break; //sh
|
||||||
if (!g_Config.bFastMemory)
|
if (!g_Config.bFastMemory)
|
||||||
{
|
{
|
||||||
FlushAll();
|
|
||||||
|
|
||||||
gpr.Lock(rt, rs);
|
gpr.Lock(rt, rs);
|
||||||
gpr.BindToRegister(rt, true, false);
|
gpr.BindToRegister(rt, true, false);
|
||||||
|
|
||||||
|
@ -198,7 +174,8 @@ namespace MIPSComp
|
||||||
SetJumpTarget(tooLow);
|
SetJumpTarget(tooLow);
|
||||||
SetJumpTarget(tooHigh);
|
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);
|
SetJumpTarget(skip);
|
||||||
gpr.UnlockAll();
|
gpr.UnlockAll();
|
||||||
|
@ -222,8 +199,6 @@ namespace MIPSComp
|
||||||
case 43: //WriteMem32(addr, R(rt)); break; //sw
|
case 43: //WriteMem32(addr, R(rt)); break; //sw
|
||||||
if (!g_Config.bFastMemory)
|
if (!g_Config.bFastMemory)
|
||||||
{
|
{
|
||||||
FlushAll();
|
|
||||||
|
|
||||||
gpr.Lock(rt, rs);
|
gpr.Lock(rt, rs);
|
||||||
gpr.BindToRegister(rt, true, false);
|
gpr.BindToRegister(rt, true, false);
|
||||||
|
|
||||||
|
@ -242,7 +217,8 @@ namespace MIPSComp
|
||||||
SetJumpTarget(tooLow);
|
SetJumpTarget(tooLow);
|
||||||
SetJumpTarget(tooHigh);
|
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);
|
SetJumpTarget(skip);
|
||||||
gpr.UnlockAll();
|
gpr.UnlockAll();
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../../../Globals.h"
|
#include "../../../Globals.h"
|
||||||
|
#include "../../../Common/Thunk.h"
|
||||||
#include "Asm.h"
|
#include "Asm.h"
|
||||||
|
|
||||||
#if defined(ARM)
|
#if defined(ARM)
|
||||||
|
@ -131,6 +132,7 @@ private:
|
||||||
FPURegCache fpr;
|
FPURegCache fpr;
|
||||||
|
|
||||||
AsmRoutineManager asm_;
|
AsmRoutineManager asm_;
|
||||||
|
ThunkManager thunks;
|
||||||
|
|
||||||
MIPSState *mips_;
|
MIPSState *mips_;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue