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