1*0b57cec5SDimitry Andric //===-- assembly.h - compiler-rt assembler support macros -----------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file defines macros for use in compiler-rt assembler source. 10*0b57cec5SDimitry Andric // This file is not part of the interface of this library. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #ifndef COMPILERRT_ASSEMBLY_H 15*0b57cec5SDimitry Andric #define COMPILERRT_ASSEMBLY_H 16*0b57cec5SDimitry Andric 17*0b57cec5SDimitry Andric #if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) 18*0b57cec5SDimitry Andric #define SEPARATOR @ 19*0b57cec5SDimitry Andric #else 20*0b57cec5SDimitry Andric #define SEPARATOR ; 21*0b57cec5SDimitry Andric #endif 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric #if defined(__APPLE__) 24*0b57cec5SDimitry Andric #define HIDDEN(name) .private_extern name 25*0b57cec5SDimitry Andric #define LOCAL_LABEL(name) L_##name 26*0b57cec5SDimitry Andric // tell linker it can break up file at label boundaries 27*0b57cec5SDimitry Andric #define FILE_LEVEL_DIRECTIVE .subsections_via_symbols 28*0b57cec5SDimitry Andric #define SYMBOL_IS_FUNC(name) 29*0b57cec5SDimitry Andric #define CONST_SECTION .const 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric #define NO_EXEC_STACK_DIRECTIVE 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric #elif defined(__ELF__) 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric #define HIDDEN(name) .hidden name 36*0b57cec5SDimitry Andric #define LOCAL_LABEL(name) .L_##name 37*0b57cec5SDimitry Andric #define FILE_LEVEL_DIRECTIVE 38*0b57cec5SDimitry Andric #if defined(__arm__) 39*0b57cec5SDimitry Andric #define SYMBOL_IS_FUNC(name) .type name,%function 40*0b57cec5SDimitry Andric #else 41*0b57cec5SDimitry Andric #define SYMBOL_IS_FUNC(name) .type name,@function 42*0b57cec5SDimitry Andric #endif 43*0b57cec5SDimitry Andric #define CONST_SECTION .section .rodata 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ 46*0b57cec5SDimitry Andric defined(__linux__) 47*0b57cec5SDimitry Andric #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits 48*0b57cec5SDimitry Andric #else 49*0b57cec5SDimitry Andric #define NO_EXEC_STACK_DIRECTIVE 50*0b57cec5SDimitry Andric #endif 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric #else // !__APPLE__ && !__ELF__ 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric #define HIDDEN(name) 55*0b57cec5SDimitry Andric #define LOCAL_LABEL(name) .L ## name 56*0b57cec5SDimitry Andric #define FILE_LEVEL_DIRECTIVE 57*0b57cec5SDimitry Andric #define SYMBOL_IS_FUNC(name) \ 58*0b57cec5SDimitry Andric .def name SEPARATOR \ 59*0b57cec5SDimitry Andric .scl 2 SEPARATOR \ 60*0b57cec5SDimitry Andric .type 32 SEPARATOR \ 61*0b57cec5SDimitry Andric .endef 62*0b57cec5SDimitry Andric #define CONST_SECTION .section .rdata,"rd" 63*0b57cec5SDimitry Andric 64*0b57cec5SDimitry Andric #define NO_EXEC_STACK_DIRECTIVE 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric #endif 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric #if defined(__arm__) 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric // Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros: 71*0b57cec5SDimitry Andric // - for '-mthumb -march=armv6' compiler defines '__thumb__' 72*0b57cec5SDimitry Andric // - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__' 73*0b57cec5SDimitry Andric #if defined(__thumb2__) || defined(__thumb__) 74*0b57cec5SDimitry Andric #define DEFINE_CODE_STATE .thumb SEPARATOR 75*0b57cec5SDimitry Andric #define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR 76*0b57cec5SDimitry Andric #if defined(__thumb2__) 77*0b57cec5SDimitry Andric #define USE_THUMB_2 78*0b57cec5SDimitry Andric #define IT(cond) it cond 79*0b57cec5SDimitry Andric #define ITT(cond) itt cond 80*0b57cec5SDimitry Andric #define ITE(cond) ite cond 81*0b57cec5SDimitry Andric #else 82*0b57cec5SDimitry Andric #define USE_THUMB_1 83*0b57cec5SDimitry Andric #define IT(cond) 84*0b57cec5SDimitry Andric #define ITT(cond) 85*0b57cec5SDimitry Andric #define ITE(cond) 86*0b57cec5SDimitry Andric #endif // defined(__thumb__2) 87*0b57cec5SDimitry Andric #else // !defined(__thumb2__) && !defined(__thumb__) 88*0b57cec5SDimitry Andric #define DEFINE_CODE_STATE .arm SEPARATOR 89*0b57cec5SDimitry Andric #define DECLARE_FUNC_ENCODING 90*0b57cec5SDimitry Andric #define IT(cond) 91*0b57cec5SDimitry Andric #define ITT(cond) 92*0b57cec5SDimitry Andric #define ITE(cond) 93*0b57cec5SDimitry Andric #endif 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric #if defined(USE_THUMB_1) && defined(USE_THUMB_2) 96*0b57cec5SDimitry Andric #error "USE_THUMB_1 and USE_THUMB_2 can't be defined together." 97*0b57cec5SDimitry Andric #endif 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 100*0b57cec5SDimitry Andric #define ARM_HAS_BX 101*0b57cec5SDimitry Andric #endif 102*0b57cec5SDimitry Andric #if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \ 103*0b57cec5SDimitry Andric (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__))) 104*0b57cec5SDimitry Andric #define __ARM_FEATURE_CLZ 105*0b57cec5SDimitry Andric #endif 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric #ifdef ARM_HAS_BX 108*0b57cec5SDimitry Andric #define JMP(r) bx r 109*0b57cec5SDimitry Andric #define JMPc(r, c) bx##c r 110*0b57cec5SDimitry Andric #else 111*0b57cec5SDimitry Andric #define JMP(r) mov pc, r 112*0b57cec5SDimitry Andric #define JMPc(r, c) mov##c pc, r 113*0b57cec5SDimitry Andric #endif 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andric // pop {pc} can't switch Thumb mode on ARMv4T 116*0b57cec5SDimitry Andric #if __ARM_ARCH >= 5 117*0b57cec5SDimitry Andric #define POP_PC() pop {pc} 118*0b57cec5SDimitry Andric #else 119*0b57cec5SDimitry Andric #define POP_PC() \ 120*0b57cec5SDimitry Andric pop {ip}; \ 121*0b57cec5SDimitry Andric JMP(ip) 122*0b57cec5SDimitry Andric #endif 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric #if defined(USE_THUMB_2) 125*0b57cec5SDimitry Andric #define WIDE(op) op.w 126*0b57cec5SDimitry Andric #else 127*0b57cec5SDimitry Andric #define WIDE(op) op 128*0b57cec5SDimitry Andric #endif 129*0b57cec5SDimitry Andric #else // !defined(__arm) 130*0b57cec5SDimitry Andric #define DECLARE_FUNC_ENCODING 131*0b57cec5SDimitry Andric #define DEFINE_CODE_STATE 132*0b57cec5SDimitry Andric #endif 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric #define GLUE2(a, b) a##b 135*0b57cec5SDimitry Andric #define GLUE(a, b) GLUE2(a, b) 136*0b57cec5SDimitry Andric #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) 137*0b57cec5SDimitry Andric 138*0b57cec5SDimitry Andric #ifdef VISIBILITY_HIDDEN 139*0b57cec5SDimitry Andric #define DECLARE_SYMBOL_VISIBILITY(name) \ 140*0b57cec5SDimitry Andric HIDDEN(SYMBOL_NAME(name)) SEPARATOR 141*0b57cec5SDimitry Andric #else 142*0b57cec5SDimitry Andric #define DECLARE_SYMBOL_VISIBILITY(name) 143*0b57cec5SDimitry Andric #endif 144*0b57cec5SDimitry Andric 145*0b57cec5SDimitry Andric #define DEFINE_COMPILERRT_FUNCTION(name) \ 146*0b57cec5SDimitry Andric DEFINE_CODE_STATE \ 147*0b57cec5SDimitry Andric FILE_LEVEL_DIRECTIVE SEPARATOR \ 148*0b57cec5SDimitry Andric .globl SYMBOL_NAME(name) SEPARATOR \ 149*0b57cec5SDimitry Andric SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 150*0b57cec5SDimitry Andric DECLARE_SYMBOL_VISIBILITY(name) \ 151*0b57cec5SDimitry Andric DECLARE_FUNC_ENCODING \ 152*0b57cec5SDimitry Andric SYMBOL_NAME(name): 153*0b57cec5SDimitry Andric 154*0b57cec5SDimitry Andric #define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \ 155*0b57cec5SDimitry Andric DEFINE_CODE_STATE \ 156*0b57cec5SDimitry Andric FILE_LEVEL_DIRECTIVE SEPARATOR \ 157*0b57cec5SDimitry Andric .globl SYMBOL_NAME(name) SEPARATOR \ 158*0b57cec5SDimitry Andric SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 159*0b57cec5SDimitry Andric DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ 160*0b57cec5SDimitry Andric .thumb_func SEPARATOR \ 161*0b57cec5SDimitry Andric SYMBOL_NAME(name): 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric #define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \ 164*0b57cec5SDimitry Andric DEFINE_CODE_STATE \ 165*0b57cec5SDimitry Andric FILE_LEVEL_DIRECTIVE SEPARATOR \ 166*0b57cec5SDimitry Andric .globl SYMBOL_NAME(name) SEPARATOR \ 167*0b57cec5SDimitry Andric SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 168*0b57cec5SDimitry Andric HIDDEN(SYMBOL_NAME(name)) SEPARATOR \ 169*0b57cec5SDimitry Andric DECLARE_FUNC_ENCODING \ 170*0b57cec5SDimitry Andric SYMBOL_NAME(name): 171*0b57cec5SDimitry Andric 172*0b57cec5SDimitry Andric #define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \ 173*0b57cec5SDimitry Andric DEFINE_CODE_STATE \ 174*0b57cec5SDimitry Andric .globl name SEPARATOR \ 175*0b57cec5SDimitry Andric SYMBOL_IS_FUNC(name) SEPARATOR \ 176*0b57cec5SDimitry Andric HIDDEN(name) SEPARATOR \ 177*0b57cec5SDimitry Andric DECLARE_FUNC_ENCODING \ 178*0b57cec5SDimitry Andric name: 179*0b57cec5SDimitry Andric 180*0b57cec5SDimitry Andric #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \ 181*0b57cec5SDimitry Andric .globl SYMBOL_NAME(name) SEPARATOR \ 182*0b57cec5SDimitry Andric SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ 183*0b57cec5SDimitry Andric DECLARE_SYMBOL_VISIBILITY(SYMBOL_NAME(name)) SEPARATOR \ 184*0b57cec5SDimitry Andric .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR 185*0b57cec5SDimitry Andric 186*0b57cec5SDimitry Andric #if defined(__ARM_EABI__) 187*0b57cec5SDimitry Andric #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \ 188*0b57cec5SDimitry Andric DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name) 189*0b57cec5SDimitry Andric #else 190*0b57cec5SDimitry Andric #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) 191*0b57cec5SDimitry Andric #endif 192*0b57cec5SDimitry Andric 193*0b57cec5SDimitry Andric #ifdef __ELF__ 194*0b57cec5SDimitry Andric #define END_COMPILERRT_FUNCTION(name) \ 195*0b57cec5SDimitry Andric .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) 196*0b57cec5SDimitry Andric #else 197*0b57cec5SDimitry Andric #define END_COMPILERRT_FUNCTION(name) 198*0b57cec5SDimitry Andric #endif 199*0b57cec5SDimitry Andric 200*0b57cec5SDimitry Andric #endif // COMPILERRT_ASSEMBLY_H 201