0
|
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
|