]> git.ipfire.org Git - thirdparty/glibc.git/blame - ports/sysdeps/aarch64/dl-trampoline.S
Mark some hypot tests no-test-inline.
[thirdparty/glibc.git] / ports / sysdeps / aarch64 / dl-trampoline.S
CommitLineData
568035b7 1/* Copyright (C) 2005-2013 Free Software Foundation, Inc.
554066b8
MS
2
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 License as
7 published by the Free Software Foundation; either version 2.1 of the
8 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 <http://www.gnu.org/licenses/>. */
18
19#include <sysdep.h>
20#include <libc-symbols.h>
21
22#include "dl-link.h"
23
24#define ip0 x16
25#define ip1 x17
26#define lr x30
27
28 .text
29 .globl _dl_runtime_resolve
30 .type _dl_runtime_resolve, #function
31 cfi_startproc
32 .align 2
33_dl_runtime_resolve:
34 /* AArch64 we get called with:
35 ip0 &PLTGOT[2]
36 ip1 temp(dl resolver entry point)
37 [sp, #8] lr
38 [sp, #0] &PLTGOT[n]
39 */
40
41 cfi_rel_offset (lr, 8)
42
43 /* Save arguments. */
44 stp x8, x9, [sp, #-80]!
45 cfi_adjust_cfa_offset (80)
46 cfi_rel_offset (x8, 0)
47 cfi_rel_offset (x9, 8)
48
49 stp x6, x7, [sp, #16]
50 cfi_rel_offset (x6, 16)
51 cfi_rel_offset (x7, 24)
52
53 stp x4, x5, [sp, #32]
54 cfi_rel_offset (x4, 32)
55 cfi_rel_offset (x5, 40)
56
57 stp x2, x3, [sp, #48]
58 cfi_rel_offset (x2, 48)
59 cfi_rel_offset (x3, 56)
60
61 stp x0, x1, [sp, #64]
62 cfi_rel_offset (x0, 64)
63 cfi_rel_offset (x1, 72)
64
65 /* Get pointer to linker struct. */
66 ldr x0, [ip0, #-8]
67
68 /* Prepare to call _dl_fixup(). */
69 ldr x1, [sp, 80] /* Recover &PLTGOT[n] */
70
71 sub x1, x1, ip0
72 add x1, x1, x1, lsl #1
73 lsl x1, x1, #3
74 sub x1, x1, #192
75 lsr x1, x1, #3
76
77 /* Call fixup routine. */
78 bl _dl_fixup
79
80 /* Save the return. */
81 mov ip0, x0
82
83 /* Get arguments and return address back. */
84 ldp x0, x1, [sp, #64]
85 ldp x2, x3, [sp, #48]
86 ldp x4, x5, [sp, #32]
87 ldp x6, x7, [sp, #16]
88 ldp x8, x9, [sp], #80
89 cfi_adjust_cfa_offset (-80)
90
91 ldp ip1, lr, [sp], #16
92 cfi_adjust_cfa_offset (-16)
93
94 /* Jump to the newly found address. */
95 br ip0
96
97 cfi_endproc
98 .size _dl_runtime_resolve, .-_dl_runtime_resolve
99#ifndef PROF
100 .globl _dl_runtime_profile
101 .type _dl_runtime_profile, #function
102 cfi_startproc
103 .align 2
104_dl_runtime_profile:
105 /* AArch64 we get called with:
106 ip0 &PLTGOT[2]
107 ip1 temp(dl resolver entry point)
108 [sp, #8] lr
109 [sp, #0] &PLTGOT[n]
110
111 Stack frame layout:
112 [sp, #...] lr
113 [sp, #...] &PLTGOT[n]
114 [sp, #96] La_aarch64_regs
115 [sp, #48] La_aarch64_retval
116 [sp, #40] frame size return from pltenter
117 [sp, #32] dl_profile_call saved x1
118 [sp, #24] dl_profile_call saved x0
119 [sp, #16] t1
120 [sp, #0] x29, lr <- x29
121 */
122
123# define OFFSET_T1 16
124# define OFFSET_SAVED_CALL_X0 OFFSET_T1 + 8
125# define OFFSET_FS OFFSET_SAVED_CALL_X0 + 16
126# define OFFSET_RV OFFSET_FS + 8
127# define OFFSET_RG OFFSET_RV + DL_SIZEOF_RV
128
129# define SF_SIZE OFFSET_RG + DL_SIZEOF_RG
130
131# define OFFSET_PLTGOTN SF_SIZE
132# define OFFSET_LR OFFSET_PLTGOTN + 8
133
134 /* Save arguments. */
135 sub sp, sp, #SF_SIZE
136 cfi_adjust_cfa_offset (SF_SIZE)
137 stp x29, x30, [SP, #0]
138 mov x29, sp
139 cfi_def_cfa_register (x29)
140 cfi_rel_offset (x29, 0)
141 cfi_rel_offset (lr, 8)
142
143 stp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*0]
144 cfi_rel_offset (x0, OFFSET_RG + DL_OFFSET_RG_X0 + 16*0 + 0)
145 cfi_rel_offset (x1, OFFSET_RG + DL_OFFSET_RG_X0 + 16*0 + 8)
146 stp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
147 cfi_rel_offset (x2, OFFSET_RG + DL_OFFSET_RG_X0 + 16*1 + 0)
148 cfi_rel_offset (x3, OFFSET_RG + DL_OFFSET_RG_X0 + 16*1 + 8)
149 stp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
150 cfi_rel_offset (x4, OFFSET_RG + DL_OFFSET_RG_X0 + 16*2 + 0)
151 cfi_rel_offset (x5, OFFSET_RG + DL_OFFSET_RG_X0 + 16*2 + 8)
152 stp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
153 cfi_rel_offset (x6, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 0)
154 cfi_rel_offset (x7, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 8)
155
156 stp d0, d1, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
157 cfi_rel_offset (d0, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0)
158 cfi_rel_offset (d1, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0 + 8)
159 stp d2, d3, [X29, #OFFSET_RG+ DL_OFFSET_RG_D0 + 16*1]
160 cfi_rel_offset (d2, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 0)
161 cfi_rel_offset (d3, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 8)
162 stp d4, d5, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
163 cfi_rel_offset (d4, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 0)
164 cfi_rel_offset (d5, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 8)
165 stp d6, d7, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
166 cfi_rel_offset (d6, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 0)
167 cfi_rel_offset (d7, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 8)
168
169 add x0, x29, #SF_SIZE + 16
170 ldr x1, [x29, #OFFSET_LR]
171 stp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_SP]
172
173 /* Get pointer to linker struct. */
174 ldr x0, [ip0, #-8]
175
176 /* Prepare to call _dl_profile_fixup(). */
177 ldr x1, [x29, OFFSET_PLTGOTN] /* Recover &PLTGOT[n] */
178
179 sub x1, x1, ip0
180 add x1, x1, x1, lsl #1
181 lsl x1, x1, #3
182 sub x1, x1, #192
183 lsr x1, x1, #3
184
185 stp x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
186
187 /* Set up extra args for _dl_profile_fixup */
188 ldr x2, [x29, #OFFSET_LR] /* load saved LR */
189 add x3, x29, #OFFSET_RG /* address of La_aarch64_reg */
190 add x4, x29, #OFFSET_FS /* address of framesize */
191 bl _dl_profile_fixup
192
193 ldr ip0, [x29, #OFFSET_FS] /* framesize == 0 */
194 cmp ip0, #0
195 bge 1f
196 cfi_remember_state
197
198 /* Save the return. */
199 mov ip0, x0
200
201 /* Get arguments and return address back. */
202 ldp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*0]
203 ldp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
204 ldp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
205 ldp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
206 ldp d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
207 ldp d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
208 ldp d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
209 ldp d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
210
211 cfi_def_cfa_register (sp)
212 ldp x29, x30, [x29, #0]
213 cfi_restore(x29)
214 cfi_restore(x30)
215
216 add sp, sp, SF_SIZE + 16
217 cfi_adjust_cfa_offset (- SF_SIZE - 16)
218
219 /* Jump to the newly found address. */
220 br ip0
221
222 cfi_restore_state
2231:
224 /* The new frame size is in ip0. */
225
226 sub x1, x29, ip0
227 and sp, x1, #0xfffffffffffffff0
228
229 str x0, [x29, #OFFSET_T1]
230
231 mov x0, sp
232 add x1, x29, #SF_SIZE + 16
233 mov x2, ip0
234 bl memcpy
235
236 ldr ip0, [x29, #OFFSET_T1]
237
238 /* Call the function. */
239 ldp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*0]
240 ldp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
241 ldp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
242 ldp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
243 ldp d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
244 ldp d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
245 ldp d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
246 ldp d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
247 blr ip0
248 stp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
249 stp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
250 stp d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
251
252 /* Setup call to pltexit */
253 ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
254 add x2, x29, #OFFSET_RG
255 add x3, x29, #OFFSET_RV
256 bl _dl_call_pltexit
257
258 ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
259 ldp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
260 ldp d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
261 /* LR from within La_aarch64_reg */
262 ldr lr, [x29, #OFFSET_RG + DL_OFFSET_RG_LR]
263 cfi_restore(lr)
264 mov sp, x29
265 cfi_def_cfa_register (sp)
266 ldr x29, [x29, #0]
267 cfi_restore(x29)
268 add sp, sp, SF_SIZE + 16
269 cfi_adjust_cfa_offset (- SF_SIZE - 16)
270
271 br lr
272
273 cfi_endproc
274 .size _dl_runtime_profile, .-_dl_runtime_profile
275#endif
276 .previous