0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncall
|
|
5 File: dyncall/dyncall_call_x64-att.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-att.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 Notes:
|
|
43 RSP+8: is always 16-byte aligned (32-byte align if __m256 is used)
|
|
44 */
|
|
45
|
|
46 GLOBAL(dcCall_x64_sysv)
|
|
47 BEGIN_PROC(dcCall_x64_sysv)
|
|
48 PUSH(RBP) /* Pseudo-prolog - preserve RBP. */
|
|
49 PUSH(RBX) /* Preserve RBX and store pointer to function in it. */
|
|
50 MOV(RSP,RBP) /* Store stack pointer in RBP. */
|
|
51 MOV(R8 ,RBX)
|
|
52 MOVSD(QWORD(RCX,0) ,XMM0) /* Copy first 8 floats to XMM0-XMM7. */
|
|
53 MOVSD(QWORD(RCX,8) ,XMM1)
|
|
54 MOVSD(QWORD(RCX,16),XMM2)
|
|
55 MOVSD(QWORD(RCX,24),XMM3)
|
|
56 MOVSD(QWORD(RCX,32),XMM4)
|
|
57 MOVSD(QWORD(RCX,40),XMM5)
|
|
58 MOVSD(QWORD(RCX,48),XMM6)
|
|
59 MOVSD(QWORD(RCX,56),XMM7)
|
|
60
|
|
61 ADD(LIT(31),RDI) /* Align stack to 32-byte. */
|
|
62 AND(LIT(-32),RDI)
|
|
63 ADD(LIT(8),RDI) /* Adjust by 8-byte for the return-address. */
|
|
64 SUB(RDI,RSP) /* Setup stack frame by subtracting the size of arguments. */
|
|
65
|
|
66 MOV(RDI,RCX) /* Store number of bytes to copy to stack in RCX (for rep movsb). */
|
|
67 MOV(RSP,RDI) /* Store pointer to beginning of stack arguments in RDI (for rep movsb). */
|
|
68
|
|
69 REP(MOVSB) /* copy bytes (@@@ should be optimized). */
|
|
70
|
|
71 MOV(QWORD(RDX,0),RDI) /* copy first six int/pointer arguments to RDI, RSI, RDX, RCX, R8, R9. */
|
|
72 MOV(QWORD(RDX,8),RSI)
|
|
73 MOV(QWORD(RDX,24),RCX)
|
|
74 MOV(QWORD(RDX,32),R8)
|
|
75 MOV(QWORD(RDX,40),R9)
|
|
76 MOV(QWORD(RDX,16),RDX) /* Set RDX last to not overwrite it to soon. */
|
|
77
|
|
78 MOVB(LIT(8),AL) /* Put upper bound of number of used xmm registers in AL. */
|
|
79 CALL_REG(RBX) /* Call function. */
|
|
80
|
|
81 MOV(RBP,RSP) /* Restore stack pointer. */
|
|
82 POP(RBX) /* Restore RBX. */
|
|
83 POP(RBP) /* Pseudo-epilog. */
|
|
84 RET()
|
|
85 END_PROC(dcCALl_x64_sysv)
|
|
86
|
|
87 /*---------------------------------------------------------------------------
|
|
88
|
|
89 Call Kernel for x64 Win64
|
|
90
|
|
91 Input:
|
|
92 RCX : size of arguments to be passed via stack
|
|
93 RDX : pointer to arguments to be passed via the stack
|
|
94 R8 : pointer to arguments of integral/pointer type to be passed via registers
|
|
95 R9 : target function pointer
|
|
96
|
|
97 */
|
|
98
|
|
99 GLOBAL(dcCall_x64_win64)
|
|
100 BEGIN_PROC(dcCall_x64_win64)
|
|
101
|
|
102 PUSH(RBP) /* Pseudo-prolog - preserve RBP. */
|
|
103 PUSH(RSI) /* Preserve RSI and RDI. */
|
|
104 PUSH(RDI)
|
|
105
|
|
106 MOV(RSP,RBP) /* Store stack pointer in RBP. */
|
|
107
|
|
108 ADD(LIT(15),RCX) /* Align stack size to 16 bytes. */
|
|
109 AND(LIT(-16),RCX)
|
|
110 SUB(RCX,RSP) /* Setup stack frame by subtracting the size of the arguments. */
|
|
111
|
|
112
|
|
113 MOV(RDX, RSI) /* Let RSI point to the arguments. */
|
|
114 MOV(RSP, RDI) /* Store pointer to beginning of stack arguments in RDI (for rep movsb). */
|
|
115 MOV(R9, RAX) /* Put function address in RAX. */
|
|
116
|
|
117 REP(MOVSB) /* @@@ should be optimized (e.g. movq) */
|
|
118
|
|
119 MOV(QWORD(R8,0),RCX) /* Copy first four arguments to RCX, RDX, R9, R8 ( and XMM0-XMM3. ) */
|
|
120 MOV(QWORD(R8,8),RDX)
|
|
121 MOV(QWORD(R8,24),R9)
|
|
122 MOV(QWORD(R8,16),R8)
|
|
123
|
|
124 MOVD(RCX, XMM0)
|
|
125 MOVD(RDX, XMM1)
|
|
126 MOVD(R8, XMM2)
|
|
127 MOVD(R9, XMM3)
|
|
128
|
|
129 PUSH(R9) /* Push first four arguments onto the stack preserve area. */
|
|
130 PUSH(R8)
|
|
131 PUSH(RDX)
|
|
132 PUSH(RCX)
|
|
133
|
|
134 CALL_REG(RAX) /* Invoke function. */
|
|
135
|
|
136 MOV(RBP, RSP) /* Restore stack pointer (such that we can pop the preserved vALues). */
|
|
137
|
|
138 POP(RDI) /* Restore RSI and RDI. */
|
|
139 POP(RSI)
|
|
140 POP(RBP) /* Pseudo-epilog. */
|
|
141
|
|
142 RET()
|
|
143
|
|
144 END_PROC(dcCall_x64_win64)
|
|
145
|
|
146 END_ASM
|
|
147
|