1/* PLT trampolines.  x86-64 version.
2   Copyright (C) 2004-2022 Free Software Foundation, Inc.
3   This file is part of the GNU C Library.
4
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.
9
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.
14
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   <https://www.gnu.org/licenses/>.  */
18
19#include <config.h>
20#include <sysdep.h>
21#include <cpu-features-offsets.h>
22#include <link-defines.h>
23#include <isa-level.h>
24
25#ifndef DL_STACK_ALIGNMENT
26/* Due to GCC bug:
27
28   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
29
30   __tls_get_addr may be called with 8-byte stack alignment.  Although
31   this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume
32   that stack will be always aligned at 16 bytes.  We use unaligned
33   16-byte move to load and store SSE registers, which has no penalty
34   on modern processors if stack is 16-byte aligned.  */
35# define DL_STACK_ALIGNMENT 8
36#endif
37
38/* True if _dl_runtime_resolve should align stack for STATE_SAVE or align
39   stack to 16 bytes before calling _dl_fixup.  */
40#define DL_RUNTIME_RESOLVE_REALIGN_STACK \
41  (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \
42   || 16 > DL_STACK_ALIGNMENT)
43
44/* Area on stack to save and restore registers used for parameter
45   passing when calling _dl_fixup.  */
46#define REGISTER_SAVE_RAX	0
47#define REGISTER_SAVE_RCX	(REGISTER_SAVE_RAX + 8)
48#define REGISTER_SAVE_RDX	(REGISTER_SAVE_RCX + 8)
49#define REGISTER_SAVE_RSI	(REGISTER_SAVE_RDX + 8)
50#define REGISTER_SAVE_RDI	(REGISTER_SAVE_RSI + 8)
51#define REGISTER_SAVE_R8	(REGISTER_SAVE_RDI + 8)
52#define REGISTER_SAVE_R9	(REGISTER_SAVE_R8 + 8)
53
54#define RESTORE_AVX
55
56#define VEC_SIZE		64
57#define VMOVA			vmovdqa64
58#define VEC(i)			zmm##i
59#define _dl_runtime_profile	_dl_runtime_profile_avx512
60# define SECTION(p)		p##.evex512
61#include "dl-trampoline.h"
62#undef _dl_runtime_profile
63#undef VEC
64#undef VMOVA
65#undef VEC_SIZE
66#undef SECTION
67
68#if MINIMUM_X86_ISA_LEVEL <= AVX_X86_ISA_LEVEL
69# define VEC_SIZE		32
70# define VMOVA			vmovdqa
71# define VEC(i)			ymm##i
72# define SECTION(p)		p##.avx
73# define _dl_runtime_profile	_dl_runtime_profile_avx
74# include "dl-trampoline.h"
75# undef _dl_runtime_profile
76# undef VEC
77# undef VMOVA
78# undef VEC_SIZE
79# undef SECTION
80#endif
81
82#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
83/* movaps/movups is 1-byte shorter.  */
84# define VEC_SIZE		16
85# define VMOVA			movaps
86# define VEC(i)			xmm##i
87# define _dl_runtime_profile	_dl_runtime_profile_sse
88# undef RESTORE_AVX
89# include "dl-trampoline.h"
90# undef _dl_runtime_profile
91# undef VEC
92# undef VMOVA
93# undef VEC_SIZE
94
95# define USE_FXSAVE
96# define STATE_SAVE_ALIGNMENT	16
97# define _dl_runtime_resolve	_dl_runtime_resolve_fxsave
98# include "dl-trampoline.h"
99# undef _dl_runtime_resolve
100# undef USE_FXSAVE
101# undef STATE_SAVE_ALIGNMENT
102#endif
103
104#define USE_XSAVE
105#define STATE_SAVE_ALIGNMENT	64
106#define _dl_runtime_resolve	_dl_runtime_resolve_xsave
107#include "dl-trampoline.h"
108#undef _dl_runtime_resolve
109#undef USE_XSAVE
110#undef STATE_SAVE_ALIGNMENT
111
112#define USE_XSAVEC
113#define STATE_SAVE_ALIGNMENT	64
114#define _dl_runtime_resolve	_dl_runtime_resolve_xsavec
115#include "dl-trampoline.h"
116#undef _dl_runtime_resolve
117#undef USE_XSAVEC
118#undef STATE_SAVE_ALIGNMENT
119