xref: /rk3399_ARM-atf/lib/compiler-rt/builtins/assembly.h (revision 127828af437b3e424d4369d6d146b43a0bbd38a5)
1 //===-- assembly.h - compiler-rt assembler support macros -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines macros for use in compiler-rt assembler source.
10 // This file is not part of the interface of this library.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef COMPILERRT_ASSEMBLY_H
15 #define COMPILERRT_ASSEMBLY_H
16 
17 #if defined(__linux__) && defined(__CET__)
18 #if __has_include(<cet.h>)
19 #include <cet.h>
20 #endif
21 #endif
22 
23 #if defined(__APPLE__) && defined(__aarch64__)
24 #define SEPARATOR %%
25 #else
26 #define SEPARATOR ;
27 #endif
28 
29 #if defined(__APPLE__)
30 #define HIDDEN(name) .private_extern name
31 #define LOCAL_LABEL(name) L_##name
32 // tell linker it can break up file at label boundaries
33 #define FILE_LEVEL_DIRECTIVE .subsections_via_symbols
34 #define SYMBOL_IS_FUNC(name)
35 #define CONST_SECTION .const
36 
37 #define NO_EXEC_STACK_DIRECTIVE
38 
39 #elif defined(__ELF__)
40 
41 #define HIDDEN(name) .hidden name
42 #define LOCAL_LABEL(name) .L_##name
43 #define FILE_LEVEL_DIRECTIVE
44 #if defined(__arm__) || defined(__aarch64__)
45 #define SYMBOL_IS_FUNC(name) .type name,%function
46 #else
47 #define SYMBOL_IS_FUNC(name) .type name,@function
48 #endif
49 #define CONST_SECTION .section .rodata
50 
51 #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) ||        \
52     defined(__linux__)
53 #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
54 #else
55 #define NO_EXEC_STACK_DIRECTIVE
56 #endif
57 
58 #else // !__APPLE__ && !__ELF__
59 
60 #define HIDDEN(name)
61 #define LOCAL_LABEL(name) .L ## name
62 #define FILE_LEVEL_DIRECTIVE
63 #define SYMBOL_IS_FUNC(name)                                                   \
64   .def FUNC_SYMBOL(name) SEPARATOR                                             \
65     .scl 2 SEPARATOR                                                           \
66     .type 32 SEPARATOR                                                         \
67   .endef
68 #define CONST_SECTION .section .rdata,"rd"
69 
70 #define NO_EXEC_STACK_DIRECTIVE
71 
72 #endif
73 
74 #if defined(__arm__) || defined(__aarch64__) || defined(__arm64ec__)
75 #define FUNC_ALIGN                                                             \
76   .text SEPARATOR                                                              \
77   .balign 16 SEPARATOR
78 #else
79 #define FUNC_ALIGN
80 #endif
81 
82 // BTI, PAC, and GCS gnu property note
83 #define NT_GNU_PROPERTY_TYPE_0 5
84 #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
85 #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 1
86 #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 2
87 #define GNU_PROPERTY_AARCH64_FEATURE_1_GCS 4
88 
89 #if defined(__ARM_FEATURE_BTI_DEFAULT)
90 #define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI
91 #else
92 #define BTI_FLAG 0
93 #endif
94 
95 #if __ARM_FEATURE_PAC_DEFAULT & 3
96 #define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC
97 #else
98 #define PAC_FLAG 0
99 #endif
100 
101 #if defined(__ARM_FEATURE_GCS_DEFAULT)
102 #define GCS_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_GCS
103 #else
104 #define GCS_FLAG 0
105 #endif
106 
107 #define GNU_PROPERTY(type, value)                                              \
108   .pushsection .note.gnu.property, "a" SEPARATOR                               \
109   .p2align 3 SEPARATOR                                                         \
110   .word 4 SEPARATOR                                                            \
111   .word 16 SEPARATOR                                                           \
112   .word NT_GNU_PROPERTY_TYPE_0 SEPARATOR                                       \
113   .asciz "GNU" SEPARATOR                                                       \
114   .word type SEPARATOR                                                         \
115   .word 4 SEPARATOR                                                            \
116   .word value SEPARATOR                                                        \
117   .word 0 SEPARATOR                                                            \
118   .popsection
119 
120 #if BTI_FLAG != 0
121 #define BTI_C hint #34
122 #define BTI_J hint #36
123 #else
124 #define BTI_C
125 #define BTI_J
126 #endif
127 
128 #if (BTI_FLAG | PAC_FLAG | GCS_FLAG) != 0
129 #define GNU_PROPERTY_BTI_PAC_GCS                                               \
130   GNU_PROPERTY(GNU_PROPERTY_AARCH64_FEATURE_1_AND,                             \
131                BTI_FLAG | PAC_FLAG | GCS_FLAG)
132 #else
133 #define GNU_PROPERTY_BTI_PAC_GCS
134 #endif
135 
136 #if defined(__clang__) || defined(__GCC_HAVE_DWARF2_CFI_ASM)
137 #define CFI_START .cfi_startproc
138 #define CFI_END .cfi_endproc
139 #else
140 #define CFI_START
141 #define CFI_END
142 #endif
143 
144 #if defined(__arm__)
145 
146 // Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros:
147 // - for '-mthumb -march=armv6' compiler defines '__thumb__'
148 // - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__'
149 #if defined(__thumb2__) || defined(__thumb__)
150 #define DEFINE_CODE_STATE .thumb SEPARATOR
151 #define DECLARE_FUNC_ENCODING    .thumb_func SEPARATOR
152 #if defined(__thumb2__)
153 #define USE_THUMB_2
154 #define IT(cond)  it cond
155 #define ITT(cond) itt cond
156 #define ITE(cond) ite cond
157 #else
158 #define USE_THUMB_1
159 #define IT(cond)
160 #define ITT(cond)
161 #define ITE(cond)
162 #endif // defined(__thumb__2)
163 #else // !defined(__thumb2__) && !defined(__thumb__)
164 #define DEFINE_CODE_STATE .arm SEPARATOR
165 #define DECLARE_FUNC_ENCODING
166 #define IT(cond)
167 #define ITT(cond)
168 #define ITE(cond)
169 #endif
170 
171 #if defined(USE_THUMB_1) && defined(USE_THUMB_2)
172 #error "USE_THUMB_1 and USE_THUMB_2 can't be defined together."
173 #endif
174 
175 #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
176 #define ARM_HAS_BX
177 #endif
178 #if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) &&  \
179     (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__)))
180 #define __ARM_FEATURE_CLZ
181 #endif
182 
183 #ifdef ARM_HAS_BX
184 #define JMP(r) bx r
185 #define JMPc(r, c) bx##c r
186 #else
187 #define JMP(r) mov pc, r
188 #define JMPc(r, c) mov##c pc, r
189 #endif
190 
191 // pop {pc} can't switch Thumb mode on ARMv4T
192 #if __ARM_ARCH >= 5
193 #define POP_PC() pop {pc}
194 #else
195 #define POP_PC()                                                               \
196   pop {ip};                                                                    \
197   JMP(ip)
198 #endif
199 
200 #if defined(USE_THUMB_2)
201 #define WIDE(op) op.w
202 #else
203 #define WIDE(op) op
204 #endif
205 
206 #if defined(__ARM_FEATURE_PAC_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT)
207 #define PACBTI_LANDING pacbti r12, lr, sp
208 #elif defined(__ARM_FEATURE_PAC_DEFAULT)
209 #define PACBTI_LANDING pac r12, lr, sp
210 #elif defined(__ARM_FEATURE_BTI_DEFAULT)
211 #define PACBTI_LANDING bti
212 #else
213 #define PACBTI_LANDING
214 #endif
215 
216 #if defined(__ARM_FEATURE_PAUTH)
217 #define PAC_RETURN bxaut r12, lr, sp
218 #else
219 #define PAC_RETURN aut r12, lr, sp SEPARATOR bx lr
220 #endif
221 
222 #else // !defined(__arm)
223 #define DECLARE_FUNC_ENCODING
224 #define DEFINE_CODE_STATE
225 #endif
226 
227 #define GLUE2_(a, b) a##b
228 #define GLUE(a, b) GLUE2_(a, b)
229 #define GLUE2(a, b) GLUE2_(a, b)
230 #define GLUE3_(a, b, c) a##b##c
231 #define GLUE3(a, b, c) GLUE3_(a, b, c)
232 #define GLUE4_(a, b, c, d) a##b##c##d
233 #define GLUE4(a, b, c, d) GLUE4_(a, b, c, d)
234 
235 #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
236 #ifndef __arm64ec__
237 #define FUNC_SYMBOL(name) name
238 #else
239 // On ARM64EC, function names and calls (but not address-taking or data symbol
240 // references) use symbols prefixed with "#".
241 #define QUOTE(a) #a
242 #define STR(a) QUOTE(a)
243 #define HASH #
244 #define FUNC_SYMBOL(name) STR(GLUE2(HASH, name))
245 #endif
246 
247 #ifdef VISIBILITY_HIDDEN
248 #define DECLARE_SYMBOL_VISIBILITY(name)                                        \
249   HIDDEN(SYMBOL_NAME(name)) SEPARATOR
250 #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) \
251   HIDDEN(name) SEPARATOR
252 #else
253 #define DECLARE_SYMBOL_VISIBILITY(name)
254 #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name)
255 #endif
256 
257 #define DEFINE_COMPILERRT_FUNCTION(name)                                       \
258   DEFINE_CODE_STATE                                                            \
259   FILE_LEVEL_DIRECTIVE SEPARATOR                                               \
260   .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR                              \
261   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
262   DECLARE_SYMBOL_VISIBILITY(name)                                              \
263   DECLARE_FUNC_ENCODING                                                        \
264   FUNC_SYMBOL(SYMBOL_NAME(name)):
265 
266 #define DEFINE_COMPILERRT_THUMB_FUNCTION(name)                                 \
267   DEFINE_CODE_STATE                                                            \
268   FILE_LEVEL_DIRECTIVE SEPARATOR                                               \
269   .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR                              \
270   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
271   DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR                                    \
272   .thumb_func SEPARATOR                                                        \
273   FUNC_SYMBOL(SYMBOL_NAME(name)):
274 
275 #define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name)                               \
276   DEFINE_CODE_STATE                                                            \
277   FILE_LEVEL_DIRECTIVE SEPARATOR                                               \
278   .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR                              \
279   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
280   HIDDEN(SYMBOL_NAME(name)) SEPARATOR                                          \
281   DECLARE_FUNC_ENCODING                                                        \
282   FUNC_SYMBOL(SYMBOL_NAME(name)):
283 
284 #define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name)                     \
285   DEFINE_CODE_STATE                                                            \
286   .globl FUNC_SYMBOL(name) SEPARATOR                                           \
287   SYMBOL_IS_FUNC(name) SEPARATOR                                               \
288   HIDDEN(name) SEPARATOR                                                       \
289   DECLARE_FUNC_ENCODING                                                        \
290   FUNC_SYMBOL(name):
291 
292 #define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name)                     \
293   DEFINE_CODE_STATE                                                            \
294   FUNC_ALIGN                                                                   \
295   .globl FUNC_SYMBOL(name) SEPARATOR                                           \
296   SYMBOL_IS_FUNC(name) SEPARATOR                                               \
297   DECLARE_SYMBOL_VISIBILITY_UNMANGLED(FUNC_SYMBOL(name)) SEPARATOR             \
298   DECLARE_FUNC_ENCODING                                                        \
299   FUNC_SYMBOL(name):                                                           \
300   SEPARATOR CFI_START                                                          \
301   SEPARATOR BTI_C
302 
303 #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target)                         \
304   .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR                              \
305   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
306   DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR                                    \
307   .set FUNC_SYMBOL(SYMBOL_NAME(name)), FUNC_SYMBOL(target) SEPARATOR
308 
309 #if defined(__ARM_EABI__)
310 #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name)                          \
311   DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name)
312 #else
313 #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name)
314 #endif
315 
316 #ifdef __ELF__
317 #define END_COMPILERRT_FUNCTION(name)                                          \
318   .size SYMBOL_NAME(name), . - SYMBOL_NAME(name)
319 #define END_COMPILERRT_OUTLINE_FUNCTION(name)                                  \
320   CFI_END SEPARATOR                                                            \
321   .size SYMBOL_NAME(name), . - SYMBOL_NAME(name)
322 #else
323 #define END_COMPILERRT_FUNCTION(name)
324 #define END_COMPILERRT_OUTLINE_FUNCTION(name)                                  \
325   CFI_END
326 #endif
327 
328 #ifdef __arm__
329 #include "int_endianness.h"
330 
331 #if _YUGA_BIG_ENDIAN
332 #define VMOV_TO_DOUBLE(dst, src0, src1) vmov dst, src1, src0 SEPARATOR
333 #define VMOV_FROM_DOUBLE(dst0, dst1, src) vmov dst1, dst0, src SEPARATOR
334 #else
335 #define VMOV_TO_DOUBLE(dst, src0, src1) vmov dst, src0, src1 SEPARATOR
336 #define VMOV_FROM_DOUBLE(dst0, dst1, src) vmov dst0, dst1, src SEPARATOR
337 #endif
338 #endif
339 
340 #endif // COMPILERRT_ASSEMBLY_H
341