Add more tests of cosh, sinh.
[glibc.git] / sysdeps / x86_64 / dl-trampoline.S
blob5f9b35dc3f9f870658d23d82dc2e92ee3a018687
1 /* PLT trampolines.  x86-64 version.
2    Copyright (C) 2004-2015 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <config.h>
20 #include <sysdep.h>
21 #include <link-defines.h>
23 #if (RTLD_SAVESPACE_SSE % 32) != 0
24 # error RTLD_SAVESPACE_SSE must be aligned to 32 bytes
25 #endif
27 /* Area on stack to save and restore registers used for parameter
28    passing when calling _dl_fixup.  */
29 #ifdef __ILP32__
30 /* X32 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX.  */
31 # define REGISTER_SAVE_AREA     (8 * 7)
32 # define REGISTER_SAVE_RAX      0
33 # define PRESERVE_BND_REGS_PREFIX
34 #else
35 /* X86-64 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as BND0,
36    BND1, BND2, BND3.  */
37 # define REGISTER_SAVE_AREA     (8 * 7 + 16 * 4)
38 /* Align bound register save area to 16 bytes.  */
39 # define REGISTER_SAVE_BND0     0
40 # define REGISTER_SAVE_BND1     (REGISTER_SAVE_BND0 + 16)
41 # define REGISTER_SAVE_BND2     (REGISTER_SAVE_BND1 + 16)
42 # define REGISTER_SAVE_BND3     (REGISTER_SAVE_BND2 + 16)
43 # define REGISTER_SAVE_RAX      (REGISTER_SAVE_BND3 + 16)
44 # ifdef HAVE_MPX_SUPPORT
45 #  define PRESERVE_BND_REGS_PREFIX bnd
46 # else
47 #  define PRESERVE_BND_REGS_PREFIX .byte 0xf2
48 # endif
49 #endif
50 #define REGISTER_SAVE_RCX       (REGISTER_SAVE_RAX + 8)
51 #define REGISTER_SAVE_RDX       (REGISTER_SAVE_RCX + 8)
52 #define REGISTER_SAVE_RSI       (REGISTER_SAVE_RDX + 8)
53 #define REGISTER_SAVE_RDI       (REGISTER_SAVE_RSI + 8)
54 #define REGISTER_SAVE_R8        (REGISTER_SAVE_RDI + 8)
55 #define REGISTER_SAVE_R9        (REGISTER_SAVE_R8 + 8)
57         .text
58         .globl _dl_runtime_resolve
59         .type _dl_runtime_resolve, @function
60         .align 16
61         cfi_startproc
62 _dl_runtime_resolve:
63         cfi_adjust_cfa_offset(16) # Incorporate PLT
64         subq $REGISTER_SAVE_AREA,%rsp
65         cfi_adjust_cfa_offset(REGISTER_SAVE_AREA)
66         # Preserve registers otherwise clobbered.
67         movq %rax, REGISTER_SAVE_RAX(%rsp)
68         movq %rcx, REGISTER_SAVE_RCX(%rsp)
69         movq %rdx, REGISTER_SAVE_RDX(%rsp)
70         movq %rsi, REGISTER_SAVE_RSI(%rsp)
71         movq %rdi, REGISTER_SAVE_RDI(%rsp)
72         movq %r8, REGISTER_SAVE_R8(%rsp)
73         movq %r9, REGISTER_SAVE_R9(%rsp)
74 #ifndef __ILP32__
75         # We also have to preserve bound registers.  These are nops if
76         # Intel MPX isn't available or disabled.
77 # ifdef HAVE_MPX_SUPPORT
78         bndmov %bnd0, REGISTER_SAVE_BND0(%rsp)
79         bndmov %bnd1, REGISTER_SAVE_BND1(%rsp)
80         bndmov %bnd2, REGISTER_SAVE_BND2(%rsp)
81         bndmov %bnd3, REGISTER_SAVE_BND3(%rsp)
82 # else
83         .byte 0x66,0x0f,0x1b,0x44,0x24,REGISTER_SAVE_BND0
84         .byte 0x66,0x0f,0x1b,0x4c,0x24,REGISTER_SAVE_BND1
85         .byte 0x66,0x0f,0x1b,0x54,0x24,REGISTER_SAVE_BND2
86         .byte 0x66,0x0f,0x1b,0x5c,0x24,REGISTER_SAVE_BND3
87 # endif
88 #endif
89         # Copy args pushed by PLT in register.
90         # %rdi: link_map, %rsi: reloc_index
91         movq (REGISTER_SAVE_AREA + 8)(%rsp), %rsi
92         movq REGISTER_SAVE_AREA(%rsp), %rdi
93         call _dl_fixup          # Call resolver.
94         movq %rax, %r11         # Save return value
95 #ifndef __ILP32__
96         # Restore bound registers.  These are nops if Intel MPX isn't
97         # avaiable or disabled.
98 # ifdef HAVE_MPX_SUPPORT
99         bndmov REGISTER_SAVE_BND3(%rsp), %bnd3
100         bndmov REGISTER_SAVE_BND2(%rsp), %bnd2
101         bndmov REGISTER_SAVE_BND1(%rsp), %bnd1
102         bndmov REGISTER_SAVE_BND0(%rsp), %bnd0
103 # else
104         .byte 0x66,0x0f,0x1a,0x5c,0x24,REGISTER_SAVE_BND3
105         .byte 0x66,0x0f,0x1a,0x54,0x24,REGISTER_SAVE_BND2
106         .byte 0x66,0x0f,0x1a,0x4c,0x24,REGISTER_SAVE_BND1
107         .byte 0x66,0x0f,0x1a,0x44,0x24,REGISTER_SAVE_BND0
108 # endif
109 #endif
110         # Get register content back.
111         movq REGISTER_SAVE_R9(%rsp), %r9
112         movq REGISTER_SAVE_R8(%rsp), %r8
113         movq REGISTER_SAVE_RDI(%rsp), %rdi
114         movq REGISTER_SAVE_RSI(%rsp), %rsi
115         movq REGISTER_SAVE_RDX(%rsp), %rdx
116         movq REGISTER_SAVE_RCX(%rsp), %rcx
117         movq REGISTER_SAVE_RAX(%rsp), %rax
118         # Adjust stack(PLT did 2 pushes)
119         addq $(REGISTER_SAVE_AREA + 16), %rsp
120         cfi_adjust_cfa_offset(-(REGISTER_SAVE_AREA + 16))
121         # Preserve bound registers.
122         PRESERVE_BND_REGS_PREFIX
123         jmp *%r11               # Jump to function address.
124         cfi_endproc
125         .size _dl_runtime_resolve, .-_dl_runtime_resolve
128 #ifndef PROF
129         .globl _dl_runtime_profile
130         .type _dl_runtime_profile, @function
131         .align 16
132         cfi_startproc
134 _dl_runtime_profile:
135         cfi_adjust_cfa_offset(16) # Incorporate PLT
136         /* The La_x86_64_regs data structure pointed to by the
137            fourth paramater must be 16-byte aligned.  This must
138            be explicitly enforced.  We have the set up a dynamically
139            sized stack frame.  %rbx points to the top half which
140            has a fixed size and preserves the original stack pointer.  */
142         subq $32, %rsp          # Allocate the local storage.
143         cfi_adjust_cfa_offset(32)
144         movq %rbx, (%rsp)
145         cfi_rel_offset(%rbx, 0)
147         /* On the stack:
148                 56(%rbx)        parameter #1
149                 48(%rbx)        return address
151                 40(%rbx)        reloc index
152                 32(%rbx)        link_map
154                 24(%rbx)        La_x86_64_regs pointer
155                 16(%rbx)        framesize
156                  8(%rbx)        rax
157                   (%rbx)        rbx
158         */
160         movq %rax, 8(%rsp)
161         movq %rsp, %rbx
162         cfi_def_cfa_register(%rbx)
164         /* Actively align the La_x86_64_regs structure.  */
165         andq $0xfffffffffffffff0, %rsp
166 # if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT
167         /* sizeof(La_x86_64_regs).  Need extra space for 8 SSE registers
168            to detect if any xmm0-xmm7 registers are changed by audit
169            module.  */
170         subq $(LR_SIZE + XMM_SIZE*8), %rsp
171 # else
172         subq $LR_SIZE, %rsp             # sizeof(La_x86_64_regs)
173 # endif
174         movq %rsp, 24(%rbx)
176         /* Fill the La_x86_64_regs structure.  */
177         movq %rdx, LR_RDX_OFFSET(%rsp)
178         movq %r8,  LR_R8_OFFSET(%rsp)
179         movq %r9,  LR_R9_OFFSET(%rsp)
180         movq %rcx, LR_RCX_OFFSET(%rsp)
181         movq %rsi, LR_RSI_OFFSET(%rsp)
182         movq %rdi, LR_RDI_OFFSET(%rsp)
183         movq %rbp, LR_RBP_OFFSET(%rsp)
185         leaq 48(%rbx), %rax
186         movq %rax, LR_RSP_OFFSET(%rsp)
188         /* We always store the XMM registers even if AVX is available.
189            This is to provide backward binary compatibility for existing
190            audit modules.  */
191         movaps %xmm0,              (LR_XMM_OFFSET)(%rsp)
192         movaps %xmm1, (LR_XMM_OFFSET +   XMM_SIZE)(%rsp)
193         movaps %xmm2, (LR_XMM_OFFSET + XMM_SIZE*2)(%rsp)
194         movaps %xmm3, (LR_XMM_OFFSET + XMM_SIZE*3)(%rsp)
195         movaps %xmm4, (LR_XMM_OFFSET + XMM_SIZE*4)(%rsp)
196         movaps %xmm5, (LR_XMM_OFFSET + XMM_SIZE*5)(%rsp)
197         movaps %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp)
198         movaps %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp)
200 # ifndef __ILP32__
201 #  ifdef HAVE_MPX_SUPPORT
202         bndmov %bnd0,              (LR_BND_OFFSET)(%rsp)  # Preserve bound
203         bndmov %bnd1, (LR_BND_OFFSET +   BND_SIZE)(%rsp)  # registers. Nops if
204         bndmov %bnd2, (LR_BND_OFFSET + BND_SIZE*2)(%rsp)  # MPX not available
205         bndmov %bnd3, (LR_BND_OFFSET + BND_SIZE*3)(%rsp)  # or disabled.
206 #  else
207         .byte 0x66,0x0f,0x1b,0x84,0x24;.long (LR_BND_OFFSET)
208         .byte 0x66,0x0f,0x1b,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE)
209         .byte 0x66,0x0f,0x1b,0x84,0x24;.long (LR_BND_OFFSET + BND_SIZE*2)
210         .byte 0x66,0x0f,0x1b,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE*3)
211 #  endif
212 # endif
214 # if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT
215         .data
216 L(have_avx):
217         .zero 4
218         .size L(have_avx), 4
219         .previous
221         cmpl    $0, L(have_avx)(%rip)
222         jne     L(defined)
223         movq    %rbx, %r11              # Save rbx
224         movl    $1, %eax
225         cpuid
226         movq    %r11,%rbx               # Restore rbx
227         xorl    %eax, %eax
228         // AVX and XSAVE supported?
229         andl    $((1 << 28) | (1 << 27)), %ecx
230         cmpl    $((1 << 28) | (1 << 27)), %ecx
231         jne     10f
232 #  ifdef HAVE_AVX512_ASM_SUPPORT
233         // AVX512 supported in processor?
234         movq    %rbx, %r11              # Save rbx
235         xorl    %ecx, %ecx
236         mov     $0x7, %eax
237         cpuid
238         andl    $(1 << 16), %ebx
239 #  endif
240         xorl    %ecx, %ecx
241         // Get XFEATURE_ENABLED_MASK
242         xgetbv
243 #  ifdef HAVE_AVX512_ASM_SUPPORT
244         test    %ebx, %ebx
245         movq    %r11, %rbx              # Restore rbx
246         je      20f
247         // Verify that XCR0[7:5] = '111b' and
248         // XCR0[2:1] = '11b' which means
249         // that zmm state is enabled
250         andl    $0xe6, %eax
251         cmpl    $0xe6, %eax
252         jne     20f
253         movl    %eax, L(have_avx)(%rip)
254 L(avx512):
255 #   define RESTORE_AVX
256 #   define VMOV    vmovdqu64
257 #   define VEC(i)  zmm##i
258 #   define MORE_CODE
259 #   include "dl-trampoline.h"
260 #   undef VMOV
261 #   undef VEC
262 #   undef RESTORE_AVX
263 #  endif
264 20:     andl    $0x6, %eax
265 10:     subl    $0x5, %eax
266         movl    %eax, L(have_avx)(%rip)
267         cmpl    $0, %eax
269 L(defined):
270         js      L(no_avx)
271 #  ifdef HAVE_AVX512_ASM_SUPPORT
272         cmpl    $0xe6, L(have_avx)(%rip)
273         je      L(avx512)
274 #  endif
276 #  define RESTORE_AVX
277 #  define VMOV    vmovdqu
278 #  define VEC(i)  ymm##i
279 #  define MORE_CODE
280 #  include "dl-trampoline.h"
282         .align 16
283 L(no_avx):
284 # endif
286 # undef RESTORE_AVX
287 # include "dl-trampoline.h"
289         cfi_endproc
290         .size _dl_runtime_profile, .-_dl_runtime_profile
291 #endif
294 #ifdef SHARED
295         .globl _dl_x86_64_save_sse
296         .type _dl_x86_64_save_sse, @function
297         .align 16
298         cfi_startproc
299 _dl_x86_64_save_sse:
300 # if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT
301         cmpl    $0, L(have_avx)(%rip)
302         jne     L(defined_5)
303         movq    %rbx, %r11              # Save rbx
304         movl    $1, %eax
305         cpuid
306         movq    %r11,%rbx               # Restore rbx
307         xorl    %eax, %eax
308         // AVX and XSAVE supported?
309         andl    $((1 << 28) | (1 << 27)), %ecx
310         cmpl    $((1 << 28) | (1 << 27)), %ecx
311         jne     1f
312 #  ifdef HAVE_AVX512_ASM_SUPPORT
313         // AVX512 supported in a processor?
314         movq    %rbx, %r11              # Save rbx
315         xorl    %ecx,%ecx
316         mov     $0x7,%eax
317         cpuid
318         andl    $(1 << 16), %ebx
319 #  endif
320         xorl    %ecx, %ecx
321         // Get XFEATURE_ENABLED_MASK
322         xgetbv
323 #  ifdef HAVE_AVX512_ASM_SUPPORT
324         test    %ebx, %ebx
325         movq    %r11, %rbx              # Restore rbx
326         je      2f
327         // Verify that XCR0[7:5] = '111b' and
328         // XCR0[2:1] = '11b' which means
329         // that zmm state is enabled
330         andl    $0xe6, %eax
331         movl    %eax, L(have_avx)(%rip)
332         cmpl    $0xe6, %eax
333         je      L(avx512_5)
334 #  endif
336 2:      andl    $0x6, %eax
337 1:      subl    $0x5, %eax
338         movl    %eax, L(have_avx)(%rip)
339         cmpl    $0, %eax
341 L(defined_5):
342         js      L(no_avx5)
343 #  ifdef HAVE_AVX512_ASM_SUPPORT
344         cmpl    $0xe6, L(have_avx)(%rip)
345         je      L(avx512_5)
346 #  endif
348         vmovdqa %ymm0, %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE
349         vmovdqa %ymm1, %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE
350         vmovdqa %ymm2, %fs:RTLD_SAVESPACE_SSE+2*YMM_SIZE
351         vmovdqa %ymm3, %fs:RTLD_SAVESPACE_SSE+3*YMM_SIZE
352         vmovdqa %ymm4, %fs:RTLD_SAVESPACE_SSE+4*YMM_SIZE
353         vmovdqa %ymm5, %fs:RTLD_SAVESPACE_SSE+5*YMM_SIZE
354         vmovdqa %ymm6, %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE
355         vmovdqa %ymm7, %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE
356         ret
357 #  ifdef HAVE_AVX512_ASM_SUPPORT
358 L(avx512_5):
359         vmovdqu64 %zmm0, %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE
360         vmovdqu64 %zmm1, %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE
361         vmovdqu64 %zmm2, %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE
362         vmovdqu64 %zmm3, %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE
363         vmovdqu64 %zmm4, %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE
364         vmovdqu64 %zmm5, %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE
365         vmovdqu64 %zmm6, %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE
366         vmovdqu64 %zmm7, %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE
367         ret
368 #  endif
369 L(no_avx5):
370 # endif
371         movdqa  %xmm0, %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE
372         movdqa  %xmm1, %fs:RTLD_SAVESPACE_SSE+1*XMM_SIZE
373         movdqa  %xmm2, %fs:RTLD_SAVESPACE_SSE+2*XMM_SIZE
374         movdqa  %xmm3, %fs:RTLD_SAVESPACE_SSE+3*XMM_SIZE
375         movdqa  %xmm4, %fs:RTLD_SAVESPACE_SSE+4*XMM_SIZE
376         movdqa  %xmm5, %fs:RTLD_SAVESPACE_SSE+5*XMM_SIZE
377         movdqa  %xmm6, %fs:RTLD_SAVESPACE_SSE+6*XMM_SIZE
378         movdqa  %xmm7, %fs:RTLD_SAVESPACE_SSE+7*XMM_SIZE
379         ret
380         cfi_endproc
381         .size _dl_x86_64_save_sse, .-_dl_x86_64_save_sse
384         .globl _dl_x86_64_restore_sse
385         .type _dl_x86_64_restore_sse, @function
386         .align 16
387         cfi_startproc
388 _dl_x86_64_restore_sse:
389 # if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT
390         cmpl    $0, L(have_avx)(%rip)
391         js      L(no_avx6)
392 #  ifdef HAVE_AVX512_ASM_SUPPORT
393         cmpl    $0xe6, L(have_avx)(%rip)
394         je      L(avx512_6)
395 #  endif
397         vmovdqa %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE, %ymm0
398         vmovdqa %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE, %ymm1
399         vmovdqa %fs:RTLD_SAVESPACE_SSE+2*YMM_SIZE, %ymm2
400         vmovdqa %fs:RTLD_SAVESPACE_SSE+3*YMM_SIZE, %ymm3
401         vmovdqa %fs:RTLD_SAVESPACE_SSE+4*YMM_SIZE, %ymm4
402         vmovdqa %fs:RTLD_SAVESPACE_SSE+5*YMM_SIZE, %ymm5
403         vmovdqa %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE, %ymm6
404         vmovdqa %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE, %ymm7
405         ret
406 #  ifdef HAVE_AVX512_ASM_SUPPORT
407 L(avx512_6):
408         vmovdqu64 %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE, %zmm0
409         vmovdqu64 %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE, %zmm1
410         vmovdqu64 %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE, %zmm2
411         vmovdqu64 %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE, %zmm3
412         vmovdqu64 %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE, %zmm4
413         vmovdqu64 %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE, %zmm5
414         vmovdqu64 %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE, %zmm6
415         vmovdqu64 %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE, %zmm7
416         ret
417 #  endif
418 L(no_avx6):
419 # endif
420         movdqa  %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE, %xmm0
421         movdqa  %fs:RTLD_SAVESPACE_SSE+1*XMM_SIZE, %xmm1
422         movdqa  %fs:RTLD_SAVESPACE_SSE+2*XMM_SIZE, %xmm2
423         movdqa  %fs:RTLD_SAVESPACE_SSE+3*XMM_SIZE, %xmm3
424         movdqa  %fs:RTLD_SAVESPACE_SSE+4*XMM_SIZE, %xmm4
425         movdqa  %fs:RTLD_SAVESPACE_SSE+5*XMM_SIZE, %xmm5
426         movdqa  %fs:RTLD_SAVESPACE_SSE+6*XMM_SIZE, %xmm6
427         movdqa  %fs:RTLD_SAVESPACE_SSE+7*XMM_SIZE, %xmm7
428         ret
429         cfi_endproc
430         .size _dl_x86_64_restore_sse, .-_dl_x86_64_restore_sse
431 #endif