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 | #include "llvm/Support/CommandLine.h" |
11 | |
12 | using namespace llvm; |
13 | using namespace RTLIB; |
14 | |
15 | #define GET_INIT_RUNTIME_LIBCALL_UTILS |
16 | #define GET_INIT_RUNTIME_LIBCALL_NAMES |
17 | #include "llvm/IR/RuntimeLibcalls.inc" |
18 | #undef GET_INIT_RUNTIME_LIBCALL_UTILS |
19 | #undef GET_INIT_RUNTIME_LIBCALL_NAMES |
20 | |
21 | static cl::opt<bool> |
22 | HexagonEnableFastMathRuntimeCalls("hexagon-fast-math" , cl::Hidden, |
23 | cl::desc("Enable Fast Math processing" )); |
24 | |
25 | static void setAArch64LibcallNames(RuntimeLibcallsInfo &Info, |
26 | const Triple &TT) { |
27 | #define LCALLNAMES(A, B, N) \ |
28 | Info.setLibcallImpl(A##N##_RELAX, B##N##_relax); \ |
29 | Info.setLibcallImpl(A##N##_ACQ, B##N##_acq); \ |
30 | Info.setLibcallImpl(A##N##_REL, B##N##_rel); \ |
31 | Info.setLibcallImpl(A##N##_ACQ_REL, B##N##_acq_rel); |
32 | #define LCALLNAME4(A, B) \ |
33 | LCALLNAMES(A, B, 1) \ |
34 | LCALLNAMES(A, B, 2) LCALLNAMES(A, B, 4) LCALLNAMES(A, B, 8) |
35 | #define LCALLNAME5(A, B) \ |
36 | LCALLNAMES(A, B, 1) \ |
37 | LCALLNAMES(A, B, 2) \ |
38 | LCALLNAMES(A, B, 4) LCALLNAMES(A, B, 8) LCALLNAMES(A, B, 16) |
39 | |
40 | if (TT.isWindowsArm64EC()) { |
41 | LCALLNAME5(RTLIB::OUTLINE_ATOMIC_CAS, RTLIB::arm64ec___aarch64_cas) |
42 | LCALLNAME4(RTLIB::OUTLINE_ATOMIC_SWP, RTLIB::arm64ec___aarch64_swp) |
43 | LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDADD, RTLIB::arm64ec___aarch64_ldadd) |
44 | LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDSET, RTLIB::arm64ec___aarch64_ldset) |
45 | LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDCLR, RTLIB::arm64ec___aarch64_ldclr) |
46 | LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDEOR, RTLIB::arm64ec___aarch64_ldeor) |
47 | } else { |
48 | LCALLNAME5(RTLIB::OUTLINE_ATOMIC_CAS, RTLIB::__aarch64_cas) |
49 | LCALLNAME4(RTLIB::OUTLINE_ATOMIC_SWP, RTLIB::__aarch64_swp) |
50 | LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDADD, RTLIB::__aarch64_ldadd) |
51 | LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDSET, RTLIB::__aarch64_ldset) |
52 | LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDCLR, RTLIB::__aarch64_ldclr) |
53 | LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDEOR, RTLIB::__aarch64_ldeor) |
54 | } |
55 | #undef LCALLNAMES |
56 | #undef LCALLNAME4 |
57 | #undef LCALLNAME5 |
58 | } |
59 | |
60 | static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, |
61 | FloatABI::ABIType FloatABIType, |
62 | EABI EABIVersion) { |
63 | if (!TT.isOSDarwin() && !TT.isiOS() && !TT.isWatchOS() && !TT.isDriverKit()) { |
64 | CallingConv::ID DefaultCC = FloatABIType == FloatABI::Hard |
65 | ? CallingConv::ARM_AAPCS_VFP |
66 | : CallingConv::ARM_AAPCS; |
67 | for (RTLIB::Libcall LC : RTLIB::libcalls()) |
68 | Info.setLibcallCallingConv(Call: LC, CC: DefaultCC); |
69 | } |
70 | |
71 | // Register based DivRem for AEABI (RTABI 4.2) |
72 | if (TT.isTargetAEABI() || TT.isAndroid() || TT.isTargetGNUAEABI() || |
73 | TT.isTargetMuslAEABI() || TT.isOSWindows()) { |
74 | if (TT.isOSWindows()) { |
75 | const struct { |
76 | const RTLIB::Libcall Op; |
77 | const RTLIB::LibcallImpl Impl; |
78 | const CallingConv::ID CC; |
79 | } LibraryCalls[] = { |
80 | {.Op: RTLIB::SDIVREM_I32, .Impl: RTLIB::__rt_sdiv, .CC: CallingConv::ARM_AAPCS}, |
81 | {.Op: RTLIB::SDIVREM_I64, .Impl: RTLIB::__rt_sdiv64, .CC: CallingConv::ARM_AAPCS}, |
82 | {.Op: RTLIB::UDIVREM_I32, .Impl: RTLIB::__rt_udiv, .CC: CallingConv::ARM_AAPCS}, |
83 | {.Op: RTLIB::UDIVREM_I64, .Impl: RTLIB::__rt_udiv64, .CC: CallingConv::ARM_AAPCS}, |
84 | }; |
85 | |
86 | for (const auto &LC : LibraryCalls) { |
87 | Info.setLibcallImpl(Call: LC.Op, Impl: LC.Impl); |
88 | Info.setLibcallCallingConv(Call: LC.Op, CC: LC.CC); |
89 | } |
90 | } else { |
91 | const struct { |
92 | const RTLIB::Libcall Op; |
93 | const RTLIB::LibcallImpl Impl; |
94 | const CallingConv::ID CC; |
95 | } LibraryCalls[] = { |
96 | {.Op: RTLIB::SDIVREM_I32, .Impl: RTLIB::__aeabi_idivmod, .CC: CallingConv::ARM_AAPCS}, |
97 | {.Op: RTLIB::SDIVREM_I64, .Impl: RTLIB::__aeabi_ldivmod, .CC: CallingConv::ARM_AAPCS}, |
98 | {.Op: RTLIB::UDIVREM_I32, .Impl: RTLIB::__aeabi_uidivmod, .CC: CallingConv::ARM_AAPCS}, |
99 | {.Op: RTLIB::UDIVREM_I64, .Impl: RTLIB::__aeabi_uldivmod, .CC: CallingConv::ARM_AAPCS}, |
100 | }; |
101 | |
102 | for (const auto &LC : LibraryCalls) { |
103 | Info.setLibcallImpl(Call: LC.Op, Impl: LC.Impl); |
104 | Info.setLibcallCallingConv(Call: LC.Op, CC: LC.CC); |
105 | } |
106 | } |
107 | } |
108 | |
109 | if (TT.isOSWindows()) { |
110 | static const struct { |
111 | const RTLIB::Libcall Op; |
112 | const RTLIB::LibcallImpl Impl; |
113 | const CallingConv::ID CC; |
114 | } LibraryCalls[] = { |
115 | {.Op: RTLIB::FPTOSINT_F32_I64, .Impl: RTLIB::__stoi64, .CC: CallingConv::ARM_AAPCS_VFP}, |
116 | {.Op: RTLIB::FPTOSINT_F64_I64, .Impl: RTLIB::__dtoi64, .CC: CallingConv::ARM_AAPCS_VFP}, |
117 | {.Op: RTLIB::FPTOUINT_F32_I64, .Impl: RTLIB::__stou64, .CC: CallingConv::ARM_AAPCS_VFP}, |
118 | {.Op: RTLIB::FPTOUINT_F64_I64, .Impl: RTLIB::__dtou64, .CC: CallingConv::ARM_AAPCS_VFP}, |
119 | {.Op: RTLIB::SINTTOFP_I64_F32, .Impl: RTLIB::__i64tos, .CC: CallingConv::ARM_AAPCS_VFP}, |
120 | {.Op: RTLIB::SINTTOFP_I64_F64, .Impl: RTLIB::__i64tod, .CC: CallingConv::ARM_AAPCS_VFP}, |
121 | {.Op: RTLIB::UINTTOFP_I64_F32, .Impl: RTLIB::__u64tos, .CC: CallingConv::ARM_AAPCS_VFP}, |
122 | {.Op: RTLIB::UINTTOFP_I64_F64, .Impl: RTLIB::__u64tod, .CC: CallingConv::ARM_AAPCS_VFP}, |
123 | }; |
124 | |
125 | for (const auto &LC : LibraryCalls) { |
126 | Info.setLibcallImpl(Call: LC.Op, Impl: LC.Impl); |
127 | Info.setLibcallCallingConv(Call: LC.Op, CC: LC.CC); |
128 | } |
129 | } |
130 | |
131 | // Use divmod compiler-rt calls for iOS 5.0 and later. |
132 | if (TT.isOSBinFormatMachO() && (!TT.isiOS() || !TT.isOSVersionLT(Major: 5, Minor: 0))) { |
133 | Info.setLibcallImpl(Call: RTLIB::SDIVREM_I32, Impl: RTLIB::__divmodsi4); |
134 | Info.setLibcallImpl(Call: RTLIB::UDIVREM_I32, Impl: RTLIB::__udivmodsi4); |
135 | } |
136 | } |
137 | |
138 | static void setMSP430Libcalls(RuntimeLibcallsInfo &Info, const Triple &TT) { |
139 | // EABI Libcalls - EABI Section 6.2 |
140 | const struct { |
141 | const RTLIB::Libcall Op; |
142 | const RTLIB::LibcallImpl Impl; |
143 | } LibraryCalls[] = { |
144 | // Floating point conversions - EABI Table 6 |
145 | {.Op: RTLIB::FPROUND_F64_F32, .Impl: RTLIB::__mspabi_cvtdf}, |
146 | {.Op: RTLIB::FPEXT_F32_F64, .Impl: RTLIB::__mspabi_cvtfd}, |
147 | // The following is NOT implemented in libgcc |
148 | //{ RTLIB::FPTOSINT_F64_I16, RTLIB::__mspabi_fixdi }, |
149 | {.Op: RTLIB::FPTOSINT_F64_I32, .Impl: RTLIB::__mspabi_fixdli}, |
150 | {.Op: RTLIB::FPTOSINT_F64_I64, .Impl: RTLIB::__mspabi_fixdlli}, |
151 | // The following is NOT implemented in libgcc |
152 | //{ RTLIB::FPTOUINT_F64_I16, RTLIB::__mspabi_fixdu }, |
153 | {.Op: RTLIB::FPTOUINT_F64_I32, .Impl: RTLIB::__mspabi_fixdul}, |
154 | {.Op: RTLIB::FPTOUINT_F64_I64, .Impl: RTLIB::__mspabi_fixdull}, |
155 | // The following is NOT implemented in libgcc |
156 | //{ RTLIB::FPTOSINT_F32_I16, RTLIB::__mspabi_fixfi }, |
157 | {.Op: RTLIB::FPTOSINT_F32_I32, .Impl: RTLIB::__mspabi_fixfli}, |
158 | {.Op: RTLIB::FPTOSINT_F32_I64, .Impl: RTLIB::__mspabi_fixflli}, |
159 | // The following is NOT implemented in libgcc |
160 | //{ RTLIB::FPTOUINT_F32_I16, RTLIB::__mspabi_fixfu }, |
161 | {.Op: RTLIB::FPTOUINT_F32_I32, .Impl: RTLIB::__mspabi_fixful}, |
162 | {.Op: RTLIB::FPTOUINT_F32_I64, .Impl: RTLIB::__mspabi_fixfull}, |
163 | // TODO The following IS implemented in libgcc |
164 | //{ RTLIB::SINTTOFP_I16_F64, RTLIB::__mspabi_fltid }, |
165 | {.Op: RTLIB::SINTTOFP_I32_F64, .Impl: RTLIB::__mspabi_fltlid}, |
166 | // TODO The following IS implemented in libgcc but is not in the EABI |
167 | {.Op: RTLIB::SINTTOFP_I64_F64, .Impl: RTLIB::__mspabi_fltllid}, |
168 | // TODO The following IS implemented in libgcc |
169 | //{ RTLIB::UINTTOFP_I16_F64, RTLIB::__mspabi_fltud }, |
170 | {.Op: RTLIB::UINTTOFP_I32_F64, .Impl: RTLIB::__mspabi_fltuld}, |
171 | // The following IS implemented in libgcc but is not in the EABI |
172 | {.Op: RTLIB::UINTTOFP_I64_F64, .Impl: RTLIB::__mspabi_fltulld}, |
173 | // TODO The following IS implemented in libgcc |
174 | //{ RTLIB::SINTTOFP_I16_F32, RTLIB::__mspabi_fltif }, |
175 | {.Op: RTLIB::SINTTOFP_I32_F32, .Impl: RTLIB::__mspabi_fltlif}, |
176 | // TODO The following IS implemented in libgcc but is not in the EABI |
177 | {.Op: RTLIB::SINTTOFP_I64_F32, .Impl: RTLIB::__mspabi_fltllif}, |
178 | // TODO The following IS implemented in libgcc |
179 | //{ RTLIB::UINTTOFP_I16_F32, RTLIB::__mspabi_fltuf }, |
180 | {.Op: RTLIB::UINTTOFP_I32_F32, .Impl: RTLIB::__mspabi_fltulf}, |
181 | // The following IS implemented in libgcc but is not in the EABI |
182 | {.Op: RTLIB::UINTTOFP_I64_F32, .Impl: RTLIB::__mspabi_fltullf}, |
183 | |
184 | // Floating point comparisons - EABI Table 7 |
185 | {.Op: RTLIB::OEQ_F64, .Impl: RTLIB::__mspabi_cmpd__oeq}, |
186 | {.Op: RTLIB::UNE_F64, .Impl: RTLIB::__mspabi_cmpd__une}, |
187 | {.Op: RTLIB::OGE_F64, .Impl: RTLIB::__mspabi_cmpd__oge}, |
188 | {.Op: RTLIB::OLT_F64, .Impl: RTLIB::__mspabi_cmpd__olt}, |
189 | {.Op: RTLIB::OLE_F64, .Impl: RTLIB::__mspabi_cmpd__ole}, |
190 | {.Op: RTLIB::OGT_F64, .Impl: RTLIB::__mspabi_cmpd__ogt}, |
191 | {.Op: RTLIB::OEQ_F32, .Impl: RTLIB::__mspabi_cmpf__oeq}, |
192 | {.Op: RTLIB::UNE_F32, .Impl: RTLIB::__mspabi_cmpf__une}, |
193 | {.Op: RTLIB::OGE_F32, .Impl: RTLIB::__mspabi_cmpf__oge}, |
194 | {.Op: RTLIB::OLT_F32, .Impl: RTLIB::__mspabi_cmpf__olt}, |
195 | {.Op: RTLIB::OLE_F32, .Impl: RTLIB::__mspabi_cmpf__ole}, |
196 | {.Op: RTLIB::OGT_F32, .Impl: RTLIB::__mspabi_cmpf__ogt}, |
197 | |
198 | // Floating point arithmetic - EABI Table 8 |
199 | {.Op: RTLIB::ADD_F64, .Impl: RTLIB::__mspabi_addd}, |
200 | {.Op: RTLIB::ADD_F32, .Impl: RTLIB::__mspabi_addf}, |
201 | {.Op: RTLIB::DIV_F64, .Impl: RTLIB::__mspabi_divd}, |
202 | {.Op: RTLIB::DIV_F32, .Impl: RTLIB::__mspabi_divf}, |
203 | {.Op: RTLIB::MUL_F64, .Impl: RTLIB::__mspabi_mpyd}, |
204 | {.Op: RTLIB::MUL_F32, .Impl: RTLIB::__mspabi_mpyf}, |
205 | {.Op: RTLIB::SUB_F64, .Impl: RTLIB::__mspabi_subd}, |
206 | {.Op: RTLIB::SUB_F32, .Impl: RTLIB::__mspabi_subf}, |
207 | // The following are NOT implemented in libgcc |
208 | // { RTLIB::NEG_F64, RTLIB::__mspabi_negd }, |
209 | // { RTLIB::NEG_F32, RTLIB::__mspabi_negf }, |
210 | |
211 | // Universal Integer Operations - EABI Table 9 |
212 | {.Op: RTLIB::SDIV_I16, .Impl: RTLIB::__mspabi_divi}, |
213 | {.Op: RTLIB::SDIV_I32, .Impl: RTLIB::__mspabi_divli}, |
214 | {.Op: RTLIB::SDIV_I64, .Impl: RTLIB::__mspabi_divlli}, |
215 | {.Op: RTLIB::UDIV_I16, .Impl: RTLIB::__mspabi_divu}, |
216 | {.Op: RTLIB::UDIV_I32, .Impl: RTLIB::__mspabi_divul}, |
217 | {.Op: RTLIB::UDIV_I64, .Impl: RTLIB::__mspabi_divull}, |
218 | {.Op: RTLIB::SREM_I16, .Impl: RTLIB::__mspabi_remi}, |
219 | {.Op: RTLIB::SREM_I32, .Impl: RTLIB::__mspabi_remli}, |
220 | {.Op: RTLIB::SREM_I64, .Impl: RTLIB::__mspabi_remlli}, |
221 | {.Op: RTLIB::UREM_I16, .Impl: RTLIB::__mspabi_remu}, |
222 | {.Op: RTLIB::UREM_I32, .Impl: RTLIB::__mspabi_remul}, |
223 | {.Op: RTLIB::UREM_I64, .Impl: RTLIB::__mspabi_remull}, |
224 | |
225 | // Bitwise Operations - EABI Table 10 |
226 | // TODO: __mspabi_[srli/srai/slli] ARE implemented in libgcc |
227 | {.Op: RTLIB::SRL_I32, .Impl: RTLIB::__mspabi_srll}, |
228 | {.Op: RTLIB::SRA_I32, .Impl: RTLIB::__mspabi_sral}, |
229 | {.Op: RTLIB::SHL_I32, .Impl: RTLIB::__mspabi_slll}, |
230 | // __mspabi_[srlll/srall/sllll/rlli/rlll] are NOT implemented in libgcc |
231 | }; |
232 | |
233 | for (const auto &LC : LibraryCalls) |
234 | Info.setLibcallImpl(Call: LC.Op, Impl: LC.Impl); |
235 | |
236 | // Several of the runtime library functions use a special calling conv |
237 | Info.setLibcallCallingConv(Call: RTLIB::UDIV_I64, CC: CallingConv::MSP430_BUILTIN); |
238 | Info.setLibcallCallingConv(Call: RTLIB::UREM_I64, CC: CallingConv::MSP430_BUILTIN); |
239 | Info.setLibcallCallingConv(Call: RTLIB::SDIV_I64, CC: CallingConv::MSP430_BUILTIN); |
240 | Info.setLibcallCallingConv(Call: RTLIB::SREM_I64, CC: CallingConv::MSP430_BUILTIN); |
241 | Info.setLibcallCallingConv(Call: RTLIB::ADD_F64, CC: CallingConv::MSP430_BUILTIN); |
242 | Info.setLibcallCallingConv(Call: RTLIB::SUB_F64, CC: CallingConv::MSP430_BUILTIN); |
243 | Info.setLibcallCallingConv(Call: RTLIB::MUL_F64, CC: CallingConv::MSP430_BUILTIN); |
244 | Info.setLibcallCallingConv(Call: RTLIB::DIV_F64, CC: CallingConv::MSP430_BUILTIN); |
245 | Info.setLibcallCallingConv(Call: RTLIB::OEQ_F64, CC: CallingConv::MSP430_BUILTIN); |
246 | Info.setLibcallCallingConv(Call: RTLIB::UNE_F64, CC: CallingConv::MSP430_BUILTIN); |
247 | Info.setLibcallCallingConv(Call: RTLIB::OGE_F64, CC: CallingConv::MSP430_BUILTIN); |
248 | Info.setLibcallCallingConv(Call: RTLIB::OLT_F64, CC: CallingConv::MSP430_BUILTIN); |
249 | Info.setLibcallCallingConv(Call: RTLIB::OLE_F64, CC: CallingConv::MSP430_BUILTIN); |
250 | Info.setLibcallCallingConv(Call: RTLIB::OGT_F64, CC: CallingConv::MSP430_BUILTIN); |
251 | |
252 | // TODO: __mspabi_srall, __mspabi_srlll, __mspabi_sllll |
253 | } |
254 | |
255 | void RuntimeLibcallsInfo::initSoftFloatCmpLibcallPredicates() { |
256 | SoftFloatCompareLibcallPredicates[RTLIB::OEQ_F32] = CmpInst::ICMP_EQ; |
257 | SoftFloatCompareLibcallPredicates[RTLIB::OEQ_F64] = CmpInst::ICMP_EQ; |
258 | SoftFloatCompareLibcallPredicates[RTLIB::OEQ_F128] = CmpInst::ICMP_EQ; |
259 | SoftFloatCompareLibcallPredicates[RTLIB::OEQ_PPCF128] = CmpInst::ICMP_EQ; |
260 | SoftFloatCompareLibcallPredicates[RTLIB::UNE_F32] = CmpInst::ICMP_NE; |
261 | SoftFloatCompareLibcallPredicates[RTLIB::UNE_F64] = CmpInst::ICMP_NE; |
262 | SoftFloatCompareLibcallPredicates[RTLIB::UNE_F128] = CmpInst::ICMP_NE; |
263 | SoftFloatCompareLibcallPredicates[RTLIB::UNE_PPCF128] = CmpInst::ICMP_NE; |
264 | SoftFloatCompareLibcallPredicates[RTLIB::OGE_F32] = CmpInst::ICMP_SGE; |
265 | SoftFloatCompareLibcallPredicates[RTLIB::OGE_F64] = CmpInst::ICMP_SGE; |
266 | SoftFloatCompareLibcallPredicates[RTLIB::OGE_F128] = CmpInst::ICMP_SGE; |
267 | SoftFloatCompareLibcallPredicates[RTLIB::OGE_PPCF128] = CmpInst::ICMP_SGE; |
268 | SoftFloatCompareLibcallPredicates[RTLIB::OLT_F32] = CmpInst::ICMP_SLT; |
269 | SoftFloatCompareLibcallPredicates[RTLIB::OLT_F64] = CmpInst::ICMP_SLT; |
270 | SoftFloatCompareLibcallPredicates[RTLIB::OLT_F128] = CmpInst::ICMP_SLT; |
271 | SoftFloatCompareLibcallPredicates[RTLIB::OLT_PPCF128] = CmpInst::ICMP_SLT; |
272 | SoftFloatCompareLibcallPredicates[RTLIB::OLE_F32] = CmpInst::ICMP_SLE; |
273 | SoftFloatCompareLibcallPredicates[RTLIB::OLE_F64] = CmpInst::ICMP_SLE; |
274 | SoftFloatCompareLibcallPredicates[RTLIB::OLE_F128] = CmpInst::ICMP_SLE; |
275 | SoftFloatCompareLibcallPredicates[RTLIB::OLE_PPCF128] = CmpInst::ICMP_SLE; |
276 | SoftFloatCompareLibcallPredicates[RTLIB::OGT_F32] = CmpInst::ICMP_SGT; |
277 | SoftFloatCompareLibcallPredicates[RTLIB::OGT_F64] = CmpInst::ICMP_SGT; |
278 | SoftFloatCompareLibcallPredicates[RTLIB::OGT_F128] = CmpInst::ICMP_SGT; |
279 | SoftFloatCompareLibcallPredicates[RTLIB::OGT_PPCF128] = CmpInst::ICMP_SGT; |
280 | SoftFloatCompareLibcallPredicates[RTLIB::UO_F32] = CmpInst::ICMP_NE; |
281 | SoftFloatCompareLibcallPredicates[RTLIB::UO_F64] = CmpInst::ICMP_NE; |
282 | SoftFloatCompareLibcallPredicates[RTLIB::UO_F128] = CmpInst::ICMP_NE; |
283 | SoftFloatCompareLibcallPredicates[RTLIB::UO_PPCF128] = CmpInst::ICMP_NE; |
284 | } |
285 | |
286 | static void setLongDoubleIsF128Libm(RuntimeLibcallsInfo &Info, |
287 | bool FiniteOnlyFuncs = false) { |
288 | Info.setLibcallImpl(Call: RTLIB::REM_F128, Impl: RTLIB::fmodf128); |
289 | Info.setLibcallImpl(Call: RTLIB::FMA_F128, Impl: RTLIB::fmaf128); |
290 | Info.setLibcallImpl(Call: RTLIB::SQRT_F128, Impl: RTLIB::sqrtf128); |
291 | Info.setLibcallImpl(Call: RTLIB::CBRT_F128, Impl: RTLIB::cbrtf128); |
292 | Info.setLibcallImpl(Call: RTLIB::LOG_F128, Impl: RTLIB::logf128); |
293 | Info.setLibcallImpl(Call: RTLIB::LOG2_F128, Impl: RTLIB::log2f128); |
294 | Info.setLibcallImpl(Call: RTLIB::LOG10_F128, Impl: RTLIB::log10f128); |
295 | Info.setLibcallImpl(Call: RTLIB::EXP_F128, Impl: RTLIB::expf128); |
296 | Info.setLibcallImpl(Call: RTLIB::EXP2_F128, Impl: RTLIB::exp2f128); |
297 | Info.setLibcallImpl(Call: RTLIB::EXP10_F128, Impl: RTLIB::exp10f128); |
298 | Info.setLibcallImpl(Call: RTLIB::SIN_F128, Impl: RTLIB::sinf128); |
299 | Info.setLibcallImpl(Call: RTLIB::COS_F128, Impl: RTLIB::cosf128); |
300 | Info.setLibcallImpl(Call: RTLIB::TAN_F128, Impl: RTLIB::tanf128); |
301 | Info.setLibcallImpl(Call: RTLIB::SINCOS_F128, Impl: RTLIB::sincosf128); |
302 | Info.setLibcallImpl(Call: RTLIB::ASIN_F128, Impl: RTLIB::asinf128); |
303 | Info.setLibcallImpl(Call: RTLIB::ACOS_F128, Impl: RTLIB::acosf128); |
304 | Info.setLibcallImpl(Call: RTLIB::ATAN_F128, Impl: RTLIB::atanf128); |
305 | Info.setLibcallImpl(Call: RTLIB::ATAN2_F128, Impl: RTLIB::atan2f128); |
306 | Info.setLibcallImpl(Call: RTLIB::SINH_F128, Impl: RTLIB::sinhf128); |
307 | Info.setLibcallImpl(Call: RTLIB::COSH_F128, Impl: RTLIB::coshf128); |
308 | Info.setLibcallImpl(Call: RTLIB::TANH_F128, Impl: RTLIB::tanhf128); |
309 | Info.setLibcallImpl(Call: RTLIB::POW_F128, Impl: RTLIB::powf128); |
310 | Info.setLibcallImpl(Call: RTLIB::CEIL_F128, Impl: RTLIB::ceilf128); |
311 | Info.setLibcallImpl(Call: RTLIB::TRUNC_F128, Impl: RTLIB::truncf128); |
312 | Info.setLibcallImpl(Call: RTLIB::RINT_F128, Impl: RTLIB::rintf128); |
313 | Info.setLibcallImpl(Call: RTLIB::NEARBYINT_F128, Impl: RTLIB::nearbyintf128); |
314 | Info.setLibcallImpl(Call: RTLIB::ROUND_F128, Impl: RTLIB::roundf128); |
315 | Info.setLibcallImpl(Call: RTLIB::ROUNDEVEN_F128, Impl: RTLIB::roundevenf128); |
316 | Info.setLibcallImpl(Call: RTLIB::FLOOR_F128, Impl: RTLIB::floorf128); |
317 | Info.setLibcallImpl(Call: RTLIB::COPYSIGN_F128, Impl: RTLIB::copysignf128); |
318 | Info.setLibcallImpl(Call: RTLIB::FMIN_F128, Impl: RTLIB::fminf128); |
319 | Info.setLibcallImpl(Call: RTLIB::FMAX_F128, Impl: RTLIB::fmaxf128); |
320 | Info.setLibcallImpl(Call: RTLIB::FMINIMUM_F128, Impl: RTLIB::fminimumf128); |
321 | Info.setLibcallImpl(Call: RTLIB::FMAXIMUM_F128, Impl: RTLIB::fmaximumf128); |
322 | Info.setLibcallImpl(Call: RTLIB::FMINIMUM_NUM_F128, Impl: RTLIB::fminimum_numf128); |
323 | Info.setLibcallImpl(Call: RTLIB::FMAXIMUM_NUM_F128, Impl: RTLIB::fmaximum_numf128); |
324 | Info.setLibcallImpl(Call: RTLIB::LROUND_F128, Impl: RTLIB::lroundf128); |
325 | Info.setLibcallImpl(Call: RTLIB::LLROUND_F128, Impl: RTLIB::llroundf128); |
326 | Info.setLibcallImpl(Call: RTLIB::LRINT_F128, Impl: RTLIB::lrintf128); |
327 | Info.setLibcallImpl(Call: RTLIB::LLRINT_F128, Impl: RTLIB::llrintf128); |
328 | Info.setLibcallImpl(Call: RTLIB::LDEXP_F128, Impl: RTLIB::ldexpf128); |
329 | Info.setLibcallImpl(Call: RTLIB::FREXP_F128, Impl: RTLIB::frexpf128); |
330 | Info.setLibcallImpl(Call: RTLIB::MODF_F128, Impl: RTLIB::modff128); |
331 | |
332 | if (FiniteOnlyFuncs) { |
333 | Info.setLibcallImpl(Call: RTLIB::LOG_FINITE_F128, Impl: RTLIB::__logf128_finite); |
334 | Info.setLibcallImpl(Call: RTLIB::LOG2_FINITE_F128, Impl: RTLIB::__log2f128_finite); |
335 | Info.setLibcallImpl(Call: RTLIB::LOG10_FINITE_F128, Impl: RTLIB::__log10f128_finite); |
336 | Info.setLibcallImpl(Call: RTLIB::EXP_FINITE_F128, Impl: RTLIB::__expf128_finite); |
337 | Info.setLibcallImpl(Call: RTLIB::EXP2_FINITE_F128, Impl: RTLIB::__exp2f128_finite); |
338 | Info.setLibcallImpl(Call: RTLIB::POW_FINITE_F128, Impl: RTLIB::__powf128_finite); |
339 | } else { |
340 | Info.setLibcallImpl(Call: RTLIB::LOG_FINITE_F128, Impl: RTLIB::Unsupported); |
341 | Info.setLibcallImpl(Call: RTLIB::LOG2_FINITE_F128, Impl: RTLIB::Unsupported); |
342 | Info.setLibcallImpl(Call: RTLIB::LOG10_FINITE_F128, Impl: RTLIB::Unsupported); |
343 | Info.setLibcallImpl(Call: RTLIB::EXP_FINITE_F128, Impl: RTLIB::Unsupported); |
344 | Info.setLibcallImpl(Call: RTLIB::EXP2_FINITE_F128, Impl: RTLIB::Unsupported); |
345 | Info.setLibcallImpl(Call: RTLIB::POW_FINITE_F128, Impl: RTLIB::Unsupported); |
346 | } |
347 | } |
348 | |
349 | void RTLIB::RuntimeLibcallsInfo::initDefaultLibCallImpls() { |
350 | std::memcpy(dest: LibcallImpls, src: DefaultLibcallImpls, n: sizeof(LibcallImpls)); |
351 | static_assert(sizeof(LibcallImpls) == sizeof(DefaultLibcallImpls), |
352 | "libcall array size should match" ); |
353 | } |
354 | |
355 | /// Set default libcall names. If a target wants to opt-out of a libcall it |
356 | /// should be placed here. |
357 | void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, |
358 | ExceptionHandling ExceptionModel, |
359 | FloatABI::ABIType FloatABI, |
360 | EABI EABIVersion, StringRef ABIName) { |
361 | // Use the f128 variants of math functions on x86 |
362 | if (TT.isX86() && TT.isGNUEnvironment()) |
363 | setLongDoubleIsF128Libm(Info&: *this, /*FiniteOnlyFuncs=*/true); |
364 | |
365 | if (TT.isX86() || TT.isVE()) { |
366 | if (ExceptionModel == ExceptionHandling::SjLj) |
367 | setLibcallImpl(Call: RTLIB::UNWIND_RESUME, Impl: RTLIB::_Unwind_SjLj_Resume); |
368 | } |
369 | |
370 | if (TT.isPPC()) { |
371 | setPPCLibCallNameOverrides(); |
372 | |
373 | // TODO: Do the finite only functions exist? |
374 | setLongDoubleIsF128Libm(Info&: *this, /*FiniteOnlyFuncs=*/false); |
375 | |
376 | // TODO: Tablegen predicate support |
377 | if (TT.isOSAIX()) { |
378 | if (TT.isPPC64()) { |
379 | setLibcallImpl(Call: RTLIB::MEMCPY, Impl: RTLIB::Unsupported); |
380 | setLibcallImpl(Call: RTLIB::MEMMOVE, Impl: RTLIB::___memmove64); |
381 | setLibcallImpl(Call: RTLIB::MEMSET, Impl: RTLIB::___memset64); |
382 | setLibcallImpl(Call: RTLIB::BZERO, Impl: RTLIB::___bzero64); |
383 | } else { |
384 | setLibcallImpl(Call: RTLIB::MEMCPY, Impl: RTLIB::Unsupported); |
385 | setLibcallImpl(Call: RTLIB::MEMMOVE, Impl: RTLIB::___memmove); |
386 | setLibcallImpl(Call: RTLIB::MEMSET, Impl: RTLIB::___memset); |
387 | setLibcallImpl(Call: RTLIB::BZERO, Impl: RTLIB::___bzero); |
388 | } |
389 | } |
390 | } |
391 | |
392 | // A few names are different on particular architectures or environments. |
393 | if (TT.isOSDarwin()) { |
394 | // For f16/f32 conversions, Darwin uses the standard naming scheme, |
395 | // instead of the gnueabi-style __gnu_*_ieee. |
396 | // FIXME: What about other targets? |
397 | setLibcallImpl(Call: RTLIB::FPEXT_F16_F32, Impl: RTLIB::__extendhfsf2); |
398 | setLibcallImpl(Call: RTLIB::FPROUND_F32_F16, Impl: RTLIB::__truncsfhf2); |
399 | |
400 | // Some darwins have an optimized __bzero/bzero function. |
401 | if (TT.isX86()) { |
402 | if (TT.isMacOSX() && !TT.isMacOSXVersionLT(Major: 10, Minor: 6)) |
403 | setLibcallImpl(Call: RTLIB::BZERO, Impl: RTLIB::__bzero); |
404 | } else if (TT.isAArch64()) |
405 | setLibcallImpl(Call: RTLIB::BZERO, Impl: RTLIB::bzero); |
406 | |
407 | if (darwinHasSinCosStret(TT)) { |
408 | setLibcallImpl(Call: RTLIB::SINCOS_STRET_F32, Impl: RTLIB::__sincosf_stret); |
409 | setLibcallImpl(Call: RTLIB::SINCOS_STRET_F64, Impl: RTLIB::__sincos_stret); |
410 | if (TT.isWatchABI()) { |
411 | setLibcallCallingConv(Call: RTLIB::SINCOS_STRET_F32, |
412 | CC: CallingConv::ARM_AAPCS_VFP); |
413 | setLibcallCallingConv(Call: RTLIB::SINCOS_STRET_F64, |
414 | CC: CallingConv::ARM_AAPCS_VFP); |
415 | } |
416 | } |
417 | |
418 | if (darwinHasExp10(TT)) { |
419 | setLibcallImpl(Call: RTLIB::EXP10_F32, Impl: RTLIB::__exp10f); |
420 | setLibcallImpl(Call: RTLIB::EXP10_F64, Impl: RTLIB::__exp10); |
421 | } else { |
422 | setLibcallImpl(Call: RTLIB::EXP10_F32, Impl: RTLIB::Unsupported); |
423 | setLibcallImpl(Call: RTLIB::EXP10_F64, Impl: RTLIB::Unsupported); |
424 | } |
425 | } |
426 | |
427 | if (hasSinCos(TT)) { |
428 | setLibcallImpl(Call: RTLIB::SINCOS_F32, Impl: RTLIB::sincosf); |
429 | setLibcallImpl(Call: RTLIB::SINCOS_F64, Impl: RTLIB::sincos); |
430 | setLibcallImpl(Call: RTLIB::SINCOS_F80, Impl: RTLIB::sincos_f80); |
431 | setLibcallImpl(Call: RTLIB::SINCOS_F128, Impl: RTLIB::sincos_f128); |
432 | setLibcallImpl(Call: RTLIB::SINCOS_PPCF128, Impl: RTLIB::sincos_ppcf128); |
433 | } |
434 | |
435 | if (TT.isPS()) { |
436 | setLibcallImpl(Call: RTLIB::SINCOS_F32, Impl: RTLIB::sincosf); |
437 | setLibcallImpl(Call: RTLIB::SINCOS_F64, Impl: RTLIB::sincos); |
438 | } |
439 | |
440 | if (TT.isOSOpenBSD()) { |
441 | setLibcallImpl(Call: RTLIB::STACKPROTECTOR_CHECK_FAIL, Impl: RTLIB::Unsupported); |
442 | } |
443 | |
444 | if (TT.isOSWindows() && !TT.isOSCygMing()) { |
445 | setLibcallImpl(Call: RTLIB::LDEXP_F32, Impl: RTLIB::Unsupported); |
446 | setLibcallImpl(Call: RTLIB::LDEXP_F80, Impl: RTLIB::Unsupported); |
447 | setLibcallImpl(Call: RTLIB::LDEXP_F128, Impl: RTLIB::Unsupported); |
448 | setLibcallImpl(Call: RTLIB::LDEXP_PPCF128, Impl: RTLIB::Unsupported); |
449 | |
450 | setLibcallImpl(Call: RTLIB::FREXP_F32, Impl: RTLIB::Unsupported); |
451 | setLibcallImpl(Call: RTLIB::FREXP_F80, Impl: RTLIB::Unsupported); |
452 | setLibcallImpl(Call: RTLIB::FREXP_F128, Impl: RTLIB::Unsupported); |
453 | setLibcallImpl(Call: RTLIB::FREXP_PPCF128, Impl: RTLIB::Unsupported); |
454 | } |
455 | |
456 | // Disable most libcalls on AMDGPU and NVPTX. |
457 | if (TT.isAMDGPU() || TT.isNVPTX()) { |
458 | for (RTLIB::Libcall LC : RTLIB::libcalls()) { |
459 | if (!isAtomicLibCall(LC)) |
460 | setLibcallImpl(Call: LC, Impl: RTLIB::Unsupported); |
461 | } |
462 | } |
463 | |
464 | if (TT.isOSMSVCRT()) { |
465 | // MSVCRT doesn't have powi; fall back to pow |
466 | setLibcallImpl(Call: RTLIB::POWI_F32, Impl: RTLIB::Unsupported); |
467 | setLibcallImpl(Call: RTLIB::POWI_F64, Impl: RTLIB::Unsupported); |
468 | } |
469 | |
470 | // Setup Windows compiler runtime calls. |
471 | if (TT.getArch() == Triple::x86 && |
472 | (TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment())) { |
473 | static const struct { |
474 | const RTLIB::Libcall Op; |
475 | const RTLIB::LibcallImpl Impl; |
476 | const CallingConv::ID CC; |
477 | } LibraryCalls[] = { |
478 | {.Op: RTLIB::SDIV_I64, .Impl: RTLIB::_alldiv, .CC: CallingConv::X86_StdCall}, |
479 | {.Op: RTLIB::UDIV_I64, .Impl: RTLIB::_aulldiv, .CC: CallingConv::X86_StdCall}, |
480 | {.Op: RTLIB::SREM_I64, .Impl: RTLIB::_allrem, .CC: CallingConv::X86_StdCall}, |
481 | {.Op: RTLIB::UREM_I64, .Impl: RTLIB::_aullrem, .CC: CallingConv::X86_StdCall}, |
482 | {.Op: RTLIB::MUL_I64, .Impl: RTLIB::_allmul, .CC: CallingConv::X86_StdCall}, |
483 | }; |
484 | |
485 | for (const auto &LC : LibraryCalls) { |
486 | setLibcallImpl(Call: LC.Op, Impl: LC.Impl); |
487 | setLibcallCallingConv(Call: LC.Op, CC: LC.CC); |
488 | } |
489 | } |
490 | |
491 | if (TT.isAArch64()) { |
492 | if (TT.isWindowsArm64EC()) { |
493 | setWindowsArm64LibCallNameOverrides(); |
494 | setLibcallImpl(Call: RTLIB::SC_MEMCPY, Impl: RTLIB::arm64ec___arm_sc_memcpy); |
495 | setLibcallImpl(Call: RTLIB::SC_MEMMOVE, Impl: RTLIB::arm64ec___arm_sc_memmove); |
496 | setLibcallImpl(Call: RTLIB::SC_MEMSET, Impl: RTLIB::arm64ec___arm_sc_memset); |
497 | } else { |
498 | setLibcallImpl(Call: RTLIB::SC_MEMCPY, Impl: RTLIB::__arm_sc_memcpy); |
499 | setLibcallImpl(Call: RTLIB::SC_MEMMOVE, Impl: RTLIB::__arm_sc_memmove); |
500 | setLibcallImpl(Call: RTLIB::SC_MEMSET, Impl: RTLIB::__arm_sc_memset); |
501 | } |
502 | |
503 | setAArch64LibcallNames(Info&: *this, TT); |
504 | } else if (TT.isARM() || TT.isThumb()) { |
505 | setARMLibcallNames(Info&: *this, TT, FloatABIType: FloatABI, EABIVersion); |
506 | } else if (TT.getArch() == Triple::ArchType::avr) { |
507 | // Division rtlib functions (not supported), use divmod functions instead |
508 | setLibcallImpl(Call: RTLIB::SDIV_I8, Impl: RTLIB::Unsupported); |
509 | setLibcallImpl(Call: RTLIB::SDIV_I16, Impl: RTLIB::Unsupported); |
510 | setLibcallImpl(Call: RTLIB::SDIV_I32, Impl: RTLIB::Unsupported); |
511 | setLibcallImpl(Call: RTLIB::UDIV_I8, Impl: RTLIB::Unsupported); |
512 | setLibcallImpl(Call: RTLIB::UDIV_I16, Impl: RTLIB::Unsupported); |
513 | setLibcallImpl(Call: RTLIB::UDIV_I32, Impl: RTLIB::Unsupported); |
514 | |
515 | // Modulus rtlib functions (not supported), use divmod functions instead |
516 | setLibcallImpl(Call: RTLIB::SREM_I8, Impl: RTLIB::Unsupported); |
517 | setLibcallImpl(Call: RTLIB::SREM_I16, Impl: RTLIB::Unsupported); |
518 | setLibcallImpl(Call: RTLIB::SREM_I32, Impl: RTLIB::Unsupported); |
519 | setLibcallImpl(Call: RTLIB::UREM_I8, Impl: RTLIB::Unsupported); |
520 | setLibcallImpl(Call: RTLIB::UREM_I16, Impl: RTLIB::Unsupported); |
521 | setLibcallImpl(Call: RTLIB::UREM_I32, Impl: RTLIB::Unsupported); |
522 | |
523 | // Division and modulus rtlib functions |
524 | setLibcallImpl(Call: RTLIB::SDIVREM_I8, Impl: RTLIB::__divmodqi4); |
525 | setLibcallImpl(Call: RTLIB::SDIVREM_I16, Impl: RTLIB::__divmodhi4); |
526 | setLibcallImpl(Call: RTLIB::SDIVREM_I32, Impl: RTLIB::__divmodsi4); |
527 | setLibcallImpl(Call: RTLIB::UDIVREM_I8, Impl: RTLIB::__udivmodqi4); |
528 | setLibcallImpl(Call: RTLIB::UDIVREM_I16, Impl: RTLIB::__udivmodhi4); |
529 | setLibcallImpl(Call: RTLIB::UDIVREM_I32, Impl: RTLIB::__udivmodsi4); |
530 | |
531 | // Several of the runtime library functions use a special calling conv |
532 | setLibcallCallingConv(Call: RTLIB::SDIVREM_I8, CC: CallingConv::AVR_BUILTIN); |
533 | setLibcallCallingConv(Call: RTLIB::SDIVREM_I16, CC: CallingConv::AVR_BUILTIN); |
534 | setLibcallCallingConv(Call: RTLIB::UDIVREM_I8, CC: CallingConv::AVR_BUILTIN); |
535 | setLibcallCallingConv(Call: RTLIB::UDIVREM_I16, CC: CallingConv::AVR_BUILTIN); |
536 | |
537 | // Trigonometric rtlib functions |
538 | setLibcallImpl(Call: RTLIB::SIN_F32, Impl: RTLIB::avr_sin); |
539 | setLibcallImpl(Call: RTLIB::COS_F32, Impl: RTLIB::avr_cos); |
540 | } |
541 | |
542 | if (!TT.isWasm()) { |
543 | // These libcalls are only available in compiler-rt, not libgcc. |
544 | if (TT.isArch32Bit()) { |
545 | setLibcallImpl(Call: RTLIB::SHL_I128, Impl: RTLIB::Unsupported); |
546 | setLibcallImpl(Call: RTLIB::SRL_I128, Impl: RTLIB::Unsupported); |
547 | setLibcallImpl(Call: RTLIB::SRA_I128, Impl: RTLIB::Unsupported); |
548 | setLibcallImpl(Call: RTLIB::MUL_I128, Impl: RTLIB::Unsupported); |
549 | setLibcallImpl(Call: RTLIB::MULO_I64, Impl: RTLIB::Unsupported); |
550 | } |
551 | |
552 | setLibcallImpl(Call: RTLIB::MULO_I128, Impl: RTLIB::Unsupported); |
553 | } else { |
554 | // Define the emscripten name for return address helper. |
555 | // TODO: when implementing other Wasm backends, make this generic or only do |
556 | // this on emscripten depending on what they end up doing. |
557 | setLibcallImpl(Call: RTLIB::RETURN_ADDRESS, Impl: RTLIB::emscripten_return_address); |
558 | } |
559 | |
560 | if (TT.getArch() == Triple::ArchType::hexagon) { |
561 | setLibcallImpl(Call: RTLIB::SDIV_I32, Impl: RTLIB::__hexagon_divsi3); |
562 | setLibcallImpl(Call: RTLIB::SDIV_I64, Impl: RTLIB::__hexagon_divdi3); |
563 | setLibcallImpl(Call: RTLIB::UDIV_I32, Impl: RTLIB::__hexagon_udivsi3); |
564 | setLibcallImpl(Call: RTLIB::UDIV_I64, Impl: RTLIB::__hexagon_udivdi3); |
565 | setLibcallImpl(Call: RTLIB::SREM_I32, Impl: RTLIB::__hexagon_modsi3); |
566 | setLibcallImpl(Call: RTLIB::SREM_I64, Impl: RTLIB::__hexagon_moddi3); |
567 | setLibcallImpl(Call: RTLIB::UREM_I32, Impl: RTLIB::__hexagon_umodsi3); |
568 | setLibcallImpl(Call: RTLIB::UREM_I64, Impl: RTLIB::__hexagon_umoddi3); |
569 | |
570 | const bool FastMath = HexagonEnableFastMathRuntimeCalls; |
571 | // This is the only fast library function for sqrtd. |
572 | if (FastMath) |
573 | setLibcallImpl(Call: RTLIB::SQRT_F64, Impl: RTLIB::__hexagon_fast2_sqrtdf2); |
574 | |
575 | // Prefix is: nothing for "slow-math", |
576 | // "fast2_" for V5+ fast-math double-precision |
577 | // (actually, keep fast-math and fast-math2 separate for now) |
578 | if (FastMath) { |
579 | setLibcallImpl(Call: RTLIB::ADD_F64, Impl: RTLIB::__hexagon_fast_adddf3); |
580 | setLibcallImpl(Call: RTLIB::SUB_F64, Impl: RTLIB::__hexagon_fast_subdf3); |
581 | setLibcallImpl(Call: RTLIB::MUL_F64, Impl: RTLIB::__hexagon_fast_muldf3); |
582 | setLibcallImpl(Call: RTLIB::DIV_F64, Impl: RTLIB::__hexagon_fast_divdf3); |
583 | setLibcallImpl(Call: RTLIB::DIV_F32, Impl: RTLIB::__hexagon_fast_divsf3); |
584 | } else { |
585 | setLibcallImpl(Call: RTLIB::ADD_F64, Impl: RTLIB::__hexagon_adddf3); |
586 | setLibcallImpl(Call: RTLIB::SUB_F64, Impl: RTLIB::__hexagon_subdf3); |
587 | setLibcallImpl(Call: RTLIB::MUL_F64, Impl: RTLIB::__hexagon_muldf3); |
588 | setLibcallImpl(Call: RTLIB::DIV_F64, Impl: RTLIB::__hexagon_divdf3); |
589 | setLibcallImpl(Call: RTLIB::DIV_F32, Impl: RTLIB::__hexagon_divsf3); |
590 | } |
591 | |
592 | if (FastMath) |
593 | setLibcallImpl(Call: RTLIB::SQRT_F32, Impl: RTLIB::__hexagon_fast2_sqrtf); |
594 | else |
595 | setLibcallImpl(Call: RTLIB::SQRT_F32, Impl: RTLIB::__hexagon_sqrtf); |
596 | |
597 | setLibcallImpl( |
598 | Call: RTLIB::HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES, |
599 | Impl: RTLIB::__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes); |
600 | } |
601 | |
602 | if (TT.getArch() == Triple::ArchType::msp430) |
603 | setMSP430Libcalls(Info&: *this, TT); |
604 | |
605 | if (TT.isSystemZ() && TT.isOSzOS()) |
606 | setZOSLibCallNameOverrides(); |
607 | |
608 | if (TT.getArch() == Triple::ArchType::xcore) |
609 | setLibcallImpl(Call: RTLIB::MEMCPY_ALIGN_4, Impl: RTLIB::__memcpy_4); |
610 | } |
611 | |
612 | bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) { |
613 | assert(TT.isOSDarwin() && "should be called with darwin triple" ); |
614 | |
615 | switch (TT.getOS()) { |
616 | case Triple::MacOSX: |
617 | return !TT.isMacOSXVersionLT(Major: 10, Minor: 9); |
618 | case Triple::IOS: |
619 | return !TT.isOSVersionLT(Major: 7, Minor: 0); |
620 | case Triple::DriverKit: |
621 | case Triple::TvOS: |
622 | case Triple::WatchOS: |
623 | case Triple::XROS: |
624 | case Triple::BridgeOS: |
625 | return true; |
626 | default: |
627 | return false; |
628 | } |
629 | } |
630 | |