Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

namespace llvm {

class TargetSubtargetInfo;

class LibcallLoweringInfo {
private:
const RTLIB::RuntimeLibcallsInfo &RTLCI;
Expand All @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class InstrItineraryData;
struct InstrStage;
class InstructionSelector;
class LegalizerInfo;
class LibcallLoweringInfo;
class MachineInstr;
struct MachineSchedPolicy;
struct MCReadAdvanceEntry;
Expand Down Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/CodeGen/LibcallLoweringInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -23,4 +25,6 @@ LibcallLoweringInfo::LibcallLoweringInfo(
LibcallImpls[LC] = Impl;
}
}

Subtarget.initLibcallLoweringInfo(*this);
}
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/TargetLoweringBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
68 changes: 0 additions & 68 deletions llvm/lib/Target/ARM/ARMISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
70 changes: 70 additions & 0 deletions llvm/lib/Target/ARM/ARMSubtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/ARM/ARMSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
62 changes: 0 additions & 62 deletions llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
64 changes: 64 additions & 0 deletions llvm/lib/Target/MSP430/MSP430Subtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
2 changes: 2 additions & 0 deletions llvm/lib/Target/MSP430/MSP430Subtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ class MSP430Subtarget : public MSP430GenSubtargetInfo {
}

const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;

void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override;
};
} // End llvm namespace

Expand Down
Loading