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
This commit is contained in:
skidau
2010-04-13 10:18:05 +00:00
parent 379c469343
commit 122d5e7b4e
4 changed files with 37 additions and 87 deletions

View File

@ -106,7 +106,7 @@ void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *par
ABI_RestoreStack(3 * 4); ABI_RestoreStack(3 * 4);
} }
// Pass a register as a paremeter. // Pass a register as a parameter.
void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) { void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
ABI_AlignStack(1 * 4); ABI_AlignStack(1 * 4);
PUSH(32, R(reg1)); PUSH(32, R(reg1));
@ -228,14 +228,14 @@ void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *par
CALL(func); CALL(func);
} }
// Pass a register as a paremeter. // Pass a register as a parameter.
void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) { void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
if (reg1 != ABI_PARAM1) if (reg1 != ABI_PARAM1)
MOV(32, R(ABI_PARAM1), R(reg1)); MOV(32, R(ABI_PARAM1), R(reg1));
CALL(func); CALL(func);
} }
// Pass two registers as paremeters. // Pass two registers as parameters.
void XEmitter::ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) { void XEmitter::ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2) {
if (reg2 != ABI_PARAM1) { if (reg2 != ABI_PARAM1) {
if (reg1 != ABI_PARAM1) if (reg1 != ABI_PARAM1)
@ -263,12 +263,6 @@ unsigned int XEmitter::ABI_GetAlignedFrameSize(unsigned int frameSize) {
return frameSize; return frameSize;
} }
void XEmitter::ABI_AlignStack(unsigned int /*frameSize*/) {
}
void XEmitter::ABI_RestoreStack(unsigned int /*frameSize*/) {
}
#ifdef _WIN32 #ifdef _WIN32
// Win64 Specific Code // Win64 Specific Code
@ -283,11 +277,11 @@ void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
PUSH(R14); PUSH(R14);
PUSH(R15); PUSH(R15);
//TODO: Also preserve XMM0-3? //TODO: Also preserve XMM0-3?
SUB(64, R(RSP), Imm8(0x28)); ABI_AlignStack(0);
} }
void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() { void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
ADD(64, R(RSP), Imm8(0x28)); ABI_RestoreStack(0);
POP(R15); POP(R15);
POP(R14); POP(R14);
POP(R13); POP(R13);
@ -309,11 +303,11 @@ void XEmitter::ABI_PushAllCallerSavedRegsAndAdjustStack() {
PUSH(R10); PUSH(R10);
PUSH(R11); PUSH(R11);
//TODO: Also preserve XMM0-15? //TODO: Also preserve XMM0-15?
SUB(64, R(RSP), Imm8(0x28)); ABI_AlignStack(0);
} }
void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() { void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() {
ADD(64, R(RSP), Imm8(0x28)); ABI_RestoreStack(0);
POP(R11); POP(R11);
POP(R10); POP(R10);
POP(R9); POP(R9);
@ -324,6 +318,14 @@ void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() {
POP(RCX); 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 #else
// Unix64 Specific Code // Unix64 Specific Code
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() { void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
@ -370,6 +372,14 @@ void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() {
POP(RCX); 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 // WIN32
#endif // 32bit #endif // 32bit

View File

@ -117,39 +117,15 @@ void Jit64::psq_st(UGeckoInstruction inst)
// One value // One value
XORPS(XMM0, R(XMM0)); // TODO: See if we can get rid of this cheaply by tweaking the code in the singleStore* functions. 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)); CVTSD2SS(XMM0, fpr.R(s));
#ifdef _M_X64 ABI_AlignStack(0);
#if _WIN32
SUB(64, R(RSP), Imm8(0x28));
#else
SUB(64, R(RSP), Imm8(0x8));
#endif
#endif
CALLptr(MDisp(EDX, (u32)(u64)asm_routines.singleStoreQuantized)); CALLptr(MDisp(EDX, (u32)(u64)asm_routines.singleStoreQuantized));
#ifdef _M_X64 ABI_RestoreStack(0);
#if _WIN32
ADD(64, R(RSP), Imm8(0x28));
#else
ADD(64, R(RSP), Imm8(0x8));
#endif
#endif
} else { } else {
// Pair of values // Pair of values
CVTPD2PS(XMM0, fpr.R(s)); CVTPD2PS(XMM0, fpr.R(s));
#ifdef _M_X64 ABI_AlignStack(0);
#if _WIN32
SUB(64, R(RSP), Imm8(0x28));
#else
SUB(64, R(RSP), Imm8(0x8));
#endif
#endif
CALLptr(MDisp(EDX, (u32)(u64)asm_routines.pairedStoreQuantized)); CALLptr(MDisp(EDX, (u32)(u64)asm_routines.pairedStoreQuantized));
#ifdef _M_X64 ABI_RestoreStack(0);
#if _WIN32
ADD(64, R(RSP), Imm8(0x28));
#else
ADD(64, R(RSP), Imm8(0x8));
#endif
#endif
} }
gpr.UnlockAll(); gpr.UnlockAll();
gpr.UnlockAllX(); gpr.UnlockAllX();
@ -195,21 +171,9 @@ void Jit64::psq_l(UGeckoInstruction inst)
#else #else
SHL(32, R(EDX), Imm8(3)); SHL(32, R(EDX), Imm8(3));
#endif #endif
#ifdef _M_X64 ABI_AlignStack(0);
#if _WIN32
SUB(64, R(RSP), Imm8(0x28));
#else
SUB(64, R(RSP), Imm8(0x8));
#endif
#endif
CALLptr(MDisp(EDX, (u32)(u64)asm_routines.pairedLoadQuantized)); CALLptr(MDisp(EDX, (u32)(u64)asm_routines.pairedLoadQuantized));
#ifdef _M_X64 ABI_RestoreStack(0);
#if _WIN32
ADD(64, R(RSP), Imm8(0x28));
#else
ADD(64, R(RSP), Imm8(0x8));
#endif
#endif
CVTPS2PD(fpr.RX(inst.RS), R(XMM0)); CVTPS2PD(fpr.RX(inst.RS), R(XMM0));
gpr.UnlockAll(); gpr.UnlockAll();
gpr.UnlockAllX(); gpr.UnlockAllX();

View File

@ -1185,21 +1185,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
Jit->SHL(32, R(EDX), Imm8(3)); Jit->SHL(32, R(EDX), Imm8(3));
#endif #endif
Jit->MOV(32, R(ECX), regLocForInst(RI, getOp1(I))); Jit->MOV(32, R(ECX), regLocForInst(RI, getOp1(I)));
#ifdef _M_X64 Jit->ABI_AlignStack(0);
#if _WIN32
Jit->SUB(64, R(RSP), Imm8(0x28));
#else
Jit->SUB(64, R(RSP), Imm8(0x8));
#endif
#endif
Jit->CALLptr(MDisp(EDX, (u32)(u64)(((JitIL *)jit)->asm_routines.pairedLoadQuantized))); Jit->CALLptr(MDisp(EDX, (u32)(u64)(((JitIL *)jit)->asm_routines.pairedLoadQuantized)));
#ifdef _M_X64 Jit->ABI_RestoreStack(0);
#if _WIN32
Jit->ADD(64, R(RSP), Imm8(0x28));
#else
Jit->ADD(64, R(RSP), Imm8(0x8));
#endif
#endif
Jit->MOVAPD(reg, R(XMM0)); Jit->MOVAPD(reg, R(XMM0));
RI.fregs[reg] = I; RI.fregs[reg] = I;
regNormalRegClear(RI, I); regNormalRegClear(RI, I);
@ -1258,21 +1246,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
#endif #endif
Jit->MOV(32, R(ECX), regLocForInst(RI, getOp2(I))); Jit->MOV(32, R(ECX), regLocForInst(RI, getOp2(I)));
Jit->MOVAPD(XMM0, fregLocForInst(RI, getOp1(I))); Jit->MOVAPD(XMM0, fregLocForInst(RI, getOp1(I)));
#ifdef _M_X64 Jit->ABI_AlignStack(0);
#if _WIN32
Jit->SUB(64, R(RSP), Imm8(0x28));
#else
Jit->SUB(64, R(RSP), Imm8(0x8));
#endif
#endif
Jit->CALLptr(MDisp(EDX, (u32)(u64)(((JitIL *)jit)->asm_routines.pairedStoreQuantized))); Jit->CALLptr(MDisp(EDX, (u32)(u64)(((JitIL *)jit)->asm_routines.pairedStoreQuantized)));
#ifdef _M_X64 Jit->ABI_RestoreStack(0);
#if _WIN32
Jit->ADD(64, R(RSP), Imm8(0x28));
#else
Jit->ADD(64, R(RSP), Imm8(0x8));
#endif
#endif
if (RI.IInfo[I - RI.FirstI] & 4) if (RI.IInfo[I - RI.FirstI] & 4)
fregClearInst(RI, getOp1(I)); fregClearInst(RI, getOp1(I));
if (RI.IInfo[I - RI.FirstI] & 8) if (RI.IInfo[I - RI.FirstI] & 8)

View File

@ -113,7 +113,7 @@ void DSPEmitter::Default(UDSPInstruction _inst)
const u8 *DSPEmitter::Compile(int start_addr) { const u8 *DSPEmitter::Compile(int start_addr) {
AlignCode16(); AlignCode16();
const u8 *entryPoint = GetCodePtr(); const u8 *entryPoint = GetCodePtr();
// ABI_PushAllCalleeSavedRegsAndAdjustStack(); ABI_AlignStack(0);
int addr = start_addr; int addr = start_addr;
@ -133,7 +133,7 @@ const u8 *DSPEmitter::Compile(int start_addr) {
FixupBranch noExceptionOccurred = J_CC(CC_L); FixupBranch noExceptionOccurred = J_CC(CC_L);
// ABI_CallFunction((void *)DSPInterpreter::HandleLoop); // ABI_CallFunction((void *)DSPInterpreter::HandleLoop);
// ABI_PopAllCalleeSavedRegsAndAdjustStack(); ABI_RestoreStack(0);
RET(); RET();
SetJumpTarget(skipCheck); 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 // These functions branch and therefore only need to be called in the
// end of each block and in this order // end of each block and in this order
ABI_CallFunction((void *)&DSPInterpreter::HandleLoop); ABI_CallFunction((void *)&DSPInterpreter::HandleLoop);
// ABI_PopAllCalleeSavedRegsAndAdjustStack(); ABI_RestoreStack(0);
RET(); RET();
SetJumpTarget(rLoopAddressExit); SetJumpTarget(rLoopAddressExit);
@ -180,7 +180,7 @@ const u8 *DSPEmitter::Compile(int start_addr) {
addr += opcode->size; addr += opcode->size;
} }
// ABI_PopAllCalleeSavedRegsAndAdjustStack(); ABI_RestoreStack(0);
RET(); RET();
blocks[start_addr] = (CompiledCode)entryPoint; blocks[start_addr] = (CompiledCode)entryPoint;