Update copyright notices with scripts/update-copyrights.
[jlayton/glibc.git] / sysdeps / powerpc / powerpc64 / sysdep.h
1 /* Assembly macros for 64-bit PowerPC.
2    Copyright (C) 2002-2013 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    <http://www.gnu.org/licenses/>.  */
18
19 #include <sysdeps/powerpc/sysdep.h>
20
21 #ifdef __ASSEMBLER__
22
23 /* Support macros for CALL_MCOUNT.  */
24         .macro SAVE_ARG NARG
25         .if \NARG
26         SAVE_ARG \NARG-1
27         std     2+\NARG,40+8*(\NARG)(1)
28         .endif
29         .endm
30
31         .macro REST_ARG NARG
32         .if \NARG
33         REST_ARG \NARG-1
34         ld      2+\NARG,112+40+8*(\NARG)(1)
35         .endif
36         .endm
37
38         .macro CFI_SAVE_ARG NARG
39         .if \NARG
40         CFI_SAVE_ARG \NARG-1
41         cfi_offset(2+\NARG,40+8*(\NARG))
42         .endif
43         .endm
44
45         .macro CFI_REST_ARG NARG
46         .if \NARG
47         CFI_REST_ARG \NARG-1
48         cfi_restore(2+\NARG)
49         .endif
50         .endm
51
52 /* If compiled for profiling, call `_mcount' at the start of each function.
53    see ppc-mcount.S for more details.  */
54         .macro CALL_MCOUNT NARG
55 #ifdef  PROF
56         mflr    r0
57         SAVE_ARG \NARG
58         std     r0,16(r1)
59         stdu    r1,-112(r1)
60         cfi_adjust_cfa_offset(112)
61         cfi_offset(lr,16)
62         CFI_SAVE_ARG \NARG
63         bl      JUMPTARGET (_mcount)
64 #ifndef SHARED
65         nop
66 #endif
67         ld      r0,128(r1)
68         REST_ARG \NARG
69         mtlr    r0
70         addi    r1,r1,112
71         cfi_adjust_cfa_offset(-112)
72         cfi_restore(lr)
73         CFI_REST_ARG \NARG
74 #endif
75         .endm
76
77 #ifdef USE_PPC64_OVERLAPPING_OPD
78 # define OPD_ENT(name)  .quad BODY_LABEL (name), .TOC.@tocbase
79 #else
80 # define OPD_ENT(name)  .quad BODY_LABEL (name), .TOC.@tocbase, 0
81 #endif
82
83 #define ENTRY_1(name)   \
84         .section        ".text";                \
85         .type BODY_LABEL(name),@function;       \
86         .globl name;                            \
87         .section ".opd","aw";                   \
88         .align 3;                               \
89 name##: OPD_ENT (name);                         \
90         .previous;
91
92 #ifdef HAVE_ASM_GLOBAL_DOT_NAME
93 # define DOT_LABEL(X) .##X
94 # define BODY_LABEL(X) .##X
95 # define ENTRY_2(name)  \
96         .globl BODY_LABEL(name);                \
97         ENTRY_1(name)                           \
98         .size name, 24;
99 # define END_2(name)    \
100         .size BODY_LABEL(name),.-BODY_LABEL(name);
101 #else
102 # define DOT_LABEL(X) X
103 # define BODY_LABEL(X) .LY##X
104 # define ENTRY_2(name)  \
105         .type name,@function;                   \
106         ENTRY_1(name)
107 # define END_2(name)    \
108         .size name,.-BODY_LABEL(name);          \
109         .size BODY_LABEL(name),.-BODY_LABEL(name);
110 #endif
111
112 #define ENTRY(name)     \
113         ENTRY_2(name)                           \
114         .align ALIGNARG(2);                     \
115 BODY_LABEL(name):                               \
116         cfi_startproc;
117
118 #define EALIGN_W_0  /* No words to insert.  */
119 #define EALIGN_W_1  nop
120 #define EALIGN_W_2  nop;nop
121 #define EALIGN_W_3  nop;nop;nop
122 #define EALIGN_W_4  EALIGN_W_3;nop
123 #define EALIGN_W_5  EALIGN_W_4;nop
124 #define EALIGN_W_6  EALIGN_W_5;nop
125 #define EALIGN_W_7  EALIGN_W_6;nop
126
127 /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
128    past a 2^alignt boundary.  */
129 #define EALIGN(name, alignt, words) \
130         ENTRY_2(name)                           \
131         .align ALIGNARG(alignt);                \
132         EALIGN_W_##words;                       \
133 BODY_LABEL(name):                               \
134         cfi_startproc;
135
136 /* Local labels stripped out by the linker.  */
137 #undef L
138 #define L(x) .L##x
139
140 #define tostring(s) #s
141 #define stringify(s) tostring(s)
142 #define XGLUE(a,b) a##b
143 #define GLUE(a,b) XGLUE(a,b)
144 #define LT_LABEL(name) GLUE(.LT,name)
145 #define LT_LABELSUFFIX(name,suffix) GLUE(GLUE(.LT,name),suffix)
146
147 /* Support Traceback tables */
148 #define TB_ASM                  0x000c000000000000
149 #define TB_GLOBALLINK           0x0000800000000000
150 #define TB_IS_EPROL             0x0000400000000000
151 #define TB_HAS_TBOFF            0x0000200000000000
152 #define TB_INT_PROC             0x0000100000000000
153 #define TB_HAS_CTL              0x0000080000000000
154 #define TB_TOCLESS              0x0000040000000000
155 #define TB_FP_PRESENT           0x0000020000000000
156 #define TB_LOG_ABORT            0x0000010000000000
157 #define TB_INT_HANDL            0x0000008000000000
158 #define TB_NAME_PRESENT         0x0000004000000000
159 #define TB_USES_ALLOCA          0x0000002000000000
160 #define TB_SAVES_CR             0x0000000200000000
161 #define TB_SAVES_LR             0x0000000100000000
162 #define TB_STORES_BC            0x0000000080000000
163 #define TB_FIXUP                0x0000000040000000
164 #define TB_FP_SAVED(fprs)       (((fprs) & 0x3f) << 24)
165 #define TB_GPR_SAVED(gprs)      (((fprs) & 0x3f) << 16)
166 #define TB_FIXEDPARMS(parms)    (((parms) & 0xff) << 8)
167 #define TB_FLOATPARMS(parms)    (((parms) & 0x7f) << 1)
168 #define TB_PARMSONSTK           0x0000000000000001
169
170 #define PPC_HIGHER(v)           (((v) >> 32) & 0xffff)
171 #define TB_DEFAULT              TB_ASM | TB_HAS_TBOFF | TB_NAME_PRESENT
172
173 #define TRACEBACK(name) \
174 LT_LABEL(name): ; \
175         .long   0 ; \
176         .quad   TB_DEFAULT ; \
177         .long   LT_LABEL(name)-BODY_LABEL(name) ; \
178         .short  LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
179 LT_LABELSUFFIX(name,_name_start): ;\
180         .ascii  stringify(name) ; \
181 LT_LABELSUFFIX(name,_name_end): ; \
182         .align  2 ;
183
184 #define TRACEBACK_MASK(name,mask) \
185 LT_LABEL(name): ; \
186         .long   0 ; \
187         .quad   TB_DEFAULT | mask ; \
188         .long   LT_LABEL(name)-BODY_LABEL(name) ; \
189         .short  LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
190 LT_LABELSUFFIX(name,_name_start): ;\
191         .ascii  stringify(name) ; \
192 LT_LABELSUFFIX(name,_name_end): ; \
193         .align  2 ;
194
195 /* END generates Traceback tables */
196 #undef  END
197 #define END(name) \
198   cfi_endproc;                  \
199   TRACEBACK(name)               \
200   END_2(name)
201
202 /* This form supports more informative traceback tables */
203 #define END_GEN_TB(name,mask)   \
204   cfi_endproc;                  \
205   TRACEBACK_MASK(name,mask)     \
206   END_2(name)
207
208 #define DO_CALL(syscall) \
209     li 0,syscall; \
210     sc
211
212 /* ppc64 is always PIC */
213 #undef JUMPTARGET
214 #define JUMPTARGET(name) DOT_LABEL(name)
215
216 #define PSEUDO(name, syscall_name, args) \
217   .section ".text";     \
218   ENTRY (name) \
219   DO_CALL (SYS_ify (syscall_name));
220
221 #ifdef SHARED
222 #define TAIL_CALL_SYSCALL_ERROR \
223     b JUMPTARGET(__syscall_error)
224 #else
225 /* Static version might be linked into a large app with a toc exceeding
226    64k.  We can't put a toc adjusting stub on a plain branch, so can't
227    tail call __syscall_error.  */
228 #define TAIL_CALL_SYSCALL_ERROR \
229     .ifdef .Local_syscall_error; \
230     b .Local_syscall_error; \
231     .else; \
232 .Local_syscall_error: \
233     mflr 0; \
234     std 0,16(1); \
235     stdu 1,-112(1); \
236     cfi_adjust_cfa_offset(112); \
237     cfi_offset(lr,16); \
238     bl JUMPTARGET(__syscall_error); \
239     nop; \
240     ld 0,112+16(1); \
241     addi 1,1,112; \
242     cfi_adjust_cfa_offset(-112); \
243     mtlr 0; \
244     cfi_restore(lr); \
245     blr; \
246     .endif
247 #endif
248
249 #define PSEUDO_RET \
250     bnslr+; \
251     TAIL_CALL_SYSCALL_ERROR
252
253 #define ret PSEUDO_RET
254
255 #undef  PSEUDO_END
256 #define PSEUDO_END(name) \
257   END (name)
258
259 #define PSEUDO_NOERRNO(name, syscall_name, args) \
260   .section ".text";     \
261   ENTRY (name) \
262   DO_CALL (SYS_ify (syscall_name));
263
264 #define PSEUDO_RET_NOERRNO \
265     blr
266
267 #define ret_NOERRNO PSEUDO_RET_NOERRNO
268
269 #undef  PSEUDO_END_NOERRNO
270 #define PSEUDO_END_NOERRNO(name) \
271   END (name)
272
273 #define PSEUDO_ERRVAL(name, syscall_name, args) \
274   .section ".text";     \
275   ENTRY (name) \
276   DO_CALL (SYS_ify (syscall_name));
277
278 #define PSEUDO_RET_ERRVAL \
279     blr
280
281 #define ret_ERRVAL PSEUDO_RET_ERRVAL
282
283 #undef  PSEUDO_END_ERRVAL
284 #define PSEUDO_END_ERRVAL(name) \
285   END (name)
286
287 #else /* !__ASSEMBLER__ */
288
289 #ifdef USE_PPC64_OVERLAPPING_OPD
290 # define OPD_ENT(name)  ".quad " BODY_PREFIX #name ", .TOC.@tocbase;"
291 #else
292 # define OPD_ENT(name)  ".quad " BODY_PREFIX #name ", .TOC.@tocbase, 0;"
293 #endif
294
295 #ifdef HAVE_ASM_GLOBAL_DOT_NAME
296 # define DOT_PREFIX "."
297 # define BODY_PREFIX "."
298 # define ENTRY_2(name)  \
299         ".globl " BODY_PREFIX #name ";\n"                               \
300         ".size  " #name ", 24;"
301 # define END_2(name)    \
302         ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
303 #else
304 # define DOT_PREFIX ""
305 # define BODY_PREFIX ".LY"
306 # define ENTRY_2(name) ".type " #name ",@function;"
307 # define END_2(name)    \
308         ".size " #name ",.-" BODY_PREFIX #name ";\n"                    \
309         ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
310 #endif
311
312 #endif  /* __ASSEMBLER__ */