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