xref: /freebsd/contrib/llvm-project/llvm/lib/IR/RuntimeLibcalls.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 
setARMLibcallNames(RuntimeLibcallsInfo & Info,const Triple & TT,FloatABI::ABIType FloatABIType,EABI EABIVersion)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 
initDefaultLibCallImpls()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.
initLibcalls(const Triple & TT,ExceptionHandling ExceptionModel,FloatABI::ABIType FloatABI,EABI EABIVersion,StringRef ABIName)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 
darwinHasExp10(const Triple & TT)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