1 //===- RuntimeLibcalls.cpp - Interface for runtime libcalls -----*- C++ -*-===// 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 #include "llvm/IR/RuntimeLibcalls.h" 10 11 using namespace llvm; 12 using namespace RTLIB; 13 14 #define GET_INIT_RUNTIME_LIBCALL_NAMES 15 #define GET_SET_TARGET_RUNTIME_LIBCALL_SETS 16 #include "llvm/IR/RuntimeLibcalls.inc" 17 #undef GET_INIT_RUNTIME_LIBCALL_NAMES 18 #undef GET_SET_TARGET_RUNTIME_LIBCALL_SETS 19 20 static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, 21 FloatABI::ABIType FloatABIType, 22 EABI EABIVersion) { 23 static const RTLIB::LibcallImpl AAPCS_Libcalls[] = { 24 RTLIB::__aeabi_dadd, RTLIB::__aeabi_ddiv, 25 RTLIB::__aeabi_dmul, RTLIB::__aeabi_dsub, 26 RTLIB::__aeabi_dcmpeq__oeq, RTLIB::__aeabi_dcmpeq__une, 27 RTLIB::__aeabi_dcmplt, RTLIB::__aeabi_dcmple, 28 RTLIB::__aeabi_dcmpge, RTLIB::__aeabi_dcmpgt, 29 RTLIB::__aeabi_dcmpun, RTLIB::__aeabi_fadd, 30 RTLIB::__aeabi_fdiv, RTLIB::__aeabi_fmul, 31 RTLIB::__aeabi_fsub, RTLIB::__aeabi_fcmpeq__oeq, 32 RTLIB::__aeabi_fcmpeq__une, RTLIB::__aeabi_fcmplt, 33 RTLIB::__aeabi_fcmple, RTLIB::__aeabi_fcmpge, 34 RTLIB::__aeabi_fcmpgt, RTLIB::__aeabi_fcmpun, 35 RTLIB::__aeabi_d2iz, RTLIB::__aeabi_d2uiz, 36 RTLIB::__aeabi_d2lz, RTLIB::__aeabi_d2ulz, 37 RTLIB::__aeabi_f2iz, RTLIB::__aeabi_f2uiz, 38 RTLIB::__aeabi_f2lz, RTLIB::__aeabi_f2ulz, 39 RTLIB::__aeabi_d2f, RTLIB::__aeabi_d2h, 40 RTLIB::__aeabi_f2d, RTLIB::__aeabi_i2d, 41 RTLIB::__aeabi_ui2d, RTLIB::__aeabi_l2d, 42 RTLIB::__aeabi_ul2d, RTLIB::__aeabi_i2f, 43 RTLIB::__aeabi_ui2f, RTLIB::__aeabi_l2f, 44 RTLIB::__aeabi_ul2f, RTLIB::__aeabi_lmul, 45 RTLIB::__aeabi_llsl, RTLIB::__aeabi_llsr, 46 RTLIB::__aeabi_lasr, RTLIB::__aeabi_idiv__i8, 47 RTLIB::__aeabi_idiv__i16, RTLIB::__aeabi_idiv__i32, 48 RTLIB::__aeabi_idivmod, RTLIB::__aeabi_uidivmod, 49 RTLIB::__aeabi_ldivmod, RTLIB::__aeabi_uidiv__i8, 50 RTLIB::__aeabi_uidiv__i16, RTLIB::__aeabi_uidiv__i32, 51 RTLIB::__aeabi_uldivmod, RTLIB::__aeabi_f2h, 52 RTLIB::__aeabi_d2h, RTLIB::__aeabi_h2f, 53 RTLIB::__aeabi_memcpy, RTLIB::__aeabi_memmove, 54 RTLIB::__aeabi_memset, RTLIB::__aeabi_memcpy4, 55 RTLIB::__aeabi_memcpy8, RTLIB::__aeabi_memmove4, 56 RTLIB::__aeabi_memmove8, RTLIB::__aeabi_memset4, 57 RTLIB::__aeabi_memset8, RTLIB::__aeabi_memclr, 58 RTLIB::__aeabi_memclr4, RTLIB::__aeabi_memclr8}; 59 60 for (RTLIB::LibcallImpl Impl : AAPCS_Libcalls) 61 Info.setLibcallImplCallingConv(Impl, CallingConv::ARM_AAPCS); 62 } 63 64 void RTLIB::RuntimeLibcallsInfo::initDefaultLibCallImpls() { 65 std::memcpy(LibcallImpls, DefaultLibcallImpls, sizeof(LibcallImpls)); 66 static_assert(sizeof(LibcallImpls) == sizeof(DefaultLibcallImpls), 67 "libcall array size should match"); 68 } 69 70 /// Set default libcall names. If a target wants to opt-out of a libcall it 71 /// should be placed here. 72 void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, 73 ExceptionHandling ExceptionModel, 74 FloatABI::ABIType FloatABI, 75 EABI EABIVersion, StringRef ABIName) { 76 setTargetRuntimeLibcallSets(TT, FloatABI); 77 78 // Early exit for targets that have fully ported to tablegen. 79 if (TT.isAMDGPU() || TT.isNVPTX() || TT.isWasm()) 80 return; 81 82 if (TT.isX86() || TT.isVE() || TT.isARM() || TT.isThumb()) { 83 if (ExceptionModel == ExceptionHandling::SjLj) 84 setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume); 85 } 86 87 // A few names are different on particular architectures or environments. 88 if (TT.isOSDarwin()) { 89 // For f16/f32 conversions, Darwin uses the standard naming scheme, 90 // instead of the gnueabi-style __gnu_*_ieee. 91 // FIXME: What about other targets? 92 setLibcallImpl(RTLIB::FPEXT_F16_F32, RTLIB::__extendhfsf2); 93 setLibcallImpl(RTLIB::FPROUND_F32_F16, RTLIB::__truncsfhf2); 94 95 if (!darwinHasExp10(TT)) { 96 setLibcallImpl(RTLIB::EXP10_F32, RTLIB::Unsupported); 97 setLibcallImpl(RTLIB::EXP10_F64, RTLIB::Unsupported); 98 } 99 } 100 101 if (TT.isOSOpenBSD()) { 102 setLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL, RTLIB::Unsupported); 103 setLibcallImpl(RTLIB::STACK_SMASH_HANDLER, RTLIB::__stack_smash_handler); 104 } 105 106 // Skip default manual processing for targets that have been fully ported to 107 // tablegen for now. Eventually the rest of this should be deleted. 108 if (TT.isX86() || TT.isAArch64() || TT.isWasm()) 109 return; 110 111 if (TT.isARM() || TT.isThumb()) { 112 setARMLibcallNames(*this, TT, FloatABI, EABIVersion); 113 return; 114 } 115 116 if (hasSinCos(TT)) { 117 setLibcallImpl(RTLIB::SINCOS_F32, RTLIB::sincosf); 118 setLibcallImpl(RTLIB::SINCOS_F64, RTLIB::sincos); 119 setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincos_f128); 120 } 121 122 // These libcalls are only available in compiler-rt, not libgcc. 123 if (TT.isArch64Bit()) { 124 setLibcallImpl(RTLIB::SHL_I128, RTLIB::__ashlti3); 125 setLibcallImpl(RTLIB::SRL_I128, RTLIB::__lshrti3); 126 setLibcallImpl(RTLIB::SRA_I128, RTLIB::__ashrti3); 127 setLibcallImpl(RTLIB::MUL_I128, RTLIB::__multi3); 128 setLibcallImpl(RTLIB::MULO_I64, RTLIB::__mulodi4); 129 } 130 131 if (TT.getArch() == Triple::ArchType::msp430) { 132 setLibcallImplCallingConv(RTLIB::__mspabi_mpyll, 133 CallingConv::MSP430_BUILTIN); 134 } 135 } 136 137 bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) { 138 switch (TT.getOS()) { 139 case Triple::MacOSX: 140 return !TT.isMacOSXVersionLT(10, 9); 141 case Triple::IOS: 142 return !TT.isOSVersionLT(7, 0); 143 case Triple::DriverKit: 144 case Triple::TvOS: 145 case Triple::WatchOS: 146 case Triple::XROS: 147 case Triple::BridgeOS: 148 return true; 149 default: 150 return false; 151 } 152 } 153