From 179ad35c2e6dff0c367dedb63c47a78c6cd052a5 Mon Sep 17 00:00:00 2001 From: aroulin Date: Wed, 26 Aug 2015 09:12:14 +0200 Subject: x64: Proper stack alignment in shader JIT function calls Import Dolphin stack handling and register saving routines Also removes the x86 parts from abi files --- src/video_core/shader/shader_jit_x64.cpp | 43 +++++++++++++------------------- 1 file changed, 17 insertions(+), 26 deletions(-) (limited to 'src/video_core/shader/shader_jit_x64.cpp') diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp index c7b63a9b7..d6011832c 100644 --- a/src/video_core/shader/shader_jit_x64.cpp +++ b/src/video_core/shader/shader_jit_x64.cpp @@ -122,6 +122,14 @@ static const X64Reg ONE = XMM14; /// Constant vector of [-0.f, -0.f, -0.f, -0.f], used to efficiently negate a vector with XOR static const X64Reg NEGBIT = XMM15; +// State registers that must not be modified by external functions calls +// Scratch registers, e.g., SRC1 and SCRATCH, have to be saved on the side if needed +static const BitSet32 persistent_regs = { + UNIFORMS, REGISTERS, // Pointers to register blocks + ADDROFFS_REG_0, ADDROFFS_REG_1, LOOPCOUNT_REG, COND0, COND1, // Cached registers + ONE+16, NEGBIT+16, // Constants +}; + /// Raw constant for the source register selector that indicates no swizzling is performed static const u8 NO_SRC_REG_SWIZZLE = 0x1b; /// Raw constant for the destination register enable mask that indicates all components are enabled @@ -295,20 +303,8 @@ void JitCompiler::Compile_UniformCondition(Instruction instr) { CMP(sizeof(bool) * 8, MDisp(UNIFORMS, offset), Imm8(0)); } -void JitCompiler::Compile_PushCallerSavedXMM() { -#ifndef _WIN32 - SUB(64, R(RSP), Imm8(2 * 16)); - MOVUPS(MDisp(RSP, 16), ONE); - MOVUPS(MDisp(RSP, 0), NEGBIT); -#endif -} - -void JitCompiler::Compile_PopCallerSavedXMM() { -#ifndef _WIN32 - MOVUPS(NEGBIT, MDisp(RSP, 0)); - MOVUPS(ONE, MDisp(RSP, 16)); - ADD(64, R(RSP), Imm8(2 * 16)); -#endif +BitSet32 JitCompiler::PersistentCallerSavedRegs() { + return persistent_regs & ABI_ALL_CALLER_SAVED; } void JitCompiler::Compile_ADD(Instruction instr) { @@ -390,12 +386,9 @@ void JitCompiler::Compile_EX2(Instruction instr) { Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1); MOVSS(XMM0, R(SRC1)); - // The following will actually break the stack alignment - ABI_PushAllCallerSavedRegsAndAdjustStack(); - Compile_PushCallerSavedXMM(); + ABI_PushRegistersAndAdjustStack(PersistentCallerSavedRegs(), 0); ABI_CallFunction(reinterpret_cast(exp2f)); - Compile_PopCallerSavedXMM(); - ABI_PopAllCallerSavedRegsAndAdjustStack(); + ABI_PopRegistersAndAdjustStack(PersistentCallerSavedRegs(), 0); SHUFPS(XMM0, R(XMM0), _MM_SHUFFLE(0, 0, 0, 0)); MOVAPS(SRC1, R(XMM0)); @@ -406,12 +399,9 @@ void JitCompiler::Compile_LG2(Instruction instr) { Compile_SwizzleSrc(instr, 1, instr.common.src1, SRC1); MOVSS(XMM0, R(SRC1)); - // The following will actually break the stack alignment - ABI_PushAllCallerSavedRegsAndAdjustStack(); - Compile_PushCallerSavedXMM(); + ABI_PushRegistersAndAdjustStack(PersistentCallerSavedRegs(), 0); ABI_CallFunction(reinterpret_cast(log2f)); - Compile_PopCallerSavedXMM(); - ABI_PopAllCallerSavedRegsAndAdjustStack(); + ABI_PopRegistersAndAdjustStack(PersistentCallerSavedRegs(), 0); SHUFPS(XMM0, R(XMM0), _MM_SHUFFLE(0, 0, 0, 0)); MOVAPS(SRC1, R(XMM0)); @@ -560,7 +550,7 @@ void JitCompiler::Compile_NOP(Instruction instr) { } void JitCompiler::Compile_END(Instruction instr) { - ABI_PopAllCalleeSavedRegsAndAdjustStack(); + ABI_PopRegistersAndAdjustStack(ABI_ALL_CALLEE_SAVED, 8); RET(); } @@ -755,7 +745,8 @@ CompiledShader* JitCompiler::Compile() { const auto& code = g_state.vs.program_code; unsigned offset = g_state.regs.vs.main_offset; - ABI_PushAllCalleeSavedRegsAndAdjustStack(); + // The stack pointer is 8 modulo 16 at the entry of a procedure + ABI_PushRegistersAndAdjustStack(ABI_ALL_CALLEE_SAVED, 8); MOV(PTRBITS, R(REGISTERS), R(ABI_PARAM1)); MOV(PTRBITS, R(UNIFORMS), ImmPtr(&g_state.vs.uniforms)); -- cgit v1.2.3