mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 06:39:46 -06:00
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:
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user