Mercurial > pub > dyncall > dyncall
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 |