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 | /// Set default libcall names. If a target wants to opt-out of a libcall it |
15 | /// should be placed here. |
16 | void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) { |
17 | std::fill(std::begin(arr&: LibcallRoutineNames), std::end(arr&: LibcallRoutineNames), |
18 | nullptr); |
19 | |
20 | #define HANDLE_LIBCALL(code, name) setLibcallName(RTLIB::code, name); |
21 | #include "llvm/IR/RuntimeLibcalls.def" |
22 | #undef HANDLE_LIBCALL |
23 | |
24 | // Initialize calling conventions to their default. |
25 | for (int LC = 0; LC < RTLIB::UNKNOWN_LIBCALL; ++LC) |
26 | setLibcallCallingConv(Call: (RTLIB::Libcall)LC, CC: CallingConv::C); |
27 | |
28 | // Use the f128 variants of math functions on x86_64 |
29 | if (TT.getArch() == Triple::ArchType::x86_64 && TT.isGNUEnvironment()) { |
30 | setLibcallName(Call: RTLIB::REM_F128, Name: "fmodf128" ); |
31 | setLibcallName(Call: RTLIB::FMA_F128, Name: "fmaf128" ); |
32 | setLibcallName(Call: RTLIB::SQRT_F128, Name: "sqrtf128" ); |
33 | setLibcallName(Call: RTLIB::CBRT_F128, Name: "cbrtf128" ); |
34 | setLibcallName(Call: RTLIB::LOG_F128, Name: "logf128" ); |
35 | setLibcallName(Call: RTLIB::LOG_FINITE_F128, Name: "__logf128_finite" ); |
36 | setLibcallName(Call: RTLIB::LOG2_F128, Name: "log2f128" ); |
37 | setLibcallName(Call: RTLIB::LOG2_FINITE_F128, Name: "__log2f128_finite" ); |
38 | setLibcallName(Call: RTLIB::LOG10_F128, Name: "log10f128" ); |
39 | setLibcallName(Call: RTLIB::LOG10_FINITE_F128, Name: "__log10f128_finite" ); |
40 | setLibcallName(Call: RTLIB::EXP_F128, Name: "expf128" ); |
41 | setLibcallName(Call: RTLIB::EXP_FINITE_F128, Name: "__expf128_finite" ); |
42 | setLibcallName(Call: RTLIB::EXP2_F128, Name: "exp2f128" ); |
43 | setLibcallName(Call: RTLIB::EXP2_FINITE_F128, Name: "__exp2f128_finite" ); |
44 | setLibcallName(Call: RTLIB::EXP10_F128, Name: "exp10f128" ); |
45 | setLibcallName(Call: RTLIB::SIN_F128, Name: "sinf128" ); |
46 | setLibcallName(Call: RTLIB::COS_F128, Name: "cosf128" ); |
47 | setLibcallName(Call: RTLIB::TAN_F128, Name: "tanf128" ); |
48 | setLibcallName(Call: RTLIB::SINCOS_F128, Name: "sincosf128" ); |
49 | setLibcallName(Call: RTLIB::ASIN_F128, Name: "asinf128" ); |
50 | setLibcallName(Call: RTLIB::ACOS_F128, Name: "acosf128" ); |
51 | setLibcallName(Call: RTLIB::ATAN_F128, Name: "atanf128" ); |
52 | setLibcallName(Call: RTLIB::SINH_F128, Name: "sinhf128" ); |
53 | setLibcallName(Call: RTLIB::COSH_F128, Name: "coshf128" ); |
54 | setLibcallName(Call: RTLIB::TANH_F128, Name: "tanhf128" ); |
55 | setLibcallName(Call: RTLIB::POW_F128, Name: "powf128" ); |
56 | setLibcallName(Call: RTLIB::POW_FINITE_F128, Name: "__powf128_finite" ); |
57 | setLibcallName(Call: RTLIB::CEIL_F128, Name: "ceilf128" ); |
58 | setLibcallName(Call: RTLIB::TRUNC_F128, Name: "truncf128" ); |
59 | setLibcallName(Call: RTLIB::RINT_F128, Name: "rintf128" ); |
60 | setLibcallName(Call: RTLIB::NEARBYINT_F128, Name: "nearbyintf128" ); |
61 | setLibcallName(Call: RTLIB::ROUND_F128, Name: "roundf128" ); |
62 | setLibcallName(Call: RTLIB::ROUNDEVEN_F128, Name: "roundevenf128" ); |
63 | setLibcallName(Call: RTLIB::FLOOR_F128, Name: "floorf128" ); |
64 | setLibcallName(Call: RTLIB::COPYSIGN_F128, Name: "copysignf128" ); |
65 | setLibcallName(Call: RTLIB::FMIN_F128, Name: "fminf128" ); |
66 | setLibcallName(Call: RTLIB::FMAX_F128, Name: "fmaxf128" ); |
67 | setLibcallName(Call: RTLIB::LROUND_F128, Name: "lroundf128" ); |
68 | setLibcallName(Call: RTLIB::LLROUND_F128, Name: "llroundf128" ); |
69 | setLibcallName(Call: RTLIB::LRINT_F128, Name: "lrintf128" ); |
70 | setLibcallName(Call: RTLIB::LLRINT_F128, Name: "llrintf128" ); |
71 | setLibcallName(Call: RTLIB::LDEXP_F128, Name: "ldexpf128" ); |
72 | setLibcallName(Call: RTLIB::FREXP_F128, Name: "frexpf128" ); |
73 | } |
74 | |
75 | // For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf". |
76 | if (TT.isPPC()) { |
77 | setLibcallName(Call: RTLIB::ADD_F128, Name: "__addkf3" ); |
78 | setLibcallName(Call: RTLIB::SUB_F128, Name: "__subkf3" ); |
79 | setLibcallName(Call: RTLIB::MUL_F128, Name: "__mulkf3" ); |
80 | setLibcallName(Call: RTLIB::DIV_F128, Name: "__divkf3" ); |
81 | setLibcallName(Call: RTLIB::POWI_F128, Name: "__powikf2" ); |
82 | setLibcallName(Call: RTLIB::FPEXT_F32_F128, Name: "__extendsfkf2" ); |
83 | setLibcallName(Call: RTLIB::FPEXT_F64_F128, Name: "__extenddfkf2" ); |
84 | setLibcallName(Call: RTLIB::FPROUND_F128_F32, Name: "__trunckfsf2" ); |
85 | setLibcallName(Call: RTLIB::FPROUND_F128_F64, Name: "__trunckfdf2" ); |
86 | setLibcallName(Call: RTLIB::FPTOSINT_F128_I32, Name: "__fixkfsi" ); |
87 | setLibcallName(Call: RTLIB::FPTOSINT_F128_I64, Name: "__fixkfdi" ); |
88 | setLibcallName(Call: RTLIB::FPTOSINT_F128_I128, Name: "__fixkfti" ); |
89 | setLibcallName(Call: RTLIB::FPTOUINT_F128_I32, Name: "__fixunskfsi" ); |
90 | setLibcallName(Call: RTLIB::FPTOUINT_F128_I64, Name: "__fixunskfdi" ); |
91 | setLibcallName(Call: RTLIB::FPTOUINT_F128_I128, Name: "__fixunskfti" ); |
92 | setLibcallName(Call: RTLIB::SINTTOFP_I32_F128, Name: "__floatsikf" ); |
93 | setLibcallName(Call: RTLIB::SINTTOFP_I64_F128, Name: "__floatdikf" ); |
94 | setLibcallName(Call: RTLIB::SINTTOFP_I128_F128, Name: "__floattikf" ); |
95 | setLibcallName(Call: RTLIB::UINTTOFP_I32_F128, Name: "__floatunsikf" ); |
96 | setLibcallName(Call: RTLIB::UINTTOFP_I64_F128, Name: "__floatundikf" ); |
97 | setLibcallName(Call: RTLIB::UINTTOFP_I128_F128, Name: "__floatuntikf" ); |
98 | setLibcallName(Call: RTLIB::OEQ_F128, Name: "__eqkf2" ); |
99 | setLibcallName(Call: RTLIB::UNE_F128, Name: "__nekf2" ); |
100 | setLibcallName(Call: RTLIB::OGE_F128, Name: "__gekf2" ); |
101 | setLibcallName(Call: RTLIB::OLT_F128, Name: "__ltkf2" ); |
102 | setLibcallName(Call: RTLIB::OLE_F128, Name: "__lekf2" ); |
103 | setLibcallName(Call: RTLIB::OGT_F128, Name: "__gtkf2" ); |
104 | setLibcallName(Call: RTLIB::UO_F128, Name: "__unordkf2" ); |
105 | } |
106 | |
107 | // A few names are different on particular architectures or environments. |
108 | if (TT.isOSDarwin()) { |
109 | // For f16/f32 conversions, Darwin uses the standard naming scheme, |
110 | // instead of the gnueabi-style __gnu_*_ieee. |
111 | // FIXME: What about other targets? |
112 | setLibcallName(Call: RTLIB::FPEXT_F16_F32, Name: "__extendhfsf2" ); |
113 | setLibcallName(Call: RTLIB::FPROUND_F32_F16, Name: "__truncsfhf2" ); |
114 | |
115 | // Some darwins have an optimized __bzero/bzero function. |
116 | switch (TT.getArch()) { |
117 | case Triple::x86: |
118 | case Triple::x86_64: |
119 | if (TT.isMacOSX() && !TT.isMacOSXVersionLT(Major: 10, Minor: 6)) |
120 | setLibcallName(Call: RTLIB::BZERO, Name: "__bzero" ); |
121 | break; |
122 | case Triple::aarch64: |
123 | case Triple::aarch64_32: |
124 | setLibcallName(Call: RTLIB::BZERO, Name: "bzero" ); |
125 | break; |
126 | default: |
127 | break; |
128 | } |
129 | |
130 | if (darwinHasSinCos(TT)) { |
131 | setLibcallName(Call: RTLIB::SINCOS_STRET_F32, Name: "__sincosf_stret" ); |
132 | setLibcallName(Call: RTLIB::SINCOS_STRET_F64, Name: "__sincos_stret" ); |
133 | if (TT.isWatchABI()) { |
134 | setLibcallCallingConv(Call: RTLIB::SINCOS_STRET_F32, |
135 | CC: CallingConv::ARM_AAPCS_VFP); |
136 | setLibcallCallingConv(Call: RTLIB::SINCOS_STRET_F64, |
137 | CC: CallingConv::ARM_AAPCS_VFP); |
138 | } |
139 | } |
140 | |
141 | switch (TT.getOS()) { |
142 | case Triple::MacOSX: |
143 | if (TT.isMacOSXVersionLT(Major: 10, Minor: 9)) { |
144 | setLibcallName(Call: RTLIB::EXP10_F32, Name: nullptr); |
145 | setLibcallName(Call: RTLIB::EXP10_F64, Name: nullptr); |
146 | } else { |
147 | setLibcallName(Call: RTLIB::EXP10_F32, Name: "__exp10f" ); |
148 | setLibcallName(Call: RTLIB::EXP10_F64, Name: "__exp10" ); |
149 | } |
150 | break; |
151 | case Triple::IOS: |
152 | if (TT.isOSVersionLT(Major: 7, Minor: 0)) { |
153 | setLibcallName(Call: RTLIB::EXP10_F32, Name: nullptr); |
154 | setLibcallName(Call: RTLIB::EXP10_F64, Name: nullptr); |
155 | break; |
156 | } |
157 | [[fallthrough]]; |
158 | case Triple::TvOS: |
159 | case Triple::WatchOS: |
160 | case Triple::XROS: |
161 | setLibcallName(Call: RTLIB::EXP10_F32, Name: "__exp10f" ); |
162 | setLibcallName(Call: RTLIB::EXP10_F64, Name: "__exp10" ); |
163 | break; |
164 | default: |
165 | break; |
166 | } |
167 | } else { |
168 | setLibcallName(Call: RTLIB::FPEXT_F16_F32, Name: "__gnu_h2f_ieee" ); |
169 | setLibcallName(Call: RTLIB::FPROUND_F32_F16, Name: "__gnu_f2h_ieee" ); |
170 | } |
171 | |
172 | if (TT.isGNUEnvironment() || TT.isOSFuchsia() || |
173 | (TT.isAndroid() && !TT.isAndroidVersionLT(Major: 9))) { |
174 | setLibcallName(Call: RTLIB::SINCOS_F32, Name: "sincosf" ); |
175 | setLibcallName(Call: RTLIB::SINCOS_F64, Name: "sincos" ); |
176 | setLibcallName(Call: RTLIB::SINCOS_F80, Name: "sincosl" ); |
177 | setLibcallName(Call: RTLIB::SINCOS_F128, Name: "sincosl" ); |
178 | setLibcallName(Call: RTLIB::SINCOS_PPCF128, Name: "sincosl" ); |
179 | } |
180 | |
181 | if (TT.isPS()) { |
182 | setLibcallName(Call: RTLIB::SINCOS_F32, Name: "sincosf" ); |
183 | setLibcallName(Call: RTLIB::SINCOS_F64, Name: "sincos" ); |
184 | } |
185 | |
186 | if (TT.isOSOpenBSD()) { |
187 | setLibcallName(Call: RTLIB::STACKPROTECTOR_CHECK_FAIL, Name: nullptr); |
188 | } |
189 | |
190 | if (TT.isOSWindows() && !TT.isOSCygMing()) { |
191 | setLibcallName(Call: RTLIB::LDEXP_F32, Name: nullptr); |
192 | setLibcallName(Call: RTLIB::LDEXP_F80, Name: nullptr); |
193 | setLibcallName(Call: RTLIB::LDEXP_F128, Name: nullptr); |
194 | setLibcallName(Call: RTLIB::LDEXP_PPCF128, Name: nullptr); |
195 | |
196 | setLibcallName(Call: RTLIB::FREXP_F32, Name: nullptr); |
197 | setLibcallName(Call: RTLIB::FREXP_F80, Name: nullptr); |
198 | setLibcallName(Call: RTLIB::FREXP_F128, Name: nullptr); |
199 | setLibcallName(Call: RTLIB::FREXP_PPCF128, Name: nullptr); |
200 | } |
201 | |
202 | if (TT.isAArch64()) { |
203 | if (TT.isOSMSVCRT()) { |
204 | // MSVCRT doesn't have powi; fall back to pow |
205 | setLibcallName(Call: RTLIB::POWI_F32, Name: nullptr); |
206 | setLibcallName(Call: RTLIB::POWI_F64, Name: nullptr); |
207 | } |
208 | } |
209 | |
210 | // Disable most libcalls on AMDGPU. |
211 | if (TT.isAMDGPU()) { |
212 | for (int I = 0; I < RTLIB::UNKNOWN_LIBCALL; ++I) { |
213 | if (I < RTLIB::ATOMIC_LOAD || I > RTLIB::ATOMIC_FETCH_NAND_16) |
214 | setLibcallName(Call: static_cast<RTLIB::Libcall>(I), Name: nullptr); |
215 | } |
216 | } |
217 | |
218 | // Disable most libcalls on NVPTX. |
219 | if (TT.isNVPTX()) { |
220 | for (int I = 0; I < RTLIB::UNKNOWN_LIBCALL; ++I) |
221 | if (I < RTLIB::ATOMIC_LOAD || I > RTLIB::ATOMIC_FETCH_NAND_16) |
222 | setLibcallName(Call: static_cast<RTLIB::Libcall>(I), Name: nullptr); |
223 | } |
224 | |
225 | if (TT.isARM() || TT.isThumb()) { |
226 | // These libcalls are not available in 32-bit. |
227 | setLibcallName(Call: RTLIB::SHL_I128, Name: nullptr); |
228 | setLibcallName(Call: RTLIB::SRL_I128, Name: nullptr); |
229 | setLibcallName(Call: RTLIB::SRA_I128, Name: nullptr); |
230 | setLibcallName(Call: RTLIB::MUL_I128, Name: nullptr); |
231 | setLibcallName(Call: RTLIB::MULO_I64, Name: nullptr); |
232 | setLibcallName(Call: RTLIB::MULO_I128, Name: nullptr); |
233 | |
234 | if (TT.isOSMSVCRT()) { |
235 | // MSVCRT doesn't have powi; fall back to pow |
236 | setLibcallName(Call: RTLIB::POWI_F32, Name: nullptr); |
237 | setLibcallName(Call: RTLIB::POWI_F64, Name: nullptr); |
238 | } |
239 | } |
240 | |
241 | if (TT.getArch() == Triple::ArchType::avr) { |
242 | // Division rtlib functions (not supported), use divmod functions instead |
243 | setLibcallName(Call: RTLIB::SDIV_I8, Name: nullptr); |
244 | setLibcallName(Call: RTLIB::SDIV_I16, Name: nullptr); |
245 | setLibcallName(Call: RTLIB::SDIV_I32, Name: nullptr); |
246 | setLibcallName(Call: RTLIB::UDIV_I8, Name: nullptr); |
247 | setLibcallName(Call: RTLIB::UDIV_I16, Name: nullptr); |
248 | setLibcallName(Call: RTLIB::UDIV_I32, Name: nullptr); |
249 | |
250 | // Modulus rtlib functions (not supported), use divmod functions instead |
251 | setLibcallName(Call: RTLIB::SREM_I8, Name: nullptr); |
252 | setLibcallName(Call: RTLIB::SREM_I16, Name: nullptr); |
253 | setLibcallName(Call: RTLIB::SREM_I32, Name: nullptr); |
254 | setLibcallName(Call: RTLIB::UREM_I8, Name: nullptr); |
255 | setLibcallName(Call: RTLIB::UREM_I16, Name: nullptr); |
256 | setLibcallName(Call: RTLIB::UREM_I32, Name: nullptr); |
257 | } |
258 | |
259 | if (TT.getArch() == Triple::ArchType::hexagon) { |
260 | // These cause problems when the shift amount is non-constant. |
261 | setLibcallName(Call: RTLIB::SHL_I128, Name: nullptr); |
262 | setLibcallName(Call: RTLIB::SRL_I128, Name: nullptr); |
263 | setLibcallName(Call: RTLIB::SRA_I128, Name: nullptr); |
264 | } |
265 | |
266 | if (TT.isLoongArch()) { |
267 | if (!TT.isLoongArch64()) { |
268 | // Set libcalls. |
269 | setLibcallName(Call: RTLIB::MUL_I128, Name: nullptr); |
270 | // The MULO libcall is not part of libgcc, only compiler-rt. |
271 | setLibcallName(Call: RTLIB::MULO_I64, Name: nullptr); |
272 | } |
273 | // The MULO libcall is not part of libgcc, only compiler-rt. |
274 | setLibcallName(Call: RTLIB::MULO_I128, Name: nullptr); |
275 | } |
276 | |
277 | if (TT.isMIPS32()) { |
278 | // These libcalls are not available in 32-bit. |
279 | setLibcallName(Call: RTLIB::SHL_I128, Name: nullptr); |
280 | setLibcallName(Call: RTLIB::SRL_I128, Name: nullptr); |
281 | setLibcallName(Call: RTLIB::SRA_I128, Name: nullptr); |
282 | setLibcallName(Call: RTLIB::MUL_I128, Name: nullptr); |
283 | setLibcallName(Call: RTLIB::MULO_I64, Name: nullptr); |
284 | setLibcallName(Call: RTLIB::MULO_I128, Name: nullptr); |
285 | } |
286 | |
287 | if (TT.isPPC()) { |
288 | if (!TT.isPPC64()) { |
289 | // These libcalls are not available in 32-bit. |
290 | setLibcallName(Call: RTLIB::SHL_I128, Name: nullptr); |
291 | setLibcallName(Call: RTLIB::SRL_I128, Name: nullptr); |
292 | setLibcallName(Call: RTLIB::SRA_I128, Name: nullptr); |
293 | setLibcallName(Call: RTLIB::MUL_I128, Name: nullptr); |
294 | setLibcallName(Call: RTLIB::MULO_I64, Name: nullptr); |
295 | } |
296 | setLibcallName(Call: RTLIB::MULO_I128, Name: nullptr); |
297 | } |
298 | |
299 | if (TT.isRISCV32()) { |
300 | // These libcalls are not available in 32-bit. |
301 | setLibcallName(Call: RTLIB::SHL_I128, Name: nullptr); |
302 | setLibcallName(Call: RTLIB::SRL_I128, Name: nullptr); |
303 | setLibcallName(Call: RTLIB::SRA_I128, Name: nullptr); |
304 | setLibcallName(Call: RTLIB::MUL_I128, Name: nullptr); |
305 | setLibcallName(Call: RTLIB::MULO_I64, Name: nullptr); |
306 | } |
307 | |
308 | if (TT.isSPARC()) { |
309 | if (!TT.isSPARC64()) { |
310 | // These libcalls are not available in 32-bit. |
311 | setLibcallName(Call: RTLIB::MULO_I64, Name: nullptr); |
312 | setLibcallName(Call: RTLIB::MUL_I128, Name: nullptr); |
313 | setLibcallName(Call: RTLIB::SHL_I128, Name: nullptr); |
314 | setLibcallName(Call: RTLIB::SRL_I128, Name: nullptr); |
315 | setLibcallName(Call: RTLIB::SRA_I128, Name: nullptr); |
316 | } |
317 | setLibcallName(Call: RTLIB::MULO_I128, Name: nullptr); |
318 | } |
319 | |
320 | if (TT.isSystemZ()) { |
321 | setLibcallName(Call: RTLIB::SRL_I128, Name: nullptr); |
322 | setLibcallName(Call: RTLIB::SHL_I128, Name: nullptr); |
323 | setLibcallName(Call: RTLIB::SRA_I128, Name: nullptr); |
324 | } |
325 | |
326 | if (TT.isX86()) { |
327 | if (TT.getArch() == Triple::ArchType::x86) { |
328 | // These libcalls are not available in 32-bit. |
329 | setLibcallName(Call: RTLIB::SHL_I128, Name: nullptr); |
330 | setLibcallName(Call: RTLIB::SRL_I128, Name: nullptr); |
331 | setLibcallName(Call: RTLIB::SRA_I128, Name: nullptr); |
332 | setLibcallName(Call: RTLIB::MUL_I128, Name: nullptr); |
333 | // The MULO libcall is not part of libgcc, only compiler-rt. |
334 | setLibcallName(Call: RTLIB::MULO_I64, Name: nullptr); |
335 | } |
336 | |
337 | // The MULO libcall is not part of libgcc, only compiler-rt. |
338 | setLibcallName(Call: RTLIB::MULO_I128, Name: nullptr); |
339 | |
340 | if (TT.isOSMSVCRT()) { |
341 | // MSVCRT doesn't have powi; fall back to pow |
342 | setLibcallName(Call: RTLIB::POWI_F32, Name: nullptr); |
343 | setLibcallName(Call: RTLIB::POWI_F64, Name: nullptr); |
344 | } |
345 | } |
346 | } |
347 | |