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/common/x64/emitter.h | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'src/common/x64/emitter.h') diff --git a/src/common/x64/emitter.h b/src/common/x64/emitter.h index a49cd2cf1..2dd0dc94e 100644 --- a/src/common/x64/emitter.h +++ b/src/common/x64/emitter.h @@ -18,6 +18,7 @@ #pragma once #include "common/assert.h" +#include "common/bit_set.h" #include "common/common_types.h" #include "common/code_block.h" @@ -356,7 +357,7 @@ private: void WriteFloatLoadStore(int bits, FloatOp op, FloatOp op_80b, const OpArg& arg); void WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg& a1, const OpArg& a2); - void ABI_CalculateFrameSize(u32 mask, size_t rsp_alignment, size_t needed_frame_size, size_t* shadowp, size_t* subtractionp, size_t* xmm_offsetp); + void ABI_CalculateFrameSize(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size, size_t* shadowp, size_t* subtractionp, size_t* xmm_offsetp); protected: void Write8(u8 value); @@ -1007,25 +1008,26 @@ public: ABI_CallFunctionC((const void*)func, param1); } - // A function that doesn't have any control over what it will do to regs, - // such as the dispatcher, should be surrounded by these. - void ABI_PushAllCalleeSavedRegsAndAdjustStack(); - void ABI_PopAllCalleeSavedRegsAndAdjustStack(); - - // A function that doesn't know anything about it's surroundings, should - // be surrounded by these to establish a safe environment, where it can roam free. - // An example is a backpatch injected function. - void ABI_PushAllCallerSavedRegsAndAdjustStack(); - void ABI_PopAllCallerSavedRegsAndAdjustStack(); - - unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize); - void ABI_AlignStack(unsigned int frameSize); - void ABI_RestoreStack(unsigned int frameSize); - - // Sets up a __cdecl function. - // Only x64 really needs the parameter count. - void ABI_EmitPrologue(int maxCallParams); - void ABI_EmitEpilogue(int maxCallParams); + /** + * Saves specified registers and adjusts the stack to be 16-byte aligned as required by the ABI + * + * @param mask Registers to push on the stack (high 16 bits are XMMs, low 16 bits are GPRs) + * @param rsp_alignment Current alignment of the stack pointer, must be 0 or 8 + * @param needed_frame_size Additional space needed, e.g., for function arguments passed on the stack + * @return Size of the shadow space, i.e., offset of the frame + */ + size_t ABI_PushRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size = 0); + + /** + * Restores specified registers and adjusts the stack to its original alignment, i.e., the alignment before + * the matching PushRegistersAndAdjustStack. + * + * @param mask Registers to restores from the stack (high 16 bits are XMMs, low 16 bits are GPRs) + * @param rsp_alignment Original alignment before the matching PushRegistersAndAdjustStack, must be 0 or 8 + * @param needed_frame_size Additional space that was needed + * @warning Stack must be currently 16-byte aligned + */ + void ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size = 0); #ifdef _M_IX86 static int ABI_GetNumXMMRegs() { return 8; } -- cgit v1.2.3