comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:3e629dc19168
1 /*
2
3 Package: dyncall
4 Library: dyncall
5 File: dyncall/dyncall_call_x64.S
6 Description: All x64 abi call kernel implementation
7 License:
8
9 Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>,
10 Tassilo Philipp <tphilipp@potion-studios.com>
11
12 Permission to use, copy, modify, and distribute this software for any
13 purpose with or without fee is hereby granted, provided that the above
14 copyright notice and this permission notice appear in all copies.
15
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
24 */
25
26
27
28 #include "../portasm/portasm-x64.S"
29
30 BEGIN_ASM
31
32 /*---------------------------------------------------------------------------
33
34 Call Kernel for x64 System V
35
36 Input:
37 RDI : size of arguments to be passed via stack
38 RSI : pointer to arguments to be passed via the stack
39 RDX : pointer to arguments of integral/pointer type to be passed via registers
40 RCX : pointer to arguments of floating point type to be passed via registers
41 R8 : target function pointer
42
43 */
44
45 GLOBAL(dcCall_x64_sysv)
46 BEGIN_PROC(dcCall_x64_sysv)
47
48 push RBP /* Pseudo-prolog - preserve RBP. */
49 push RBX /* Preserve RBX and store pointer to function in it. */
50
51 mov RBP, RSP /* Store stack pointer in RBP. */
52
53 mov RBX, R8
54
55 movsd XMM0, qword ptr[RCX ] /* Copy first 8 floats to XMM0-XMM7 (this makes RCX free to use). */
56 movsd XMM1, qword ptr[RCX+ 8]
57 movsd XMM2, qword ptr[RCX+16]
58 movsd XMM3, qword ptr[RCX+24]
59 movsd XMM4, qword ptr[RCX+32]
60 movsd XMM5, qword ptr[RCX+40]
61 movsd XMM6, qword ptr[RCX+48]
62 movsd XMM7, qword ptr[RCX+56]
63
64 sub RSP, RDI /* Setup stack frame by subtracting the size of the arguments. */
65
66 and RSP, -32 /* Align stack to 32-byte border. */
67
68 mov RCX, RDI /* Store number of bytes to copy to stack in RCX (for rep movsb). */
69 mov RDI, RSP /* Store pointer to beginning of stack arguments in RDI (for rep movsb). */
70
71 rep movsb /* @@@ should be optimized (e.g. movq) */
72
73 mov RDI, qword ptr[RDX ] /* Copy first six int/pointer arguments to RDI, RSI, RDX, RCX, R8, R9. */
74 mov RSI, qword ptr[RDX+ 8]
75 mov RCX, qword ptr[RDX+24]
76 mov R8, qword ptr[RDX+32]
77 mov R9, qword ptr[RDX+40]
78 mov RDX, qword ptr[RDX+16] /* Set RDX last to not overwrite it to soon. */
79
80 mov AL, 8 /* Put upper bound of number of used xmm registers in AL. */
81 call RBX /* Invoke function. */
82
83 mov RSP, RBP /* Restore stack pointer (such that we can pop the preserved vALues). */
84
85 pop RBX /* Restore RBX. */
86 pop RBP /* Pseudo-epilog. */
87
88 ret
89 END_PROC(dcCall_x64_sysv)
90
91 /*---------------------------------------------------------------------------
92
93 Call Kernel for x64 Win64
94
95 Input:
96 RCX : size of arguments to be passed via stack
97 RDX : pointer to arguments to be passed via the stack
98 R8 : pointer to arguments of integral/pointer type to be passed via registers
99 R9 : target function pointer
100
101 */
102
103 GLOBAL(dcCall_x64_win64)
104 BEGIN_PROC(dcCall_x64_win64)
105
106 push RBP /* Pseudo-prolog - preserve RBP. */
107 push RSI /* Preserve RSI and RDI. */
108 push RDI
109
110 /* and RSP, -16 /* Align frame to 16 bytes. */
111 mov RBP, RSP /* Store stack pointer in RBP. */
112
113 add RCX, 15 /* Align stack size to 16 bytes. */
114 and RCX, -16
115 sub RSP, RCX /* Setup stack frame by subtracting the size of the arguments. */
116
117 mov RSI, RDX /* Let RSI point to the arguments. */
118 mov RDI, RSP /* Store pointer to beginning of stack arguments in RDI (for rep movsb). */
119 mov RAX, R9 /* Put function address in RAX. */
120
121 rep movsb /* @@@ should be optimized (e.g. movq) */
122
123 mov RCX, qword ptr[R8 ] /* Copy first four arguments to RCX, RDX, R8, R9 and XMM0-XMM3. */
124 mov RDX, qword ptr[R8+ 8]
125 mov R9, qword ptr[R8+24] /* Set R9 first to not overwrite R8 too soon. */
126 mov R8, qword ptr[R8+16]
127 movd XMM0, RCX
128 movd XMM1, RDX
129 movd XMM2, R8
130 movd XMM3, R9
131
132 push R9 /* Push first four arguments onto the stack preserve area. */
133 push R8
134 push RDX
135 push RCX
136
137 call RAX /* Invoke function. */
138
139 mov RSP, RBP /* Restore stack pointer (such that we can pop the preserved vALues). */
140
141 pop RDI /* Restore RSI and RDI. */
142 pop RSI
143 pop RBP /* Pseudo-epilog. */
144
145 ret
146
147 END_PROC(dcCall_x64_win64)
148
149 END_ASM
150