]> git.ipfire.org Git - thirdparty/glibc.git/blame - ports/sysdeps/arm/sysdep.h
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / ports / sysdeps / arm / sysdep.h
CommitLineData
d80b3f3c 1/* Assembler macros for ARM.
d4697bc9 2 Copyright (C) 1997-2014 Free Software Foundation, Inc.
d80b3f3c
UD
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
3214b89b
AJ
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.
d80b3f3c
UD
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
3214b89b 13 Lesser General Public License for more details.
d80b3f3c 14
3214b89b 15 You should have received a copy of the GNU Lesser General Public
ab84e3ff
PE
16 License along with the GNU C Library. If not, see
17 <http://www.gnu.org/licenses/>. */
d80b3f3c
UD
18
19#include <sysdeps/generic/sysdep.h>
94fd527b 20#include <features.h>
d80b3f3c 21
3377126b
RH
22/* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */
23#ifndef __ARM_ARCH
24# ifdef __ARM_ARCH_2__
25# define __ARM_ARCH 2
26# elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__)
27# define __ARM_ARCH 3
28# elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__)
29# define __ARM_ARCH 4
30# elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \
31 || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
32 || defined(__ARM_ARCH_5TEJ__)
33# define __ARM_ARCH 5
34# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
35 || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
36 || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
37# define __ARM_ARCH 6
38# elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
39 || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
40 || defined(__ARM_ARCH_7EM__)
41# define __ARM_ARCH 7
42# else
43# error unknown arm architecture
44# endif
45#endif
46
47#if __ARM_ARCH > 4 || defined (__ARM_ARCH_4T__)
48# define ARCH_HAS_BX
49#endif
50#if __ARM_ARCH > 4
51# define ARCH_HAS_BLX
52#endif
79fd8731
RH
53#if __ARM_ARCH > 6 || defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6ZK__)
54# define ARCH_HAS_HARD_TP
55#endif
3377126b
RH
56#if __ARM_ARCH > 6 || defined (__ARM_ARCH_6T2__)
57# define ARCH_HAS_T2
47f0752a
RM
58#endif
59
e0ebc3b2 60#ifdef __ASSEMBLER__
d80b3f3c
UD
61
62/* Syntactic details of assembler. */
63
0c56aa63 64#define ALIGNARG(log2) log2
d80b3f3c
UD
65#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
66
fe0955cd
UD
67#define PLTJMP(_x) _x##(PLT)
68
3377126b 69#ifdef ARCH_HAS_BX
46dede0c
RH
70# define BX(R) bx R
71# define BXC(C, R) bx##C R
3377126b 72# ifdef ARCH_HAS_BLX
46dede0c 73# define BLX(R) blx R
3377126b
RH
74# else
75# define BLX(R) mov lr, pc; bx R
46dede0c 76# endif
644d8224 77#else
46dede0c
RH
78# define BX(R) mov pc, R
79# define BXC(C, R) mov##C pc, R
80# define BLX(R) mov lr, pc; mov pc, R
d80b3f3c
UD
81#endif
82
46dede0c
RH
83#define DO_RET(R) BX(R)
84#define RETINSTR(C, R) BXC(C, R)
85
d80b3f3c 86/* Define an entry point visible from C. */
63cc0e75
RH
87#define ENTRY(name) \
88 .globl C_SYMBOL_NAME(name); \
89 .type C_SYMBOL_NAME(name),%function; \
90 .align ALIGNARG(4); \
91 C_LABEL(name) \
92 CFI_SECTIONS; \
93 cfi_startproc; \
94 CALL_MCOUNT
95
96#define CFI_SECTIONS \
97 .cfi_sections .debug_frame
f4564ff0 98
d80b3f3c 99#undef END
63cc0e75
RH
100#define END(name) \
101 cfi_endproc; \
102 ASM_SIZE_DIRECTIVE(name)
d80b3f3c
UD
103
104/* If compiled for profiling, call `mcount' at the start of each function. */
105#ifdef PROF
84664590
JM
106/* Call __gnu_mcount_nc if GCC >= 4.4. */
107#if __GNUC_PREREQ(4,4)
63cc0e75 108#define CALL_MCOUNT \
55668624 109 push {lr}; \
63cc0e75
RH
110 cfi_adjust_cfa_offset (4); \
111 cfi_rel_offset (lr, 0); \
112 bl PLTJMP(mcount); \
113 cfi_adjust_cfa_offset (-4); \
114 cfi_restore (lr)
94fd527b 115#else /* else call _mcount */
63cc0e75 116#define CALL_MCOUNT \
55668624 117 push {lr}; \
63cc0e75
RH
118 cfi_adjust_cfa_offset (4); \
119 cfi_rel_offset (lr, 0); \
120 bl PLTJMP(mcount); \
55668624 121 pops {lr}; \
63cc0e75
RH
122 cfi_adjust_cfa_offset (-4); \
123 cfi_restore (lr)
94fd527b 124#endif
d80b3f3c
UD
125#else
126#define CALL_MCOUNT /* Do nothing. */
127#endif
128
d80b3f3c
UD
129/* Since C identifiers are not normally prefixed with an underscore
130 on this system, the asm identifier `syscall_error' intrudes on the
131 C name space. Make sure we use an innocuous name. */
132#define syscall_error __syscall_error
84664590 133#if __GNUC_PREREQ(4,4)
94fd527b
MM
134#define mcount __gnu_mcount_nc
135#else
d80b3f3c
UD
136#define mcount _mcount
137#endif
138
27489557
DG
139/* Tag_ABI_align8_preserved: This code preserves 8-byte
140 alignment in any callee. */
141 .eabi_attribute 25, 1
142/* Tag_ABI_align8_needed: This code may require 8-byte alignment from
143 the caller. */
144 .eabi_attribute 24, 1
27489557 145
5ff5dfe7
RH
146/* The thumb2 encoding is reasonably complete. Unless suppressed, use it. */
147 .syntax unified
148# if defined(__thumb2__) && !defined(NO_THUMB)
149 .thumb
150#else
151# undef __thumb__
152# undef __thumb2__
153 .arm
154# endif
155
cd24e113
RH
156/* Load or store to/from a pc-relative EXPR into/from R, using T. */
157# ifdef __thumb2__
158# define LDST_PCREL(OP, R, T, EXPR) \
159 ldr T, 98f; \
160 .subsection 2; \
16198: .word EXPR - 99f - PC_OFS; \
162 .previous; \
16399: add T, T, pc; \
164 OP R, [T]
165# else
166# define LDST_PCREL(OP, R, T, EXPR) \
167 ldr T, 98f; \
168 .subsection 2; \
16998: .word EXPR - 99f - PC_OFS; \
170 .previous; \
17199: OP R, [pc, T]
172# endif
3ae44082 173
b7f2d27d
WN
174/* Load or store to/from a global EXPR into/from R, using T. */
175# define LDST_GLOBAL(OP, R, T, EXPR) \
176 ldr T, 99f; \
177 ldr R, 100f; \
17898: add T, T, pc; \
179 ldr T, [T, R]; \
180 .subsection 2; \
18199: .word _GLOBAL_OFFSET_TABLE_ - 98b - PC_OFS; \
182100: .word EXPR##(GOT); \
183 .previous; \
184 OP R, [T]
185
3ae44082
RH
186/* Cope with negative memory offsets, which thumb can't encode.
187 Use NEGOFF_ADJ_BASE to (conditionally) alter the base register,
188 and then NEGOFF_OFF1 to use 0 for thumb and the offset for arm,
189 or NEGOFF_OFF2 to use A-B for thumb and A for arm. */
190# ifdef __thumb2__
191# define NEGOFF_ADJ_BASE(R, OFF) add R, R, $OFF
192# define NEGOFF_ADJ_BASE2(D, S, OFF) add D, S, $OFF
193# define NEGOFF_OFF1(R, OFF) [R]
194# define NEGOFF_OFF2(R, OFFA, OFFB) [R, $((OFFA) - (OFFB))]
195# else
196# define NEGOFF_ADJ_BASE(R, OFF)
197# define NEGOFF_ADJ_BASE2(D, S, OFF) mov D, S
198# define NEGOFF_OFF1(R, OFF) [R, $OFF]
199# define NEGOFF_OFF2(R, OFFA, OFFB) [R, $OFFA]
200# endif
5232b909
RH
201
202/* Helper to get the TLS base pointer. The interface is that TMP is a
203 register that may be used to hold the LR, if necessary. TMP may be
204 LR itself to indicate that LR need not be saved. The base pointer
79fd8731 205 is returned in R0. Only R0 and TMP are modified. */
5232b909 206
79fd8731
RH
207# ifdef ARCH_HAS_HARD_TP
208/* If the cpu has cp15 available, use it. */
209# define GET_TLS(TMP) mrc p15, 0, r0, c13, c0, 3
210# else
211/* At this generic level we have no tricks to pull. Call the ABI routine. */
212# define GET_TLS(TMP) \
5232b909
RH
213 push { r1, r2, r3, lr }; \
214 cfi_remember_state; \
215 cfi_adjust_cfa_offset (16); \
216 cfi_rel_offset (r1, 0); \
217 cfi_rel_offset (r2, 4); \
218 cfi_rel_offset (r3, 8); \
219 cfi_rel_offset (lr, 12); \
220 bl __aeabi_read_tp; \
221 pop { r1, r2, r3, lr }; \
222 cfi_restore_state
79fd8731 223# endif /* ARCH_HAS_HARD_TP */
5232b909 224
a7ac7522
RM
225# ifndef ARM_SFI_MACROS
226# define ARM_SFI_MACROS 1
227/* This assembly macro is prepended to any load/store instruction,
228 pulling the base register out of the addressing mode syntax and
229 making it the first operand of the macro. For example:
230 ldr r0, [r1]
231 becomes:
232 sfi_breg r1, ldr r0, [\B]
233 The \B stands in for the base register that is the first operand
234 to the macro, so we can avoid error-prone repetition of the base
235 register in two places on the line.
236
237 This is used for all memory access through a base register other
238 than PC or SP. It's intended to support SFI schemes such as
239 Native Client, where the OS will enforce that all load/store
240 instructions use a special form. In any such configuration,
241 another sysdep.h file will have defined ARM_SFI_MACROS and
242 provided its own assembly macros with the same interface. */
243
244 .macro sfi_breg basereg, insn, operands:vararg
245 .macro _sfi_breg_doit B
246 \insn \operands
247 .endm
248 _sfi_breg_doit \basereg
249 .purgem _sfi_breg_doit
250 .endm
251
252/* This assembly macro replaces the "pld" instruction.
253 The syntax:
254 sfi_pld REGISTER, #OFFSET
255 is exactly equivalent to:
256 sfi_breg REGISTER, pld [\B, #OFFSET]
257 (and ", #OFFSET" is optional). We have a separate macro
258 only to work around a bug in GAS versions prior to 2.23.2,
259 that misparses the sfi_breg macro expansion in this case. */
260
261 .macro sfi_pld basereg, offset=#0
262 pld [\basereg, \offset]
263 .endm
264
1362a2aa
RM
265/* This macro precedes any instruction that directly changes the SP.
266 It's not needed for push/pop or for any kind of load or store that
267 implicitly changes the SP via the ! syntax. */
268# define sfi_sp /* Nothing to do. */
269
a7ac7522
RM
270# endif
271
7214d558
RM
272/* These are the directives used for EABI unwind info.
273 Wrap them in macros so another configuration's sysdep.h
274 file can define them away if it doesn't use EABI unwind info. */
275# define eabi_fnstart .fnstart
276# define eabi_fnend .fnend
277# define eabi_save(...) .save __VA_ARGS__
278# define eabi_cantunwind .cantunwind
279# define eabi_pad(n) .pad n
280
e0ebc3b2 281#endif /* __ASSEMBLER__ */
783a65c2
RH
282
283/* This number is the offset from the pc at the current location. */
5ff5dfe7 284#ifdef __thumb__
783a65c2
RH
285# define PC_OFS 4
286#else
287# define PC_OFS 8
288#endif