-
Notifications
You must be signed in to change notification settings - Fork 14.3k
TableGen: Generate enum for runtime libcall implementations #144973
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/arsenm/tablegen/add-runtime-libcall-backend
Are you sure you want to change the base?
TableGen: Generate enum for runtime libcall implementations #144973
Conversation
Work towards separating the ABI existence of libcalls vs. the lowering selection. Set libcall selection through enums, rather than through raw string names.
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-backend-mips @llvm/pr-subscribers-llvm-ir Author: Matt Arsenault (arsenm) ChangesWork towards separating the ABI existence of libcalls vs. the Patch is 122.30 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/144973.diff 12 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 727526055e592..69ae4f80297d5 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -3558,13 +3558,8 @@ class LLVM_ABI TargetLoweringBase {
return nullptr;
}
- /// Rename the default libcall routine name for the specified libcall.
- void setLibcallName(RTLIB::Libcall Call, const char *Name) {
- Libcalls.setLibcallName(Call, Name);
- }
-
- void setLibcallName(ArrayRef<RTLIB::Libcall> Calls, const char *Name) {
- Libcalls.setLibcallName(Calls, Name);
+ void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
+ Libcalls.setLibcallImpl(Call, Impl);
}
/// Get the libcall routine name for the specified libcall.
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h
index e063076fac71a..912715fbf6b19 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -23,6 +23,10 @@
#include "llvm/Support/Compiler.h"
#include "llvm/TargetParser/Triple.h"
+/// TableGen will produce 2 enums, RTLIB::Libcall and
+/// RTLIB::LibcallImpl. RTLIB::Libcall describes abstract functionality the
+/// compiler may choose to access, RTLIB::LibcallImpl describes a particular ABI
+/// implementation, which includes a name and type signature.
#define GET_RUNTIME_LIBCALL_ENUM
#include "llvm/IR/RuntimeLibcalls.inc"
#undef GET_RUNTIME_LIBCALL_ENUM
@@ -48,38 +52,46 @@ struct RuntimeLibcallsInfo {
FloatABI::ABIType FloatABI = FloatABI::Default,
EABI EABIVersion = EABI::Default) {
initSoftFloatCmpLibcallPredicates();
- initDefaultLibCallNames();
+ initDefaultLibCallImpls();
initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion);
}
/// Rename the default libcall routine name for the specified libcall.
- void setLibcallName(RTLIB::Libcall Call, const char *Name) {
- LibcallRoutineNames[Call] = Name;
- }
-
- void setLibcallName(ArrayRef<RTLIB::Libcall> Calls, const char *Name) {
- for (auto Call : Calls)
- setLibcallName(Call, Name);
+ void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
+ LibcallImpls[Call] = Impl;
}
/// Get the libcall routine name for the specified libcall.
+ // FIXME: This should be removed. Only LibcallImpl should have a name.
const char *getLibcallName(RTLIB::Libcall Call) const {
- return LibcallRoutineNames[Call];
+ return LibCallImplNames[LibcallImpls[Call]];
+ }
+
+ /// Get the libcall routine name for the specified libcall implementation.
+ const char *getLibcallImplName(RTLIB::LibcallImpl CallImpl) const {
+ return LibCallImplNames[CallImpl];
+ }
+
+ /// Return the lowering's selection of implementation call for \p Call
+ RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
+ return LibcallImpls[Call];
}
/// Set the CallingConv that should be used for the specified libcall.
+ // FIXME: This should be a function of RTLIB::LibcallImpl
void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
LibcallCallingConvs[Call] = CC;
}
/// Get the CallingConv that should be used for the specified libcall.
+ // FIXME: This should be a function of RTLIB::LibcallImpl
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
return LibcallCallingConvs[Call];
}
- ArrayRef<const char *> getLibcallNames() const {
- // Trim UNKNOWN_LIBCALL from the end
- return ArrayRef(LibcallRoutineNames).drop_back();
+ ArrayRef<RTLIB::LibcallImpl> getLibcallImpls() const {
+ // Trim Unsupported from the start
+ return ArrayRef(LibcallImpls).drop_front();
}
/// Get the comparison predicate that's to be used to test the result of the
@@ -91,6 +103,7 @@ struct RuntimeLibcallsInfo {
}
// FIXME: This should be removed. This should be private constant.
+ // FIXME: This should be a function of RTLIB::LibcallImpl
void setSoftFloatCmpLibcallPredicate(RTLIB::Libcall Call,
CmpInst::Predicate Pred) {
SoftFloatCompareLibcallPredicates[Call] = Pred;
@@ -107,11 +120,12 @@ struct RuntimeLibcallsInfo {
}
private:
- static const char *const
- DefaultLibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1];
+ static const RTLIB::LibcallImpl
+ DefaultLibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1];
- /// Stores the name each libcall.
- const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1] = {nullptr};
+ /// Stores the implementation choice for each each libcall.
+ RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
+ RTLIB::Unsupported};
static_assert(static_cast<int>(CallingConv::C) == 0,
"default calling conv should be encoded as 0");
@@ -127,6 +141,13 @@ struct RuntimeLibcallsInfo {
// opcode.
CmpInst::Predicate SoftFloatCompareLibcallPredicates[RTLIB::UNKNOWN_LIBCALL];
+ /// Names of concrete implementations of runtime calls. e.g. __ashlsi3 for
+ /// SHL_I32
+ static const char *const LibCallImplNames[RTLIB::NumLibcallImpls];
+
+ /// Map from a concrete LibcallImpl implementation to its RTLIB::Libcall kind.
+ static const RTLIB::Libcall ImplToLibcall[RTLIB::NumLibcallImpls];
+
static bool darwinHasSinCosStret(const Triple &TT) {
assert(TT.isOSDarwin() && "should be called with darwin triple");
// Don't bother with 32 bit x86.
@@ -148,7 +169,7 @@ struct RuntimeLibcallsInfo {
(TT.isAndroid() && !TT.isAndroidVersionLT(9));
}
- void initDefaultLibCallNames();
+ void initDefaultLibCallImpls();
/// Generated by tablegen.
void setPPCLibCallNameOverrides();
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index c6f00c345cde8..c910fce2edd80 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -8,6 +8,13 @@
include "llvm/IR/RuntimeLibcallsImpl.td"
+//--------------------------------------------------------------------
+// Utility classes
+//--------------------------------------------------------------------
+
+class DuplicateLibcallImplWithPrefix<RuntimeLibcallImpl Impl, string prefix>
+ : RuntimeLibcallImpl<Impl.Provides, prefix#Impl.LibCallFuncName>;
+
//--------------------------------------------------------------------
// Declare all kinds of used libcalls
//--------------------------------------------------------------------
@@ -299,6 +306,13 @@ multiclass AtomicOrderSizeLibcall {
def _ACQ_REL : RuntimeLibcall;
}
+multiclass AtomicOrderSizeLibcallImpl<string ProvidesBase> {
+ def _relax : RuntimeLibcallImpl<!cast<RuntimeLibcall>(ProvidesBase#"_RELAX")>;
+ def _acq : RuntimeLibcallImpl<!cast<RuntimeLibcall>(ProvidesBase#"_ACQ")>;
+ def _rel : RuntimeLibcallImpl<!cast<RuntimeLibcall>(ProvidesBase#"_REL")>;
+ def _acq_rel : RuntimeLibcallImpl<!cast<RuntimeLibcall>(ProvidesBase#"_ACQ_REL")>;
+}
+
// Out-of-line atomics libcalls
defset list<RuntimeLibcall> LibCalls__OutOfLineAtomic = {
foreach MemSize = [1, 2, 4, 8, 16] in {
@@ -324,6 +338,12 @@ def RETURN_ADDRESS : RuntimeLibcall;
def CLEAR_CACHE : RuntimeLibcall;
def RISCV_FLUSH_ICACHE : RuntimeLibcall;
+// Mips16 calls
+def MIPS16_RET_DC : RuntimeLibcall;
+def MIPS16_RET_DF : RuntimeLibcall;
+def MIPS16_RET_SC : RuntimeLibcall;
+def MIPS16_RET_SF : RuntimeLibcall;
+
multiclass LibmLongDoubleLibCall<string libcall_basename = !toupper(NAME),
string rtbasename = NAME> {
def NAME#"_f128"
@@ -882,7 +902,7 @@ def exp10f128 : RuntimeLibcallImpl<EXP10_F128>;
def sinf128 : RuntimeLibcallImpl<SIN_F128>;
def cosf128 : RuntimeLibcallImpl<COS_F128>;
def tanf128 : RuntimeLibcallImpl<TAN_F128>;
-def tanhf128 : RuntimeLibcallImpl<TAN_F128>;
+def tanhf128 : RuntimeLibcallImpl<TANH_F128>;
def sincosf128 : RuntimeLibcallImpl<SINCOS_F128>;
def powf128 : RuntimeLibcallImpl<POW_F128>;
def fminf128 : RuntimeLibcallImpl<FMIN_F128>;
@@ -926,6 +946,465 @@ def __exp2f128_finite : RuntimeLibcallImpl<EXP2_FINITE_F128>;
def __exp10f128_finite : RuntimeLibcallImpl<EXP10_FINITE_F128>;
def __powf128_finite : RuntimeLibcallImpl<POW_FINITE_F128>;
+//===----------------------------------------------------------------------===//
+// AArch64 Runtime Libcalls
+//===----------------------------------------------------------------------===//
+
+defset list<RuntimeLibcallImpl> AArch64LibcallImpls = {
+ foreach MemSize = [1, 2, 4, 8, 16] in {
+ defm __aarch64_cas#MemSize
+ : AtomicOrderSizeLibcallImpl<"OUTLINE_ATOMIC_CAS"#MemSize>;
+ }
+
+ foreach MemSize = [1, 2, 4, 8] in {
+ defm __aarch64_swp#MemSize
+ : AtomicOrderSizeLibcallImpl<"OUTLINE_ATOMIC_SWP"#MemSize>;
+ defm __aarch64_ldadd#MemSize
+ : AtomicOrderSizeLibcallImpl<"OUTLINE_ATOMIC_LDADD"#MemSize>;
+ defm __aarch64_ldset#MemSize
+ : AtomicOrderSizeLibcallImpl<"OUTLINE_ATOMIC_LDSET"#MemSize>;
+ defm __aarch64_ldclr#MemSize
+ : AtomicOrderSizeLibcallImpl<"OUTLINE_ATOMIC_LDCLR"#MemSize>;
+ defm __aarch64_ldeor#MemSize
+ : AtomicOrderSizeLibcallImpl<"OUTLINE_ATOMIC_LDEOR"#MemSize>;
+ }
+}
+
+foreach libcall = AArch64LibcallImpls in {
+ def arm64ec_#libcall : DuplicateLibcallImplWithPrefix<libcall, "#">;
+}
+
+foreach libcall = DefaultRuntimeLibcallImpls in {
+ def arm64ec_#libcall : DuplicateLibcallImplWithPrefix<libcall, "#">;
+}
+
+//===----------------------------------------------------------------------===//
+// ARM Runtime Libcalls
+//===----------------------------------------------------------------------===//
+
+// if (isTargetMachO()) {
+// if (Subtarget->isThumb() && Subtarget->hasVFP2Base() &&
+// Subtarget->hasARMOps() && !Subtarget->useSoftFloat()) {
+
+def __addsf3vfp : RuntimeLibcallImpl<ADD_F32>;
+def __subsf3vfp : RuntimeLibcallImpl<SUB_F32>;
+def __mulsf3vfp : RuntimeLibcallImpl<MUL_F32>;
+def __divsf3vfp : RuntimeLibcallImpl<DIV_F32>;
+
+// Double-precision floating-point arithmetic.
+def __adddf3vfp : RuntimeLibcallImpl<ADD_F64>;
+def __subdf3vfp : RuntimeLibcallImpl<SUB_F64>;
+def __muldf3vfp : RuntimeLibcallImpl<MUL_F64>;
+def __divdf3vfp : RuntimeLibcallImpl<DIV_F64>;
+
+// Single-precision comparisons.
+
+// TODO: Track setcc type
+def __eqsf2vfp : RuntimeLibcallImpl<OEQ_F32>; // CmpInst::ICMP_NE
+def __nesf2vfp : RuntimeLibcallImpl<UNE_F32>; // CmpInst::ICMP_NE
+def __ltsf2vfp : RuntimeLibcallImpl<OLT_F32>; // CmpInst::ICMP_NE
+def __lesf2vfp : RuntimeLibcallImpl<OLE_F32>; // CmpInst::ICMP_NE
+def __gesf2vfp : RuntimeLibcallImpl<OGE_F32>; // CmpInst::ICMP_NE
+def __gtsf2vfp : RuntimeLibcallImpl<OGT_F32>; // CmpInst::ICMP_NE
+def __unordsf2vfp : RuntimeLibcallImpl<UO_F32>; // CmpInst::ICMP_NE
+
+// Double-precision comparisons.
+def __eqdf2vfp : RuntimeLibcallImpl<OEQ_F64>; // CmpInst::ICMP_NE
+def __nedf2vfp : RuntimeLibcallImpl<UNE_F64>; // CmpInst::ICMP_NE
+def __ltdf2vfp : RuntimeLibcallImpl<OLT_F64>; // CmpInst::ICMP_NE
+def __ledf2vfp : RuntimeLibcallImpl<OLE_F64>; // CmpInst::ICMP_NE
+def __gedf2vfp : RuntimeLibcallImpl<OGE_F64>; // CmpInst::ICMP_NE
+def __gtdf2vfp : RuntimeLibcallImpl<OGT_F64>; // CmpInst::ICMP_NE
+def __unorddf2vfp : RuntimeLibcallImpl<UO_F64>; // CmpInst::ICMP_NE
+
+// Floating-point to integer conversions.
+// i64 conversions are done via library routines even when generating VFP
+// instructions, so use the same ones.
+def __fixdfsivfp : RuntimeLibcallImpl<FPTOSINT_F64_I32>;
+def __fixunsdfsivfp : RuntimeLibcallImpl<FPTOUINT_F64_I32>;
+def __fixsfsivfp : RuntimeLibcallImpl<FPTOSINT_F32_I32>;
+def __fixunssfsivfp : RuntimeLibcallImpl<FPTOUINT_F32_I32>;
+
+// Conversions between floating types.
+def __truncdfsf2vfp : RuntimeLibcallImpl<FPROUND_F64_F32>;
+def __extendsfdf2vfp : RuntimeLibcallImpl<FPEXT_F32_F64>;
+
+// 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.
+def __floatsidfvfp : RuntimeLibcallImpl<SINTTOFP_I32_F64>;
+def __floatunssidfvfp : RuntimeLibcallImpl<UINTTOFP_I32_F64>;
+def __floatsisfvfp : RuntimeLibcallImpl<SINTTOFP_I32_F32>;
+def __floatunssisfvfp : RuntimeLibcallImpl<UINTTOFP_I32_F32>;
+
+// // RTLIB
+// if (isAAPCS_ABI() &&
+// (isTargetAEABI() || isTargetGNUAEABI() ||
+// isTargetMuslAEABI() || isTargetAndroid())) {
+
+// TODO: Set CallingConv = ARM_AAPCS
+
+// Double-precision floating-point arithmetic helper functions
+// RTABI chapter 4.1.2, Table 2
+def __aeabi_dadd : RuntimeLibcallImpl<ADD_F64>; // CallingConv::ARM_AAPCS
+def __aeabi_ddiv : RuntimeLibcallImpl<DIV_F64>; // CallingConv::ARM_AAPCS
+def __aeabi_dmul : RuntimeLibcallImpl<MUL_F64>; // CallingConv::ARM_AAPCS
+def __aeabi_dsub : RuntimeLibcallImpl<SUB_F64>; // CallingConv::ARM_AAPCS
+
+// Double-precision floating-point comparison helper functions
+// RTABI chapter 4.1.2, Table 3
+def __aeabi_dcmpeq__ne : RuntimeLibcallImpl<OEQ_F64, "__aeabi_dcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
+def __aeabi_dcmpeq__eq : RuntimeLibcallImpl<UNE_F64, "__aeabi_dcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ
+def __aeabi_dcmplt : RuntimeLibcallImpl<OLT_F64>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
+def __aeabi_dcmple : RuntimeLibcallImpl<OLE_F64>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
+def __aeabi_dcmpge : RuntimeLibcallImpl<OGE_F64>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
+def __aeabi_dcmpgt : RuntimeLibcallImpl<OGT_F64>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
+def __aeabi_dcmpun : RuntimeLibcallImpl<UO_F64>; // CallingConv::ARM_AAPCS
+
+// Single-precision floating-point arithmetic helper functions
+// RTABI chapter 4.1.2, Table 4
+def __aeabi_fadd : RuntimeLibcallImpl<ADD_F32>; // CallingConv::ARM_AAPCS
+def __aeabi_fdiv : RuntimeLibcallImpl<DIV_F32>; // CallingConv::ARM_AAPCS
+def __aeabi_fmul : RuntimeLibcallImpl<MUL_F32>; // CallingConv::ARM_AAPCS
+def __aeabi_fsub : RuntimeLibcallImpl<SUB_F32>; // CallingConv::ARM_AAPCS
+
+// Single-precision floating-point comparison helper functions
+// RTABI chapter 4.1.2, Table 5
+def __aeabi_fcmpeq__ne : RuntimeLibcallImpl<OEQ_F32, "__aeabi_fcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
+def __aeabi_fcmpeq__eq : RuntimeLibcallImpl<UNE_F32, "__aeabi_fcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ
+def __aeabi_fcmplt : RuntimeLibcallImpl<OLT_F32>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
+def __aeabi_fcmple : RuntimeLibcallImpl<OLE_F32>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
+def __aeabi_fcmpge : RuntimeLibcallImpl<OGE_F32>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
+def __aeabi_fcmpgt : RuntimeLibcallImpl<OGT_F32>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
+def __aeabi_fcmpun : RuntimeLibcallImpl<UO_F32>; // CallingConv::ARM_AAPCS
+
+// Floating-point to integer conversions.
+// RTABI chapter 4.1.2, Table 6
+def __aeabi_d2iz : RuntimeLibcallImpl<FPTOSINT_F64_I32>; // CallingConv::ARM_AAPCS
+def __aeabi_d2uiz : RuntimeLibcallImpl<FPTOUINT_F64_I32>; // CallingConv::ARM_AAPCS
+def __aeabi_d2lz : RuntimeLibcallImpl<FPTOSINT_F64_I64>; // CallingConv::ARM_AAPCS
+def __aeabi_d2ulz : RuntimeLibcallImpl<FPTOUINT_F64_I64>; // CallingConv::ARM_AAPCS
+def __aeabi_f2iz : RuntimeLibcallImpl<FPTOSINT_F32_I32>; // CallingConv::ARM_AAPCS
+def __aeabi_f2uiz : RuntimeLibcallImpl<FPTOUINT_F32_I32>; // CallingConv::ARM_AAPCS
+def __aeabi_f2lz : RuntimeLibcallImpl<FPTOSINT_F32_I64>; // CallingConv::ARM_AAPCS
+def __aeabi_f2ulz : RuntimeLibcallImpl<FPTOUINT_F32_I64>; // CallingConv::ARM_AAPCS
+
+// Conversions between floating types.
+// RTABI chapter 4.1.2, Table 7
+def __aeabi_d2f : RuntimeLibcallImpl<FPROUND_F64_F32>; // CallingConv::ARM_AAPCS
+def __aeabi_d2h : RuntimeLibcallImpl<FPROUND_F64_F16>; // CallingConv::ARM_AAPCS
+def __aeabi_f2d : RuntimeLibcallImpl<FPEXT_F32_F64>; // CallingConv::ARM_AAPCS
+
+// Integer to floating-point conversions.
+// RTABI chapter 4.1.2, Table 8
+def __aeabi_i2d : RuntimeLibcallImpl<SINTTOFP_I32_F64>; // CallingConv::ARM_AAPCS
+def __aeabi_ui2d : RuntimeLibcallImpl<UINTTOFP_I32_F64>; // CallingConv::ARM_AAPCS
+def __aeabi_l2d : RuntimeLibcallImpl<SINTTOFP_I64_F64>; // CallingConv::ARM_AAPCS
+def __aeabi_ul2d : RuntimeLibcallImpl<UINTTOFP_I64_F64>; // CallingConv::ARM_AAPCS
+def __aeabi_i2f : RuntimeLibcallImpl<SINTTOFP_I32_F32>; // CallingConv::ARM_AAPCS
+def __aeabi_ui2f : RuntimeLibcallImpl<UINTTOFP_I32_F32>; // CallingConv::ARM_AAPCS
+def __aeabi_l2f : RuntimeLibcallImpl<SINTTOFP_I64_F32>; // CallingConv::ARM_AAPCS
+def __aeabi_ul2f : RuntimeLibcallImpl<UINTTOFP_I64_F32>; // CallingConv::ARM_AAPCS
+
+// Long long helper functions
+// RTABI chapter 4.2, Table 9
+def __aeabi_lmul : RuntimeLibcallImpl<MUL_I64>; // CallingConv::ARM_AAPCS
+def __aeabi_llsl : RuntimeLibcallImpl<SHL_I64>; // CallingConv::ARM_AAPCS
+def __aeabi_llsr : RuntimeLibcallImpl<SRL_I64>; // CallingConv::ARM_AAPCS
+def __aeabi_lasr : RuntimeLibcallImpl<SRA_I64>; // CallingConv::ARM_AAPCS
+
+// Integer division functions
+// RTABI chapter 4.3.1
+def __aeabi_idiv__i8 : RuntimeLibcallImpl<SDIV_I8, "__aeabi_idiv">; // CallingConv::ARM_AAPCS
+def __aeabi_idiv__i16 : RuntimeLibcallImpl<SDIV_I16, "__aeabi_idiv">; // CallingConv::ARM_AAPCS
+def __aeabi_idiv__i32 : RuntimeLibcallImpl<SDIV_I32, "__aeabi_idiv">; // CallingConv::ARM_AAPCS
+def __aeabi_ldivmod : RuntimeLibcallImpl<SDIV_I64>; // CallingConv::ARM_AAPCS
+def __aeabi_uidiv__i8 : RuntimeLibcallImpl<UDIV_I8, "__aeabi_uidiv">; // CallingConv::ARM_AAPCS
+def __aeabi_uidiv__i16 : RuntimeLibcallImpl<UDIV_I16, "__aeabi_uidiv">; // CallingConv::ARM_AAPCS
+def __aeabi_uidiv__i32 : RuntimeLibcallImpl<UDIV_I32, "__aeabi_uidiv">; // CallingConv::ARM_AAPCS
+def __aeabi_uldivmod : RuntimeLibcallImpl<UDIV_I64>; // CallingConv::ARM_AAPCS
+
+def __aeabi_idivmod : RuntimeLibcallImpl<SDIVREM_I32>; // CallingConv::ARM_AAPCS
+def __aeabi_uidivmod : RuntimeLibcallImpl<UDIVREM_I32>; // CallingConv::ARM_AAPCS
+
+// EABI dependent RTLIB
+
+// Memory operations
+// RTABI chapter 4.3.4
+def __aeabi_memcpy : RuntimeLibcallImpl<MEMCPY>; // CallingConv::ARM_AAPCS
+def __aeabi_memmove : RuntimeLibcallImpl<MEMMOVE>; // CallingConv::ARM_AAPCS
+def __aeabi_memset : RuntimeLibcallImpl<MEMSET>; // CallingConv::ARM_AAPCS
+
+// isTargetWindows()
+def __stoi64 : RuntimeLibcallImpl<FPTOSINT_F32_I64>; // CallingConv::ARM_AAPCS_VFP
+def __dtoi64 : RuntimeLibcallImpl<FPTOSINT_F64_I64>; // CallingConv::ARM_AAPCS_VFP
+def __stou64 : RuntimeLibcallImpl<FPTOUINT_F32_I64>; // CallingConv::ARM_AAPCS_VFP
+def __dtou64 : RuntimeLibcallImpl<FPTOUINT_F64_I64>; // CallingConv::ARM_AAPCS_VFP
+def __i64tos : RuntimeLibcallImpl<SINTTOFP_I64_F32>; // CallingConv::ARM_AAPCS_VFP
+def __i64tod : RuntimeLibcallImpl<SINTTOFP_I64_F64>; // CallingConv::ARM_AAPCS_VFP
+def __u64tos : RuntimeLibcallImpl<UINTTOFP_I64_F32>; // CallingConv::ARM_AAPCS_VFP
+def __u64tod : RuntimeLibcallImpl<UINTTOFP_I64_F64>; // CallingConv::ARM_AAPCS_VFP
+
+def __rt_sdiv : RuntimeLibcallImpl<SDIVREM_I32>; // CallingConv::ARM_AAPCS
+def __rt_sdiv64 : RuntimeLibcallImpl<SDIVREM_I64>; // CallingConv::ARM_AAPCS
+def __rt_udiv : RuntimeLibcallImpl<UDIVREM_I32>; // CallingConv::ARM_AAPCS
+def __rt_udiv64 : RuntimeLibcallImpl<UDIVREM_I64>; // CallingConv::ARM_AAPCS
+
+// Use divmod compiler-rt calls for iOS 5.0 and later.
+// isTargetMachO() &&
+// !(isTargetIOS() && isOSVersionLT(5, 0))
+def __divmodsi4 : RuntimeLibcallImpl<SDIVREM_I32>;
+def __udivmodsi4 : RuntimeLibcallImpl<UDIVREM_I32>;
+
+// FIXME: Change calling convention of FPROUND_F32_F16,
+// RTLIB::FPROUND_F64_F16, FPEXT_F16_F32 for !Subtarget->isTargetWatchABI())
+
+// In EABI, these functions have an __aeabi_ prefix, but in GNUEABI they have
+// a __gnu_ prefix (which is the default).
+// isTargetAEABI()
+def __aeabi_f2h : RuntimeLibcallImpl<FPROUND_F32_F16>; // CallingConv::ARM_AAPCS
+//def __aeabi_d2h : RuntimeLibcallImpl<FPROUND_F64_F16>; // CallingConv::ARM_AAPCS
+def __aeabi_h2f : RuntimeLibcallImpl<FPEXT_F16_F32>; // CallingConv::ARM_AAPCS
+
+// !isTargetMachO()
+def __gnu_f2h_ieee : RuntimeLibcallImpl<FPROUND_F32_F16>;
+def __gnu_h2f_ieee : RuntimeLibcallImpl<FPEXT_F16_F32>;
+
+//===----------------------------------------------------------------------===//
+// AVR Runtime Libcalls
+//===---------------------------------------------------...
[truncated]
|
Work towards separating the ABI existence of libcalls vs. the
lowering selection. Set libcall selection through enums, rather
than through raw string names.