{-# language NoMonomorphismRestriction #-}
{-# language CPP #-}
{-# language DataKinds #-}
module CodeGen.X86.CallConv where
import Foreign
import Data.Monoid
import CodeGen.X86.Asm
import CodeGen.X86.CodeGen
#if defined (mingw32_HOST_OS) || defined (mingw64_HOST_OS)
callFun :: Operand RW S64 -> FunPtr a -> Code
callFun r p = do
sub rsp 32
mov r (fromIntegral $ ptrToIntPtr $ castFunPtrToPtr p)
call r
add rsp 32
#elif defined (darwin_HOST_OS)
callFun :: Operand RW S64 -> FunPtr a -> Code
callFun r p = do
push r15
mov r15 15
not_ r15
and_ r15 rsp
xchg r15 rsp
mov r (fromIntegral $ ptrToIntPtr $ castFunPtrToPtr p)
call r
mov rsp r15
pop r15
#else
callFun :: Operand RW S64 -> FunPtr a -> Code
callFun r p = do
mov r $ fromIntegral $ ptrToIntPtr $ castFunPtrToPtr p
call r
#endif
saveNonVolatile :: Code -> Code
saveNonVolatile code = prologue >> code >> epilogue >> ret
saveR12R15 :: Code -> Code
saveR12R15 code = do
push r12
push r13
push r14
push r15
code
pop r15
pop r14
pop r13
pop r12
#if defined (mingw32_HOST_OS) || defined (mingw64_HOST_OS)
arg1 = rcx
arg2 = rdx
arg3 = r8
arg4 = r9
result = rax
prologue = do
push rbp
push rbx
push rdi
push rsi
epilogue = do
pop rsi
pop rdi
pop rbx
pop rbp
#else
arg1 = rdi
arg2 = rsi
arg3 = rdx
arg4 = rcx
arg5 = r8
arg6 = r9
result = rax
prologue = do
push rbp
push rbx
epilogue = do
pop rbx
pop rbp
#endif