annotate libffi/src/x86/unix64.S @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* -----------------------------------------------------------------------
kono
parents:
diff changeset
2 unix64.S - Copyright (c) 2013 The Written Word, Inc.
kono
parents:
diff changeset
3 - Copyright (c) 2008 Red Hat, Inc
kono
parents:
diff changeset
4 - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 x86-64 Foreign Function Interface
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 Permission is hereby granted, free of charge, to any person obtaining
kono
parents:
diff changeset
9 a copy of this software and associated documentation files (the
kono
parents:
diff changeset
10 ``Software''), to deal in the Software without restriction, including
kono
parents:
diff changeset
11 without limitation the rights to use, copy, modify, merge, publish,
kono
parents:
diff changeset
12 distribute, sublicense, and/or sell copies of the Software, and to
kono
parents:
diff changeset
13 permit persons to whom the Software is furnished to do so, subject to
kono
parents:
diff changeset
14 the following conditions:
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 The above copyright notice and this permission notice shall be included
kono
parents:
diff changeset
17 in all copies or substantial portions of the Software.
kono
parents:
diff changeset
18
kono
parents:
diff changeset
19 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
kono
parents:
diff changeset
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
kono
parents:
diff changeset
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
kono
parents:
diff changeset
22 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
kono
parents:
diff changeset
23 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
kono
parents:
diff changeset
24 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kono
parents:
diff changeset
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
kono
parents:
diff changeset
26 DEALINGS IN THE SOFTWARE.
kono
parents:
diff changeset
27 ----------------------------------------------------------------------- */
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29 #ifdef __x86_64__
kono
parents:
diff changeset
30 #define LIBFFI_ASM
kono
parents:
diff changeset
31 #include <fficonfig.h>
kono
parents:
diff changeset
32 #include <ffi.h>
kono
parents:
diff changeset
33 #include "internal64.h"
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 .text
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 #define C2(X, Y) X ## Y
kono
parents:
diff changeset
38 #define C1(X, Y) C2(X, Y)
kono
parents:
diff changeset
39 #ifdef __USER_LABEL_PREFIX__
kono
parents:
diff changeset
40 # define C(X) C1(__USER_LABEL_PREFIX__, X)
kono
parents:
diff changeset
41 #else
kono
parents:
diff changeset
42 # define C(X) X
kono
parents:
diff changeset
43 #endif
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 #ifdef __APPLE__
kono
parents:
diff changeset
46 # define L(X) C1(L, X)
kono
parents:
diff changeset
47 #else
kono
parents:
diff changeset
48 # define L(X) C1(.L, X)
kono
parents:
diff changeset
49 #endif
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 #ifdef __ELF__
kono
parents:
diff changeset
52 # define PLT(X) X@PLT
kono
parents:
diff changeset
53 # define ENDF(X) .type X,@function; .size X, . - X
kono
parents:
diff changeset
54 #else
kono
parents:
diff changeset
55 # define PLT(X) X
kono
parents:
diff changeset
56 # define ENDF(X)
kono
parents:
diff changeset
57 #endif
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 /* This macro allows the safe creation of jump tables without an
kono
parents:
diff changeset
60 actual table. The entry points into the table are all 8 bytes.
kono
parents:
diff changeset
61 The use of ORG asserts that we're at the correct location. */
kono
parents:
diff changeset
62 /* ??? The clang assembler doesn't handle .org with symbolic expressions. */
kono
parents:
diff changeset
63 #if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
kono
parents:
diff changeset
64 # define E(BASE, X) .balign 8
kono
parents:
diff changeset
65 #else
kono
parents:
diff changeset
66 # define E(BASE, X) .balign 8; .org BASE + X * 8
kono
parents:
diff changeset
67 #endif
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 /* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
kono
parents:
diff changeset
70 void *raddr, void (*fnaddr)(void));
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
kono
parents:
diff changeset
73 for this function. This has been allocated by ffi_call. We also
kono
parents:
diff changeset
74 deallocate some of the stack that has been alloca'd. */
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 .balign 8
kono
parents:
diff changeset
77 .globl C(ffi_call_unix64)
kono
parents:
diff changeset
78 FFI_HIDDEN(C(ffi_call_unix64))
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 C(ffi_call_unix64):
kono
parents:
diff changeset
81 L(UW0):
kono
parents:
diff changeset
82 movq (%rsp), %r10 /* Load return address. */
kono
parents:
diff changeset
83 leaq (%rdi, %rsi), %rax /* Find local stack base. */
kono
parents:
diff changeset
84 movq %rdx, (%rax) /* Save flags. */
kono
parents:
diff changeset
85 movq %rcx, 8(%rax) /* Save raddr. */
kono
parents:
diff changeset
86 movq %rbp, 16(%rax) /* Save old frame pointer. */
kono
parents:
diff changeset
87 movq %r10, 24(%rax) /* Relocate return address. */
kono
parents:
diff changeset
88 movq %rax, %rbp /* Finalize local stack frame. */
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 /* New stack frame based off rbp. This is a itty bit of unwind
kono
parents:
diff changeset
91 trickery in that the CFA *has* changed. There is no easy way
kono
parents:
diff changeset
92 to describe it correctly on entry to the function. Fortunately,
kono
parents:
diff changeset
93 it doesn't matter too much since at all points we can correctly
kono
parents:
diff changeset
94 unwind back to ffi_call. Note that the location to which we
kono
parents:
diff changeset
95 moved the return address is (the new) CFA-8, so from the
kono
parents:
diff changeset
96 perspective of the unwind info, it hasn't moved. */
kono
parents:
diff changeset
97 L(UW1):
kono
parents:
diff changeset
98 /* cfi_def_cfa(%rbp, 32) */
kono
parents:
diff changeset
99 /* cfi_rel_offset(%rbp, 16) */
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 movq %rdi, %r10 /* Save a copy of the register area. */
kono
parents:
diff changeset
102 movq %r8, %r11 /* Save a copy of the target fn. */
kono
parents:
diff changeset
103 movl %r9d, %eax /* Set number of SSE registers. */
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 /* Load up all argument registers. */
kono
parents:
diff changeset
106 movq (%r10), %rdi
kono
parents:
diff changeset
107 movq 0x08(%r10), %rsi
kono
parents:
diff changeset
108 movq 0x10(%r10), %rdx
kono
parents:
diff changeset
109 movq 0x18(%r10), %rcx
kono
parents:
diff changeset
110 movq 0x20(%r10), %r8
kono
parents:
diff changeset
111 movq 0x28(%r10), %r9
kono
parents:
diff changeset
112 movl 0xb0(%r10), %eax
kono
parents:
diff changeset
113 testl %eax, %eax
kono
parents:
diff changeset
114 jnz L(load_sse)
kono
parents:
diff changeset
115 L(ret_from_load_sse):
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 /* Deallocate the reg arg area, except for r10, then load via pop. */
kono
parents:
diff changeset
118 leaq 0xb8(%r10), %rsp
kono
parents:
diff changeset
119 popq %r10
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 /* Call the user function. */
kono
parents:
diff changeset
122 call *%r11
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 /* Deallocate stack arg area; local stack frame in redzone. */
kono
parents:
diff changeset
125 leaq 24(%rbp), %rsp
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 movq 0(%rbp), %rcx /* Reload flags. */
kono
parents:
diff changeset
128 movq 8(%rbp), %rdi /* Reload raddr. */
kono
parents:
diff changeset
129 movq 16(%rbp), %rbp /* Reload old frame pointer. */
kono
parents:
diff changeset
130 L(UW2):
kono
parents:
diff changeset
131 /* cfi_remember_state */
kono
parents:
diff changeset
132 /* cfi_def_cfa(%rsp, 8) */
kono
parents:
diff changeset
133 /* cfi_restore(%rbp) */
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 /* The first byte of the flags contains the FFI_TYPE. */
kono
parents:
diff changeset
136 cmpb $UNIX64_RET_LAST, %cl
kono
parents:
diff changeset
137 movzbl %cl, %r10d
kono
parents:
diff changeset
138 leaq L(store_table)(%rip), %r11
kono
parents:
diff changeset
139 ja L(sa)
kono
parents:
diff changeset
140 leaq (%r11, %r10, 8), %r10
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 /* Prep for the structure cases: scratch area in redzone. */
kono
parents:
diff changeset
143 leaq -20(%rsp), %rsi
kono
parents:
diff changeset
144 jmp *%r10
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 .balign 8
kono
parents:
diff changeset
147 L(store_table):
kono
parents:
diff changeset
148 E(L(store_table), UNIX64_RET_VOID)
kono
parents:
diff changeset
149 ret
kono
parents:
diff changeset
150 E(L(store_table), UNIX64_RET_UINT8)
kono
parents:
diff changeset
151 movzbl %al, %eax
kono
parents:
diff changeset
152 movq %rax, (%rdi)
kono
parents:
diff changeset
153 ret
kono
parents:
diff changeset
154 E(L(store_table), UNIX64_RET_UINT16)
kono
parents:
diff changeset
155 movzwl %ax, %eax
kono
parents:
diff changeset
156 movq %rax, (%rdi)
kono
parents:
diff changeset
157 ret
kono
parents:
diff changeset
158 E(L(store_table), UNIX64_RET_UINT32)
kono
parents:
diff changeset
159 movl %eax, %eax
kono
parents:
diff changeset
160 movq %rax, (%rdi)
kono
parents:
diff changeset
161 ret
kono
parents:
diff changeset
162 E(L(store_table), UNIX64_RET_SINT8)
kono
parents:
diff changeset
163 movsbq %al, %rax
kono
parents:
diff changeset
164 movq %rax, (%rdi)
kono
parents:
diff changeset
165 ret
kono
parents:
diff changeset
166 E(L(store_table), UNIX64_RET_SINT16)
kono
parents:
diff changeset
167 movswq %ax, %rax
kono
parents:
diff changeset
168 movq %rax, (%rdi)
kono
parents:
diff changeset
169 ret
kono
parents:
diff changeset
170 E(L(store_table), UNIX64_RET_SINT32)
kono
parents:
diff changeset
171 cltq
kono
parents:
diff changeset
172 movq %rax, (%rdi)
kono
parents:
diff changeset
173 ret
kono
parents:
diff changeset
174 E(L(store_table), UNIX64_RET_INT64)
kono
parents:
diff changeset
175 movq %rax, (%rdi)
kono
parents:
diff changeset
176 ret
kono
parents:
diff changeset
177 E(L(store_table), UNIX64_RET_XMM32)
kono
parents:
diff changeset
178 movd %xmm0, (%rdi)
kono
parents:
diff changeset
179 ret
kono
parents:
diff changeset
180 E(L(store_table), UNIX64_RET_XMM64)
kono
parents:
diff changeset
181 movq %xmm0, (%rdi)
kono
parents:
diff changeset
182 ret
kono
parents:
diff changeset
183 E(L(store_table), UNIX64_RET_X87)
kono
parents:
diff changeset
184 fstpt (%rdi)
kono
parents:
diff changeset
185 ret
kono
parents:
diff changeset
186 E(L(store_table), UNIX64_RET_X87_2)
kono
parents:
diff changeset
187 fstpt (%rdi)
kono
parents:
diff changeset
188 fstpt 16(%rdi)
kono
parents:
diff changeset
189 ret
kono
parents:
diff changeset
190 E(L(store_table), UNIX64_RET_ST_XMM0_RAX)
kono
parents:
diff changeset
191 movq %rax, 8(%rsi)
kono
parents:
diff changeset
192 jmp L(s3)
kono
parents:
diff changeset
193 E(L(store_table), UNIX64_RET_ST_RAX_XMM0)
kono
parents:
diff changeset
194 movq %xmm0, 8(%rsi)
kono
parents:
diff changeset
195 jmp L(s2)
kono
parents:
diff changeset
196 E(L(store_table), UNIX64_RET_ST_XMM0_XMM1)
kono
parents:
diff changeset
197 movq %xmm1, 8(%rsi)
kono
parents:
diff changeset
198 jmp L(s3)
kono
parents:
diff changeset
199 E(L(store_table), UNIX64_RET_ST_RAX_RDX)
kono
parents:
diff changeset
200 movq %rdx, 8(%rsi)
kono
parents:
diff changeset
201 L(s2):
kono
parents:
diff changeset
202 movq %rax, (%rsi)
kono
parents:
diff changeset
203 shrl $UNIX64_SIZE_SHIFT, %ecx
kono
parents:
diff changeset
204 rep movsb
kono
parents:
diff changeset
205 ret
kono
parents:
diff changeset
206 .balign 8
kono
parents:
diff changeset
207 L(s3):
kono
parents:
diff changeset
208 movq %xmm0, (%rsi)
kono
parents:
diff changeset
209 shrl $UNIX64_SIZE_SHIFT, %ecx
kono
parents:
diff changeset
210 rep movsb
kono
parents:
diff changeset
211 ret
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 L(sa): call PLT(C(abort))
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 /* Many times we can avoid loading any SSE registers at all.
kono
parents:
diff changeset
216 It's not worth an indirect jump to load the exact set of
kono
parents:
diff changeset
217 SSE registers needed; zero or all is a good compromise. */
kono
parents:
diff changeset
218 .balign 2
kono
parents:
diff changeset
219 L(UW3):
kono
parents:
diff changeset
220 /* cfi_restore_state */
kono
parents:
diff changeset
221 L(load_sse):
kono
parents:
diff changeset
222 movdqa 0x30(%r10), %xmm0
kono
parents:
diff changeset
223 movdqa 0x40(%r10), %xmm1
kono
parents:
diff changeset
224 movdqa 0x50(%r10), %xmm2
kono
parents:
diff changeset
225 movdqa 0x60(%r10), %xmm3
kono
parents:
diff changeset
226 movdqa 0x70(%r10), %xmm4
kono
parents:
diff changeset
227 movdqa 0x80(%r10), %xmm5
kono
parents:
diff changeset
228 movdqa 0x90(%r10), %xmm6
kono
parents:
diff changeset
229 movdqa 0xa0(%r10), %xmm7
kono
parents:
diff changeset
230 jmp L(ret_from_load_sse)
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 L(UW4):
kono
parents:
diff changeset
233 ENDF(C(ffi_call_unix64))
kono
parents:
diff changeset
234
kono
parents:
diff changeset
235 /* 6 general registers, 8 vector registers,
kono
parents:
diff changeset
236 32 bytes of rvalue, 8 bytes of alignment. */
kono
parents:
diff changeset
237 #define ffi_closure_OFS_G 0
kono
parents:
diff changeset
238 #define ffi_closure_OFS_V (6*8)
kono
parents:
diff changeset
239 #define ffi_closure_OFS_RVALUE (ffi_closure_OFS_V + 8*16)
kono
parents:
diff changeset
240 #define ffi_closure_FS (ffi_closure_OFS_RVALUE + 32 + 8)
kono
parents:
diff changeset
241
kono
parents:
diff changeset
242 /* The location of rvalue within the red zone after deallocating the frame. */
kono
parents:
diff changeset
243 #define ffi_closure_RED_RVALUE (ffi_closure_OFS_RVALUE - ffi_closure_FS)
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 .balign 2
kono
parents:
diff changeset
246 .globl C(ffi_closure_unix64_sse)
kono
parents:
diff changeset
247 FFI_HIDDEN(C(ffi_closure_unix64_sse))
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 C(ffi_closure_unix64_sse):
kono
parents:
diff changeset
250 L(UW5):
kono
parents:
diff changeset
251 subq $ffi_closure_FS, %rsp
kono
parents:
diff changeset
252 L(UW6):
kono
parents:
diff changeset
253 /* cfi_adjust_cfa_offset(ffi_closure_FS) */
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 movdqa %xmm0, ffi_closure_OFS_V+0x00(%rsp)
kono
parents:
diff changeset
256 movdqa %xmm1, ffi_closure_OFS_V+0x10(%rsp)
kono
parents:
diff changeset
257 movdqa %xmm2, ffi_closure_OFS_V+0x20(%rsp)
kono
parents:
diff changeset
258 movdqa %xmm3, ffi_closure_OFS_V+0x30(%rsp)
kono
parents:
diff changeset
259 movdqa %xmm4, ffi_closure_OFS_V+0x40(%rsp)
kono
parents:
diff changeset
260 movdqa %xmm5, ffi_closure_OFS_V+0x50(%rsp)
kono
parents:
diff changeset
261 movdqa %xmm6, ffi_closure_OFS_V+0x60(%rsp)
kono
parents:
diff changeset
262 movdqa %xmm7, ffi_closure_OFS_V+0x70(%rsp)
kono
parents:
diff changeset
263 jmp L(sse_entry1)
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 L(UW7):
kono
parents:
diff changeset
266 ENDF(C(ffi_closure_unix64_sse))
kono
parents:
diff changeset
267
kono
parents:
diff changeset
268 .balign 2
kono
parents:
diff changeset
269 .globl C(ffi_closure_unix64)
kono
parents:
diff changeset
270 FFI_HIDDEN(C(ffi_closure_unix64))
kono
parents:
diff changeset
271
kono
parents:
diff changeset
272 C(ffi_closure_unix64):
kono
parents:
diff changeset
273 L(UW8):
kono
parents:
diff changeset
274 subq $ffi_closure_FS, %rsp
kono
parents:
diff changeset
275 L(UW9):
kono
parents:
diff changeset
276 /* cfi_adjust_cfa_offset(ffi_closure_FS) */
kono
parents:
diff changeset
277 L(sse_entry1):
kono
parents:
diff changeset
278 movq %rdi, ffi_closure_OFS_G+0x00(%rsp)
kono
parents:
diff changeset
279 movq %rsi, ffi_closure_OFS_G+0x08(%rsp)
kono
parents:
diff changeset
280 movq %rdx, ffi_closure_OFS_G+0x10(%rsp)
kono
parents:
diff changeset
281 movq %rcx, ffi_closure_OFS_G+0x18(%rsp)
kono
parents:
diff changeset
282 movq %r8, ffi_closure_OFS_G+0x20(%rsp)
kono
parents:
diff changeset
283 movq %r9, ffi_closure_OFS_G+0x28(%rsp)
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 #ifdef __ILP32__
kono
parents:
diff changeset
286 movl FFI_TRAMPOLINE_SIZE(%r10), %edi /* Load cif */
kono
parents:
diff changeset
287 movl FFI_TRAMPOLINE_SIZE+4(%r10), %esi /* Load fun */
kono
parents:
diff changeset
288 movl FFI_TRAMPOLINE_SIZE+8(%r10), %edx /* Load user_data */
kono
parents:
diff changeset
289 #else
kono
parents:
diff changeset
290 movq FFI_TRAMPOLINE_SIZE(%r10), %rdi /* Load cif */
kono
parents:
diff changeset
291 movq FFI_TRAMPOLINE_SIZE+8(%r10), %rsi /* Load fun */
kono
parents:
diff changeset
292 movq FFI_TRAMPOLINE_SIZE+16(%r10), %rdx /* Load user_data */
kono
parents:
diff changeset
293 #endif
kono
parents:
diff changeset
294 L(do_closure):
kono
parents:
diff changeset
295 leaq ffi_closure_OFS_RVALUE(%rsp), %rcx /* Load rvalue */
kono
parents:
diff changeset
296 movq %rsp, %r8 /* Load reg_args */
kono
parents:
diff changeset
297 leaq ffi_closure_FS+8(%rsp), %r9 /* Load argp */
kono
parents:
diff changeset
298 call C(ffi_closure_unix64_inner)
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 /* Deallocate stack frame early; return value is now in redzone. */
kono
parents:
diff changeset
301 addq $ffi_closure_FS, %rsp
kono
parents:
diff changeset
302 L(UW10):
kono
parents:
diff changeset
303 /* cfi_adjust_cfa_offset(-ffi_closure_FS) */
kono
parents:
diff changeset
304
kono
parents:
diff changeset
305 /* The first byte of the return value contains the FFI_TYPE. */
kono
parents:
diff changeset
306 cmpb $UNIX64_RET_LAST, %al
kono
parents:
diff changeset
307 movzbl %al, %r10d
kono
parents:
diff changeset
308 leaq L(load_table)(%rip), %r11
kono
parents:
diff changeset
309 ja L(la)
kono
parents:
diff changeset
310 leaq (%r11, %r10, 8), %r10
kono
parents:
diff changeset
311 leaq ffi_closure_RED_RVALUE(%rsp), %rsi
kono
parents:
diff changeset
312 jmp *%r10
kono
parents:
diff changeset
313
kono
parents:
diff changeset
314 .balign 8
kono
parents:
diff changeset
315 L(load_table):
kono
parents:
diff changeset
316 E(L(load_table), UNIX64_RET_VOID)
kono
parents:
diff changeset
317 ret
kono
parents:
diff changeset
318 E(L(load_table), UNIX64_RET_UINT8)
kono
parents:
diff changeset
319 movzbl (%rsi), %eax
kono
parents:
diff changeset
320 ret
kono
parents:
diff changeset
321 E(L(load_table), UNIX64_RET_UINT16)
kono
parents:
diff changeset
322 movzwl (%rsi), %eax
kono
parents:
diff changeset
323 ret
kono
parents:
diff changeset
324 E(L(load_table), UNIX64_RET_UINT32)
kono
parents:
diff changeset
325 movl (%rsi), %eax
kono
parents:
diff changeset
326 ret
kono
parents:
diff changeset
327 E(L(load_table), UNIX64_RET_SINT8)
kono
parents:
diff changeset
328 movsbl (%rsi), %eax
kono
parents:
diff changeset
329 ret
kono
parents:
diff changeset
330 E(L(load_table), UNIX64_RET_SINT16)
kono
parents:
diff changeset
331 movswl (%rsi), %eax
kono
parents:
diff changeset
332 ret
kono
parents:
diff changeset
333 E(L(load_table), UNIX64_RET_SINT32)
kono
parents:
diff changeset
334 movl (%rsi), %eax
kono
parents:
diff changeset
335 ret
kono
parents:
diff changeset
336 E(L(load_table), UNIX64_RET_INT64)
kono
parents:
diff changeset
337 movq (%rsi), %rax
kono
parents:
diff changeset
338 ret
kono
parents:
diff changeset
339 E(L(load_table), UNIX64_RET_XMM32)
kono
parents:
diff changeset
340 movd (%rsi), %xmm0
kono
parents:
diff changeset
341 ret
kono
parents:
diff changeset
342 E(L(load_table), UNIX64_RET_XMM64)
kono
parents:
diff changeset
343 movq (%rsi), %xmm0
kono
parents:
diff changeset
344 ret
kono
parents:
diff changeset
345 E(L(load_table), UNIX64_RET_X87)
kono
parents:
diff changeset
346 fldt (%rsi)
kono
parents:
diff changeset
347 ret
kono
parents:
diff changeset
348 E(L(load_table), UNIX64_RET_X87_2)
kono
parents:
diff changeset
349 fldt 16(%rsi)
kono
parents:
diff changeset
350 fldt (%rsi)
kono
parents:
diff changeset
351 ret
kono
parents:
diff changeset
352 E(L(load_table), UNIX64_RET_ST_XMM0_RAX)
kono
parents:
diff changeset
353 movq 8(%rsi), %rax
kono
parents:
diff changeset
354 jmp L(l3)
kono
parents:
diff changeset
355 E(L(load_table), UNIX64_RET_ST_RAX_XMM0)
kono
parents:
diff changeset
356 movq 8(%rsi), %xmm0
kono
parents:
diff changeset
357 jmp L(l2)
kono
parents:
diff changeset
358 E(L(load_table), UNIX64_RET_ST_XMM0_XMM1)
kono
parents:
diff changeset
359 movq 8(%rsi), %xmm1
kono
parents:
diff changeset
360 jmp L(l3)
kono
parents:
diff changeset
361 E(L(load_table), UNIX64_RET_ST_RAX_RDX)
kono
parents:
diff changeset
362 movq 8(%rsi), %rdx
kono
parents:
diff changeset
363 L(l2):
kono
parents:
diff changeset
364 movq (%rsi), %rax
kono
parents:
diff changeset
365 ret
kono
parents:
diff changeset
366 .balign 8
kono
parents:
diff changeset
367 L(l3):
kono
parents:
diff changeset
368 movq (%rsi), %xmm0
kono
parents:
diff changeset
369 ret
kono
parents:
diff changeset
370
kono
parents:
diff changeset
371 L(la): call PLT(C(abort))
kono
parents:
diff changeset
372
kono
parents:
diff changeset
373 L(UW11):
kono
parents:
diff changeset
374 ENDF(C(ffi_closure_unix64))
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 .balign 2
kono
parents:
diff changeset
377 .globl C(ffi_go_closure_unix64_sse)
kono
parents:
diff changeset
378 FFI_HIDDEN(C(ffi_go_closure_unix64_sse))
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 C(ffi_go_closure_unix64_sse):
kono
parents:
diff changeset
381 L(UW12):
kono
parents:
diff changeset
382 subq $ffi_closure_FS, %rsp
kono
parents:
diff changeset
383 L(UW13):
kono
parents:
diff changeset
384 /* cfi_adjust_cfa_offset(ffi_closure_FS) */
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 movdqa %xmm0, ffi_closure_OFS_V+0x00(%rsp)
kono
parents:
diff changeset
387 movdqa %xmm1, ffi_closure_OFS_V+0x10(%rsp)
kono
parents:
diff changeset
388 movdqa %xmm2, ffi_closure_OFS_V+0x20(%rsp)
kono
parents:
diff changeset
389 movdqa %xmm3, ffi_closure_OFS_V+0x30(%rsp)
kono
parents:
diff changeset
390 movdqa %xmm4, ffi_closure_OFS_V+0x40(%rsp)
kono
parents:
diff changeset
391 movdqa %xmm5, ffi_closure_OFS_V+0x50(%rsp)
kono
parents:
diff changeset
392 movdqa %xmm6, ffi_closure_OFS_V+0x60(%rsp)
kono
parents:
diff changeset
393 movdqa %xmm7, ffi_closure_OFS_V+0x70(%rsp)
kono
parents:
diff changeset
394 jmp L(sse_entry2)
kono
parents:
diff changeset
395
kono
parents:
diff changeset
396 L(UW14):
kono
parents:
diff changeset
397 ENDF(C(ffi_go_closure_unix64_sse))
kono
parents:
diff changeset
398
kono
parents:
diff changeset
399 .balign 2
kono
parents:
diff changeset
400 .globl C(ffi_go_closure_unix64)
kono
parents:
diff changeset
401 FFI_HIDDEN(C(ffi_go_closure_unix64))
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 C(ffi_go_closure_unix64):
kono
parents:
diff changeset
404 L(UW15):
kono
parents:
diff changeset
405 subq $ffi_closure_FS, %rsp
kono
parents:
diff changeset
406 L(UW16):
kono
parents:
diff changeset
407 /* cfi_adjust_cfa_offset(ffi_closure_FS) */
kono
parents:
diff changeset
408 L(sse_entry2):
kono
parents:
diff changeset
409 movq %rdi, ffi_closure_OFS_G+0x00(%rsp)
kono
parents:
diff changeset
410 movq %rsi, ffi_closure_OFS_G+0x08(%rsp)
kono
parents:
diff changeset
411 movq %rdx, ffi_closure_OFS_G+0x10(%rsp)
kono
parents:
diff changeset
412 movq %rcx, ffi_closure_OFS_G+0x18(%rsp)
kono
parents:
diff changeset
413 movq %r8, ffi_closure_OFS_G+0x20(%rsp)
kono
parents:
diff changeset
414 movq %r9, ffi_closure_OFS_G+0x28(%rsp)
kono
parents:
diff changeset
415
kono
parents:
diff changeset
416 #ifdef __ILP32__
kono
parents:
diff changeset
417 movl 4(%r10), %edi /* Load cif */
kono
parents:
diff changeset
418 movl 8(%r10), %esi /* Load fun */
kono
parents:
diff changeset
419 movl %r10d, %edx /* Load closure (user_data) */
kono
parents:
diff changeset
420 #else
kono
parents:
diff changeset
421 movq 8(%r10), %rdi /* Load cif */
kono
parents:
diff changeset
422 movq 16(%r10), %rsi /* Load fun */
kono
parents:
diff changeset
423 movq %r10, %rdx /* Load closure (user_data) */
kono
parents:
diff changeset
424 #endif
kono
parents:
diff changeset
425 jmp L(do_closure)
kono
parents:
diff changeset
426
kono
parents:
diff changeset
427 L(UW17):
kono
parents:
diff changeset
428 ENDF(C(ffi_go_closure_unix64))
kono
parents:
diff changeset
429
kono
parents:
diff changeset
430 /* Sadly, OSX cctools-as doesn't understand .cfi directives at all. */
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 #ifdef __APPLE__
kono
parents:
diff changeset
433 .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
kono
parents:
diff changeset
434 EHFrame0:
kono
parents:
diff changeset
435 #elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)
kono
parents:
diff changeset
436 .section .eh_frame,"a",@unwind
kono
parents:
diff changeset
437 #else
kono
parents:
diff changeset
438 .section .eh_frame,"a",@progbits
kono
parents:
diff changeset
439 #endif
kono
parents:
diff changeset
440
kono
parents:
diff changeset
441 #ifdef HAVE_AS_X86_PCREL
kono
parents:
diff changeset
442 # define PCREL(X) X - .
kono
parents:
diff changeset
443 #else
kono
parents:
diff changeset
444 # define PCREL(X) X@rel
kono
parents:
diff changeset
445 #endif
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 /* Simplify advancing between labels. Assume DW_CFA_advance_loc1 fits. */
kono
parents:
diff changeset
448 #define ADV(N, P) .byte 2, L(N)-L(P)
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 .balign 8
kono
parents:
diff changeset
451 L(CIE):
kono
parents:
diff changeset
452 .set L(set0),L(ECIE)-L(SCIE)
kono
parents:
diff changeset
453 .long L(set0) /* CIE Length */
kono
parents:
diff changeset
454 L(SCIE):
kono
parents:
diff changeset
455 .long 0 /* CIE Identifier Tag */
kono
parents:
diff changeset
456 .byte 1 /* CIE Version */
kono
parents:
diff changeset
457 .ascii "zR\0" /* CIE Augmentation */
kono
parents:
diff changeset
458 .byte 1 /* CIE Code Alignment Factor */
kono
parents:
diff changeset
459 .byte 0x78 /* CIE Data Alignment Factor */
kono
parents:
diff changeset
460 .byte 0x10 /* CIE RA Column */
kono
parents:
diff changeset
461 .byte 1 /* Augmentation size */
kono
parents:
diff changeset
462 .byte 0x1b /* FDE Encoding (pcrel sdata4) */
kono
parents:
diff changeset
463 .byte 0xc, 7, 8 /* DW_CFA_def_cfa, %rsp offset 8 */
kono
parents:
diff changeset
464 .byte 0x80+16, 1 /* DW_CFA_offset, %rip offset 1*-8 */
kono
parents:
diff changeset
465 .balign 8
kono
parents:
diff changeset
466 L(ECIE):
kono
parents:
diff changeset
467
kono
parents:
diff changeset
468 .set L(set1),L(EFDE1)-L(SFDE1)
kono
parents:
diff changeset
469 .long L(set1) /* FDE Length */
kono
parents:
diff changeset
470 L(SFDE1):
kono
parents:
diff changeset
471 .long L(SFDE1)-L(CIE) /* FDE CIE offset */
kono
parents:
diff changeset
472 .long PCREL(L(UW0)) /* Initial location */
kono
parents:
diff changeset
473 .long L(UW4)-L(UW0) /* Address range */
kono
parents:
diff changeset
474 .byte 0 /* Augmentation size */
kono
parents:
diff changeset
475 ADV(UW1, UW0)
kono
parents:
diff changeset
476 .byte 0xc, 6, 32 /* DW_CFA_def_cfa, %rbp 32 */
kono
parents:
diff changeset
477 .byte 0x80+6, 2 /* DW_CFA_offset, %rbp 2*-8 */
kono
parents:
diff changeset
478 ADV(UW2, UW1)
kono
parents:
diff changeset
479 .byte 0xa /* DW_CFA_remember_state */
kono
parents:
diff changeset
480 .byte 0xc, 7, 8 /* DW_CFA_def_cfa, %rsp 8 */
kono
parents:
diff changeset
481 .byte 0xc0+6 /* DW_CFA_restore, %rbp */
kono
parents:
diff changeset
482 ADV(UW3, UW2)
kono
parents:
diff changeset
483 .byte 0xb /* DW_CFA_restore_state */
kono
parents:
diff changeset
484 .balign 8
kono
parents:
diff changeset
485 L(EFDE1):
kono
parents:
diff changeset
486
kono
parents:
diff changeset
487 .set L(set2),L(EFDE2)-L(SFDE2)
kono
parents:
diff changeset
488 .long L(set2) /* FDE Length */
kono
parents:
diff changeset
489 L(SFDE2):
kono
parents:
diff changeset
490 .long L(SFDE2)-L(CIE) /* FDE CIE offset */
kono
parents:
diff changeset
491 .long PCREL(L(UW5)) /* Initial location */
kono
parents:
diff changeset
492 .long L(UW7)-L(UW5) /* Address range */
kono
parents:
diff changeset
493 .byte 0 /* Augmentation size */
kono
parents:
diff changeset
494 ADV(UW6, UW5)
kono
parents:
diff changeset
495 .byte 0xe /* DW_CFA_def_cfa_offset */
kono
parents:
diff changeset
496 .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */
kono
parents:
diff changeset
497 .balign 8
kono
parents:
diff changeset
498 L(EFDE2):
kono
parents:
diff changeset
499
kono
parents:
diff changeset
500 .set L(set3),L(EFDE3)-L(SFDE3)
kono
parents:
diff changeset
501 .long L(set3) /* FDE Length */
kono
parents:
diff changeset
502 L(SFDE3):
kono
parents:
diff changeset
503 .long L(SFDE3)-L(CIE) /* FDE CIE offset */
kono
parents:
diff changeset
504 .long PCREL(L(UW8)) /* Initial location */
kono
parents:
diff changeset
505 .long L(UW11)-L(UW8) /* Address range */
kono
parents:
diff changeset
506 .byte 0 /* Augmentation size */
kono
parents:
diff changeset
507 ADV(UW9, UW8)
kono
parents:
diff changeset
508 .byte 0xe /* DW_CFA_def_cfa_offset */
kono
parents:
diff changeset
509 .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */
kono
parents:
diff changeset
510 ADV(UW10, UW9)
kono
parents:
diff changeset
511 .byte 0xe, 8 /* DW_CFA_def_cfa_offset 8 */
kono
parents:
diff changeset
512 L(EFDE3):
kono
parents:
diff changeset
513
kono
parents:
diff changeset
514 .set L(set4),L(EFDE4)-L(SFDE4)
kono
parents:
diff changeset
515 .long L(set4) /* FDE Length */
kono
parents:
diff changeset
516 L(SFDE4):
kono
parents:
diff changeset
517 .long L(SFDE4)-L(CIE) /* FDE CIE offset */
kono
parents:
diff changeset
518 .long PCREL(L(UW12)) /* Initial location */
kono
parents:
diff changeset
519 .long L(UW14)-L(UW12) /* Address range */
kono
parents:
diff changeset
520 .byte 0 /* Augmentation size */
kono
parents:
diff changeset
521 ADV(UW13, UW12)
kono
parents:
diff changeset
522 .byte 0xe /* DW_CFA_def_cfa_offset */
kono
parents:
diff changeset
523 .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */
kono
parents:
diff changeset
524 .balign 8
kono
parents:
diff changeset
525 L(EFDE4):
kono
parents:
diff changeset
526
kono
parents:
diff changeset
527 .set L(set5),L(EFDE5)-L(SFDE5)
kono
parents:
diff changeset
528 .long L(set5) /* FDE Length */
kono
parents:
diff changeset
529 L(SFDE5):
kono
parents:
diff changeset
530 .long L(SFDE5)-L(CIE) /* FDE CIE offset */
kono
parents:
diff changeset
531 .long PCREL(L(UW15)) /* Initial location */
kono
parents:
diff changeset
532 .long L(UW17)-L(UW15) /* Address range */
kono
parents:
diff changeset
533 .byte 0 /* Augmentation size */
kono
parents:
diff changeset
534 ADV(UW16, UW15)
kono
parents:
diff changeset
535 .byte 0xe /* DW_CFA_def_cfa_offset */
kono
parents:
diff changeset
536 .byte ffi_closure_FS + 8, 1 /* uleb128, assuming 128 <= FS < 255 */
kono
parents:
diff changeset
537 .balign 8
kono
parents:
diff changeset
538 L(EFDE5):
kono
parents:
diff changeset
539 #ifdef __APPLE__
kono
parents:
diff changeset
540 .subsections_via_symbols
kono
parents:
diff changeset
541 #endif
kono
parents:
diff changeset
542
kono
parents:
diff changeset
543 #endif /* __x86_64__ */
kono
parents:
diff changeset
544 #if defined __ELF__ && defined __linux__
kono
parents:
diff changeset
545 .section .note.GNU-stack,"",@progbits
kono
parents:
diff changeset
546 #endif