From 122d5e7b4ebd77ab1c802cb91b7587daeb82e241 Mon Sep 17 00:00:00 2001 From: skidau Date: Tue, 13 Apr 2010 10:18:05 +0000 Subject: [PATCH] Fixed the crash in DSP LLE JIT on x64 by aligning the stack. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5357 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/ABI.cpp | 36 +++++++++----- .../Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp | 48 +++---------------- .../Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp | 32 ++----------- Source/Core/DSPCore/Src/DSPEmitter.cpp | 8 ++-- 4 files changed, 37 insertions(+), 87 deletions(-) diff --git a/Source/Core/Common/Src/ABI.cpp b/Source/Core/Common/Src/ABI.cpp index 6efe455f5b..f565a77633 100644 --- a/Source/Core/Common/Src/ABI.cpp +++ b/Source/Core/Common/Src/ABI.cpp @@ -106,7 +106,7 @@ void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *par ABI_RestoreStack(3 * 4); } -// Pass a register as a paremeter. +// Pass a register as a parameter. void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) { ABI_AlignStack(1 * 4); PUSH(32, R(reg1)); @@ -228,14 +228,14 @@ void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *par CALL(func); } -// Pass a register as a paremeter. +// Pass a register as a parameter. void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) { if (reg1 != ABI_PARAM1) MOV(32, R(ABI_PARAM1), R(reg1)); CALL(func); } -// Pass two registers as paremeters. +// Pass two registers as parameters. void XEmitter::ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) { if (reg2 != ABI_PARAM1) { if (reg1 != ABI_PARAM1) @@ -263,12 +263,6 @@ unsigned int XEmitter::ABI_GetAlignedFrameSize(unsigned int frameSize) { return frameSize; } -void XEmitter::ABI_AlignStack(unsigned int /*frameSize*/) { -} - -void XEmitter::ABI_RestoreStack(unsigned int /*frameSize*/) { -} - #ifdef _WIN32 // Win64 Specific Code @@ -283,11 +277,11 @@ void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() { PUSH(R14); PUSH(R15); //TODO: Also preserve XMM0-3? - SUB(64, R(RSP), Imm8(0x28)); + ABI_AlignStack(0); } void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() { - ADD(64, R(RSP), Imm8(0x28)); + ABI_RestoreStack(0); POP(R15); POP(R14); POP(R13); @@ -309,11 +303,11 @@ void XEmitter::ABI_PushAllCallerSavedRegsAndAdjustStack() { PUSH(R10); PUSH(R11); //TODO: Also preserve XMM0-15? - SUB(64, R(RSP), Imm8(0x28)); + ABI_AlignStack(0); } void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() { - ADD(64, R(RSP), Imm8(0x28)); + ABI_RestoreStack(0); POP(R11); POP(R10); POP(R9); @@ -324,6 +318,14 @@ void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() { POP(RCX); } +void XEmitter::ABI_AlignStack(unsigned int /*frameSize*/) { + SUB(64, R(RSP), Imm8(0x28)); +} + +void XEmitter::ABI_RestoreStack(unsigned int /*frameSize*/) { + ADD(64, R(RSP), Imm8(0x28)); +} + #else // Unix64 Specific Code void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() { @@ -370,6 +372,14 @@ void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() { POP(RCX); } +void XEmitter::ABI_AlignStack(unsigned int /*frameSize*/) { + SUB(64, R(RSP), Imm8(0x08)); +} + +void XEmitter::ABI_RestoreStack(unsigned int /*frameSize*/) { + ADD(64, R(RSP), Imm8(0x08)); +} + #endif // WIN32 #endif // 32bit diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp index bd0bf4338b..9809d29872 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp @@ -117,39 +117,15 @@ void Jit64::psq_st(UGeckoInstruction inst) // One value XORPS(XMM0, R(XMM0)); // TODO: See if we can get rid of this cheaply by tweaking the code in the singleStore* functions. CVTSD2SS(XMM0, fpr.R(s)); -#ifdef _M_X64 -#if _WIN32 - SUB(64, R(RSP), Imm8(0x28)); -#else - SUB(64, R(RSP), Imm8(0x8)); -#endif -#endif + ABI_AlignStack(0); CALLptr(MDisp(EDX, (u32)(u64)asm_routines.singleStoreQuantized)); -#ifdef _M_X64 -#if _WIN32 - ADD(64, R(RSP), Imm8(0x28)); -#else - ADD(64, R(RSP), Imm8(0x8)); -#endif -#endif + ABI_RestoreStack(0); } else { // Pair of values CVTPD2PS(XMM0, fpr.R(s)); -#ifdef _M_X64 -#if _WIN32 - SUB(64, R(RSP), Imm8(0x28)); -#else - SUB(64, R(RSP), Imm8(0x8)); -#endif -#endif + ABI_AlignStack(0); CALLptr(MDisp(EDX, (u32)(u64)asm_routines.pairedStoreQuantized)); -#ifdef _M_X64 -#if _WIN32 - ADD(64, R(RSP), Imm8(0x28)); -#else - ADD(64, R(RSP), Imm8(0x8)); -#endif -#endif + ABI_RestoreStack(0); } gpr.UnlockAll(); gpr.UnlockAllX(); @@ -195,21 +171,9 @@ void Jit64::psq_l(UGeckoInstruction inst) #else SHL(32, R(EDX), Imm8(3)); #endif -#ifdef _M_X64 -#if _WIN32 - SUB(64, R(RSP), Imm8(0x28)); -#else - SUB(64, R(RSP), Imm8(0x8)); -#endif -#endif + ABI_AlignStack(0); CALLptr(MDisp(EDX, (u32)(u64)asm_routines.pairedLoadQuantized)); -#ifdef _M_X64 -#if _WIN32 - ADD(64, R(RSP), Imm8(0x28)); -#else - ADD(64, R(RSP), Imm8(0x8)); -#endif -#endif + ABI_RestoreStack(0); CVTPS2PD(fpr.RX(inst.RS), R(XMM0)); gpr.UnlockAll(); gpr.UnlockAllX(); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp index db90f44c7b..3867c6cc04 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp @@ -1185,21 +1185,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak Jit->SHL(32, R(EDX), Imm8(3)); #endif Jit->MOV(32, R(ECX), regLocForInst(RI, getOp1(I))); -#ifdef _M_X64 -#if _WIN32 - Jit->SUB(64, R(RSP), Imm8(0x28)); -#else - Jit->SUB(64, R(RSP), Imm8(0x8)); -#endif -#endif + Jit->ABI_AlignStack(0); Jit->CALLptr(MDisp(EDX, (u32)(u64)(((JitIL *)jit)->asm_routines.pairedLoadQuantized))); -#ifdef _M_X64 -#if _WIN32 - Jit->ADD(64, R(RSP), Imm8(0x28)); -#else - Jit->ADD(64, R(RSP), Imm8(0x8)); -#endif -#endif + Jit->ABI_RestoreStack(0); Jit->MOVAPD(reg, R(XMM0)); RI.fregs[reg] = I; regNormalRegClear(RI, I); @@ -1258,21 +1246,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak #endif Jit->MOV(32, R(ECX), regLocForInst(RI, getOp2(I))); Jit->MOVAPD(XMM0, fregLocForInst(RI, getOp1(I))); -#ifdef _M_X64 -#if _WIN32 - Jit->SUB(64, R(RSP), Imm8(0x28)); -#else - Jit->SUB(64, R(RSP), Imm8(0x8)); -#endif -#endif + Jit->ABI_AlignStack(0); Jit->CALLptr(MDisp(EDX, (u32)(u64)(((JitIL *)jit)->asm_routines.pairedStoreQuantized))); -#ifdef _M_X64 -#if _WIN32 - Jit->ADD(64, R(RSP), Imm8(0x28)); -#else - Jit->ADD(64, R(RSP), Imm8(0x8)); -#endif -#endif + Jit->ABI_RestoreStack(0); if (RI.IInfo[I - RI.FirstI] & 4) fregClearInst(RI, getOp1(I)); if (RI.IInfo[I - RI.FirstI] & 8) diff --git a/Source/Core/DSPCore/Src/DSPEmitter.cpp b/Source/Core/DSPCore/Src/DSPEmitter.cpp index 9598962285..96722cef6d 100644 --- a/Source/Core/DSPCore/Src/DSPEmitter.cpp +++ b/Source/Core/DSPCore/Src/DSPEmitter.cpp @@ -113,7 +113,7 @@ void DSPEmitter::Default(UDSPInstruction _inst) const u8 *DSPEmitter::Compile(int start_addr) { AlignCode16(); const u8 *entryPoint = GetCodePtr(); - // ABI_PushAllCalleeSavedRegsAndAdjustStack(); + ABI_AlignStack(0); int addr = start_addr; @@ -133,7 +133,7 @@ const u8 *DSPEmitter::Compile(int start_addr) { FixupBranch noExceptionOccurred = J_CC(CC_L); // ABI_CallFunction((void *)DSPInterpreter::HandleLoop); - // ABI_PopAllCalleeSavedRegsAndAdjustStack(); + ABI_RestoreStack(0); RET(); SetJumpTarget(skipCheck); @@ -158,7 +158,7 @@ const u8 *DSPEmitter::Compile(int start_addr) { // These functions branch and therefore only need to be called in the // end of each block and in this order ABI_CallFunction((void *)&DSPInterpreter::HandleLoop); - // ABI_PopAllCalleeSavedRegsAndAdjustStack(); + ABI_RestoreStack(0); RET(); SetJumpTarget(rLoopAddressExit); @@ -180,7 +180,7 @@ const u8 *DSPEmitter::Compile(int start_addr) { addr += opcode->size; } - // ABI_PopAllCalleeSavedRegsAndAdjustStack(); + ABI_RestoreStack(0); RET(); blocks[start_addr] = (CompiledCode)entryPoint;