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
12 changes: 10 additions & 2 deletions llvm/include/llvm/IR/RuntimeLibcalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
100 changes: 98 additions & 2 deletions llvm/include/llvm/IR/RuntimeLibcalls.td
Original file line number Diff line number Diff line change
Expand Up @@ -1498,8 +1498,101 @@ 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_f2d,
__aeabi_h2f,
__aeabi_f2h,
__aeabi_d2h,

// 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;
}

Expand All @@ -1519,6 +1612,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() &&
Expand Down
6 changes: 3 additions & 3 deletions llvm/include/llvm/TargetParser/ARMTargetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,9 @@ LLVM_ABI ProfileKind parseArchProfile(StringRef Arch);
LLVM_ABI unsigned parseArchVersion(StringRef Arch);

LLVM_ABI void fillValidCPUArchList(SmallVectorImpl<StringRef> &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.
///
Expand Down
102 changes: 27 additions & 75 deletions llvm/lib/IR/RuntimeLibcalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,92 +22,39 @@ using namespace RTLIB;
#undef GET_INIT_RUNTIME_LIBCALL_NAMES
#undef GET_SET_TARGET_RUNTIME_LIBCALL_SETS

static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT,
FloatABI::ABIType FloatABIType, EABI EABIVersion,
StringRef ABIName) {
// 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.
if (!TT.isWatchABI()) {
ARM::ARMABI TargetABI = ARM::computeTargetABI(TT, ABIName);

if (TargetABI == ARM::ARM_ABI_AAPCS || TargetABI == ARM::ARM_ABI_AAPCS16) {
Info.setLibcallImplCallingConv(RTLIB::__truncsfhf2,
CallingConv::ARM_AAPCS);
Info.setLibcallImplCallingConv(RTLIB::__truncdfhf2,
CallingConv::ARM_AAPCS);
Info.setLibcallImplCallingConv(RTLIB::__extendhfsf2,
CallingConv::ARM_AAPCS);
Info.setLibcallImplCallingConv(RTLIB::__gnu_h2f_ieee,
CallingConv::ARM_AAPCS);
Info.setLibcallImplCallingConv(RTLIB::__gnu_f2h_ieee,
CallingConv::ARM_AAPCS);
} else {
Info.setLibcallImplCallingConv(RTLIB::__truncsfhf2,
CallingConv::ARM_APCS);
Info.setLibcallImplCallingConv(RTLIB::__truncdfhf2,
CallingConv::ARM_APCS);
Info.setLibcallImplCallingConv(RTLIB::__extendhfsf2,
CallingConv::ARM_APCS);
Info.setLibcallImplCallingConv(RTLIB::__gnu_h2f_ieee,
CallingConv::ARM_APCS);
Info.setLibcallImplCallingConv(RTLIB::__gnu_f2h_ieee,
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
/// should be placed here.
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);

if (TT.isARM() || TT.isThumb()) {
setARMLibcallNames(*this, TT, FloatABI, EABIVersion, ABIName);
// 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.
if (!TT.isWatchABI()) {
if (isAAPCS_ABI(TT, ABIName)) {
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);
}
}

return;
}

Expand Down Expand Up @@ -162,6 +109,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:
Expand Down
Loading
Loading