10b57cec5SDimitry Andric //===-- assembly.h - compiler-rt assembler support macros -----------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines macros for use in compiler-rt assembler source. 100b57cec5SDimitry Andric // This file is not part of the interface of this library. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef COMPILERRT_ASSEMBLY_H 150b57cec5SDimitry Andric #define COMPILERRT_ASSEMBLY_H 160b57cec5SDimitry Andric 1704eeddc0SDimitry Andric #if defined(__linux__) && defined(__CET__) 1804eeddc0SDimitry Andric #if __has_include(<cet.h>) 1904eeddc0SDimitry Andric #include <cet.h> 2004eeddc0SDimitry Andric #endif 2104eeddc0SDimitry Andric #endif 2204eeddc0SDimitry Andric 23e8d8bef9SDimitry Andric #if defined(__APPLE__) && defined(__aarch64__) 24e8d8bef9SDimitry Andric #define SEPARATOR %% 250b57cec5SDimitry Andric #else 260b57cec5SDimitry Andric #define SEPARATOR ; 270b57cec5SDimitry Andric #endif 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric #if defined(__APPLE__) 300b57cec5SDimitry Andric #define HIDDEN(name) .private_extern name 310b57cec5SDimitry Andric #define LOCAL_LABEL(name) L_##name 320b57cec5SDimitry Andric // tell linker it can break up file at label boundaries 330b57cec5SDimitry Andric #define FILE_LEVEL_DIRECTIVE .subsections_via_symbols 340b57cec5SDimitry Andric #define SYMBOL_IS_FUNC(name) 350b57cec5SDimitry Andric #define CONST_SECTION .const 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric #define NO_EXEC_STACK_DIRECTIVE 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric #elif defined(__ELF__) 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric #define HIDDEN(name) .hidden name 420b57cec5SDimitry Andric #define LOCAL_LABEL(name) .L_##name 430b57cec5SDimitry Andric #define FILE_LEVEL_DIRECTIVE 44e8d8bef9SDimitry Andric #if defined(__arm__) || defined(__aarch64__) 450b57cec5SDimitry Andric #define SYMBOL_IS_FUNC(name) .type name,%function 460b57cec5SDimitry Andric #else 470b57cec5SDimitry Andric #define SYMBOL_IS_FUNC(name) .type name,@function 480b57cec5SDimitry Andric #endif 490b57cec5SDimitry Andric #define CONST_SECTION .section .rodata 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ 520b57cec5SDimitry Andric defined(__linux__) 530b57cec5SDimitry Andric #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits 540b57cec5SDimitry Andric #else 550b57cec5SDimitry Andric #define NO_EXEC_STACK_DIRECTIVE 560b57cec5SDimitry Andric #endif 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric #else // !__APPLE__ && !__ELF__ 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric #define HIDDEN(name) 610b57cec5SDimitry Andric #define LOCAL_LABEL(name) .L ## name 620b57cec5SDimitry Andric #define FILE_LEVEL_DIRECTIVE 630b57cec5SDimitry Andric #define SYMBOL_IS_FUNC(name) \ 640b57cec5SDimitry Andric .def name SEPARATOR \ 650b57cec5SDimitry Andric .scl 2 SEPARATOR \ 660b57cec5SDimitry Andric .type 32 SEPARATOR \ 670b57cec5SDimitry Andric .endef 680b57cec5SDimitry Andric #define CONST_SECTION .section .rdata,"rd" 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric #define NO_EXEC_STACK_DIRECTIVE 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric #endif 730b57cec5SDimitry Andric 74e8d8bef9SDimitry Andric #if defined(__arm__) || defined(__aarch64__) 75e8d8bef9SDimitry Andric #define FUNC_ALIGN \ 76e8d8bef9SDimitry Andric .text SEPARATOR \ 77e8d8bef9SDimitry Andric .balign 16 SEPARATOR 78e8d8bef9SDimitry Andric #else 79e8d8bef9SDimitry Andric #define FUNC_ALIGN 80e8d8bef9SDimitry Andric #endif 81e8d8bef9SDimitry Andric 82e8d8bef9SDimitry Andric // BTI and PAC gnu property note 83e8d8bef9SDimitry Andric #define NT_GNU_PROPERTY_TYPE_0 5 84e8d8bef9SDimitry Andric #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 85e8d8bef9SDimitry Andric #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 1 86e8d8bef9SDimitry Andric #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 2 87e8d8bef9SDimitry Andric 88e8d8bef9SDimitry Andric #if defined(__ARM_FEATURE_BTI_DEFAULT) 89e8d8bef9SDimitry Andric #define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI 90e8d8bef9SDimitry Andric #else 91e8d8bef9SDimitry Andric #define BTI_FLAG 0 92e8d8bef9SDimitry Andric #endif 93e8d8bef9SDimitry Andric 94e8d8bef9SDimitry Andric #if __ARM_FEATURE_PAC_DEFAULT & 3 95e8d8bef9SDimitry Andric #define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC 96e8d8bef9SDimitry Andric #else 97e8d8bef9SDimitry Andric #define PAC_FLAG 0 98e8d8bef9SDimitry Andric #endif 99e8d8bef9SDimitry Andric 100e8d8bef9SDimitry Andric #define GNU_PROPERTY(type, value) \ 101e8d8bef9SDimitry Andric .pushsection .note.gnu.property, "a" SEPARATOR \ 102e8d8bef9SDimitry Andric .p2align 3 SEPARATOR \ 103e8d8bef9SDimitry Andric .word 4 SEPARATOR \ 104e8d8bef9SDimitry Andric .word 16 SEPARATOR \ 105e8d8bef9SDimitry Andric .word NT_GNU_PROPERTY_TYPE_0 SEPARATOR \ 106e8d8bef9SDimitry Andric .asciz "GNU" SEPARATOR \ 107e8d8bef9SDimitry Andric .word type SEPARATOR \ 108e8d8bef9SDimitry Andric .word 4 SEPARATOR \ 109e8d8bef9SDimitry Andric .word value SEPARATOR \ 110e8d8bef9SDimitry Andric .word 0 SEPARATOR \ 111e8d8bef9SDimitry Andric .popsection 112e8d8bef9SDimitry Andric 113e8d8bef9SDimitry Andric #if BTI_FLAG != 0 114fe6060f1SDimitry Andric #define BTI_C hint #34 115fe6060f1SDimitry Andric #define BTI_J hint #36 116e8d8bef9SDimitry Andric #else 117e8d8bef9SDimitry Andric #define BTI_C 118fe6060f1SDimitry Andric #define BTI_J 119e8d8bef9SDimitry Andric #endif 120e8d8bef9SDimitry Andric 121e8d8bef9SDimitry Andric #if (BTI_FLAG | PAC_FLAG) != 0 122e8d8bef9SDimitry Andric #define GNU_PROPERTY_BTI_PAC \ 123e8d8bef9SDimitry Andric GNU_PROPERTY(GNU_PROPERTY_AARCH64_FEATURE_1_AND, BTI_FLAG | PAC_FLAG) 124e8d8bef9SDimitry Andric #else 125e8d8bef9SDimitry Andric #define GNU_PROPERTY_BTI_PAC 126e8d8bef9SDimitry Andric #endif 127e8d8bef9SDimitry Andric 128e8d8bef9SDimitry Andric #if defined(__clang__) || defined(__GCC_HAVE_DWARF2_CFI_ASM) 129e8d8bef9SDimitry Andric #define CFI_START .cfi_startproc 130e8d8bef9SDimitry Andric #define CFI_END .cfi_endproc 131e8d8bef9SDimitry Andric #else 132e8d8bef9SDimitry Andric #define CFI_START 133e8d8bef9SDimitry Andric #define CFI_END 134e8d8bef9SDimitry Andric #endif 135e8d8bef9SDimitry Andric 1360b57cec5SDimitry Andric #if defined(__arm__) 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric // Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros: 1390b57cec5SDimitry Andric // - for '-mthumb -march=armv6' compiler defines '__thumb__' 1400b57cec5SDimitry Andric // - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__' 1410b57cec5SDimitry Andric #if defined(__thumb2__) || defined(__thumb__) 1420b57cec5SDimitry Andric #define DEFINE_CODE_STATE .thumb SEPARATOR 1430b57cec5SDimitry Andric #define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR 1440b57cec5SDimitry Andric #if defined(__thumb2__) 1450b57cec5SDimitry Andric #define USE_THUMB_2 1460b57cec5SDimitry Andric #define IT(cond) it cond 1470b57cec5SDimitry Andric #define ITT(cond) itt cond 1480b57cec5SDimitry Andric #define ITE(cond) ite cond 1490b57cec5SDimitry Andric #else 1500b57cec5SDimitry Andric #define USE_THUMB_1 1510b57cec5SDimitry Andric #define IT(cond) 1520b57cec5SDimitry Andric #define ITT(cond) 1530b57cec5SDimitry Andric #define ITE(cond) 1540b57cec5SDimitry Andric #endif // defined(__thumb__2) 1550b57cec5SDimitry Andric #else // !defined(__thumb2__) && !defined(__thumb__) 1560b57cec5SDimitry Andric #define DEFINE_CODE_STATE .arm SEPARATOR 1570b57cec5SDimitry Andric #define DECLARE_FUNC_ENCODING 1580b57cec5SDimitry Andric #define IT(cond) 1590b57cec5SDimitry Andric #define ITT(cond) 1600b57cec5SDimitry Andric #define ITE(cond) 1610b57cec5SDimitry Andric #endif 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric #if defined(USE_THUMB_1) && defined(USE_THUMB_2) 1640b57cec5SDimitry Andric #error "USE_THUMB_1 and USE_THUMB_2 can't be defined together." 1650b57cec5SDimitry Andric #endif 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 1680b57cec5SDimitry Andric #define ARM_HAS_BX 1690b57cec5SDimitry Andric #endif 1700b57cec5SDimitry Andric #if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \ 1710b57cec5SDimitry Andric (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__))) 1720b57cec5SDimitry Andric #define __ARM_FEATURE_CLZ 1730b57cec5SDimitry Andric #endif 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric #ifdef ARM_HAS_BX 1760b57cec5SDimitry Andric #define JMP(r) bx r 1770b57cec5SDimitry Andric #define JMPc(r, c) bx##c r 1780b57cec5SDimitry Andric #else 1790b57cec5SDimitry Andric #define JMP(r) mov pc, r 1800b57cec5SDimitry Andric #define JMPc(r, c) mov##c pc, r 1810b57cec5SDimitry Andric #endif 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric // pop {pc} can't switch Thumb mode on ARMv4T 1840b57cec5SDimitry Andric #if __ARM_ARCH >= 5 1850b57cec5SDimitry Andric #define POP_PC() pop {pc} 1860b57cec5SDimitry Andric #else 1870b57cec5SDimitry Andric #define POP_PC() \ 1880b57cec5SDimitry Andric pop {ip}; \ 1890b57cec5SDimitry Andric JMP(ip) 1900b57cec5SDimitry Andric #endif 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric #if defined(USE_THUMB_2) 1930b57cec5SDimitry Andric #define WIDE(op) op.w 1940b57cec5SDimitry Andric #else 1950b57cec5SDimitry Andric #define WIDE(op) op 1960b57cec5SDimitry Andric #endif 1970b57cec5SDimitry Andric #else // !defined(__arm) 1980b57cec5SDimitry Andric #define DECLARE_FUNC_ENCODING 1990b57cec5SDimitry Andric #define DEFINE_CODE_STATE 2000b57cec5SDimitry Andric #endif 2010b57cec5SDimitry Andric 202e8d8bef9SDimitry Andric #define GLUE2_(a, b) a##b 203e8d8bef9SDimitry Andric #define GLUE(a, b) GLUE2_(a, b) 204e8d8bef9SDimitry Andric #define GLUE2(a, b) GLUE2_(a, b) 205e8d8bef9SDimitry Andric #define GLUE3_(a, b, c) a##b##c 206e8d8bef9SDimitry Andric #define GLUE3(a, b, c) GLUE3_(a, b, c) 207e8d8bef9SDimitry Andric #define GLUE4_(a, b, c, d) a##b##c##d 208e8d8bef9SDimitry Andric #define GLUE4(a, b, c, d) GLUE4_(a, b, c, d) 209e8d8bef9SDimitry Andric 2100b57cec5SDimitry Andric #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric #ifdef VISIBILITY_HIDDEN 2130b57cec5SDimitry Andric #define DECLARE_SYMBOL_VISIBILITY(name) \ 2140b57cec5SDimitry Andric HIDDEN(SYMBOL_NAME(name)) SEPARATOR 215fe6060f1SDimitry Andric #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) \ 216fe6060f1SDimitry Andric HIDDEN(name) SEPARATOR 2170b57cec5SDimitry Andric #else 2180b57cec5SDimitry Andric #define DECLARE_SYMBOL_VISIBILITY(name) 219fe6060f1SDimitry Andric #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) 2200b57cec5SDimitry Andric #endif 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric #define DEFINE_COMPILERRT_FUNCTION(name) \ 2230b57cec5SDimitry Andric DEFINE_CODE_STATE \ 2240b57cec5SDimitry Andric FILE_LEVEL_DIRECTIVE SEPARATOR \ 2250b57cec5SDimitry Andric .globl SYMBOL_NAME(name) SEPARATOR \ 2260b57cec5SDimitry Andric SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 2270b57cec5SDimitry Andric DECLARE_SYMBOL_VISIBILITY(name) \ 2280b57cec5SDimitry Andric DECLARE_FUNC_ENCODING \ 2290b57cec5SDimitry Andric SYMBOL_NAME(name): 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric #define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \ 2320b57cec5SDimitry Andric DEFINE_CODE_STATE \ 2330b57cec5SDimitry Andric FILE_LEVEL_DIRECTIVE SEPARATOR \ 2340b57cec5SDimitry Andric .globl SYMBOL_NAME(name) SEPARATOR \ 2350b57cec5SDimitry Andric SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 2360b57cec5SDimitry Andric DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ 2370b57cec5SDimitry Andric .thumb_func SEPARATOR \ 2380b57cec5SDimitry Andric SYMBOL_NAME(name): 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric #define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \ 2410b57cec5SDimitry Andric DEFINE_CODE_STATE \ 2420b57cec5SDimitry Andric FILE_LEVEL_DIRECTIVE SEPARATOR \ 2430b57cec5SDimitry Andric .globl SYMBOL_NAME(name) SEPARATOR \ 2440b57cec5SDimitry Andric SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 2450b57cec5SDimitry Andric HIDDEN(SYMBOL_NAME(name)) SEPARATOR \ 2460b57cec5SDimitry Andric DECLARE_FUNC_ENCODING \ 2470b57cec5SDimitry Andric SYMBOL_NAME(name): 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric #define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \ 2500b57cec5SDimitry Andric DEFINE_CODE_STATE \ 2510b57cec5SDimitry Andric .globl name SEPARATOR \ 2520b57cec5SDimitry Andric SYMBOL_IS_FUNC(name) SEPARATOR \ 2530b57cec5SDimitry Andric HIDDEN(name) SEPARATOR \ 2540b57cec5SDimitry Andric DECLARE_FUNC_ENCODING \ 2550b57cec5SDimitry Andric name: 2560b57cec5SDimitry Andric 257e8d8bef9SDimitry Andric #define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \ 258e8d8bef9SDimitry Andric DEFINE_CODE_STATE \ 259e8d8bef9SDimitry Andric FUNC_ALIGN \ 260e8d8bef9SDimitry Andric .globl name SEPARATOR \ 261e8d8bef9SDimitry Andric SYMBOL_IS_FUNC(name) SEPARATOR \ 262fe6060f1SDimitry Andric DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) SEPARATOR \ 263e8d8bef9SDimitry Andric DECLARE_FUNC_ENCODING \ 2645f757f3fSDimitry Andric name: \ 2655f757f3fSDimitry Andric SEPARATOR CFI_START \ 2665f757f3fSDimitry Andric SEPARATOR BTI_C 267e8d8bef9SDimitry Andric 2680b57cec5SDimitry Andric #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \ 2690b57cec5SDimitry Andric .globl SYMBOL_NAME(name) SEPARATOR \ 2700b57cec5SDimitry Andric SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 27106c3fb27SDimitry Andric DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ 2720b57cec5SDimitry Andric .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric #if defined(__ARM_EABI__) 2750b57cec5SDimitry Andric #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \ 2760b57cec5SDimitry Andric DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name) 2770b57cec5SDimitry Andric #else 2780b57cec5SDimitry Andric #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) 2790b57cec5SDimitry Andric #endif 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric #ifdef __ELF__ 2820b57cec5SDimitry Andric #define END_COMPILERRT_FUNCTION(name) \ 2830b57cec5SDimitry Andric .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) 284e8d8bef9SDimitry Andric #define END_COMPILERRT_OUTLINE_FUNCTION(name) \ 285e8d8bef9SDimitry Andric CFI_END SEPARATOR \ 286e8d8bef9SDimitry Andric .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) 2870b57cec5SDimitry Andric #else 2880b57cec5SDimitry Andric #define END_COMPILERRT_FUNCTION(name) 289e8d8bef9SDimitry Andric #define END_COMPILERRT_OUTLINE_FUNCTION(name) \ 290e8d8bef9SDimitry Andric CFI_END 2910b57cec5SDimitry Andric #endif 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric #endif // COMPILERRT_ASSEMBLY_H 294