diff dyncall/dyncall_call_x64.S @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dyncall/dyncall_call_x64.S	Thu Mar 19 22:24:28 2015 +0100
@@ -0,0 +1,150 @@
+/*
+
+ Package: dyncall
+ Library: dyncall
+ File: dyncall/dyncall_call_x64.S
+ Description: All x64 abi call kernel implementation
+ License:
+
+   Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>,
+                           Tassilo Philipp <tphilipp@potion-studios.com>
+
+   Permission to use, copy, modify, and distribute this software for any
+   purpose with or without fee is hereby granted, provided that the above
+   copyright notice and this permission notice appear in all copies.
+
+   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+*/
+
+
+
+#include "../portasm/portasm-x64.S"
+
+BEGIN_ASM
+
+/*---------------------------------------------------------------------------
+  
+  Call Kernel for x64 System V
+  
+  Input:
+    RDI : size of arguments to be passed via stack 
+    RSI : pointer to arguments to be passed via the stack 
+    RDX : pointer to arguments of integral/pointer type to be passed via registers 
+    RCX : pointer to arguments of floating point type to be passed via registers 
+    R8  : target function pointer 
+
+*/
+
+GLOBAL(dcCall_x64_sysv)
+BEGIN_PROC(dcCall_x64_sysv)
+
+	push	RBP			/* Pseudo-prolog - preserve RBP. */
+	push	RBX			/* Preserve RBX and store pointer to function in it. */
+
+	mov	RBP, RSP		/* Store stack pointer in RBP.   */
+
+	mov	RBX, R8
+
+	movsd	XMM0, qword ptr[RCX   ]	/* Copy first 8 floats to XMM0-XMM7 (this makes RCX free to use). */
+	movsd	XMM1, qword ptr[RCX+ 8]
+	movsd	XMM2, qword ptr[RCX+16]
+	movsd	XMM3, qword ptr[RCX+24]
+	movsd	XMM4, qword ptr[RCX+32]
+	movsd	XMM5, qword ptr[RCX+40]
+	movsd	XMM6, qword ptr[RCX+48]
+	movsd	XMM7, qword ptr[RCX+56]
+
+	sub	RSP, RDI		/* Setup stack frame by subtracting the size of the arguments. */
+
+	and     RSP, -32		/* Align stack to 32-byte border. */
+
+	mov	RCX, RDI		/* Store number of bytes to copy to stack in RCX (for rep movsb). */
+	mov	RDI, RSP		/* Store pointer to beginning of stack arguments in RDI (for rep movsb). */
+
+	rep movsb			/* @@@ should be optimized (e.g. movq) */
+
+	mov	RDI, qword ptr[RDX   ]	/* Copy first six int/pointer arguments to RDI, RSI, RDX, RCX, R8, R9. */
+	mov	RSI, qword ptr[RDX+ 8]
+	mov	RCX, qword ptr[RDX+24]
+	mov	R8,  qword ptr[RDX+32]
+	mov	R9,  qword ptr[RDX+40]
+	mov	RDX, qword ptr[RDX+16]	/* Set RDX last to not overwrite it to soon. */
+
+	mov	AL, 8						/* Put upper bound of number of used xmm registers in AL. */
+	call	RBX						/* Invoke function. */
+
+	mov	RSP, RBP					/* Restore stack pointer (such that we can pop the preserved vALues). */
+
+	pop	RBX						/* Restore RBX. */
+	pop	RBP						/* Pseudo-epilog. */
+
+	ret
+END_PROC(dcCall_x64_sysv)
+
+/*---------------------------------------------------------------------------
+
+  Call Kernel for x64 Win64
+	
+  Input:
+    RCX : size of arguments to be passed via stack 
+    RDX : pointer to arguments to be passed via the stack 
+    R8  : pointer to arguments of integral/pointer type to be passed via registers 
+    R9  : target function pointer
+
+*/
+
+GLOBAL(dcCall_x64_win64)
+BEGIN_PROC(dcCall_x64_win64)
+
+	push	RBP			/* Pseudo-prolog - preserve RBP. */
+	push	RSI			/* Preserve RSI and RDI. */
+	push	RDI
+	
+	/* and  RSP, -16		/* Align frame to 16 bytes.    */
+	mov	RBP, RSP		/* Store stack pointer in RBP. */
+
+	add	RCX, 15			/* Align stack size to 16 bytes. */
+	and	RCX, -16
+	sub	RSP, RCX		/* Setup stack frame by subtracting the size of the arguments. */
+
+	mov	RSI, RDX		/* Let RSI point to the arguments. */
+	mov	RDI, RSP		/* Store pointer to beginning of stack arguments in RDI (for rep movsb). */
+	mov	RAX, R9			/* Put function address in RAX. */
+
+	rep movsb			/* @@@ should be optimized (e.g. movq) */
+
+	mov	RCX,  qword ptr[R8   ]	/* Copy first four arguments to RCX, RDX, R8, R9 and XMM0-XMM3. */
+	mov	RDX,  qword ptr[R8+ 8]
+	mov	R9,   qword ptr[R8+24]	/* Set R9 first to not overwrite R8 too soon. */
+	mov	R8,   qword ptr[R8+16]
+	movd	XMM0, RCX
+	movd	XMM1, RDX
+	movd	XMM2, R8
+	movd	XMM3, R9
+
+	push	R9			/* Push first four arguments onto the stack preserve area. */
+	push	R8
+	push	RDX
+	push	RCX
+
+	call	RAX			/* Invoke function. */
+
+	mov	RSP, RBP		/* Restore stack pointer (such that we can pop the preserved vALues). */
+
+	pop	RDI			/* Restore RSI and RDI. */
+	pop	RSI
+	pop	RBP			/* Pseudo-epilog. */
+
+	ret
+
+END_PROC(dcCall_x64_win64)
+
+END_ASM
+