]>
Commit | Line | Data |
---|---|---|
92456a4e | 1 | #ifdef __x86_64__ |
062b8279 AH |
2 | #define LIBFFI_ASM |
3 | #include <fficonfig.h> | |
4 | #include <ffi.h> | |
b1760f7f | 5 | #include <ffi_cfi.h> |
92456a4e | 6 | #include "asmnames.h" |
54fde020 | 7 | |
b1760f7f RH |
8 | #if defined(HAVE_AS_CFI_PSEUDO_OP) |
9 | .cfi_sections .debug_frame | |
10 | #endif | |
34fa7690 | 11 | |
92456a4e L |
12 | #ifdef X86_WIN64 |
13 | #define SEH(...) __VA_ARGS__ | |
b1760f7f RH |
14 | #define arg0 %rcx |
15 | #define arg1 %rdx | |
16 | #define arg2 %r8 | |
17 | #define arg3 %r9 | |
34fa7690 | 18 | #else |
92456a4e L |
19 | #define SEH(...) |
20 | #define arg0 %rdi | |
21 | #define arg1 %rsi | |
22 | #define arg2 %rdx | |
23 | #define arg3 %rcx | |
34fa7690 AG |
24 | #endif |
25 | ||
92456a4e L |
26 | /* This macro allows the safe creation of jump tables without an |
27 | actual table. The entry points into the table are all 8 bytes. | |
28 | The use of ORG asserts that we're at the correct location. */ | |
29 | /* ??? The clang assembler doesn't handle .org with symbolic expressions. */ | |
30 | #if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__)) | |
31 | # define E(BASE, X) .balign 8 | |
32 | #else | |
33 | # define E(BASE, X) .balign 8; .org BASE + (X) * 8 | |
34 | #endif | |
b1760f7f RH |
35 | |
36 | .text | |
37 | ||
38 | /* ffi_call_win64 (void *stack, struct win64_call_frame *frame, void *r10) | |
39 | ||
40 | Bit o trickiness here -- FRAME is the base of the stack frame | |
41 | for this function. This has been allocated by ffi_call. We also | |
42 | deallocate some of the stack that has been alloca'd. */ | |
43 | ||
44 | .align 8 | |
92456a4e L |
45 | .globl C(ffi_call_win64) |
46 | FFI_HIDDEN(C(ffi_call_win64)) | |
b1760f7f | 47 | |
92456a4e L |
48 | SEH(.seh_proc ffi_call_win64) |
49 | C(ffi_call_win64): | |
b1760f7f | 50 | cfi_startproc |
92456a4e | 51 | _CET_ENDBR |
b1760f7f RH |
52 | /* Set up the local stack frame and install it in rbp/rsp. */ |
53 | movq (%rsp), %rax | |
54 | movq %rbp, (arg1) | |
55 | movq %rax, 8(arg1) | |
56 | movq arg1, %rbp | |
57 | cfi_def_cfa(%rbp, 16) | |
58 | cfi_rel_offset(%rbp, 0) | |
92456a4e L |
59 | SEH(.seh_pushreg %rbp) |
60 | SEH(.seh_setframe %rbp, 0) | |
61 | SEH(.seh_endprologue) | |
b1760f7f RH |
62 | movq arg0, %rsp |
63 | ||
64 | movq arg2, %r10 | |
65 | ||
66 | /* Load all slots into both general and xmm registers. */ | |
67 | movq (%rsp), %rcx | |
68 | movsd (%rsp), %xmm0 | |
69 | movq 8(%rsp), %rdx | |
70 | movsd 8(%rsp), %xmm1 | |
71 | movq 16(%rsp), %r8 | |
72 | movsd 16(%rsp), %xmm2 | |
73 | movq 24(%rsp), %r9 | |
74 | movsd 24(%rsp), %xmm3 | |
75 | ||
76 | call *16(%rbp) | |
77 | ||
78 | movl 24(%rbp), %ecx | |
79 | movq 32(%rbp), %r8 | |
80 | leaq 0f(%rip), %r10 | |
81 | cmpl $FFI_TYPE_SMALL_STRUCT_4B, %ecx | |
82 | leaq (%r10, %rcx, 8), %r10 | |
83 | ja 99f | |
92456a4e | 84 | _CET_NOTRACK jmp *%r10 |
b1760f7f RH |
85 | |
86 | /* Below, we're space constrained most of the time. Thus we eschew the | |
87 | modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes). */ | |
88 | .macro epilogue | |
89 | leaveq | |
90 | cfi_remember_state | |
91 | cfi_def_cfa(%rsp, 8) | |
92 | cfi_restore(%rbp) | |
93 | ret | |
94 | cfi_restore_state | |
95 | .endm | |
96 | ||
97 | .align 8 | |
98 | 0: | |
92456a4e | 99 | E(0b, FFI_TYPE_VOID) |
b1760f7f | 100 | epilogue |
92456a4e | 101 | E(0b, FFI_TYPE_INT) |
b1760f7f RH |
102 | movslq %eax, %rax |
103 | movq %rax, (%r8) | |
104 | epilogue | |
92456a4e | 105 | E(0b, FFI_TYPE_FLOAT) |
b1760f7f RH |
106 | movss %xmm0, (%r8) |
107 | epilogue | |
92456a4e | 108 | E(0b, FFI_TYPE_DOUBLE) |
b1760f7f RH |
109 | movsd %xmm0, (%r8) |
110 | epilogue | |
92456a4e L |
111 | // FFI_TYPE_LONGDOUBLE may be FFI_TYPE_DOUBLE but we need a different value here. |
112 | E(0b, FFI_TYPE_DOUBLE + 1) | |
113 | call PLT(C(abort)) | |
114 | E(0b, FFI_TYPE_UINT8) | |
b1760f7f RH |
115 | movzbl %al, %eax |
116 | movq %rax, (%r8) | |
117 | epilogue | |
92456a4e | 118 | E(0b, FFI_TYPE_SINT8) |
b1760f7f RH |
119 | movsbq %al, %rax |
120 | jmp 98f | |
92456a4e | 121 | E(0b, FFI_TYPE_UINT16) |
b1760f7f RH |
122 | movzwl %ax, %eax |
123 | movq %rax, (%r8) | |
124 | epilogue | |
92456a4e | 125 | E(0b, FFI_TYPE_SINT16) |
b1760f7f RH |
126 | movswq %ax, %rax |
127 | jmp 98f | |
92456a4e | 128 | E(0b, FFI_TYPE_UINT32) |
b1760f7f RH |
129 | movl %eax, %eax |
130 | movq %rax, (%r8) | |
131 | epilogue | |
92456a4e | 132 | E(0b, FFI_TYPE_SINT32) |
b1760f7f RH |
133 | movslq %eax, %rax |
134 | movq %rax, (%r8) | |
135 | epilogue | |
92456a4e | 136 | E(0b, FFI_TYPE_UINT64) |
b1760f7f RH |
137 | 98: movq %rax, (%r8) |
138 | epilogue | |
92456a4e | 139 | E(0b, FFI_TYPE_SINT64) |
b1760f7f RH |
140 | movq %rax, (%r8) |
141 | epilogue | |
92456a4e | 142 | E(0b, FFI_TYPE_STRUCT) |
b1760f7f | 143 | epilogue |
92456a4e | 144 | E(0b, FFI_TYPE_POINTER) |
b1760f7f RH |
145 | movq %rax, (%r8) |
146 | epilogue | |
92456a4e L |
147 | E(0b, FFI_TYPE_COMPLEX) |
148 | call PLT(C(abort)) | |
149 | E(0b, FFI_TYPE_SMALL_STRUCT_1B) | |
b1760f7f RH |
150 | movb %al, (%r8) |
151 | epilogue | |
92456a4e | 152 | E(0b, FFI_TYPE_SMALL_STRUCT_2B) |
b1760f7f RH |
153 | movw %ax, (%r8) |
154 | epilogue | |
92456a4e | 155 | E(0b, FFI_TYPE_SMALL_STRUCT_4B) |
b1760f7f RH |
156 | movl %eax, (%r8) |
157 | epilogue | |
158 | ||
159 | .align 8 | |
92456a4e | 160 | 99: call PLT(C(abort)) |
b1760f7f | 161 | |
92456a4e | 162 | epilogue |
b1760f7f RH |
163 | |
164 | cfi_endproc | |
92456a4e | 165 | SEH(.seh_endproc) |
062b8279 | 166 | |
54fde020 | 167 | |
b1760f7f RH |
168 | /* 32 bytes of outgoing register stack space, 8 bytes of alignment, |
169 | 16 bytes of result, 32 bytes of xmm registers. */ | |
170 | #define ffi_clo_FS (32+8+16+32) | |
171 | #define ffi_clo_OFF_R (32+8) | |
172 | #define ffi_clo_OFF_X (32+8+16) | |
173 | ||
174 | .align 8 | |
92456a4e L |
175 | .globl C(ffi_go_closure_win64) |
176 | FFI_HIDDEN(C(ffi_go_closure_win64)) | |
b1760f7f | 177 | |
92456a4e L |
178 | SEH(.seh_proc ffi_go_closure_win64) |
179 | C(ffi_go_closure_win64): | |
b1760f7f | 180 | cfi_startproc |
92456a4e | 181 | _CET_ENDBR |
b1760f7f | 182 | /* Save all integer arguments into the incoming reg stack space. */ |
92456a4e L |
183 | movq %rcx, 8(%rsp) |
184 | movq %rdx, 16(%rsp) | |
185 | movq %r8, 24(%rsp) | |
186 | movq %r9, 32(%rsp) | |
187 | ||
188 | movq 8(%r10), %rcx /* load cif */ | |
189 | movq 16(%r10), %rdx /* load fun */ | |
190 | movq %r10, %r8 /* closure is user_data */ | |
b1760f7f RH |
191 | jmp 0f |
192 | cfi_endproc | |
92456a4e | 193 | SEH(.seh_endproc) |
54fde020 | 194 | |
b1760f7f | 195 | .align 8 |
92456a4e L |
196 | .globl C(ffi_closure_win64) |
197 | FFI_HIDDEN(C(ffi_closure_win64)) | |
b1760f7f | 198 | |
92456a4e L |
199 | SEH(.seh_proc ffi_closure_win64) |
200 | C(ffi_closure_win64): | |
b1760f7f | 201 | cfi_startproc |
92456a4e | 202 | _CET_ENDBR |
b1760f7f | 203 | /* Save all integer arguments into the incoming reg stack space. */ |
92456a4e L |
204 | movq %rcx, 8(%rsp) |
205 | movq %rdx, 16(%rsp) | |
206 | movq %r8, 24(%rsp) | |
207 | movq %r9, 32(%rsp) | |
208 | ||
209 | movq FFI_TRAMPOLINE_SIZE(%r10), %rcx /* load cif */ | |
210 | movq FFI_TRAMPOLINE_SIZE+8(%r10), %rdx /* load fun */ | |
211 | movq FFI_TRAMPOLINE_SIZE+16(%r10), %r8 /* load user_data */ | |
b1760f7f RH |
212 | 0: |
213 | subq $ffi_clo_FS, %rsp | |
214 | cfi_adjust_cfa_offset(ffi_clo_FS) | |
92456a4e L |
215 | SEH(.seh_stackalloc ffi_clo_FS) |
216 | SEH(.seh_endprologue) | |
062b8279 | 217 | |
b1760f7f RH |
218 | /* Save all sse arguments into the stack frame. */ |
219 | movsd %xmm0, ffi_clo_OFF_X(%rsp) | |
220 | movsd %xmm1, ffi_clo_OFF_X+8(%rsp) | |
221 | movsd %xmm2, ffi_clo_OFF_X+16(%rsp) | |
222 | movsd %xmm3, ffi_clo_OFF_X+24(%rsp) | |
54fde020 | 223 | |
92456a4e L |
224 | leaq ffi_clo_OFF_R(%rsp), %r9 |
225 | call PLT(C(ffi_closure_win64_inner)) | |
54fde020 | 226 | |
b1760f7f RH |
227 | /* Load the result into both possible result registers. */ |
228 | movq ffi_clo_OFF_R(%rsp), %rax | |
229 | movsd ffi_clo_OFF_R(%rsp), %xmm0 | |
54fde020 | 230 | |
b1760f7f RH |
231 | addq $ffi_clo_FS, %rsp |
232 | cfi_adjust_cfa_offset(-ffi_clo_FS) | |
233 | ret | |
062b8279 | 234 | |
b1760f7f | 235 | cfi_endproc |
92456a4e L |
236 | SEH(.seh_endproc) |
237 | ||
238 | #if defined(FFI_EXEC_STATIC_TRAMP) | |
239 | .align 8 | |
240 | .globl C(ffi_closure_win64_alt) | |
241 | FFI_HIDDEN(C(ffi_closure_win64_alt)) | |
242 | ||
243 | SEH(.seh_proc ffi_closure_win64_alt) | |
244 | C(ffi_closure_win64_alt): | |
245 | _CET_ENDBR | |
246 | movq 8(%rsp), %r10 | |
247 | addq $16, %rsp | |
248 | jmp C(ffi_closure_win64) | |
249 | SEH(.seh_endproc) | |
250 | #endif | |
251 | #endif /* __x86_64__ */ | |
252 | ||
253 | #if defined __ELF__ && defined __linux__ | |
254 | .section .note.GNU-stack,"",@progbits | |
255 | #endif |