1*8a6a9560SDaniel Boulby //===-- assembly.h - compiler-rt assembler support macros -----------------===// 2*8a6a9560SDaniel Boulby // 3*8a6a9560SDaniel Boulby // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*8a6a9560SDaniel Boulby // See https://llvm.org/LICENSE.txt for license information. 5*8a6a9560SDaniel Boulby // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*8a6a9560SDaniel Boulby // 7*8a6a9560SDaniel Boulby //===----------------------------------------------------------------------===// 8*8a6a9560SDaniel Boulby // 9*8a6a9560SDaniel Boulby // This file defines macros for use in compiler-rt assembler source. 10*8a6a9560SDaniel Boulby // This file is not part of the interface of this library. 11*8a6a9560SDaniel Boulby // 12*8a6a9560SDaniel Boulby //===----------------------------------------------------------------------===// 130e14a7fbSdp-arm 140e14a7fbSdp-arm #ifndef COMPILERRT_ASSEMBLY_H 150e14a7fbSdp-arm #define COMPILERRT_ASSEMBLY_H 160e14a7fbSdp-arm 17*8a6a9560SDaniel Boulby #if defined(__linux__) && defined(__CET__) 18*8a6a9560SDaniel Boulby #if __has_include(<cet.h>) 19*8a6a9560SDaniel Boulby #include <cet.h> 20*8a6a9560SDaniel Boulby #endif 21*8a6a9560SDaniel Boulby #endif 22*8a6a9560SDaniel Boulby 23*8a6a9560SDaniel Boulby #if defined(__APPLE__) && defined(__aarch64__) 24*8a6a9560SDaniel Boulby #define SEPARATOR %% 250e14a7fbSdp-arm #else 260e14a7fbSdp-arm #define SEPARATOR ; 270e14a7fbSdp-arm #endif 280e14a7fbSdp-arm 290e14a7fbSdp-arm #if defined(__APPLE__) 300e14a7fbSdp-arm #define HIDDEN(name) .private_extern name 310e14a7fbSdp-arm #define LOCAL_LABEL(name) L_##name 320e14a7fbSdp-arm // tell linker it can break up file at label boundaries 330e14a7fbSdp-arm #define FILE_LEVEL_DIRECTIVE .subsections_via_symbols 340e14a7fbSdp-arm #define SYMBOL_IS_FUNC(name) 350e14a7fbSdp-arm #define CONST_SECTION .const 360e14a7fbSdp-arm 370e14a7fbSdp-arm #define NO_EXEC_STACK_DIRECTIVE 380e14a7fbSdp-arm 390e14a7fbSdp-arm #elif defined(__ELF__) 400e14a7fbSdp-arm 410e14a7fbSdp-arm #define HIDDEN(name) .hidden name 420e14a7fbSdp-arm #define LOCAL_LABEL(name) .L_##name 430e14a7fbSdp-arm #define FILE_LEVEL_DIRECTIVE 44*8a6a9560SDaniel Boulby #if defined(__arm__) || defined(__aarch64__) 450e14a7fbSdp-arm #define SYMBOL_IS_FUNC(name) .type name,%function 460e14a7fbSdp-arm #else 470e14a7fbSdp-arm #define SYMBOL_IS_FUNC(name) .type name,@function 480e14a7fbSdp-arm #endif 490e14a7fbSdp-arm #define CONST_SECTION .section .rodata 500e14a7fbSdp-arm 51*8a6a9560SDaniel Boulby #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ 52*8a6a9560SDaniel Boulby defined(__linux__) 530e14a7fbSdp-arm #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits 540e14a7fbSdp-arm #else 550e14a7fbSdp-arm #define NO_EXEC_STACK_DIRECTIVE 560e14a7fbSdp-arm #endif 570e14a7fbSdp-arm 580e14a7fbSdp-arm #else // !__APPLE__ && !__ELF__ 590e14a7fbSdp-arm 600e14a7fbSdp-arm #define HIDDEN(name) 610e14a7fbSdp-arm #define LOCAL_LABEL(name) .L ## name 620e14a7fbSdp-arm #define FILE_LEVEL_DIRECTIVE 630e14a7fbSdp-arm #define SYMBOL_IS_FUNC(name) \ 640e14a7fbSdp-arm .def name SEPARATOR \ 650e14a7fbSdp-arm .scl 2 SEPARATOR \ 660e14a7fbSdp-arm .type 32 SEPARATOR \ 670e14a7fbSdp-arm .endef 680e14a7fbSdp-arm #define CONST_SECTION .section .rdata,"rd" 690e14a7fbSdp-arm 700e14a7fbSdp-arm #define NO_EXEC_STACK_DIRECTIVE 710e14a7fbSdp-arm 720e14a7fbSdp-arm #endif 730e14a7fbSdp-arm 74*8a6a9560SDaniel Boulby #if defined(__arm__) || defined(__aarch64__) 75*8a6a9560SDaniel Boulby #define FUNC_ALIGN \ 76*8a6a9560SDaniel Boulby .text SEPARATOR \ 77*8a6a9560SDaniel Boulby .balign 16 SEPARATOR 78*8a6a9560SDaniel Boulby #else 79*8a6a9560SDaniel Boulby #define FUNC_ALIGN 80*8a6a9560SDaniel Boulby #endif 81*8a6a9560SDaniel Boulby 82*8a6a9560SDaniel Boulby // BTI and PAC gnu property note 83*8a6a9560SDaniel Boulby #define NT_GNU_PROPERTY_TYPE_0 5 84*8a6a9560SDaniel Boulby #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 85*8a6a9560SDaniel Boulby #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 1 86*8a6a9560SDaniel Boulby #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 2 87*8a6a9560SDaniel Boulby 88*8a6a9560SDaniel Boulby #if defined(__ARM_FEATURE_BTI_DEFAULT) 89*8a6a9560SDaniel Boulby #define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI 90*8a6a9560SDaniel Boulby #else 91*8a6a9560SDaniel Boulby #define BTI_FLAG 0 92*8a6a9560SDaniel Boulby #endif 93*8a6a9560SDaniel Boulby 94*8a6a9560SDaniel Boulby #if __ARM_FEATURE_PAC_DEFAULT & 3 95*8a6a9560SDaniel Boulby #define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC 96*8a6a9560SDaniel Boulby #else 97*8a6a9560SDaniel Boulby #define PAC_FLAG 0 98*8a6a9560SDaniel Boulby #endif 99*8a6a9560SDaniel Boulby 100*8a6a9560SDaniel Boulby #define GNU_PROPERTY(type, value) \ 101*8a6a9560SDaniel Boulby .pushsection .note.gnu.property, "a" SEPARATOR \ 102*8a6a9560SDaniel Boulby .p2align 3 SEPARATOR \ 103*8a6a9560SDaniel Boulby .word 4 SEPARATOR \ 104*8a6a9560SDaniel Boulby .word 16 SEPARATOR \ 105*8a6a9560SDaniel Boulby .word NT_GNU_PROPERTY_TYPE_0 SEPARATOR \ 106*8a6a9560SDaniel Boulby .asciz "GNU" SEPARATOR \ 107*8a6a9560SDaniel Boulby .word type SEPARATOR \ 108*8a6a9560SDaniel Boulby .word 4 SEPARATOR \ 109*8a6a9560SDaniel Boulby .word value SEPARATOR \ 110*8a6a9560SDaniel Boulby .word 0 SEPARATOR \ 111*8a6a9560SDaniel Boulby .popsection 112*8a6a9560SDaniel Boulby 113*8a6a9560SDaniel Boulby #if BTI_FLAG != 0 114*8a6a9560SDaniel Boulby #define BTI_C hint #34 115*8a6a9560SDaniel Boulby #define BTI_J hint #36 116*8a6a9560SDaniel Boulby #else 117*8a6a9560SDaniel Boulby #define BTI_C 118*8a6a9560SDaniel Boulby #define BTI_J 119*8a6a9560SDaniel Boulby #endif 120*8a6a9560SDaniel Boulby 121*8a6a9560SDaniel Boulby #if (BTI_FLAG | PAC_FLAG) != 0 122*8a6a9560SDaniel Boulby #define GNU_PROPERTY_BTI_PAC \ 123*8a6a9560SDaniel Boulby GNU_PROPERTY(GNU_PROPERTY_AARCH64_FEATURE_1_AND, BTI_FLAG | PAC_FLAG) 124*8a6a9560SDaniel Boulby #else 125*8a6a9560SDaniel Boulby #define GNU_PROPERTY_BTI_PAC 126*8a6a9560SDaniel Boulby #endif 127*8a6a9560SDaniel Boulby 128*8a6a9560SDaniel Boulby #if defined(__clang__) || defined(__GCC_HAVE_DWARF2_CFI_ASM) 129*8a6a9560SDaniel Boulby #define CFI_START .cfi_startproc 130*8a6a9560SDaniel Boulby #define CFI_END .cfi_endproc 131*8a6a9560SDaniel Boulby #else 132*8a6a9560SDaniel Boulby #define CFI_START 133*8a6a9560SDaniel Boulby #define CFI_END 134*8a6a9560SDaniel Boulby #endif 135*8a6a9560SDaniel Boulby 1360e14a7fbSdp-arm #if defined(__arm__) 137*8a6a9560SDaniel Boulby 138*8a6a9560SDaniel Boulby // Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros: 139*8a6a9560SDaniel Boulby // - for '-mthumb -march=armv6' compiler defines '__thumb__' 140*8a6a9560SDaniel Boulby // - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__' 141*8a6a9560SDaniel Boulby #if defined(__thumb2__) || defined(__thumb__) 142*8a6a9560SDaniel Boulby #define DEFINE_CODE_STATE .thumb SEPARATOR 143*8a6a9560SDaniel Boulby #define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR 144*8a6a9560SDaniel Boulby #if defined(__thumb2__) 145*8a6a9560SDaniel Boulby #define USE_THUMB_2 146*8a6a9560SDaniel Boulby #define IT(cond) it cond 147*8a6a9560SDaniel Boulby #define ITT(cond) itt cond 148*8a6a9560SDaniel Boulby #define ITE(cond) ite cond 149*8a6a9560SDaniel Boulby #else 150*8a6a9560SDaniel Boulby #define USE_THUMB_1 151*8a6a9560SDaniel Boulby #define IT(cond) 152*8a6a9560SDaniel Boulby #define ITT(cond) 153*8a6a9560SDaniel Boulby #define ITE(cond) 154*8a6a9560SDaniel Boulby #endif // defined(__thumb__2) 155*8a6a9560SDaniel Boulby #else // !defined(__thumb2__) && !defined(__thumb__) 156*8a6a9560SDaniel Boulby #define DEFINE_CODE_STATE .arm SEPARATOR 157*8a6a9560SDaniel Boulby #define DECLARE_FUNC_ENCODING 158*8a6a9560SDaniel Boulby #define IT(cond) 159*8a6a9560SDaniel Boulby #define ITT(cond) 160*8a6a9560SDaniel Boulby #define ITE(cond) 161*8a6a9560SDaniel Boulby #endif 162*8a6a9560SDaniel Boulby 163*8a6a9560SDaniel Boulby #if defined(USE_THUMB_1) && defined(USE_THUMB_2) 164*8a6a9560SDaniel Boulby #error "USE_THUMB_1 and USE_THUMB_2 can't be defined together." 165*8a6a9560SDaniel Boulby #endif 166*8a6a9560SDaniel Boulby 1670e14a7fbSdp-arm #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 1680e14a7fbSdp-arm #define ARM_HAS_BX 1690e14a7fbSdp-arm #endif 170*8a6a9560SDaniel Boulby #if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \ 1710e14a7fbSdp-arm (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__))) 1720e14a7fbSdp-arm #define __ARM_FEATURE_CLZ 1730e14a7fbSdp-arm #endif 1740e14a7fbSdp-arm 1750e14a7fbSdp-arm #ifdef ARM_HAS_BX 1760e14a7fbSdp-arm #define JMP(r) bx r 1770e14a7fbSdp-arm #define JMPc(r, c) bx##c r 1780e14a7fbSdp-arm #else 1790e14a7fbSdp-arm #define JMP(r) mov pc, r 1800e14a7fbSdp-arm #define JMPc(r, c) mov##c pc, r 1810e14a7fbSdp-arm #endif 1820e14a7fbSdp-arm 1830e14a7fbSdp-arm // pop {pc} can't switch Thumb mode on ARMv4T 1840e14a7fbSdp-arm #if __ARM_ARCH >= 5 1850e14a7fbSdp-arm #define POP_PC() pop {pc} 1860e14a7fbSdp-arm #else 1870e14a7fbSdp-arm #define POP_PC() \ 1880e14a7fbSdp-arm pop {ip}; \ 1890e14a7fbSdp-arm JMP(ip) 1900e14a7fbSdp-arm #endif 1910e14a7fbSdp-arm 192*8a6a9560SDaniel Boulby #if defined(USE_THUMB_2) 1930e14a7fbSdp-arm #define WIDE(op) op.w 1940e14a7fbSdp-arm #else 1950e14a7fbSdp-arm #define WIDE(op) op 1960e14a7fbSdp-arm #endif 197*8a6a9560SDaniel Boulby #else // !defined(__arm) 198*8a6a9560SDaniel Boulby #define DECLARE_FUNC_ENCODING 199*8a6a9560SDaniel Boulby #define DEFINE_CODE_STATE 2000e14a7fbSdp-arm #endif 2010e14a7fbSdp-arm 202*8a6a9560SDaniel Boulby #define GLUE2_(a, b) a##b 203*8a6a9560SDaniel Boulby #define GLUE(a, b) GLUE2_(a, b) 204*8a6a9560SDaniel Boulby #define GLUE2(a, b) GLUE2_(a, b) 205*8a6a9560SDaniel Boulby #define GLUE3_(a, b, c) a##b##c 206*8a6a9560SDaniel Boulby #define GLUE3(a, b, c) GLUE3_(a, b, c) 207*8a6a9560SDaniel Boulby #define GLUE4_(a, b, c, d) a##b##c##d 208*8a6a9560SDaniel Boulby #define GLUE4(a, b, c, d) GLUE4_(a, b, c, d) 209*8a6a9560SDaniel Boulby 2100e14a7fbSdp-arm #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) 2110e14a7fbSdp-arm 2120e14a7fbSdp-arm #ifdef VISIBILITY_HIDDEN 2130e14a7fbSdp-arm #define DECLARE_SYMBOL_VISIBILITY(name) \ 2140e14a7fbSdp-arm HIDDEN(SYMBOL_NAME(name)) SEPARATOR 215*8a6a9560SDaniel Boulby #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) \ 216*8a6a9560SDaniel Boulby HIDDEN(name) SEPARATOR 2170e14a7fbSdp-arm #else 2180e14a7fbSdp-arm #define DECLARE_SYMBOL_VISIBILITY(name) 219*8a6a9560SDaniel Boulby #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) 2200e14a7fbSdp-arm #endif 2210e14a7fbSdp-arm 2220e14a7fbSdp-arm #define DEFINE_COMPILERRT_FUNCTION(name) \ 223*8a6a9560SDaniel Boulby DEFINE_CODE_STATE \ 2240e14a7fbSdp-arm FILE_LEVEL_DIRECTIVE SEPARATOR \ 2250e14a7fbSdp-arm .globl SYMBOL_NAME(name) SEPARATOR \ 2260e14a7fbSdp-arm SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 2270e14a7fbSdp-arm DECLARE_SYMBOL_VISIBILITY(name) \ 228*8a6a9560SDaniel Boulby DECLARE_FUNC_ENCODING \ 2290e14a7fbSdp-arm SYMBOL_NAME(name): 2300e14a7fbSdp-arm 2310e14a7fbSdp-arm #define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \ 232*8a6a9560SDaniel Boulby DEFINE_CODE_STATE \ 2330e14a7fbSdp-arm FILE_LEVEL_DIRECTIVE SEPARATOR \ 2340e14a7fbSdp-arm .globl SYMBOL_NAME(name) SEPARATOR \ 2350e14a7fbSdp-arm SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 2360e14a7fbSdp-arm DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ 2370e14a7fbSdp-arm .thumb_func SEPARATOR \ 2380e14a7fbSdp-arm SYMBOL_NAME(name): 2390e14a7fbSdp-arm 2400e14a7fbSdp-arm #define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \ 241*8a6a9560SDaniel Boulby DEFINE_CODE_STATE \ 2420e14a7fbSdp-arm FILE_LEVEL_DIRECTIVE SEPARATOR \ 2430e14a7fbSdp-arm .globl SYMBOL_NAME(name) SEPARATOR \ 2440e14a7fbSdp-arm SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 2450e14a7fbSdp-arm HIDDEN(SYMBOL_NAME(name)) SEPARATOR \ 246*8a6a9560SDaniel Boulby DECLARE_FUNC_ENCODING \ 2470e14a7fbSdp-arm SYMBOL_NAME(name): 2480e14a7fbSdp-arm 2490e14a7fbSdp-arm #define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \ 250*8a6a9560SDaniel Boulby DEFINE_CODE_STATE \ 2510e14a7fbSdp-arm .globl name SEPARATOR \ 2520e14a7fbSdp-arm SYMBOL_IS_FUNC(name) SEPARATOR \ 2530e14a7fbSdp-arm HIDDEN(name) SEPARATOR \ 254*8a6a9560SDaniel Boulby DECLARE_FUNC_ENCODING \ 2550e14a7fbSdp-arm name: 2560e14a7fbSdp-arm 257*8a6a9560SDaniel Boulby #define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \ 258*8a6a9560SDaniel Boulby DEFINE_CODE_STATE \ 259*8a6a9560SDaniel Boulby FUNC_ALIGN \ 260*8a6a9560SDaniel Boulby .globl name SEPARATOR \ 261*8a6a9560SDaniel Boulby SYMBOL_IS_FUNC(name) SEPARATOR \ 262*8a6a9560SDaniel Boulby DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) SEPARATOR \ 263*8a6a9560SDaniel Boulby CFI_START SEPARATOR \ 264*8a6a9560SDaniel Boulby DECLARE_FUNC_ENCODING \ 265*8a6a9560SDaniel Boulby name: SEPARATOR BTI_C 266*8a6a9560SDaniel Boulby 2670e14a7fbSdp-arm #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \ 2680e14a7fbSdp-arm .globl SYMBOL_NAME(name) SEPARATOR \ 2690e14a7fbSdp-arm SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 2700e14a7fbSdp-arm DECLARE_SYMBOL_VISIBILITY(SYMBOL_NAME(name)) SEPARATOR \ 2710e14a7fbSdp-arm .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR 2720e14a7fbSdp-arm 2730e14a7fbSdp-arm #if defined(__ARM_EABI__) 2740e14a7fbSdp-arm #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \ 2750e14a7fbSdp-arm DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name) 2760e14a7fbSdp-arm #else 2770e14a7fbSdp-arm #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) 2780e14a7fbSdp-arm #endif 2790e14a7fbSdp-arm 2800e14a7fbSdp-arm #ifdef __ELF__ 2810e14a7fbSdp-arm #define END_COMPILERRT_FUNCTION(name) \ 2820e14a7fbSdp-arm .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) 283*8a6a9560SDaniel Boulby #define END_COMPILERRT_OUTLINE_FUNCTION(name) \ 284*8a6a9560SDaniel Boulby CFI_END SEPARATOR \ 285*8a6a9560SDaniel Boulby .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) 2860e14a7fbSdp-arm #else 2870e14a7fbSdp-arm #define END_COMPILERRT_FUNCTION(name) 288*8a6a9560SDaniel Boulby #define END_COMPILERRT_OUTLINE_FUNCTION(name) \ 289*8a6a9560SDaniel Boulby CFI_END 2900e14a7fbSdp-arm #endif 2910e14a7fbSdp-arm 292*8a6a9560SDaniel Boulby #endif // COMPILERRT_ASSEMBLY_H 293