]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/powerpc/powerpc64/sysdep.h
PowerPC64 strncpy, stpncpy and strstr fixes
[thirdparty/glibc.git] / sysdeps / powerpc / powerpc64 / sysdep.h
CommitLineData
b80a3db0 1/* Assembly macros for 64-bit PowerPC.
bfff8b1b 2 Copyright (C) 2002-2017 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
PE
16 License along with the GNU C Library; if not, see
17 <http://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
590b40f7 149#define ENTRY(name) \
d31beafa 150 .section ".text"; \
4b6e7667 151 ENTRY_2(name); \
590b40f7 152 .align ALIGNARG(2); \
9759bbf1 153BODY_LABEL(name): \
696caf1d
UW
154 cfi_startproc; \
155 LOCALENTRY(name)
b80a3db0
RM
156
157#define EALIGN_W_0 /* No words to insert. */
158#define EALIGN_W_1 nop
159#define EALIGN_W_2 nop;nop
160#define EALIGN_W_3 nop;nop;nop
161#define EALIGN_W_4 EALIGN_W_3;nop
162#define EALIGN_W_5 EALIGN_W_4;nop
163#define EALIGN_W_6 EALIGN_W_5;nop
164#define EALIGN_W_7 EALIGN_W_6;nop
165
166/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
590b40f7 167 past a 2^alignt boundary. */
b80a3db0 168#define EALIGN(name, alignt, words) \
d31beafa 169 .section ".text"; \
4b6e7667 170 ENTRY_2(name); \
590b40f7
UD
171 .align ALIGNARG(alignt); \
172 EALIGN_W_##words; \
9759bbf1 173BODY_LABEL(name): \
696caf1d
UW
174 cfi_startproc; \
175 LOCALENTRY(name)
b80a3db0
RM
176
177/* Local labels stripped out by the linker. */
178#undef L
179#define L(x) .L##x
180
181#define tostring(s) #s
182#define stringify(s) tostring(s)
183#define XGLUE(a,b) a##b
184#define GLUE(a,b) XGLUE(a,b)
185#define LT_LABEL(name) GLUE(.LT,name)
186#define LT_LABELSUFFIX(name,suffix) GLUE(GLUE(.LT,name),suffix)
187
188/* Support Traceback tables */
189#define TB_ASM 0x000c000000000000
590b40f7 190#define TB_GLOBALLINK 0x0000800000000000
b80a3db0 191#define TB_IS_EPROL 0x0000400000000000
590b40f7 192#define TB_HAS_TBOFF 0x0000200000000000
b80a3db0
RM
193#define TB_INT_PROC 0x0000100000000000
194#define TB_HAS_CTL 0x0000080000000000
195#define TB_TOCLESS 0x0000040000000000
590b40f7
UD
196#define TB_FP_PRESENT 0x0000020000000000
197#define TB_LOG_ABORT 0x0000010000000000
198#define TB_INT_HANDL 0x0000008000000000
199#define TB_NAME_PRESENT 0x0000004000000000
200#define TB_USES_ALLOCA 0x0000002000000000
b80a3db0
RM
201#define TB_SAVES_CR 0x0000000200000000
202#define TB_SAVES_LR 0x0000000100000000
590b40f7 203#define TB_STORES_BC 0x0000000080000000
b80a3db0
RM
204#define TB_FIXUP 0x0000000040000000
205#define TB_FP_SAVED(fprs) (((fprs) & 0x3f) << 24)
206#define TB_GPR_SAVED(gprs) (((fprs) & 0x3f) << 16)
207#define TB_FIXEDPARMS(parms) (((parms) & 0xff) << 8)
208#define TB_FLOATPARMS(parms) (((parms) & 0x7f) << 1)
590b40f7 209#define TB_PARMSONSTK 0x0000000000000001
b80a3db0 210
590b40f7
UD
211#define PPC_HIGHER(v) (((v) >> 32) & 0xffff)
212#define TB_DEFAULT TB_ASM | TB_HAS_TBOFF | TB_NAME_PRESENT
b80a3db0
RM
213
214#define TRACEBACK(name) \
215LT_LABEL(name): ; \
216 .long 0 ; \
217 .quad TB_DEFAULT ; \
590b40f7 218 .long LT_LABEL(name)-BODY_LABEL(name) ; \
b80a3db0
RM
219 .short LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
220LT_LABELSUFFIX(name,_name_start): ;\
221 .ascii stringify(name) ; \
222LT_LABELSUFFIX(name,_name_end): ; \
4b6e7667 223 .p2align 2
b80a3db0
RM
224
225#define TRACEBACK_MASK(name,mask) \
226LT_LABEL(name): ; \
227 .long 0 ; \
228 .quad TB_DEFAULT | mask ; \
590b40f7 229 .long LT_LABEL(name)-BODY_LABEL(name) ; \
b80a3db0
RM
230 .short LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
231LT_LABELSUFFIX(name,_name_start): ;\
232 .ascii stringify(name) ; \
233LT_LABELSUFFIX(name,_name_end): ; \
4b6e7667 234 .p2align 2
b80a3db0
RM
235
236/* END generates Traceback tables */
237#undef END
238#define END(name) \
9759bbf1 239 cfi_endproc; \
4b6e7667 240 TRACEBACK(name); \
590b40f7 241 END_2(name)
b80a3db0
RM
242
243/* This form supports more informative traceback tables */
244#define END_GEN_TB(name,mask) \
9759bbf1 245 cfi_endproc; \
4b6e7667 246 TRACEBACK_MASK(name,mask); \
590b40f7 247 END_2(name)
b80a3db0 248
56cf2763
AZ
249#if !IS_IN(rtld) && defined (ENABLE_LOCK_ELISION)
250# define ABORT_TRANSACTION \
251 cmpdi 13,0; \
252 beq 1f; \
253 lwz 0,TM_CAPABLE(13); \
254 cmpwi 0,0; \
255 beq 1f; \
18173559
PM
256 li 11,_ABORT_SYSCALL; \
257 tabort. 11; \
4b6e7667 258 .p2align 4; \
56cf2763
AZ
2591:
260#else
261# define ABORT_TRANSACTION
262#endif
263
b80a3db0 264#define DO_CALL(syscall) \
56cf2763 265 ABORT_TRANSACTION \
b80a3db0
RM
266 li 0,syscall; \
267 sc
268
269/* ppc64 is always PIC */
29d9a17d 270#undef JUMPTARGET
4b6e7667 271#define JUMPTARGET(name) FUNC_LABEL(name)
b80a3db0
RM
272
273#define PSEUDO(name, syscall_name, args) \
4b6e7667
AM
274 .section ".text"; \
275 ENTRY (name); \
276 DO_CALL (SYS_ify (syscall_name))
b80a3db0 277
bebff237
AM
278#ifdef SHARED
279#define TAIL_CALL_SYSCALL_ERROR \
280 b JUMPTARGET(__syscall_error)
281#else
282/* Static version might be linked into a large app with a toc exceeding
283 64k. We can't put a toc adjusting stub on a plain branch, so can't
284 tail call __syscall_error. */
285#define TAIL_CALL_SYSCALL_ERROR \
286 .ifdef .Local_syscall_error; \
287 b .Local_syscall_error; \
288 .else; \
289.Local_syscall_error: \
290 mflr 0; \
8b8a692c
UW
291 std 0,FRAME_LR_SAVE(1); \
292 stdu 1,-FRAME_MIN_SIZE(1); \
293 cfi_adjust_cfa_offset(FRAME_MIN_SIZE); \
294 cfi_offset(lr,FRAME_LR_SAVE); \
bebff237
AM
295 bl JUMPTARGET(__syscall_error); \
296 nop; \
8b8a692c
UW
297 ld 0,FRAME_MIN_SIZE+FRAME_LR_SAVE(1); \
298 addi 1,1,FRAME_MIN_SIZE; \
299 cfi_adjust_cfa_offset(-FRAME_MIN_SIZE); \
bebff237
AM
300 mtlr 0; \
301 cfi_restore(lr); \
302 blr; \
303 .endif
304#endif
305
b80a3db0 306#define PSEUDO_RET \
aff4519d 307 bnslr+; \
bebff237 308 TAIL_CALL_SYSCALL_ERROR
b80a3db0
RM
309
310#define ret PSEUDO_RET
311
312#undef PSEUDO_END
313#define PSEUDO_END(name) \
314 END (name)
315
9eb88290 316#define PSEUDO_NOERRNO(name, syscall_name, args) \
4b6e7667
AM
317 .section ".text"; \
318 ENTRY (name); \
319 DO_CALL (SYS_ify (syscall_name))
9eb88290
UD
320
321#define PSEUDO_RET_NOERRNO \
322 blr
323
324#define ret_NOERRNO PSEUDO_RET_NOERRNO
325
326#undef PSEUDO_END_NOERRNO
c6289757 327#define PSEUDO_END_NOERRNO(name) \
9eb88290
UD
328 END (name)
329
137ffcdc 330#define PSEUDO_ERRVAL(name, syscall_name, args) \
4b6e7667
AM
331 .section ".text"; \
332 ENTRY (name); \
333 DO_CALL (SYS_ify (syscall_name))
137ffcdc
UD
334
335#define PSEUDO_RET_ERRVAL \
336 blr
337
338#define ret_ERRVAL PSEUDO_RET_ERRVAL
339
340#undef PSEUDO_END_ERRVAL
341#define PSEUDO_END_ERRVAL(name) \
342 END (name)
343
590b40f7 344#else /* !__ASSEMBLER__ */
b80a3db0 345
696caf1d
UW
346#if _CALL_ELF != 2
347
d31beafa 348#define PPC64_LOAD_FUNCPTR(ptr) \
4b6e7667
AM
349 "ld 12,0(" #ptr ")\n" \
350 "ld 2,8(" #ptr ")\n" \
351 "mtctr 12\n" \
352 "ld 11,16(" #ptr ")"
d31beafa 353
590b40f7 354#ifdef USE_PPC64_OVERLAPPING_OPD
4b6e7667 355# define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase"
590b40f7 356#else
4b6e7667 357# define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase, 0"
590b40f7
UD
358#endif
359
d31beafa 360#define ENTRY_1(name) \
4b6e7667
AM
361 ".type " BODY_PREFIX #name ",@function\n" \
362 ".globl " #name "\n" \
363 ".pushsection \".opd\",\"aw\"\n" \
364 ".p2align 3\n" \
d31beafa
UW
365#name ":\n" \
366 OPD_ENT (name) "\n" \
4b6e7667 367 ".popsection"
d31beafa 368
5ca10a0c
AZ
369#define DOT_PREFIX ""
370#define BODY_PREFIX ".LY"
371#define ENTRY_2(name) \
4b6e7667 372 ".type " #name ",@function\n" \
d31beafa 373 ENTRY_1(name)
5ca10a0c 374#define END_2(name) \
4b6e7667
AM
375 ".size " #name ",.-" BODY_PREFIX #name "\n" \
376 ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name
696caf1d
UW
377#define LOCALENTRY(name)
378
379#else /* _CALL_ELF */
380
381#define PPC64_LOAD_FUNCPTR(ptr) \
4b6e7667
AM
382 "mr 12," #ptr "\n" \
383 "mtctr 12"
696caf1d
UW
384
385#define DOT_PREFIX ""
386#define BODY_PREFIX ""
387#define ENTRY_2(name) \
4b6e7667
AM
388 ".type " #name ",@function\n" \
389 ".globl " #name
696caf1d 390#define END_2(name) \
4b6e7667 391 ".size " #name ",.-" #name
696caf1d 392#define LOCALENTRY(name) \
4b6e7667
AM
393 "1: addis 2,12,.TOC.-1b@ha\n" \
394 "addi 2,2,.TOC.-1b@l\n" \
395 ".localentry " #name ",.-" #name
696caf1d
UW
396
397#endif /* _CALL_ELF */
b80a3db0
RM
398
399#endif /* __ASSEMBLER__ */