[llvm-branch-commits] [llvm] TableGen: Generate enum for runtime libcall implementations (PR #144973)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jun 19 19:53:52 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
Work towards separating the ABI existence of libcalls vs. the
lowering selection. Set libcall selection through enums, rather
than through raw string names.
---
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:
- (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+2-7)
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.h (+38-17)
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+561-1)
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+268-263)
- (modified) llvm/lib/LTO/LTO.cpp (+8-2)
- (modified) llvm/lib/Object/IRSymtab.cpp (+3-3)
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+108-102)
- (modified) llvm/lib/Target/MSP430/MSP430ISelLowering.cpp (+32-32)
- (modified) llvm/lib/Target/Mips/Mips16ISelLowering.cpp (+49-40)
- (modified) llvm/lib/Target/Sparc/SparcISelLowering.cpp (+43-43)
- (modified) llvm/test/TableGen/RuntimeLibcallEmitter.td (+45-8)
- (modified) llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp (+60-20)
``````````diff
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]
``````````
</details>
https://github.com/llvm/llvm-project/pull/144973
More information about the llvm-branch-commits
mailing list