@@ -129,6 +129,76 @@ const RegisterBankInfo *ARMSubtarget::getRegBankInfo() const {
129129 return RegBankInfo.get ();
130130}
131131
132+ void ARMSubtarget::initLibcallLoweringInfo (LibcallLoweringInfo &Info) const {
133+ const Triple &TT = getTargetTriple ();
134+ if (TT.isOSBinFormatMachO ()) {
135+ // Uses VFP for Thumb libfuncs if available.
136+ if (isThumb () && hasVFP2Base () && hasARMOps () && !useSoftFloat ()) {
137+ // clang-format off
138+ static const struct {
139+ const RTLIB::Libcall Op;
140+ const RTLIB::LibcallImpl Impl;
141+ } LibraryCalls[] = {
142+ // Single-precision floating-point arithmetic.
143+ { RTLIB::ADD_F32, RTLIB::impl___addsf3vfp },
144+ { RTLIB::SUB_F32, RTLIB::impl___subsf3vfp },
145+ { RTLIB::MUL_F32, RTLIB::impl___mulsf3vfp },
146+ { RTLIB::DIV_F32, RTLIB::impl___divsf3vfp },
147+
148+ // Double-precision floating-point arithmetic.
149+ { RTLIB::ADD_F64, RTLIB::impl___adddf3vfp },
150+ { RTLIB::SUB_F64, RTLIB::impl___subdf3vfp },
151+ { RTLIB::MUL_F64, RTLIB::impl___muldf3vfp },
152+ { RTLIB::DIV_F64, RTLIB::impl___divdf3vfp },
153+
154+ // Single-precision comparisons.
155+ { RTLIB::OEQ_F32, RTLIB::impl___eqsf2vfp },
156+ { RTLIB::UNE_F32, RTLIB::impl___nesf2vfp },
157+ { RTLIB::OLT_F32, RTLIB::impl___ltsf2vfp },
158+ { RTLIB::OLE_F32, RTLIB::impl___lesf2vfp },
159+ { RTLIB::OGE_F32, RTLIB::impl___gesf2vfp },
160+ { RTLIB::OGT_F32, RTLIB::impl___gtsf2vfp },
161+ { RTLIB::UO_F32, RTLIB::impl___unordsf2vfp },
162+
163+ // Double-precision comparisons.
164+ { RTLIB::OEQ_F64, RTLIB::impl___eqdf2vfp },
165+ { RTLIB::UNE_F64, RTLIB::impl___nedf2vfp },
166+ { RTLIB::OLT_F64, RTLIB::impl___ltdf2vfp },
167+ { RTLIB::OLE_F64, RTLIB::impl___ledf2vfp },
168+ { RTLIB::OGE_F64, RTLIB::impl___gedf2vfp },
169+ { RTLIB::OGT_F64, RTLIB::impl___gtdf2vfp },
170+ { RTLIB::UO_F64, RTLIB::impl___unorddf2vfp },
171+
172+ // Floating-point to integer conversions.
173+ // i64 conversions are done via library routines even when generating VFP
174+ // instructions, so use the same ones.
175+ { RTLIB::FPTOSINT_F64_I32, RTLIB::impl___fixdfsivfp },
176+ { RTLIB::FPTOUINT_F64_I32, RTLIB::impl___fixunsdfsivfp },
177+ { RTLIB::FPTOSINT_F32_I32, RTLIB::impl___fixsfsivfp },
178+ { RTLIB::FPTOUINT_F32_I32, RTLIB::impl___fixunssfsivfp },
179+
180+ // Conversions between floating types.
181+ { RTLIB::FPROUND_F64_F32, RTLIB::impl___truncdfsf2vfp },
182+ { RTLIB::FPEXT_F32_F64, RTLIB::impl___extendsfdf2vfp },
183+
184+ // Integer to floating-point conversions.
185+ // i64 conversions are done via library routines even when generating VFP
186+ // instructions, so use the same ones.
187+ // FIXME: There appears to be some naming inconsistency in ARM libgcc:
188+ // e.g., __floatunsidf vs. __floatunssidfvfp.
189+ { RTLIB::SINTTOFP_I32_F64, RTLIB::impl___floatsidfvfp },
190+ { RTLIB::UINTTOFP_I32_F64, RTLIB::impl___floatunssidfvfp },
191+ { RTLIB::SINTTOFP_I32_F32, RTLIB::impl___floatsisfvfp },
192+ { RTLIB::UINTTOFP_I32_F32, RTLIB::impl___floatunssisfvfp },
193+ };
194+ // clang-format on
195+
196+ for (const auto &LC : LibraryCalls)
197+ Info.setLibcallImpl (LC.Op , LC.Impl );
198+ }
199+ }
200+ }
201+
132202bool ARMSubtarget::isXRaySupported () const {
133203 // We don't currently suppport Thumb, but Windows requires Thumb.
134204 return hasV6Ops () && hasARMOps () && !isTargetWindows ();
0 commit comments