]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/powerpc/powerpc64/sysdep.h
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / powerpc / powerpc64 / sysdep.h
CommitLineData
b80a3db0 1/* Assembly macros for 64-bit PowerPC.
04277e02 2 Copyright (C) 2002-2019 Free Software Foundation, Inc.
b80a3db0
RM
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
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
b80a3db0 18
b80a3db0
RM
19#include <sysdeps/powerpc/sysdep.h>
20
afe01786
UD
21#ifdef __ASSEMBLER__
22
8b8a692c 23/* Stack frame offsets. */
8b8a692c
UW
24#define FRAME_BACKCHAIN 0
25#define FRAME_CR_SAVE 8
26#define FRAME_LR_SAVE 16
fb499eb0
AM
27#if _CALL_ELF != 2
28#define FRAME_MIN_SIZE 112
29#define FRAME_MIN_SIZE_PARM 112
8b8a692c
UW
30#define FRAME_TOC_SAVE 40
31#define FRAME_PARM_SAVE 48
8b8a692c
UW
32#else
33#define FRAME_MIN_SIZE 32
34#define FRAME_MIN_SIZE_PARM 96
8b8a692c
UW
35#define FRAME_TOC_SAVE 24
36#define FRAME_PARM_SAVE 32
8b8a692c
UW
37#endif
38
d7d06f79
UD
39/* Support macros for CALL_MCOUNT. */
40 .macro SAVE_ARG NARG
41 .if \NARG
42 SAVE_ARG \NARG-1
dd885436 43 std 2+\NARG,-FRAME_MIN_SIZE_PARM+FRAME_PARM_SAVE-8+8*(\NARG)(1)
d7d06f79
UD
44 .endif
45 .endm
46
47 .macro REST_ARG NARG
48 .if \NARG
49 REST_ARG \NARG-1
dd885436 50 ld 2+\NARG,FRAME_PARM_SAVE-8+8*(\NARG)(1)
bebff237
AM
51 .endif
52 .endm
53
54 .macro CFI_SAVE_ARG NARG
55 .if \NARG
56 CFI_SAVE_ARG \NARG-1
dd885436 57 cfi_offset(2+\NARG,-FRAME_MIN_SIZE_PARM+FRAME_PARM_SAVE-8+8*(\NARG))
bebff237
AM
58 .endif
59 .endm
60
61 .macro CFI_REST_ARG NARG
62 .if \NARG
63 CFI_REST_ARG \NARG-1
64 cfi_restore(2+\NARG)
d7d06f79
UD
65 .endif
66 .endm
67
b80a3db0
RM
68/* If compiled for profiling, call `_mcount' at the start of each function.
69 see ppc-mcount.S for more details. */
d7d06f79 70 .macro CALL_MCOUNT NARG
b80a3db0 71#ifdef PROF
d7d06f79
UD
72 mflr r0
73 SAVE_ARG \NARG
8b8a692c
UW
74 std r0,FRAME_LR_SAVE(r1)
75 stdu r1,-FRAME_MIN_SIZE_PARM(r1)
76 cfi_adjust_cfa_offset(FRAME_MIN_SIZE_PARM)
77 cfi_offset(lr,FRAME_LR_SAVE)
bebff237 78 CFI_SAVE_ARG \NARG
d7d06f79 79 bl JUMPTARGET (_mcount)
bebff237
AM
80#ifndef SHARED
81 nop
82#endif
8b8a692c 83 ld r0,FRAME_MIN_SIZE_PARM+FRAME_LR_SAVE(r1)
d7d06f79 84 REST_ARG \NARG
d7d06f79 85 mtlr r0
8b8a692c
UW
86 addi r1,r1,FRAME_MIN_SIZE_PARM
87 cfi_adjust_cfa_offset(-FRAME_MIN_SIZE_PARM)
bebff237
AM
88 cfi_restore(lr)
89 CFI_REST_ARG \NARG
d7d06f79
UD
90#endif
91 .endm
b80a3db0 92
696caf1d
UW
93#if _CALL_ELF != 2
94
d31beafa
UW
95/* Macro to prepare for calling via a function pointer. */
96 .macro PPC64_LOAD_FUNCPTR PTR
97 ld r12,0(\PTR)
98 ld r2,8(\PTR)
99 mtctr r12
100 ld r11,16(\PTR)
101 .endm
102
590b40f7
UD
103#ifdef USE_PPC64_OVERLAPPING_OPD
104# define OPD_ENT(name) .quad BODY_LABEL (name), .TOC.@tocbase
105#else
106# define OPD_ENT(name) .quad BODY_LABEL (name), .TOC.@tocbase, 0
107#endif
b80a3db0 108
4b6e7667 109#define ENTRY_1(name) \
590b40f7
UD
110 .type BODY_LABEL(name),@function; \
111 .globl name; \
112 .section ".opd","aw"; \
4b6e7667
AM
113 .p2align 3;FUNC_LABEL(name): \
114 OPD_ENT (name); \
115 .previous
590b40f7 116
4b6e7667 117#define FUNC_LABEL(X) X
5ca10a0c 118#define BODY_LABEL(X) .LY##X
4b6e7667 119#define ENTRY_2(name) \
590b40f7
UD
120 .type name,@function; \
121 ENTRY_1(name)
4b6e7667 122#define END_2(name) \
590b40f7 123 .size name,.-BODY_LABEL(name); \
4b6e7667 124 .size BODY_LABEL(name),.-BODY_LABEL(name)
696caf1d
UW
125#define LOCALENTRY(name)
126
4b6e7667 127#else /* _CALL_ELF == 2 */
696caf1d
UW
128
129/* Macro to prepare for calling via a function pointer. */
130 .macro PPC64_LOAD_FUNCPTR PTR
131 mr r12,\PTR
132 mtctr r12
133 .endm
134
4b6e7667 135#define FUNC_LABEL(X) X
696caf1d 136#define BODY_LABEL(X) X
4b6e7667 137#define ENTRY_2(name) \
696caf1d 138 .globl name; \
4b6e7667
AM
139 .type name,@function
140#define END_2(name) \
141 .size name,.-name
142#define LOCALENTRY(name) \
1431: addis r2,r12,.TOC.-1b@ha; \
144 addi r2,r2,.TOC.-1b@l; \
145 .localentry name,.-name
696caf1d
UW
146
147#endif /* _CALL_ELF */
b80a3db0 148
d5b41185
AM
149 .macro NOPS NARG
150 .if \NARG
151 NOPS \NARG-1
152 nop
153 .endif
154 .endm
b80a3db0 155
d5b41185
AM
156 .macro ENTRY_3 name, alignp2=2, nopwords=0
157 .text
158 ENTRY_2(\name)
159 .p2align \alignp2
160 NOPS \nopwords
161BODY_LABEL(\name):
162 .endm
163
164/* Use ENTRY_TOCLESS for functions that make no use of r2 and
165 guarantee r2 is unchanged on exit. Any function that has @toc or
166 @got relocs uses r2. Functions that call other functions via the
167 PLT use r2. Use ENTRY for functions that may use or change r2.
168 The first argument is the function name.
169 The optional second argument specifies alignment of the function's
170 code, as the logarithm base two of the byte alignment. For
171 example, a value of four aligns to a sixteen byte boundary.
172 The optional third argument specifies the number of NOPs to emit
173 before the start of the function's code. */
174#ifndef PROF
175#define ENTRY_TOCLESS(name, ...) \
176 ENTRY_3 name, ## __VA_ARGS__; \
177 cfi_startproc
178
179#define ENTRY(name, ...) \
180 ENTRY_TOCLESS(name, ## __VA_ARGS__); \
181 LOCALENTRY(name)
182#else
183/* The call to _mcount is potentially via the plt, so profiling code
184 is never free of an r2 use. */
185#define ENTRY_TOCLESS(name, ...) \
186 ENTRY_3 name, ## __VA_ARGS__; \
696caf1d
UW
187 cfi_startproc; \
188 LOCALENTRY(name)
b80a3db0 189
d5b41185
AM
190#define ENTRY(name, ...) \
191 ENTRY_TOCLESS(name, ## __VA_ARGS__)
192#endif
193
b80a3db0
RM
194/* Local labels stripped out by the linker. */
195#undef L
196#define L(x) .L##x
197
198#define tostring(s) #s
199#define stringify(s) tostring(s)
200#define XGLUE(a,b) a##b
201#define GLUE(a,b) XGLUE(a,b)
202#define LT_LABEL(name) GLUE(.LT,name)
203#define LT_LABELSUFFIX(name,suffix) GLUE(GLUE(.LT,name),suffix)
204
205/* Support Traceback tables */
206#define TB_ASM 0x000c000000000000
590b40f7 207#define TB_GLOBALLINK 0x0000800000000000
b80a3db0 208#define TB_IS_EPROL 0x0000400000000000
590b40f7 209#define TB_HAS_TBOFF 0x0000200000000000
b80a3db0
RM
210#define TB_INT_PROC 0x0000100000000000
211#define TB_HAS_CTL 0x0000080000000000
212#define TB_TOCLESS 0x0000040000000000
590b40f7
UD
213#define TB_FP_PRESENT 0x0000020000000000
214#define TB_LOG_ABORT 0x0000010000000000
215#define TB_INT_HANDL 0x0000008000000000
216#define TB_NAME_PRESENT 0x0000004000000000
217#define TB_USES_ALLOCA 0x0000002000000000
b80a3db0
RM
218#define TB_SAVES_CR 0x0000000200000000
219#define TB_SAVES_LR 0x0000000100000000
590b40f7 220#define TB_STORES_BC 0x0000000080000000
b80a3db0
RM
221#define TB_FIXUP 0x0000000040000000
222#define TB_FP_SAVED(fprs) (((fprs) & 0x3f) << 24)
223#define TB_GPR_SAVED(gprs) (((fprs) & 0x3f) << 16)
224#define TB_FIXEDPARMS(parms) (((parms) & 0xff) << 8)
225#define TB_FLOATPARMS(parms) (((parms) & 0x7f) << 1)
590b40f7 226#define TB_PARMSONSTK 0x0000000000000001
b80a3db0 227
590b40f7
UD
228#define PPC_HIGHER(v) (((v) >> 32) & 0xffff)
229#define TB_DEFAULT TB_ASM | TB_HAS_TBOFF | TB_NAME_PRESENT
b80a3db0
RM
230
231#define TRACEBACK(name) \
232LT_LABEL(name): ; \
233 .long 0 ; \
234 .quad TB_DEFAULT ; \
590b40f7 235 .long LT_LABEL(name)-BODY_LABEL(name) ; \
b80a3db0
RM
236 .short LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
237LT_LABELSUFFIX(name,_name_start): ;\
238 .ascii stringify(name) ; \
239LT_LABELSUFFIX(name,_name_end): ; \
4b6e7667 240 .p2align 2
b80a3db0
RM
241
242#define TRACEBACK_MASK(name,mask) \
243LT_LABEL(name): ; \
244 .long 0 ; \
245 .quad TB_DEFAULT | mask ; \
590b40f7 246 .long LT_LABEL(name)-BODY_LABEL(name) ; \
b80a3db0
RM
247 .short LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
248LT_LABELSUFFIX(name,_name_start): ;\
249 .ascii stringify(name) ; \
250LT_LABELSUFFIX(name,_name_end): ; \
4b6e7667 251 .p2align 2
b80a3db0
RM
252
253/* END generates Traceback tables */
254#undef END
255#define END(name) \
9759bbf1 256 cfi_endproc; \
4b6e7667 257 TRACEBACK(name); \
590b40f7 258 END_2(name)
b80a3db0
RM
259
260/* This form supports more informative traceback tables */
261#define END_GEN_TB(name,mask) \
9759bbf1 262 cfi_endproc; \
4b6e7667 263 TRACEBACK_MASK(name,mask); \
590b40f7 264 END_2(name)
b80a3db0
RM
265
266#define DO_CALL(syscall) \
267 li 0,syscall; \
268 sc
269
270/* ppc64 is always PIC */
29d9a17d 271#undef JUMPTARGET
4b6e7667 272#define JUMPTARGET(name) FUNC_LABEL(name)
b80a3db0
RM
273
274#define PSEUDO(name, syscall_name, args) \
4b6e7667
AM
275 .section ".text"; \
276 ENTRY (name); \
277 DO_CALL (SYS_ify (syscall_name))
b80a3db0 278
bebff237
AM
279#ifdef SHARED
280#define TAIL_CALL_SYSCALL_ERROR \
281 b JUMPTARGET(__syscall_error)
282#else
283/* Static version might be linked into a large app with a toc exceeding
284 64k. We can't put a toc adjusting stub on a plain branch, so can't
285 tail call __syscall_error. */
286#define TAIL_CALL_SYSCALL_ERROR \
287 .ifdef .Local_syscall_error; \
288 b .Local_syscall_error; \
289 .else; \
290.Local_syscall_error: \
291 mflr 0; \
8b8a692c
UW
292 std 0,FRAME_LR_SAVE(1); \
293 stdu 1,-FRAME_MIN_SIZE(1); \
294 cfi_adjust_cfa_offset(FRAME_MIN_SIZE); \
295 cfi_offset(lr,FRAME_LR_SAVE); \
bebff237
AM
296 bl JUMPTARGET(__syscall_error); \
297 nop; \
8b8a692c
UW
298 ld 0,FRAME_MIN_SIZE+FRAME_LR_SAVE(1); \
299 addi 1,1,FRAME_MIN_SIZE; \
300 cfi_adjust_cfa_offset(-FRAME_MIN_SIZE); \
bebff237
AM
301 mtlr 0; \
302 cfi_restore(lr); \
303 blr; \
304 .endif
305#endif
306
b80a3db0 307#define PSEUDO_RET \
aff4519d 308 bnslr+; \
bebff237 309 TAIL_CALL_SYSCALL_ERROR
b80a3db0
RM
310
311#define ret PSEUDO_RET
312
313#undef PSEUDO_END
314#define PSEUDO_END(name) \
315 END (name)
316
9eb88290 317#define PSEUDO_NOERRNO(name, syscall_name, args) \
4b6e7667
AM
318 .section ".text"; \
319 ENTRY (name); \
320 DO_CALL (SYS_ify (syscall_name))
9eb88290
UD
321
322#define PSEUDO_RET_NOERRNO \
323 blr
324
325#define ret_NOERRNO PSEUDO_RET_NOERRNO
326
327#undef PSEUDO_END_NOERRNO
c6289757 328#define PSEUDO_END_NOERRNO(name) \
9eb88290
UD
329 END (name)
330
137ffcdc 331#define PSEUDO_ERRVAL(name, syscall_name, args) \
4b6e7667
AM
332 .section ".text"; \
333 ENTRY (name); \
334 DO_CALL (SYS_ify (syscall_name))
137ffcdc
UD
335
336#define PSEUDO_RET_ERRVAL \
337 blr
338
339#define ret_ERRVAL PSEUDO_RET_ERRVAL
340
341#undef PSEUDO_END_ERRVAL
342#define PSEUDO_END_ERRVAL(name) \
343 END (name)
344
590b40f7 345#else /* !__ASSEMBLER__ */
b80a3db0 346
696caf1d
UW
347#if _CALL_ELF != 2
348
d31beafa 349#define PPC64_LOAD_FUNCPTR(ptr) \
4b6e7667
AM
350 "ld 12,0(" #ptr ")\n" \
351 "ld 2,8(" #ptr ")\n" \
352 "mtctr 12\n" \
353 "ld 11,16(" #ptr ")"
d31beafa 354
590b40f7 355#ifdef USE_PPC64_OVERLAPPING_OPD
4b6e7667 356# define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase"
590b40f7 357#else
4b6e7667 358# define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase, 0"
590b40f7
UD
359#endif
360
d31beafa 361#define ENTRY_1(name) \
4b6e7667
AM
362 ".type " BODY_PREFIX #name ",@function\n" \
363 ".globl " #name "\n" \
364 ".pushsection \".opd\",\"aw\"\n" \
365 ".p2align 3\n" \
d31beafa
UW
366#name ":\n" \
367 OPD_ENT (name) "\n" \
4b6e7667 368 ".popsection"
d31beafa 369
5ca10a0c
AZ
370#define DOT_PREFIX ""
371#define BODY_PREFIX ".LY"
372#define ENTRY_2(name) \
4b6e7667 373 ".type " #name ",@function\n" \
d31beafa 374 ENTRY_1(name)
5ca10a0c 375#define END_2(name) \
4b6e7667
AM
376 ".size " #name ",.-" BODY_PREFIX #name "\n" \
377 ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name
696caf1d
UW
378#define LOCALENTRY(name)
379
380#else /* _CALL_ELF */
381
382#define PPC64_LOAD_FUNCPTR(ptr) \
4b6e7667
AM
383 "mr 12," #ptr "\n" \
384 "mtctr 12"
696caf1d
UW
385
386#define DOT_PREFIX ""
387#define BODY_PREFIX ""
388#define ENTRY_2(name) \
4b6e7667
AM
389 ".type " #name ",@function\n" \
390 ".globl " #name
696caf1d 391#define END_2(name) \
4b6e7667 392 ".size " #name ",.-" #name
696caf1d 393#define LOCALENTRY(name) \
4b6e7667
AM
394 "1: addis 2,12,.TOC.-1b@ha\n" \
395 "addi 2,2,.TOC.-1b@l\n" \
396 ".localentry " #name ",.-" #name
696caf1d
UW
397
398#endif /* _CALL_ELF */
b80a3db0
RM
399
400#endif /* __ASSEMBLER__ */