diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h index f39e2e3c26900..2d1d07c5fd81b 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.h +++ b/llvm/include/llvm/IR/RuntimeLibcalls.h @@ -182,6 +182,14 @@ struct RuntimeLibcallsInfo { return true; } + static bool hasAEABILibcalls(const Triple &TT) { + return TT.isTargetAEABI() || TT.isTargetGNUAEABI() || + TT.isTargetMuslAEABI() || TT.isAndroid(); + } + + LLVM_READONLY + static bool isAAPCS_ABI(const Triple &TT, StringRef ABIName); + static bool darwinHasExp10(const Triple &TT); /// Return true if the target has sincosf/sincos/sincosl functions @@ -195,8 +203,8 @@ struct RuntimeLibcallsInfo { } /// Generated by tablegen. - void setTargetRuntimeLibcallSets(const Triple &TT, - FloatABI::ABIType FloatABI); + void setTargetRuntimeLibcallSets(const Triple &TT, FloatABI::ABIType FloatABI, + EABI ABIType, StringRef ABIName); /// Set default libcall names. If a target wants to opt-out of a libcall it /// should be placed here. diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td index df472d4b9cfee..6940859dea629 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.td +++ b/llvm/include/llvm/IR/RuntimeLibcalls.td @@ -1498,8 +1498,99 @@ def WindowARMFPIntCasts : LibcallImpls< def AEABIDivRemCalls : LibcallImpls< (add __aeabi_idivmod, __aeabi_ldivmod, __aeabi_uidivmod, __aeabi_uldivmod), - RuntimeLibcallPredicate<[{TT.isTargetAEABI() || TT.isAndroid() || TT.isTargetGNUAEABI() || - TT.isTargetMuslAEABI()}]>> { + RuntimeLibcallPredicate<[{hasAEABILibcalls(TT)}]>> { + let CallingConv = ARM_AAPCS; +} + +def AEABICalls : LibcallImpls< + (add + // Double-precision floating-point arithmetic helper functions + // RTABI chapter 4.1.2, Table 2 + __aeabi_dadd, + __aeabi_ddiv, + __aeabi_dmul, + __aeabi_dsub, + + // Double-precision floating-point comparison helper functions + // RTABI chapter 4.1.2, Table 3 + __aeabi_dcmpeq__oeq, + __aeabi_dcmpeq__une, + __aeabi_dcmplt, + __aeabi_dcmple, + __aeabi_dcmpge, + __aeabi_dcmpgt, + __aeabi_dcmpun, + + // Single-precision floating-point arithmetic helper functions + // RTABI chapter 4.1.2, Table 4 + __aeabi_fadd, + __aeabi_fdiv, + __aeabi_fmul, + __aeabi_fsub, + + // Single-precision floating-point comparison helper functions + // RTABI chapter 4.1.2, Table 5 + __aeabi_fcmpeq__oeq, + __aeabi_fcmpeq__une, + __aeabi_fcmplt, + __aeabi_fcmple, + __aeabi_fcmpge, + __aeabi_fcmpgt, + __aeabi_fcmpun, + + // Floating-point to integer conversions. + // RTABI chapter 4.1.2, Table 6 + __aeabi_d2iz, + __aeabi_d2uiz, + __aeabi_d2lz, + __aeabi_d2ulz, + __aeabi_f2iz, + __aeabi_f2uiz, + __aeabi_f2lz, + __aeabi_f2ulz, + + // Conversions between floating types. + // RTABI chapter 4.1.2, Table 7 + __aeabi_d2f, + __aeabi_d2h, + __aeabi_f2d, + + // Integer to floating-point conversions. + // RTABI chapter 4.1.2, Table 8 + __aeabi_i2d, + __aeabi_ui2d, + __aeabi_l2d, + __aeabi_ul2d, + __aeabi_i2f, + __aeabi_ui2f, + __aeabi_l2f, + __aeabi_ul2f, + + // Long long helper functions + // RTABI chapter 4.2, Table 9 + __aeabi_lmul, + __aeabi_llsl, + __aeabi_llsr, + __aeabi_lasr, + + // Integer division functions + // RTABI chapter 4.3.1 + __aeabi_idiv, + __aeabi_uidiv), + RuntimeLibcallPredicate<[{hasAEABILibcalls(TT) && isAAPCS_ABI(TT, ABIName)}]>> { + let CallingConv = ARM_AAPCS; +} + +// EABI dependent RTLIB, Memory operations +// RTABI chapter 4.3.4 +def AEABI45MemCalls : LibcallImpls< + (add __aeabi_memcpy, __aeabi_memcpy4, __aeabi_memcpy8, + __aeabi_memmove, __aeabi_memmove4, __aeabi_memmove8, + __aeabi_memset, __aeabi_memset4, __aeabi_memset8, + __aeabi_memclr, __aeabi_memclr4, __aeabi_memclr8), + RuntimeLibcallPredicate<[{(EABIVersion == EABI::EABI4 || + EABIVersion == EABI::EABI5) && + hasAEABILibcalls(TT) && isAAPCS_ABI(TT, ABIName)}]>> { let CallingConv = ARM_AAPCS; } @@ -1519,6 +1610,9 @@ def ARMSystemLibrary LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128, DefaultLibmExp10, + AEABICalls, + AEABI45MemCalls, + // Use divmod compiler-rt calls for iOS 5.0 and later. LibcallImpls<(add __divmodsi4, __udivmodsi4), RuntimeLibcallPredicate<[{TT.isOSBinFormatMachO() && diff --git a/llvm/include/llvm/TargetParser/ARMTargetParser.h b/llvm/include/llvm/TargetParser/ARMTargetParser.h index 90eae9ef78da6..919598c894cd5 100644 --- a/llvm/include/llvm/TargetParser/ARMTargetParser.h +++ b/llvm/include/llvm/TargetParser/ARMTargetParser.h @@ -270,9 +270,9 @@ LLVM_ABI ProfileKind parseArchProfile(StringRef Arch); LLVM_ABI unsigned parseArchVersion(StringRef Arch); LLVM_ABI void fillValidCPUArchList(SmallVectorImpl &Values); -LLVM_ABI StringRef computeDefaultTargetABI(const Triple &TT); - -LLVM_ABI ARMABI computeTargetABI(const Triple &TT, StringRef ABIName = ""); +LLVM_ABI LLVM_READONLY StringRef computeDefaultTargetABI(const Triple &TT); +LLVM_ABI LLVM_READONLY ARMABI computeTargetABI(const Triple &TT, + StringRef ABIName = ""); /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting. /// diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index d794c49e56c34..f0bd2f17501c7 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -55,44 +55,6 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, CallingConv::ARM_APCS); } } - - static const RTLIB::LibcallImpl AAPCS_Libcalls[] = { - RTLIB::__aeabi_dadd, RTLIB::__aeabi_ddiv, - RTLIB::__aeabi_dmul, RTLIB::__aeabi_dsub, - RTLIB::__aeabi_dcmpeq__oeq, RTLIB::__aeabi_dcmpeq__une, - RTLIB::__aeabi_dcmplt, RTLIB::__aeabi_dcmple, - RTLIB::__aeabi_dcmpge, RTLIB::__aeabi_dcmpgt, - RTLIB::__aeabi_dcmpun, RTLIB::__aeabi_fadd, - RTLIB::__aeabi_fdiv, RTLIB::__aeabi_fmul, - RTLIB::__aeabi_fsub, RTLIB::__aeabi_fcmpeq__oeq, - RTLIB::__aeabi_fcmpeq__une, RTLIB::__aeabi_fcmplt, - RTLIB::__aeabi_fcmple, RTLIB::__aeabi_fcmpge, - RTLIB::__aeabi_fcmpgt, RTLIB::__aeabi_fcmpun, - RTLIB::__aeabi_d2iz, RTLIB::__aeabi_d2uiz, - RTLIB::__aeabi_d2lz, RTLIB::__aeabi_d2ulz, - RTLIB::__aeabi_f2iz, RTLIB::__aeabi_f2uiz, - RTLIB::__aeabi_f2lz, RTLIB::__aeabi_f2ulz, - RTLIB::__aeabi_d2f, RTLIB::__aeabi_d2h, - RTLIB::__aeabi_f2d, RTLIB::__aeabi_i2d, - RTLIB::__aeabi_ui2d, RTLIB::__aeabi_l2d, - RTLIB::__aeabi_ul2d, RTLIB::__aeabi_i2f, - RTLIB::__aeabi_ui2f, RTLIB::__aeabi_l2f, - RTLIB::__aeabi_ul2f, RTLIB::__aeabi_lmul, - RTLIB::__aeabi_llsl, RTLIB::__aeabi_llsr, - RTLIB::__aeabi_lasr, RTLIB::__aeabi_idiv, - RTLIB::__aeabi_idivmod, RTLIB::__aeabi_uidivmod, - RTLIB::__aeabi_ldivmod, RTLIB::__aeabi_uidiv, - RTLIB::__aeabi_uldivmod, RTLIB::__aeabi_f2h, - RTLIB::__aeabi_d2h, RTLIB::__aeabi_h2f, - RTLIB::__aeabi_memcpy, RTLIB::__aeabi_memmove, - RTLIB::__aeabi_memset, RTLIB::__aeabi_memcpy4, - RTLIB::__aeabi_memcpy8, RTLIB::__aeabi_memmove4, - RTLIB::__aeabi_memmove8, RTLIB::__aeabi_memset4, - RTLIB::__aeabi_memset8, RTLIB::__aeabi_memclr, - RTLIB::__aeabi_memclr4, RTLIB::__aeabi_memclr8}; - - for (RTLIB::LibcallImpl Impl : AAPCS_Libcalls) - Info.setLibcallImplCallingConv(Impl, CallingConv::ARM_AAPCS); } /// Set default libcall names. If a target wants to opt-out of a libcall it @@ -101,7 +63,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName) { - setTargetRuntimeLibcallSets(TT, FloatABI); + setTargetRuntimeLibcallSets(TT, FloatABI, EABIVersion, ABIName); if (ExceptionModel == ExceptionHandling::SjLj) setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume); @@ -162,6 +124,11 @@ RuntimeLibcallsInfo::getRecognizedLibcallImpls(StringRef FuncName) { return make_range(EntriesBegin, EntriesEnd); } +bool RuntimeLibcallsInfo::isAAPCS_ABI(const Triple &TT, StringRef ABIName) { + const ARM::ARMABI TargetABI = ARM::computeTargetABI(TT, ABIName); + return TargetABI == ARM::ARM_ABI_AAPCS || TargetABI == ARM::ARM_ABI_AAPCS16; +} + bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) { switch (TT.getOS()) { case Triple::MacOSX: diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 178d200406e2e..441223190ec3d 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -587,126 +587,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, } } - // RTLIB - if (TM.isAAPCS_ABI() && (TT.isTargetAEABI() || TT.isTargetGNUAEABI() || - TT.isTargetMuslAEABI() || TT.isAndroid())) { - // 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. - // clang-format off - static const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Double-precision floating-point arithmetic helper functions - // RTABI chapter 4.1.2, Table 2 - { RTLIB::ADD_F64, RTLIB::__aeabi_dadd }, - { RTLIB::DIV_F64, RTLIB::__aeabi_ddiv }, - { RTLIB::MUL_F64, RTLIB::__aeabi_dmul }, - { RTLIB::SUB_F64, RTLIB::__aeabi_dsub }, - - // Double-precision floating-point comparison helper functions - // RTABI chapter 4.1.2, Table 3 - { RTLIB::OEQ_F64, RTLIB::__aeabi_dcmpeq__oeq }, - { RTLIB::UNE_F64, RTLIB::__aeabi_dcmpeq__une }, - { RTLIB::OLT_F64, RTLIB::__aeabi_dcmplt }, - { RTLIB::OLE_F64, RTLIB::__aeabi_dcmple }, - { RTLIB::OGE_F64, RTLIB::__aeabi_dcmpge }, - { RTLIB::OGT_F64, RTLIB::__aeabi_dcmpgt }, - { RTLIB::UO_F64, RTLIB::__aeabi_dcmpun }, - - // Single-precision floating-point arithmetic helper functions - // RTABI chapter 4.1.2, Table 4 - { RTLIB::ADD_F32, RTLIB::__aeabi_fadd }, - { RTLIB::DIV_F32, RTLIB::__aeabi_fdiv }, - { RTLIB::MUL_F32, RTLIB::__aeabi_fmul }, - { RTLIB::SUB_F32, RTLIB::__aeabi_fsub }, - - // Single-precision floating-point comparison helper functions - // RTABI chapter 4.1.2, Table 5 - { RTLIB::OEQ_F32, RTLIB::__aeabi_fcmpeq__oeq }, - { RTLIB::UNE_F32, RTLIB::__aeabi_fcmpeq__une }, - { RTLIB::OLT_F32, RTLIB::__aeabi_fcmplt}, - { RTLIB::OLE_F32, RTLIB::__aeabi_fcmple }, - { RTLIB::OGE_F32, RTLIB::__aeabi_fcmpge }, - { RTLIB::OGT_F32, RTLIB::__aeabi_fcmpgt }, - { RTLIB::UO_F32, RTLIB::__aeabi_fcmpun }, - - // Floating-point to integer conversions. - // RTABI chapter 4.1.2, Table 6 - { RTLIB::FPTOSINT_F64_I32, RTLIB::__aeabi_d2iz }, - { RTLIB::FPTOUINT_F64_I32, RTLIB::__aeabi_d2uiz }, - { RTLIB::FPTOSINT_F64_I64, RTLIB::__aeabi_d2lz }, - { RTLIB::FPTOUINT_F64_I64, RTLIB::__aeabi_d2ulz }, - { RTLIB::FPTOSINT_F32_I32, RTLIB::__aeabi_f2iz }, - { RTLIB::FPTOUINT_F32_I32, RTLIB::__aeabi_f2uiz }, - { RTLIB::FPTOSINT_F32_I64, RTLIB::__aeabi_f2lz }, - { RTLIB::FPTOUINT_F32_I64, RTLIB::__aeabi_f2ulz }, - - // Conversions between floating types. - // RTABI chapter 4.1.2, Table 7 - { RTLIB::FPROUND_F64_F32, RTLIB::__aeabi_d2f }, - { RTLIB::FPROUND_F64_F16, RTLIB::__aeabi_d2h }, - { RTLIB::FPEXT_F32_F64, RTLIB::__aeabi_f2d }, - - // Integer to floating-point conversions. - // RTABI chapter 4.1.2, Table 8 - { RTLIB::SINTTOFP_I32_F64, RTLIB::__aeabi_i2d }, - { RTLIB::UINTTOFP_I32_F64, RTLIB::__aeabi_ui2d }, - { RTLIB::SINTTOFP_I64_F64, RTLIB::__aeabi_l2d }, - { RTLIB::UINTTOFP_I64_F64, RTLIB::__aeabi_ul2d }, - { RTLIB::SINTTOFP_I32_F32, RTLIB::__aeabi_i2f }, - { RTLIB::UINTTOFP_I32_F32, RTLIB::__aeabi_ui2f }, - { RTLIB::SINTTOFP_I64_F32, RTLIB::__aeabi_l2f }, - { RTLIB::UINTTOFP_I64_F32, RTLIB::__aeabi_ul2f }, - - // Long long helper functions - // RTABI chapter 4.2, Table 9 - { RTLIB::MUL_I64, RTLIB::__aeabi_lmul }, - { RTLIB::SHL_I64, RTLIB::__aeabi_llsl }, - { RTLIB::SRL_I64, RTLIB::__aeabi_llsr }, - { RTLIB::SRA_I64, RTLIB::__aeabi_lasr }, - - // Integer division functions - // RTABI chapter 4.3.1 - { RTLIB::SDIV_I32, RTLIB::__aeabi_idiv }, - { RTLIB::SDIV_I64, RTLIB::__aeabi_ldivmod }, - { RTLIB::UDIV_I32, RTLIB::__aeabi_uidiv }, - { RTLIB::UDIV_I64, RTLIB::__aeabi_uldivmod }, - }; - // clang-format on - - for (const auto &LC : LibraryCalls) - setLibcallImpl(LC.Op, LC.Impl); - - // EABI dependent RTLIB - if (TM.Options.EABIVersion == EABI::EABI4 || - TM.Options.EABIVersion == EABI::EABI5) { - static const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } MemOpsLibraryCalls[] = { - // Memory operations - // RTABI chapter 4.3.4 - {RTLIB::MEMCPY, RTLIB::__aeabi_memcpy}, - {RTLIB::MEMMOVE, RTLIB::__aeabi_memmove}, - {RTLIB::MEMSET, RTLIB::__aeabi_memset}, - {RTLIB::AEABI_MEMCPY4, RTLIB::__aeabi_memcpy4}, - {RTLIB::AEABI_MEMCPY8, RTLIB::__aeabi_memcpy8}, - {RTLIB::AEABI_MEMMOVE4, RTLIB::__aeabi_memmove4}, - {RTLIB::AEABI_MEMMOVE8, RTLIB::__aeabi_memmove8}, - {RTLIB::AEABI_MEMSET4, RTLIB::__aeabi_memset4}, - {RTLIB::AEABI_MEMSET8, RTLIB::__aeabi_memset8}, - {RTLIB::AEABI_MEMCLR, RTLIB::__aeabi_memclr}, - {RTLIB::AEABI_MEMCLR4, RTLIB::__aeabi_memclr4}, - {RTLIB::AEABI_MEMCLR8, RTLIB::__aeabi_memclr8}, - }; - - for (const auto &LC : MemOpsLibraryCalls) - setLibcallImpl(LC.Op, LC.Impl); - } - } - // In EABI, these functions have an __aeabi_ prefix, but in GNUEABI they have // a __gnu_ prefix (which is the default). if (TT.isTargetAEABI()) { diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td index 49d5ecaa0e5c5..c49abd2cd6b83 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td @@ -41,7 +41,7 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary; -// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(const llvm::Triple &TT, FloatABI::ABIType FloatABI) { +// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(const llvm::Triple &TT, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName) { // CHECK: if (TT.getArch() == Triple::avr && TT.isOSHurd()) { // CHECK-NEXT: const CallingConv::ID DefaultCC = isFoo() ? CallingConv::Fast : CallingConv::GHC; // CHECK-NEXT: for (CallingConv::ID &Entry : LibcallImplCallingConvs) { diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter.td b/llvm/test/TableGen/RuntimeLibcallEmitter.td index 642f8b85a89c6..34dc7a1aa56db 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter.td @@ -150,7 +150,7 @@ def BlahLibrary : SystemRuntimeLibrary