diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td index 736b439748c12..04de19e257c9b 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.td +++ b/llvm/include/llvm/IR/RuntimeLibcalls.td @@ -1280,6 +1280,9 @@ def AMDGPUSystemLibrary : SystemRuntimeLibrary; // ARM Runtime Libcalls //===----------------------------------------------------------------------===// +def isTargetAEABIAndAAPCS_ABI : RuntimeLibcallPredicate< + [{TT.isTargetAEABI() && isAAPCS_ABI(TT, ABIName)}]>; + // if (isTargetMachO()) { // if (Subtarget->isThumb() && Subtarget->hasVFP2Base() && // Subtarget->hasARMOps() && !Subtarget->useSoftFloat()) { @@ -1473,7 +1476,6 @@ def __udivmodsi4 : RuntimeLibcallImpl; // a __gnu_ prefix (which is the default). // isTargetAEABI() def __aeabi_f2h : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS -//def __aeabi_d2h : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS def __aeabi_h2f : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS // !isTargetMachO() @@ -1481,6 +1483,28 @@ def __gnu_f2h_ieee : RuntimeLibcallImpl; def __gnu_h2f_ieee : RuntimeLibcallImpl; +// The half <-> float conversion functions are always soft-float on +// non-watchos platforms, but are needed for some targets which use a +// hard-float calling convention by default. +def ARMHalfConvertLibcallCallingConv : LibcallCallingConv< + [{TT.isWatchABI() ? DefaultCC : + (isAAPCS_ABI(TT, ABIName) ? CallingConv::ARM_AAPCS : CallingConv::ARM_APCS)}] +>; + +def GNUEABIHalfConvertCalls : + LibcallImpls<(add __gnu_f2h_ieee, __gnu_h2f_ieee), + RuntimeLibcallPredicate<[{!TT.isOSBinFormatMachO() && + !TT.isTargetAEABI()}]>> { + let CallingConv = ARMHalfConvertLibcallCallingConv; +} + +// In EABI, these functions have an __aeabi_ prefix, but in GNUEABI +// they have a __gnu_ prefix (which is the default). +def EABIHalfConvertCalls : LibcallImpls<(add __aeabi_f2h, __aeabi_h2f), + isTargetAEABIAndAAPCS_ABI> { + let CallingConv = ARM_AAPCS; +} + def WindowARMDivRemCalls : LibcallImpls< (add __rt_sdiv, __rt_sdiv64, __rt_udiv, __rt_udiv64), isOSWindows> { @@ -1553,8 +1577,8 @@ def AEABICalls : LibcallImpls< // RTABI chapter 4.1.2, Table 7 __aeabi_d2f, __aeabi_f2d, - __aeabi_h2f, - __aeabi_f2h, + //__aeabi_h2f added separately + //__aeabi_f2h added separately __aeabi_d2h, // Integer to floating-point conversions. @@ -1614,6 +1638,8 @@ def ARMSystemLibrary AEABICalls, AEABI45MemCalls, + EABIHalfConvertCalls, + GNUEABIHalfConvertCalls, // Use divmod compiler-rt calls for iOS 5.0 and later. LibcallImpls<(add __divmodsi4, __udivmodsi4), diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index ff54d2da4ea2f..ac845c4998783 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -42,16 +42,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, setLibcallImplCallingConv(RTLIB::__truncsfhf2, CallingConv::ARM_AAPCS); setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_AAPCS); setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_AAPCS); - setLibcallImplCallingConv(RTLIB::__gnu_h2f_ieee, - CallingConv::ARM_AAPCS); - setLibcallImplCallingConv(RTLIB::__gnu_f2h_ieee, - CallingConv::ARM_AAPCS); } else { setLibcallImplCallingConv(RTLIB::__truncsfhf2, CallingConv::ARM_APCS); setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_APCS); setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_APCS); - setLibcallImplCallingConv(RTLIB::__gnu_h2f_ieee, CallingConv::ARM_APCS); - setLibcallImplCallingConv(RTLIB::__gnu_f2h_ieee, CallingConv::ARM_APCS); } } diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index bd246943f63fc..8ea567cfb9d31 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -587,28 +587,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, } } - // In EABI, these functions have an __aeabi_ prefix, but in GNUEABI they have - // a __gnu_ prefix (which is the default). - if (TT.isTargetAEABI()) { - // FIXME: This does not depend on the subtarget and should go directly into - // RuntimeLibcalls. This is only here because of missing support for setting - // the calling convention of an implementation. - static const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - {RTLIB::FPROUND_F32_F16, RTLIB::__aeabi_f2h}, - {RTLIB::FPEXT_F16_F32, RTLIB::__aeabi_h2f}, - }; - - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - } - } else if (!TT.isOSBinFormatMachO()) { - setLibcallImpl(RTLIB::FPROUND_F32_F16, RTLIB::__gnu_f2h_ieee); - setLibcallImpl(RTLIB::FPEXT_F16_F32, RTLIB::__gnu_h2f_ieee); - } - if (Subtarget->isThumb1Only()) addRegisterClass(MVT::i32, &ARM::tGPRRegClass); else