diff --git a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h index e88079e796e7d..8624fd2403a12 100644 --- a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h +++ b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h @@ -13,6 +13,8 @@ namespace llvm { +class TargetSubtargetInfo; + class LibcallLoweringInfo { private: const RTLIB::RuntimeLibcallsInfo &RTLCI; @@ -21,7 +23,12 @@ class LibcallLoweringInfo { RTLIB::Unsupported}; public: - LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI); + LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI, + const TargetSubtargetInfo &Subtarget); + + const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const { + return RTLCI; + } /// Get the libcall routine name for the specified libcall. // FIXME: This should be removed. Only LibcallImpl should have a name. diff --git a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h index a1a130aa27798..6f95f0fea6441 100644 --- a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h +++ b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h @@ -38,6 +38,7 @@ class InstrItineraryData; struct InstrStage; class InstructionSelector; class LegalizerInfo; +class LibcallLoweringInfo; class MachineInstr; struct MachineSchedPolicy; struct MCReadAdvanceEntry; @@ -139,6 +140,12 @@ class LLVM_ABI TargetSubtargetInfo : public MCSubtargetInfo { return nullptr; } + /// Configure the LibcallLoweringInfo for this subtarget. The libcalls will be + /// pre-configured with defaults based on RuntimeLibcallsInfo. This may be + /// used to override those decisions, such as disambiguating alternative + /// implementations. + virtual void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const {} + /// Resolve a SchedClass at runtime, where SchedClass identifies an /// MCSchedClassDesc with the isVariant property. This may return the ID of /// another variant SchedClass, but repeated invocation must quickly terminate diff --git a/llvm/lib/CodeGen/LibcallLoweringInfo.cpp b/llvm/lib/CodeGen/LibcallLoweringInfo.cpp index 5c1698cb6060e..6f3607e8db824 100644 --- a/llvm/lib/CodeGen/LibcallLoweringInfo.cpp +++ b/llvm/lib/CodeGen/LibcallLoweringInfo.cpp @@ -7,11 +7,13 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/LibcallLoweringInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" using namespace llvm; LibcallLoweringInfo::LibcallLoweringInfo( - const RTLIB::RuntimeLibcallsInfo &RTLCI) + const RTLIB::RuntimeLibcallsInfo &RTLCI, + const TargetSubtargetInfo &Subtarget) : RTLCI(RTLCI) { // TODO: This should be generated with lowering predicates, and assert the // call is available. @@ -23,4 +25,6 @@ LibcallLoweringInfo::LibcallLoweringInfo( LibcallImpls[LC] = Impl; } } + + Subtarget.initLibcallLoweringInfo(*this); } diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 3a3b5298b1a2e..1d674b283db15 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -755,7 +755,7 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm, RuntimeLibcallInfo(TM.getTargetTriple(), TM.Options.ExceptionModel, TM.Options.FloatABIType, TM.Options.EABIVersion, TM.Options.MCOptions.getABIName(), TM.Options.VecLib), - Libcalls(RuntimeLibcallInfo) { + Libcalls(RuntimeLibcallInfo, STI) { initActions(); // Perform these initializations only once. diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 2ad8f877ff11b..32f3e5fa3c842 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -518,74 +518,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, const Triple &TT = TM.getTargetTriple(); - if (TT.isOSBinFormatMachO()) { - // Uses VFP for Thumb libfuncs if available. - if (Subtarget->isThumb() && Subtarget->hasVFP2Base() && - Subtarget->hasARMOps() && !Subtarget->useSoftFloat()) { - // clang-format off - static const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Single-precision floating-point arithmetic. - { RTLIB::ADD_F32, RTLIB::impl___addsf3vfp }, - { RTLIB::SUB_F32, RTLIB::impl___subsf3vfp }, - { RTLIB::MUL_F32, RTLIB::impl___mulsf3vfp }, - { RTLIB::DIV_F32, RTLIB::impl___divsf3vfp }, - - // Double-precision floating-point arithmetic. - { RTLIB::ADD_F64, RTLIB::impl___adddf3vfp }, - { RTLIB::SUB_F64, RTLIB::impl___subdf3vfp }, - { RTLIB::MUL_F64, RTLIB::impl___muldf3vfp }, - { RTLIB::DIV_F64, RTLIB::impl___divdf3vfp }, - - // Single-precision comparisons. - { RTLIB::OEQ_F32, RTLIB::impl___eqsf2vfp }, - { RTLIB::UNE_F32, RTLIB::impl___nesf2vfp }, - { RTLIB::OLT_F32, RTLIB::impl___ltsf2vfp }, - { RTLIB::OLE_F32, RTLIB::impl___lesf2vfp }, - { RTLIB::OGE_F32, RTLIB::impl___gesf2vfp }, - { RTLIB::OGT_F32, RTLIB::impl___gtsf2vfp }, - { RTLIB::UO_F32, RTLIB::impl___unordsf2vfp }, - - // Double-precision comparisons. - { RTLIB::OEQ_F64, RTLIB::impl___eqdf2vfp }, - { RTLIB::UNE_F64, RTLIB::impl___nedf2vfp }, - { RTLIB::OLT_F64, RTLIB::impl___ltdf2vfp }, - { RTLIB::OLE_F64, RTLIB::impl___ledf2vfp }, - { RTLIB::OGE_F64, RTLIB::impl___gedf2vfp }, - { RTLIB::OGT_F64, RTLIB::impl___gtdf2vfp }, - { RTLIB::UO_F64, RTLIB::impl___unorddf2vfp }, - - // Floating-point to integer conversions. - // i64 conversions are done via library routines even when generating VFP - // instructions, so use the same ones. - { RTLIB::FPTOSINT_F64_I32, RTLIB::impl___fixdfsivfp }, - { RTLIB::FPTOUINT_F64_I32, RTLIB::impl___fixunsdfsivfp }, - { RTLIB::FPTOSINT_F32_I32, RTLIB::impl___fixsfsivfp }, - { RTLIB::FPTOUINT_F32_I32, RTLIB::impl___fixunssfsivfp }, - - // Conversions between floating types. - { RTLIB::FPROUND_F64_F32, RTLIB::impl___truncdfsf2vfp }, - { RTLIB::FPEXT_F32_F64, RTLIB::impl___extendsfdf2vfp }, - - // Integer to floating-point conversions. - // i64 conversions are done via library routines even when generating VFP - // instructions, so use the same ones. - // FIXME: There appears to be some naming inconsistency in ARM libgcc: - // e.g., __floatunsidf vs. __floatunssidfvfp. - { RTLIB::SINTTOFP_I32_F64, RTLIB::impl___floatsidfvfp }, - { RTLIB::UINTTOFP_I32_F64, RTLIB::impl___floatunssidfvfp }, - { RTLIB::SINTTOFP_I32_F32, RTLIB::impl___floatsisfvfp }, - { RTLIB::UINTTOFP_I32_F32, RTLIB::impl___floatunssisfvfp }, - }; - // clang-format on - - for (const auto &LC : LibraryCalls) - setLibcallImpl(LC.Op, LC.Impl); - } - } - if (Subtarget->isThumb1Only()) addRegisterClass(MVT::i32, &ARM::tGPRRegClass); else diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp index 7ec232ae9bac5..cad0cb6a441a0 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.cpp +++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp @@ -129,6 +129,76 @@ const RegisterBankInfo *ARMSubtarget::getRegBankInfo() const { return RegBankInfo.get(); } +void ARMSubtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const { + const Triple &TT = getTargetTriple(); + if (TT.isOSBinFormatMachO()) { + // Uses VFP for Thumb libfuncs if available. + if (isThumb() && hasVFP2Base() && hasARMOps() && !useSoftFloat()) { + // clang-format off + static const struct { + const RTLIB::Libcall Op; + const RTLIB::LibcallImpl Impl; + } LibraryCalls[] = { + // Single-precision floating-point arithmetic. + { RTLIB::ADD_F32, RTLIB::impl___addsf3vfp }, + { RTLIB::SUB_F32, RTLIB::impl___subsf3vfp }, + { RTLIB::MUL_F32, RTLIB::impl___mulsf3vfp }, + { RTLIB::DIV_F32, RTLIB::impl___divsf3vfp }, + + // Double-precision floating-point arithmetic. + { RTLIB::ADD_F64, RTLIB::impl___adddf3vfp }, + { RTLIB::SUB_F64, RTLIB::impl___subdf3vfp }, + { RTLIB::MUL_F64, RTLIB::impl___muldf3vfp }, + { RTLIB::DIV_F64, RTLIB::impl___divdf3vfp }, + + // Single-precision comparisons. + { RTLIB::OEQ_F32, RTLIB::impl___eqsf2vfp }, + { RTLIB::UNE_F32, RTLIB::impl___nesf2vfp }, + { RTLIB::OLT_F32, RTLIB::impl___ltsf2vfp }, + { RTLIB::OLE_F32, RTLIB::impl___lesf2vfp }, + { RTLIB::OGE_F32, RTLIB::impl___gesf2vfp }, + { RTLIB::OGT_F32, RTLIB::impl___gtsf2vfp }, + { RTLIB::UO_F32, RTLIB::impl___unordsf2vfp }, + + // Double-precision comparisons. + { RTLIB::OEQ_F64, RTLIB::impl___eqdf2vfp }, + { RTLIB::UNE_F64, RTLIB::impl___nedf2vfp }, + { RTLIB::OLT_F64, RTLIB::impl___ltdf2vfp }, + { RTLIB::OLE_F64, RTLIB::impl___ledf2vfp }, + { RTLIB::OGE_F64, RTLIB::impl___gedf2vfp }, + { RTLIB::OGT_F64, RTLIB::impl___gtdf2vfp }, + { RTLIB::UO_F64, RTLIB::impl___unorddf2vfp }, + + // Floating-point to integer conversions. + // i64 conversions are done via library routines even when generating VFP + // instructions, so use the same ones. + { RTLIB::FPTOSINT_F64_I32, RTLIB::impl___fixdfsivfp }, + { RTLIB::FPTOUINT_F64_I32, RTLIB::impl___fixunsdfsivfp }, + { RTLIB::FPTOSINT_F32_I32, RTLIB::impl___fixsfsivfp }, + { RTLIB::FPTOUINT_F32_I32, RTLIB::impl___fixunssfsivfp }, + + // Conversions between floating types. + { RTLIB::FPROUND_F64_F32, RTLIB::impl___truncdfsf2vfp }, + { RTLIB::FPEXT_F32_F64, RTLIB::impl___extendsfdf2vfp }, + + // Integer to floating-point conversions. + // i64 conversions are done via library routines even when generating VFP + // instructions, so use the same ones. + // FIXME: There appears to be some naming inconsistency in ARM libgcc: + // e.g., __floatunsidf vs. __floatunssidfvfp. + { RTLIB::SINTTOFP_I32_F64, RTLIB::impl___floatsidfvfp }, + { RTLIB::UINTTOFP_I32_F64, RTLIB::impl___floatunssidfvfp }, + { RTLIB::SINTTOFP_I32_F32, RTLIB::impl___floatsisfvfp }, + { RTLIB::UINTTOFP_I32_F32, RTLIB::impl___floatunssisfvfp }, + }; + // clang-format on + + for (const auto &LC : LibraryCalls) + Info.setLibcallImpl(LC.Op, LC.Impl); + } + } +} + bool ARMSubtarget::isXRaySupported() const { // We don't currently suppport Thumb, but Windows requires Thumb. return hasV6Ops() && hasARMOps() && !isTargetWindows(); diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index 4a0883cc662e7..2a90f4223cbce 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -258,6 +258,7 @@ class ARMSubtarget : public ARMGenSubtargetInfo { InstructionSelector *getInstructionSelector() const override; const LegalizerInfo *getLegalizerInfo() const override; const RegisterBankInfo *getRegBankInfo() const override; + void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override; private: ARMSelectionDAGInfo TSInfo; diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp index 89f38c847b1eb..e118169377fe2 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -148,68 +148,6 @@ MSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM, setOperationAction(ISD::VACOPY, MVT::Other, Expand); setOperationAction(ISD::JumpTable, MVT::i16, Custom); - if (STI.hasHWMult16()) { - const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw}, - {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw}, - {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw}, - // TODO The __mspabi_mpysl*_hw functions ARE implemented in libgcc - // TODO The __mspabi_mpyul*_hw functions ARE implemented in libgcc - }; - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - } - } else if (STI.hasHWMult32()) { - const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw}, - {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw32}, - {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw32}, - // TODO The __mspabi_mpysl*_hw32 functions ARE implemented in libgcc - // TODO The __mspabi_mpyul*_hw32 functions ARE implemented in libgcc - }; - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - } - } else if (STI.hasHWMultF5()) { - const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_f5hw}, - {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_f5hw}, - {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_f5hw}, - // TODO The __mspabi_mpysl*_f5hw functions ARE implemented in libgcc - // TODO The __mspabi_mpyul*_f5hw functions ARE implemented in libgcc - }; - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - } - } else { // NoHWMult - const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi}, - {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl}, - {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll}, - // The __mspabi_mpysl* functions are NOT implemented in libgcc - // The __mspabi_mpyul* functions are NOT implemented in libgcc - }; - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - } - } - setMinFunctionAlignment(Align(2)); setPrefFunctionAlignment(Align(2)); setMaxAtomicSizeInBitsSupported(0); diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp index 89fc4b21cfb88..386f2a0fa8f47 100644 --- a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp +++ b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp @@ -68,3 +68,67 @@ MSP430Subtarget::~MSP430Subtarget() = default; const SelectionDAGTargetInfo *MSP430Subtarget::getSelectionDAGInfo() const { return TSInfo.get(); } + +void MSP430Subtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const { + if (hasHWMult16()) { + const struct { + const RTLIB::Libcall Op; + const RTLIB::LibcallImpl Impl; + } LibraryCalls[] = { + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw}, + {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw}, + {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw}, + // TODO The __mspabi_mpysl*_hw functions ARE implemented in libgcc + // TODO The __mspabi_mpyul*_hw functions ARE implemented in libgcc + }; + for (const auto &LC : LibraryCalls) { + Info.setLibcallImpl(LC.Op, LC.Impl); + } + } else if (hasHWMult32()) { + const struct { + const RTLIB::Libcall Op; + const RTLIB::LibcallImpl Impl; + } LibraryCalls[] = { + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw}, + {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw32}, + {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw32}, + // TODO The __mspabi_mpysl*_hw32 functions ARE implemented in libgcc + // TODO The __mspabi_mpyul*_hw32 functions ARE implemented in libgcc + }; + for (const auto &LC : LibraryCalls) { + Info.setLibcallImpl(LC.Op, LC.Impl); + } + } else if (hasHWMultF5()) { + const struct { + const RTLIB::Libcall Op; + const RTLIB::LibcallImpl Impl; + } LibraryCalls[] = { + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_f5hw}, + {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_f5hw}, + {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_f5hw}, + // TODO The __mspabi_mpysl*_f5hw functions ARE implemented in libgcc + // TODO The __mspabi_mpyul*_f5hw functions ARE implemented in libgcc + }; + for (const auto &LC : LibraryCalls) { + Info.setLibcallImpl(LC.Op, LC.Impl); + } + } else { // NoHWMult + const struct { + const RTLIB::Libcall Op; + const RTLIB::LibcallImpl Impl; + } LibraryCalls[] = { + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi}, + {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl}, + {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll}, + // The __mspabi_mpysl* functions are NOT implemented in libgcc + // The __mspabi_mpyul* functions are NOT implemented in libgcc + }; + for (const auto &LC : LibraryCalls) { + Info.setLibcallImpl(LC.Op, LC.Impl); + } + } +} diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.h b/llvm/lib/Target/MSP430/MSP430Subtarget.h index f7a9896ac8edc..4cb5c9b7467e5 100644 --- a/llvm/lib/Target/MSP430/MSP430Subtarget.h +++ b/llvm/lib/Target/MSP430/MSP430Subtarget.h @@ -74,6 +74,8 @@ class MSP430Subtarget : public MSP430GenSubtargetInfo { } const SelectionDAGTargetInfo *getSelectionDAGInfo() const override; + + void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override; }; } // End llvm namespace diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp index 51049c83dec52..ac32426288e08 100644 --- a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp +++ b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp @@ -44,26 +44,6 @@ struct Mips16IntrinsicHelperType{ }; } // namespace -// Libcalls for which no helper is generated. Sorted by name for binary search. -static const RTLIB::LibcallImpl HardFloatLibCalls[] = { - RTLIB::impl___mips16_adddf3, RTLIB::impl___mips16_addsf3, - RTLIB::impl___mips16_divdf3, RTLIB::impl___mips16_divsf3, - RTLIB::impl___mips16_eqdf2, RTLIB::impl___mips16_eqsf2, - RTLIB::impl___mips16_extendsfdf2, RTLIB::impl___mips16_fix_truncdfsi, - RTLIB::impl___mips16_fix_truncsfsi, RTLIB::impl___mips16_floatsidf, - RTLIB::impl___mips16_floatsisf, RTLIB::impl___mips16_floatunsidf, - RTLIB::impl___mips16_floatunsisf, RTLIB::impl___mips16_gedf2, - RTLIB::impl___mips16_gesf2, RTLIB::impl___mips16_gtdf2, - RTLIB::impl___mips16_gtsf2, RTLIB::impl___mips16_ledf2, - RTLIB::impl___mips16_lesf2, RTLIB::impl___mips16_ltdf2, - RTLIB::impl___mips16_ltsf2, RTLIB::impl___mips16_muldf3, - RTLIB::impl___mips16_mulsf3, RTLIB::impl___mips16_nedf2, - RTLIB::impl___mips16_nesf2, RTLIB::impl___mips16_ret_dc, - RTLIB::impl___mips16_ret_df, RTLIB::impl___mips16_ret_sc, - RTLIB::impl___mips16_ret_sf, RTLIB::impl___mips16_subdf3, - RTLIB::impl___mips16_subsf3, RTLIB::impl___mips16_truncdfsf2, - RTLIB::impl___mips16_unorddf2, RTLIB::impl___mips16_unordsf2}; - static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = { {"__fixunsdfsi", "__mips16_call_stub_2" }, {"ceil", "__mips16_call_stub_df_2"}, @@ -97,9 +77,6 @@ Mips16TargetLowering::Mips16TargetLowering(const MipsTargetMachine &TM, // Set up the register classes addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass); - if (!Subtarget.useSoftFloat()) - setMips16HardFloatLibCalls(); - setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, LibCall); setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, LibCall); setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, LibCall); @@ -218,16 +195,6 @@ bool Mips16TargetLowering::isEligibleForTailCallOptimization( return false; } -void Mips16TargetLowering::setMips16HardFloatLibCalls() { - for (unsigned I = 0; I != std::size(HardFloatLibCalls); ++I) { - assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) && - "Array not sorted!"); - RTLIB::Libcall LC = - RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(HardFloatLibCalls[I]); - setLibcallImpl(LC, HardFloatLibCalls[I]); - } -} - // // The Mips16 hard float is a crazy quilt inherited from gcc. I have a much // cleaner way to do all of this but it will have to wait until the traditional @@ -384,7 +351,8 @@ static bool isMips16HardFloatLibcall(StringRef Name) { iota_range ParsedLibcalls = RTLIB::RuntimeLibcallsInfo::lookupLibcallImplName(Name); return !ParsedLibcalls.empty() && - binary_search(HardFloatLibCalls, *ParsedLibcalls.begin()); + binary_search(MipsSubtarget::HardFloatLibCalls, + *ParsedLibcalls.begin()); } void Mips16TargetLowering:: diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.h b/llvm/lib/Target/Mips/Mips16ISelLowering.h index f120cbbd24f91..8f9f01b46b5a8 100644 --- a/llvm/lib/Target/Mips/Mips16ISelLowering.h +++ b/llvm/lib/Target/Mips/Mips16ISelLowering.h @@ -35,8 +35,6 @@ namespace llvm { const CCState &CCInfo, unsigned NextStackOffset, const MipsFunctionInfo &FI) const override; - void setMips16HardFloatLibCalls(); - unsigned int getMips16HelperFunctionStubNumber(ArgListTy &Args) const; diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp index 8c4bb15a7e617..b22647a851c2b 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.cpp +++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp @@ -305,3 +305,35 @@ const RegisterBankInfo *MipsSubtarget::getRegBankInfo() const { InstructionSelector *MipsSubtarget::getInstructionSelector() const { return InstSelector.get(); } + +// Libcalls for which no helper is generated. Sorted by name for binary search. +const RTLIB::LibcallImpl MipsSubtarget::HardFloatLibCalls[34] = { + RTLIB::impl___mips16_adddf3, RTLIB::impl___mips16_addsf3, + RTLIB::impl___mips16_divdf3, RTLIB::impl___mips16_divsf3, + RTLIB::impl___mips16_eqdf2, RTLIB::impl___mips16_eqsf2, + RTLIB::impl___mips16_extendsfdf2, RTLIB::impl___mips16_fix_truncdfsi, + RTLIB::impl___mips16_fix_truncsfsi, RTLIB::impl___mips16_floatsidf, + RTLIB::impl___mips16_floatsisf, RTLIB::impl___mips16_floatunsidf, + RTLIB::impl___mips16_floatunsisf, RTLIB::impl___mips16_gedf2, + RTLIB::impl___mips16_gesf2, RTLIB::impl___mips16_gtdf2, + RTLIB::impl___mips16_gtsf2, RTLIB::impl___mips16_ledf2, + RTLIB::impl___mips16_lesf2, RTLIB::impl___mips16_ltdf2, + RTLIB::impl___mips16_ltsf2, RTLIB::impl___mips16_muldf3, + RTLIB::impl___mips16_mulsf3, RTLIB::impl___mips16_nedf2, + RTLIB::impl___mips16_nesf2, RTLIB::impl___mips16_ret_dc, + RTLIB::impl___mips16_ret_df, RTLIB::impl___mips16_ret_sc, + RTLIB::impl___mips16_ret_sf, RTLIB::impl___mips16_subdf3, + RTLIB::impl___mips16_subsf3, RTLIB::impl___mips16_truncdfsf2, + RTLIB::impl___mips16_unorddf2, RTLIB::impl___mips16_unordsf2}; + +void MipsSubtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const { + if (inMips16Mode() && !useSoftFloat()) { + for (unsigned I = 0; I != std::size(HardFloatLibCalls); ++I) { + assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) && + "Array not sorted!"); + RTLIB::Libcall LC = + RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(HardFloatLibCalls[I]); + Info.setLibcallImpl(LC, HardFloatLibCalls[I]); + } + } +} diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h index 52f892a160c38..0fbd425df1695 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.h +++ b/llvm/lib/Target/Mips/MipsSubtarget.h @@ -247,6 +247,8 @@ class MipsSubtarget : public MipsGenSubtargetInfo { /// subtarget options. Definition of function is auto generated by tblgen. void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); + static const RTLIB::LibcallImpl HardFloatLibCalls[34]; + bool hasMips1() const { return MipsArchVersion >= Mips1; } bool hasMips2() const { return MipsArchVersion >= Mips2; } bool hasMips3() const { return MipsArchVersion >= Mips3; } @@ -400,6 +402,8 @@ class MipsSubtarget : public MipsGenSubtargetInfo { return &InstrItins; } + void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override; + protected: // GlobalISel related APIs. std::unique_ptr CallLoweringInfo; diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index dc1196127e3d4..a4a9eafd52ffe 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -1905,42 +1905,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::FP_EXTEND, MVT::f128, Custom); setOperationAction(ISD::FP_ROUND, MVT::f64, Custom); - setOperationAction(ISD::FP_ROUND, MVT::f32, Custom); - - // Setup Runtime library names. - if (Subtarget->is64Bit() && !Subtarget->useSoftFloat()) { - setLibcallImpl(RTLIB::ADD_F128, RTLIB::impl__Qp_add); - setLibcallImpl(RTLIB::SUB_F128, RTLIB::impl__Qp_sub); - setLibcallImpl(RTLIB::MUL_F128, RTLIB::impl__Qp_mul); - setLibcallImpl(RTLIB::DIV_F128, RTLIB::impl__Qp_div); - setLibcallImpl(RTLIB::SQRT_F128, RTLIB::impl__Qp_sqrt); - setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::impl__Qp_qtoi); - setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::impl__Qp_qtoui); - setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::impl__Qp_itoq); - setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::impl__Qp_uitoq); - setLibcallImpl(RTLIB::FPTOSINT_F128_I64, RTLIB::impl__Qp_qtox); - setLibcallImpl(RTLIB::FPTOUINT_F128_I64, RTLIB::impl__Qp_qtoux); - setLibcallImpl(RTLIB::SINTTOFP_I64_F128, RTLIB::impl__Qp_xtoq); - setLibcallImpl(RTLIB::UINTTOFP_I64_F128, RTLIB::impl__Qp_uxtoq); - setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::impl__Qp_stoq); - setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::impl__Qp_dtoq); - setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::impl__Qp_qtos); - setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::impl__Qp_qtod); - } else if (!Subtarget->useSoftFloat()) { - setLibcallImpl(RTLIB::ADD_F128, RTLIB::impl__Q_add); - setLibcallImpl(RTLIB::SUB_F128, RTLIB::impl__Q_sub); - setLibcallImpl(RTLIB::MUL_F128, RTLIB::impl__Q_mul); - setLibcallImpl(RTLIB::DIV_F128, RTLIB::impl__Q_div); - setLibcallImpl(RTLIB::SQRT_F128, RTLIB::impl__Q_sqrt); - setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::impl__Q_qtoi); - setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::impl__Q_qtou); - setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::impl__Q_itoq); - setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::impl__Q_utoq); - setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::impl__Q_stoq); - setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::impl__Q_dtoq); - setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::impl__Q_qtos); - setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::impl__Q_qtod); - } + setOperationAction(ISD::FP_ROUND, MVT::f32, Custom); } if (Subtarget->fixAllFDIVSQRT()) { diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp index 005930834a0c3..1d72d0bdada03 100644 --- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp +++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp @@ -68,6 +68,46 @@ const SelectionDAGTargetInfo *SparcSubtarget::getSelectionDAGInfo() const { return TSInfo.get(); } +void SparcSubtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const { + if (hasHardQuad()) + return; + + // Setup Runtime library names. + if (is64Bit() && !useSoftFloat()) { + Info.setLibcallImpl(RTLIB::ADD_F128, RTLIB::impl__Qp_add); + Info.setLibcallImpl(RTLIB::SUB_F128, RTLIB::impl__Qp_sub); + Info.setLibcallImpl(RTLIB::MUL_F128, RTLIB::impl__Qp_mul); + Info.setLibcallImpl(RTLIB::DIV_F128, RTLIB::impl__Qp_div); + Info.setLibcallImpl(RTLIB::SQRT_F128, RTLIB::impl__Qp_sqrt); + Info.setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::impl__Qp_qtoi); + Info.setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::impl__Qp_qtoui); + Info.setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::impl__Qp_itoq); + Info.setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::impl__Qp_uitoq); + Info.setLibcallImpl(RTLIB::FPTOSINT_F128_I64, RTLIB::impl__Qp_qtox); + Info.setLibcallImpl(RTLIB::FPTOUINT_F128_I64, RTLIB::impl__Qp_qtoux); + Info.setLibcallImpl(RTLIB::SINTTOFP_I64_F128, RTLIB::impl__Qp_xtoq); + Info.setLibcallImpl(RTLIB::UINTTOFP_I64_F128, RTLIB::impl__Qp_uxtoq); + Info.setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::impl__Qp_stoq); + Info.setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::impl__Qp_dtoq); + Info.setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::impl__Qp_qtos); + Info.setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::impl__Qp_qtod); + } else if (!useSoftFloat()) { + Info.setLibcallImpl(RTLIB::ADD_F128, RTLIB::impl__Q_add); + Info.setLibcallImpl(RTLIB::SUB_F128, RTLIB::impl__Q_sub); + Info.setLibcallImpl(RTLIB::MUL_F128, RTLIB::impl__Q_mul); + Info.setLibcallImpl(RTLIB::DIV_F128, RTLIB::impl__Q_div); + Info.setLibcallImpl(RTLIB::SQRT_F128, RTLIB::impl__Q_sqrt); + Info.setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::impl__Q_qtoi); + Info.setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::impl__Q_qtou); + Info.setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::impl__Q_itoq); + Info.setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::impl__Q_utoq); + Info.setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::impl__Q_stoq); + Info.setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::impl__Q_dtoq); + Info.setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::impl__Q_qtos); + Info.setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::impl__Q_qtod); + } +} + int SparcSubtarget::getAdjustedFrameSize(int frameSize) const { if (is64Bit()) { diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.h b/llvm/lib/Target/Sparc/SparcSubtarget.h index f575f6d7da37f..02d56eb8f3000 100644 --- a/llvm/lib/Target/Sparc/SparcSubtarget.h +++ b/llvm/lib/Target/Sparc/SparcSubtarget.h @@ -63,6 +63,8 @@ class SparcSubtarget : public SparcGenSubtargetInfo { const SelectionDAGTargetInfo *getSelectionDAGInfo() const override; + void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override; + bool enableMachineScheduler() const override; #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \