Remove unnecessary uses of NOT_IN_libc
[glibc.git] / sysdeps / arm / sysdep.h
blob4c41213c37d5d06965189491df8ae1964518f77c
1 /* Assembler macros for ARM.
2 Copyright (C) 1997-2014 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
19 #include <sysdeps/generic/sysdep.h>
20 #include <features.h>
22 #ifndef __ASSEMBLER__
23 # include <stdint.h>
24 #endif
26 /* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */
27 #ifndef __ARM_ARCH
28 # ifdef __ARM_ARCH_2__
29 # define __ARM_ARCH 2
30 # elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__)
31 # define __ARM_ARCH 3
32 # elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__)
33 # define __ARM_ARCH 4
34 # elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \
35 || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
36 || defined(__ARM_ARCH_5TEJ__)
37 # define __ARM_ARCH 5
38 # elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
39 || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
40 || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
41 # define __ARM_ARCH 6
42 # elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
43 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
44 || defined(__ARM_ARCH_7EM__)
45 # define __ARM_ARCH 7
46 # else
47 # error unknown arm architecture
48 # endif
49 #endif
51 #if __ARM_ARCH > 4 || defined (__ARM_ARCH_4T__)
52 # define ARCH_HAS_BX
53 #endif
54 #if __ARM_ARCH > 4
55 # define ARCH_HAS_BLX
56 #endif
57 #if __ARM_ARCH > 6 || defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6ZK__)
58 # define ARCH_HAS_HARD_TP
59 #endif
60 #if __ARM_ARCH > 6 || defined (__ARM_ARCH_6T2__)
61 # define ARCH_HAS_T2
62 #endif
64 #ifdef __ASSEMBLER__
66 /* Syntactic details of assembler. */
68 #define ALIGNARG(log2) log2
69 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name
71 #define PLTJMP(_x) _x##(PLT)
73 #ifdef ARCH_HAS_BX
74 # define BX(R) bx R
75 # define BXC(C, R) bx##C R
76 # ifdef ARCH_HAS_BLX
77 # define BLX(R) blx R
78 # else
79 # define BLX(R) mov lr, pc; bx R
80 # endif
81 #else
82 # define BX(R) mov pc, R
83 # define BXC(C, R) mov##C pc, R
84 # define BLX(R) mov lr, pc; mov pc, R
85 #endif
87 #define DO_RET(R) BX(R)
88 #define RETINSTR(C, R) BXC(C, R)
90 /* Define an entry point visible from C. */
91 #define ENTRY(name) \
92 .globl C_SYMBOL_NAME(name); \
93 .type C_SYMBOL_NAME(name),%function; \
94 .align ALIGNARG(4); \
95 C_LABEL(name) \
96 CFI_SECTIONS; \
97 cfi_startproc; \
98 CALL_MCOUNT
100 #define CFI_SECTIONS \
101 .cfi_sections .debug_frame
103 #undef END
104 #define END(name) \
105 cfi_endproc; \
106 ASM_SIZE_DIRECTIVE(name)
108 /* If compiled for profiling, call `mcount' at the start of each function. */
109 #ifdef PROF
110 /* Call __gnu_mcount_nc if GCC >= 4.4. */
111 #if __GNUC_PREREQ(4,4)
112 #define CALL_MCOUNT \
113 push {lr}; \
114 cfi_adjust_cfa_offset (4); \
115 cfi_rel_offset (lr, 0); \
116 bl PLTJMP(mcount); \
117 cfi_adjust_cfa_offset (-4); \
118 cfi_restore (lr)
119 #else /* else call _mcount */
120 #define CALL_MCOUNT \
121 push {lr}; \
122 cfi_adjust_cfa_offset (4); \
123 cfi_rel_offset (lr, 0); \
124 bl PLTJMP(mcount); \
125 pops {lr}; \
126 cfi_adjust_cfa_offset (-4); \
127 cfi_restore (lr)
128 #endif
129 #else
130 #define CALL_MCOUNT /* Do nothing. */
131 #endif
133 /* Since C identifiers are not normally prefixed with an underscore
134 on this system, the asm identifier `syscall_error' intrudes on the
135 C name space. Make sure we use an innocuous name. */
136 #define syscall_error __syscall_error
137 #if __GNUC_PREREQ(4,4)
138 #define mcount __gnu_mcount_nc
139 #else
140 #define mcount _mcount
141 #endif
143 /* Tag_ABI_align8_preserved: This code preserves 8-byte
144 alignment in any callee. */
145 .eabi_attribute 25, 1
146 /* Tag_ABI_align8_needed: This code may require 8-byte alignment from
147 the caller. */
148 .eabi_attribute 24, 1
150 /* The thumb2 encoding is reasonably complete. Unless suppressed, use it. */
151 .syntax unified
152 # if defined(__thumb2__) && !defined(NO_THUMB)
153 .thumb
154 #else
155 # undef __thumb__
156 # undef __thumb2__
157 .arm
158 # endif
160 /* Load or store to/from a pc-relative EXPR into/from R, using T. */
161 # ifdef __thumb2__
162 # define LDST_PCREL(OP, R, T, EXPR) \
163 ldr T, 98f; \
164 .subsection 2; \
165 98: .word EXPR - 99f - PC_OFS; \
166 .previous; \
167 99: add T, T, pc; \
168 OP R, [T]
169 # else
170 # define LDST_PCREL(OP, R, T, EXPR) \
171 ldr T, 98f; \
172 .subsection 2; \
173 98: .word EXPR - 99f - PC_OFS; \
174 .previous; \
175 99: OP R, [pc, T]
176 # endif
178 /* Load or store to/from a global EXPR into/from R, using T. */
179 # define LDST_GLOBAL(OP, R, T, EXPR) \
180 ldr T, 99f; \
181 ldr R, 100f; \
182 98: add T, T, pc; \
183 ldr T, [T, R]; \
184 .subsection 2; \
185 99: .word _GLOBAL_OFFSET_TABLE_ - 98b - PC_OFS; \
186 100: .word EXPR##(GOT); \
187 .previous; \
188 OP R, [T]
190 /* Cope with negative memory offsets, which thumb can't encode.
191 Use NEGOFF_ADJ_BASE to (conditionally) alter the base register,
192 and then NEGOFF_OFF1 to use 0 for thumb and the offset for arm,
193 or NEGOFF_OFF2 to use A-B for thumb and A for arm. */
194 # ifdef __thumb2__
195 # define NEGOFF_ADJ_BASE(R, OFF) add R, R, $OFF
196 # define NEGOFF_ADJ_BASE2(D, S, OFF) add D, S, $OFF
197 # define NEGOFF_OFF1(R, OFF) [R]
198 # define NEGOFF_OFF2(R, OFFA, OFFB) [R, $((OFFA) - (OFFB))]
199 # else
200 # define NEGOFF_ADJ_BASE(R, OFF)
201 # define NEGOFF_ADJ_BASE2(D, S, OFF) mov D, S
202 # define NEGOFF_OFF1(R, OFF) [R, $OFF]
203 # define NEGOFF_OFF2(R, OFFA, OFFB) [R, $OFFA]
204 # endif
206 /* Helper to get the TLS base pointer. The interface is that TMP is a
207 register that may be used to hold the LR, if necessary. TMP may be
208 LR itself to indicate that LR need not be saved. The base pointer
209 is returned in R0. Only R0 and TMP are modified. */
211 # ifdef ARCH_HAS_HARD_TP
212 /* If the cpu has cp15 available, use it. */
213 # define GET_TLS(TMP) mrc p15, 0, r0, c13, c0, 3
214 # else
215 /* At this generic level we have no tricks to pull. Call the ABI routine. */
216 # define GET_TLS(TMP) \
217 push { r1, r2, r3, lr }; \
218 cfi_remember_state; \
219 cfi_adjust_cfa_offset (16); \
220 cfi_rel_offset (r1, 0); \
221 cfi_rel_offset (r2, 4); \
222 cfi_rel_offset (r3, 8); \
223 cfi_rel_offset (lr, 12); \
224 bl __aeabi_read_tp; \
225 pop { r1, r2, r3, lr }; \
226 cfi_restore_state
227 # endif /* ARCH_HAS_HARD_TP */
229 # ifndef ARM_SFI_MACROS
230 # define ARM_SFI_MACROS 1
231 /* This assembly macro is prepended to any load/store instruction,
232 pulling the base register out of the addressing mode syntax and
233 making it the first operand of the macro. For example:
234 ldr r0, [r1]
235 becomes:
236 sfi_breg r1, ldr r0, [\B]
237 The \B stands in for the base register that is the first operand
238 to the macro, so we can avoid error-prone repetition of the base
239 register in two places on the line.
241 This is used for all memory access through a base register other
242 than PC or SP. It's intended to support SFI schemes such as
243 Native Client, where the OS will enforce that all load/store
244 instructions use a special form. In any such configuration,
245 another sysdep.h file will have defined ARM_SFI_MACROS and
246 provided its own assembly macros with the same interface. */
248 .macro sfi_breg basereg, insn, operands:vararg
249 .macro _sfi_breg_doit B
250 \insn \operands
251 .endm
252 _sfi_breg_doit \basereg
253 .purgem _sfi_breg_doit
254 .endm
256 /* This assembly macro replaces the "pld" instruction.
257 The syntax:
258 sfi_pld REGISTER, #OFFSET
259 is exactly equivalent to:
260 sfi_breg REGISTER, pld [\B, #OFFSET]
261 (and ", #OFFSET" is optional). We have a separate macro
262 only to work around a bug in GAS versions prior to 2.23.2,
263 that misparses the sfi_breg macro expansion in this case. */
265 .macro sfi_pld basereg, offset=#0
266 pld [\basereg, \offset]
267 .endm
269 /* This macro precedes any instruction that directly changes the SP.
270 It's not needed for push/pop or for any kind of load or store that
271 implicitly changes the SP via the ! syntax. */
272 # define sfi_sp /* Nothing to do. */
274 # endif
276 /* These are the directives used for EABI unwind info.
277 Wrap them in macros so another configuration's sysdep.h
278 file can define them away if it doesn't use EABI unwind info. */
279 # define eabi_fnstart .fnstart
280 # define eabi_fnend .fnend
281 # define eabi_save(...) .save __VA_ARGS__
282 # define eabi_cantunwind .cantunwind
283 # define eabi_pad(n) .pad n
285 #endif /* __ASSEMBLER__ */
287 /* This number is the offset from the pc at the current location. */
288 #ifdef __thumb__
289 # define PC_OFS 4
290 #else
291 # define PC_OFS 8
292 #endif
294 /* Pointer mangling support. */
295 #if (defined IS_IN_rtld || \
296 (!defined SHARED && (!defined NOT_IN_libc || defined IS_IN_libpthread)))
297 # ifdef __ASSEMBLER__
298 # define PTR_MANGLE_LOAD(guard, tmp) \
299 LDST_PCREL(ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local));
300 # define PTR_MANGLE(dst, src, guard, tmp) \
301 PTR_MANGLE_LOAD(guard, tmp); \
302 PTR_MANGLE2(dst, src, guard)
303 /* Use PTR_MANGLE2 for efficiency if guard is already loaded. */
304 # define PTR_MANGLE2(dst, src, guard) \
305 eor dst, src, guard
306 # define PTR_DEMANGLE(dst, src, guard, tmp) \
307 PTR_MANGLE (dst, src, guard, tmp)
308 # define PTR_DEMANGLE2(dst, src, guard) \
309 PTR_MANGLE2 (dst, src, guard)
310 # else
311 extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
312 # define PTR_MANGLE(var) \
313 (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
314 # define PTR_DEMANGLE(var) PTR_MANGLE (var)
315 # endif
316 #else
317 # ifdef __ASSEMBLER__
318 # define PTR_MANGLE_LOAD(guard, tmp) \
319 LDST_GLOBAL(ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard));
320 # define PTR_MANGLE(dst, src, guard, tmp) \
321 PTR_MANGLE_LOAD(guard, tmp); \
322 PTR_MANGLE2(dst, src, guard)
323 /* Use PTR_MANGLE2 for efficiency if guard is already loaded. */
324 # define PTR_MANGLE2(dst, src, guard) \
325 eor dst, src, guard
326 # define PTR_DEMANGLE(dst, src, guard, tmp) \
327 PTR_MANGLE (dst, src, guard, tmp)
328 # define PTR_DEMANGLE2(dst, src, guard) \
329 PTR_MANGLE2 (dst, src, guard)
330 # else
331 extern uintptr_t __pointer_chk_guard attribute_relro;
332 # define PTR_MANGLE(var) \
333 (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
334 # define PTR_DEMANGLE(var) PTR_MANGLE (var)
335 # endif
336 #endif