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 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 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 getLibcallNames() const { - // Trim UNKNOWN_LIBCALL from the end - return ArrayRef(LibcallRoutineNames).drop_back(); + ArrayRef 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(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; + //-------------------------------------------------------------------- // Declare all kinds of used libcalls //-------------------------------------------------------------------- @@ -299,6 +306,13 @@ multiclass AtomicOrderSizeLibcall { def _ACQ_REL : RuntimeLibcall; } +multiclass AtomicOrderSizeLibcallImpl { + def _relax : RuntimeLibcallImpl(ProvidesBase#"_RELAX")>; + def _acq : RuntimeLibcallImpl(ProvidesBase#"_ACQ")>; + def _rel : RuntimeLibcallImpl(ProvidesBase#"_REL")>; + def _acq_rel : RuntimeLibcallImpl(ProvidesBase#"_ACQ_REL")>; +} + // Out-of-line atomics libcalls defset list 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 { def NAME#"_f128" @@ -882,7 +902,7 @@ def exp10f128 : RuntimeLibcallImpl; def sinf128 : RuntimeLibcallImpl; def cosf128 : RuntimeLibcallImpl; def tanf128 : RuntimeLibcallImpl; -def tanhf128 : RuntimeLibcallImpl; +def tanhf128 : RuntimeLibcallImpl; def sincosf128 : RuntimeLibcallImpl; def powf128 : RuntimeLibcallImpl; def fminf128 : RuntimeLibcallImpl; @@ -926,6 +946,465 @@ def __exp2f128_finite : RuntimeLibcallImpl; def __exp10f128_finite : RuntimeLibcallImpl; def __powf128_finite : RuntimeLibcallImpl; +//===----------------------------------------------------------------------===// +// AArch64 Runtime Libcalls +//===----------------------------------------------------------------------===// + +defset list 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; +} + +foreach libcall = DefaultRuntimeLibcallImpls in { + def arm64ec_#libcall : DuplicateLibcallImplWithPrefix; +} + +//===----------------------------------------------------------------------===// +// ARM Runtime Libcalls +//===----------------------------------------------------------------------===// + +// if (isTargetMachO()) { +// if (Subtarget->isThumb() && Subtarget->hasVFP2Base() && +// Subtarget->hasARMOps() && !Subtarget->useSoftFloat()) { + +def __addsf3vfp : RuntimeLibcallImpl; +def __subsf3vfp : RuntimeLibcallImpl; +def __mulsf3vfp : RuntimeLibcallImpl; +def __divsf3vfp : RuntimeLibcallImpl; + +// Double-precision floating-point arithmetic. +def __adddf3vfp : RuntimeLibcallImpl; +def __subdf3vfp : RuntimeLibcallImpl; +def __muldf3vfp : RuntimeLibcallImpl; +def __divdf3vfp : RuntimeLibcallImpl; + +// Single-precision comparisons. + +// TODO: Track setcc type +def __eqsf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __nesf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __ltsf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __lesf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __gesf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __gtsf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __unordsf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE + +// Double-precision comparisons. +def __eqdf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __nedf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __ltdf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __ledf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __gedf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __gtdf2vfp : RuntimeLibcallImpl; // CmpInst::ICMP_NE +def __unorddf2vfp : RuntimeLibcallImpl; // 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; +def __fixunsdfsivfp : RuntimeLibcallImpl; +def __fixsfsivfp : RuntimeLibcallImpl; +def __fixunssfsivfp : RuntimeLibcallImpl; + +// Conversions between floating types. +def __truncdfsf2vfp : RuntimeLibcallImpl; +def __extendsfdf2vfp : RuntimeLibcallImpl; + +// 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; +def __floatunssidfvfp : RuntimeLibcallImpl; +def __floatsisfvfp : RuntimeLibcallImpl; +def __floatunssisfvfp : RuntimeLibcallImpl; + +// // 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; // CallingConv::ARM_AAPCS +def __aeabi_ddiv : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_dmul : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_dsub : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// Double-precision floating-point comparison helper functions +// RTABI chapter 4.1.2, Table 3 +def __aeabi_dcmpeq__ne : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE +def __aeabi_dcmpeq__eq : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ +def __aeabi_dcmplt : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE +def __aeabi_dcmple : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE +def __aeabi_dcmpge : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE +def __aeabi_dcmpgt : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE +def __aeabi_dcmpun : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// Single-precision floating-point arithmetic helper functions +// RTABI chapter 4.1.2, Table 4 +def __aeabi_fadd : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_fdiv : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_fmul : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_fsub : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// Single-precision floating-point comparison helper functions +// RTABI chapter 4.1.2, Table 5 +def __aeabi_fcmpeq__ne : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE +def __aeabi_fcmpeq__eq : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ +def __aeabi_fcmplt : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE +def __aeabi_fcmple : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE +def __aeabi_fcmpge : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE +def __aeabi_fcmpgt : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE +def __aeabi_fcmpun : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// Floating-point to integer conversions. +// RTABI chapter 4.1.2, Table 6 +def __aeabi_d2iz : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_d2uiz : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_d2lz : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_d2ulz : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_f2iz : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_f2uiz : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_f2lz : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_f2ulz : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// Conversions between floating types. +// RTABI chapter 4.1.2, Table 7 +def __aeabi_d2f : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_d2h : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_f2d : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// Integer to floating-point conversions. +// RTABI chapter 4.1.2, Table 8 +def __aeabi_i2d : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_ui2d : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_l2d : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_ul2d : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_i2f : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_ui2f : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_l2f : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_ul2f : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// Long long helper functions +// RTABI chapter 4.2, Table 9 +def __aeabi_lmul : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_llsl : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_llsr : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_lasr : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// Integer division functions +// RTABI chapter 4.3.1 +def __aeabi_idiv__i8 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_idiv__i16 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_idiv__i32 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_ldivmod : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_uidiv__i8 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_uidiv__i16 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_uidiv__i32 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_uldivmod : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +def __aeabi_idivmod : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_uidivmod : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// EABI dependent RTLIB + +// Memory operations +// RTABI chapter 4.3.4 +def __aeabi_memcpy : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_memmove : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_memset : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// isTargetWindows() +def __stoi64 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS_VFP +def __dtoi64 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS_VFP +def __stou64 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS_VFP +def __dtou64 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS_VFP +def __i64tos : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS_VFP +def __i64tod : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS_VFP +def __u64tos : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS_VFP +def __u64tod : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS_VFP + +def __rt_sdiv : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __rt_sdiv64 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __rt_udiv : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __rt_udiv64 : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// Use divmod compiler-rt calls for iOS 5.0 and later. +// isTargetMachO() && +// !(isTargetIOS() && isOSVersionLT(5, 0)) +def __divmodsi4 : RuntimeLibcallImpl; +def __udivmodsi4 : RuntimeLibcallImpl; + +// 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; // CallingConv::ARM_AAPCS +//def __aeabi_d2h : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS +def __aeabi_h2f : RuntimeLibcallImpl; // CallingConv::ARM_AAPCS + +// !isTargetMachO() +def __gnu_f2h_ieee : RuntimeLibcallImpl; +def __gnu_h2f_ieee : RuntimeLibcallImpl; + +//===----------------------------------------------------------------------===// +// AVR Runtime Libcalls +//===----------------------------------------------------------------------===// + +// Several of the runtime library functions use a special calling conv +def __divmodqi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN +def __divmodhi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN +//def __divmodsi4 : RuntimeLibcallImpl; +def __udivmodqi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN +def __udivmodhi4 : RuntimeLibcallImpl; // CallingConv::AVR_BUILTIN +//def __udivmodsi4 : RuntimeLibcallImpl; + +// Standard sinf/cosf name replaced with "sin" and "cos". Define a +// separate Impl so we can set a different type signature. +def avr_sin : RuntimeLibcallImpl; +def avr_cos : RuntimeLibcallImpl; + +//===----------------------------------------------------------------------===// +// Hexagon Runtime Libcalls +//===----------------------------------------------------------------------===// + +def __hexagon_divsi3 : RuntimeLibcallImpl; +def __hexagon_divdi3 : RuntimeLibcallImpl; +def __hexagon_udivsi3 : RuntimeLibcallImpl; +def __hexagon_udivdi3 : RuntimeLibcallImpl; +def __hexagon_modsi3 : RuntimeLibcallImpl; +def __hexagon_moddi3 : RuntimeLibcallImpl; +def __hexagon_umodsi3 : RuntimeLibcallImpl; +def __hexagon_umoddi3 : RuntimeLibcallImpl; + +// FIXME: "Fast" versions should be treated as a separate RTLIB::FAST_* function +def __hexagon_adddf3 : RuntimeLibcallImpl; +def __hexagon_fast_adddf3 : RuntimeLibcallImpl; + +def __hexagon_subdf3 : RuntimeLibcallImpl; +def __hexagon_fast_subdf3 : RuntimeLibcallImpl; + +def __hexagon_muldf3 : RuntimeLibcallImpl; +def __hexagon_fast_muldf3 : RuntimeLibcallImpl; + +def __hexagon_divdf3 : RuntimeLibcallImpl; +def __hexagon_fast_divdf3 : RuntimeLibcallImpl; + +def __hexagon_divsf3 : RuntimeLibcallImpl; +def __hexagon_fast_divsf3 : RuntimeLibcallImpl; + +def __hexagon_sqrtf : RuntimeLibcallImpl; +def __hexagon_fast2_sqrtf : RuntimeLibcallImpl; + +// This is the only fast library function for sqrtd. +def __hexagon_fast2_sqrtdf2 : RuntimeLibcallImpl; + +//===----------------------------------------------------------------------===// +// Mips16 Runtime Libcalls +//===----------------------------------------------------------------------===// + +// Hard float libcalls +def __mips16_adddf3 : RuntimeLibcallImpl; +def __mips16_addsf3 : RuntimeLibcallImpl; +def __mips16_divdf3 : RuntimeLibcallImpl; +def __mips16_divsf3 : RuntimeLibcallImpl; +def __mips16_eqdf2 : RuntimeLibcallImpl; +def __mips16_eqsf2 : RuntimeLibcallImpl; +def __mips16_extendsfdf2 : RuntimeLibcallImpl; +def __mips16_fix_truncdfsi : RuntimeLibcallImpl; +def __mips16_fix_truncsfsi : RuntimeLibcallImpl; +def __mips16_floatsidf : RuntimeLibcallImpl; +def __mips16_floatsisf : RuntimeLibcallImpl; +def __mips16_floatunsidf : RuntimeLibcallImpl; +def __mips16_floatunsisf : RuntimeLibcallImpl; +def __mips16_gedf2 : RuntimeLibcallImpl; +def __mips16_gesf2 : RuntimeLibcallImpl; +def __mips16_gtdf2 : RuntimeLibcallImpl; +def __mips16_gtsf2 : RuntimeLibcallImpl; +def __mips16_ledf2 : RuntimeLibcallImpl; +def __mips16_lesf2 : RuntimeLibcallImpl; +def __mips16_ltdf2 : RuntimeLibcallImpl; +def __mips16_ltsf2 : RuntimeLibcallImpl; +def __mips16_muldf3 : RuntimeLibcallImpl; +def __mips16_mulsf3 : RuntimeLibcallImpl; +def __mips16_nedf2 : RuntimeLibcallImpl; +def __mips16_nesf2 : RuntimeLibcallImpl; +def __mips16_ret_dc : RuntimeLibcallImpl; +def __mips16_ret_df : RuntimeLibcallImpl; +def __mips16_ret_sc : RuntimeLibcallImpl; +def __mips16_ret_sf : RuntimeLibcallImpl; +def __mips16_subdf3 : RuntimeLibcallImpl; +def __mips16_subsf3 : RuntimeLibcallImpl; +def __mips16_truncdfsf2 : RuntimeLibcallImpl; +def __mips16_unorddf2 : RuntimeLibcallImpl; +def __mips16_unordsf2 : RuntimeLibcallImpl; + +//===----------------------------------------------------------------------===// +// MSP430 Runtime Libcalls +//===----------------------------------------------------------------------===// + +// EABI Libcalls - EABI Section 6.2 + +// Floating point conversions - EABI Table 6 +def __mspabi_cvtdf : RuntimeLibcallImpl; +def __mspabi_cvtfd : RuntimeLibcallImpl; + +// The following is NOT implemented in libgcc +//def __mspabi_fixdi : RuntimeLibcallImpl; +def __mspabi_fixdli : RuntimeLibcallImpl; +def __mspabi_fixdlli : RuntimeLibcallImpl; + +// The following is NOT implemented in libgcc +//def __mspabi_fixdu : RuntimeLibcallImpl; +def __mspabi_fixdul : RuntimeLibcallImpl; +def __mspabi_fixdull : RuntimeLibcallImpl; + +// The following is NOT implemented in libgcc +//def __mspabi_fixfi : RuntimeLibcallImpl; +def __mspabi_fixfli : RuntimeLibcallImpl; +def __mspabi_fixflli : RuntimeLibcallImpl; + +// The following is NOT implemented in libgcc +//def __mspabi_fixfu : RuntimeLibcallImpl; +def __mspabi_fixful : RuntimeLibcallImpl; +def __mspabi_fixfull : RuntimeLibcallImpl; + +// TODO The following IS implemented in libgcc +//def __mspabi_fltid : RuntimeLibcallImpl; +def __mspabi_fltlid : RuntimeLibcallImpl; + +// TODO The following IS implemented in libgcc but is not in the EABI +def __mspabi_fltllid : RuntimeLibcallImpl; + +// TODO The following IS implemented in libgcc +//def __mspabi_fltud : RuntimeLibcallImpl; +def __mspabi_fltuld : RuntimeLibcallImpl; + +// The following IS implemented in libgcc but is not in the EABI +def __mspabi_fltulld : RuntimeLibcallImpl; + +// TODO The following IS implemented in libgcc +//def __mspabi_fltif : RuntimeLibcallImpl; +def __mspabi_fltlif : RuntimeLibcallImpl; + +// TODO The following IS implemented in libgcc but is not in the EABI +def __mspabi_fltllif : RuntimeLibcallImpl; + +// TODO The following IS implemented in libgcc +//def __mspabi_fltuf : RuntimeLibcallImpl; +def __mspabi_fltulf : RuntimeLibcallImpl; + +// The following IS implemented in libgcc but is not in the EABI +def __mspabi_fltullf : RuntimeLibcallImpl; + +// Floating point comparisons - EABI Table 7 +def __mspabi_cmpd__oeq : RuntimeLibcallImpl; +def __mspabi_cmpd__une : RuntimeLibcallImpl; +def __mspabi_cmpd__oge : RuntimeLibcallImpl; +def __mspabi_cmpd__olt : RuntimeLibcallImpl; +def __mspabi_cmpd__ole : RuntimeLibcallImpl; +def __mspabi_cmpd__ogt : RuntimeLibcallImpl; +def __mspabi_cmpf__oeq : RuntimeLibcallImpl; +def __mspabi_cmpf__une : RuntimeLibcallImpl; +def __mspabi_cmpf__oge : RuntimeLibcallImpl; +def __mspabi_cmpf__olt : RuntimeLibcallImpl; +def __mspabi_cmpf__ole : RuntimeLibcallImpl; +def __mspabi_cmpf__ogt : RuntimeLibcallImpl; + +// Floating point arithmetic - EABI Table 8 +def __mspabi_addd : RuntimeLibcallImpl; +def __mspabi_addf : RuntimeLibcallImpl; +def __mspabi_divd : RuntimeLibcallImpl; +def __mspabi_divf : RuntimeLibcallImpl; +def __mspabi_mpyd : RuntimeLibcallImpl; +def __mspabi_mpyf : RuntimeLibcallImpl; +def __mspabi_subd : RuntimeLibcallImpl; +def __mspabi_subf : RuntimeLibcallImpl; + +// The following are NOT implemented in libgcc +// def __mspabi_negd : RuntimeLibcallImpl; +// def __mspabi_negf : RuntimeLibcallImpl; + +// Universal Integer Operations - EABI Table 9 +def __mspabi_divi : RuntimeLibcallImpl; +def __mspabi_divli : RuntimeLibcallImpl; +def __mspabi_divlli : RuntimeLibcallImpl; +def __mspabi_divu : RuntimeLibcallImpl; +def __mspabi_divul : RuntimeLibcallImpl; +def __mspabi_divull : RuntimeLibcallImpl; +def __mspabi_remi : RuntimeLibcallImpl; +def __mspabi_remli : RuntimeLibcallImpl; +def __mspabi_remlli : RuntimeLibcallImpl; +def __mspabi_remu : RuntimeLibcallImpl; +def __mspabi_remul : RuntimeLibcallImpl; +def __mspabi_remull : RuntimeLibcallImpl; + +// Bitwise Operations - EABI Table 10 +// TODO: __mspabi_[srli/srai/slli] ARE implemented in libgcc +def __mspabi_srll : RuntimeLibcallImpl; +def __mspabi_sral : RuntimeLibcallImpl; +def __mspabi_slll : RuntimeLibcallImpl; +// __mspabi_[srlll/srall/sllll/rlli/rlll] are NOT implemented in libgcc + +// hasHWMult16() +// Integer Multiply - EABI Table 9 +//def __mspabi_mpyi_hw : RuntimeLibcallImpl; +def __mspabi_mpyl_hw : RuntimeLibcallImpl; +def __mspabi_mpyll_hw : RuntimeLibcallImpl; +// TODO The __mspabi_mpysl*_hw functions ARE implemented in libgcc +// TODO The __mspabi_mpyul*_hw functions ARE implemented in libgcc + +// hasHWMult32() +// Integer Multiply - EABI Table 9 +def __mspabi_mpyi_hw : RuntimeLibcallImpl; +def __mspabi_mpyl_hw32 : RuntimeLibcallImpl; +def __mspabi_mpyll_hw32 : RuntimeLibcallImpl; +// TODO The __mspabi_mpysl*_hw32 functions ARE implemented in libgcc +// TODO The __mspabi_mpyul*_hw32 functions ARE implemented in libgcc + +// hasHWMultF5() +// Integer Multiply - EABI Table 9 +def __mspabi_mpyi_f5hw : RuntimeLibcallImpl; +def __mspabi_mpyl_f5hw : RuntimeLibcallImpl; +def __mspabi_mpyll_f5hw : RuntimeLibcallImpl; +// TODO The __mspabi_mpysl*_f5hw functions ARE implemented in libgcc +// TODO The __mspabi_mpyul*_f5hw functions ARE implemented in libgcc + +// NoHWMult +// Integer Multiply - EABI Table 9 +def __mspabi_mpyi : RuntimeLibcallImpl; +def __mspabi_mpyl : RuntimeLibcallImpl; +def __mspabi_mpyll : RuntimeLibcallImpl; +// The __mspabi_mpysl* functions are NOT implemented in libgcc +// The __mspabi_mpyul* functions are NOT implemented in libgcc + +// setLibcallCallingConv(MUL_I64, CallingConv::MSP430_BUILTIN); + //===----------------------------------------------------------------------===// // PPC Runtime Libcalls //===----------------------------------------------------------------------===// @@ -964,6 +1443,78 @@ def __lekf2 : PPCRuntimeLibcallImpl; def __gtkf2 : PPCRuntimeLibcallImpl; def __unordkf2 : PPCRuntimeLibcallImpl; +// PPC64 && Subtarget.isAIXABI() +def ___memmove64 : RuntimeLibcallImpl; +def ___memset64 : RuntimeLibcallImpl; +def ___bzero64 : RuntimeLibcallImpl; + +// !PPC64 && Subtarget.isAIXABI() +def ___memmove : RuntimeLibcallImpl; +def ___memset : RuntimeLibcallImpl; +def ___bzero : RuntimeLibcallImpl; + +//===----------------------------------------------------------------------===// +// SPARC Runtime Libcalls +//===----------------------------------------------------------------------===// + +// Subtarget->useSoftMulDiv() +def sparc_umul : RuntimeLibcallImpl; +def sparc_div : RuntimeLibcallImpl; +def sparc_udiv : RuntimeLibcallImpl; +def sparc_rem : RuntimeLibcallImpl; +def sparc_urem : RuntimeLibcallImpl; + +// SPARC64 && !Subtarget->useSoftFloat() +def _Qp_add : RuntimeLibcallImpl; +def _Qp_sub : RuntimeLibcallImpl; +def _Qp_mul : RuntimeLibcallImpl; +def _Qp_div : RuntimeLibcallImpl; +def _Qp_sqrt : RuntimeLibcallImpl; +def _Qp_qtoi : RuntimeLibcallImpl; +def _Qp_qtoui : RuntimeLibcallImpl; +def _Qp_itoq : RuntimeLibcallImpl; +def _Qp_uitoq : RuntimeLibcallImpl; +def _Qp_qtox : RuntimeLibcallImpl; +def _Qp_qtoux : RuntimeLibcallImpl; +def _Qp_xtoq : RuntimeLibcallImpl; +def _Qp_uxtoq : RuntimeLibcallImpl; +def _Qp_stoq : RuntimeLibcallImpl; +def _Qp_dtoq : RuntimeLibcallImpl; +def _Qp_qtos : RuntimeLibcallImpl; +def _Qp_qtod : RuntimeLibcallImpl; + +// SPARC32 && !Subtarget->useSoftFloat() +def _Q_add : RuntimeLibcallImpl; +def _Q_sub : RuntimeLibcallImpl; +def _Q_mul : RuntimeLibcallImpl; +def _Q_div : RuntimeLibcallImpl; +def _Q_sqrt : RuntimeLibcallImpl; +def _Q_qtoi : RuntimeLibcallImpl; +def _Q_qtou : RuntimeLibcallImpl; +def _Q_itoq : RuntimeLibcallImpl; +def _Q_utoq : RuntimeLibcallImpl; +def _Q_stoq : RuntimeLibcallImpl; +def _Q_dtoq : RuntimeLibcallImpl; +def _Q_qtos : RuntimeLibcallImpl; +def _Q_qtod : RuntimeLibcallImpl; + +// SPARC32 && (Subtarget->hasHardQuad() || !Subtarget->useSoftFloat()) +def _Q_qtoll : RuntimeLibcallImpl; +def _Q_qtoull : RuntimeLibcallImpl; +def _Q_lltoq : RuntimeLibcallImpl; +def _Q_ulltoq : RuntimeLibcallImpl; + +//===----------------------------------------------------------------------===// +// Windows Runtime Libcalls +//===----------------------------------------------------------------------===// + +// TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment() +def _alldiv : RuntimeLibcallImpl; // CallingConv::X86_StdCall +def _aulldiv : RuntimeLibcallImpl; // CallingConv::X86_StdCall +def _allrem : RuntimeLibcallImpl; // CallingConv::X86_StdCall +def _aullrem : RuntimeLibcallImpl; // CallingConv::X86_StdCall +def _allmul : RuntimeLibcallImpl; // CallingConv::X86_StdCall + //===----------------------------------------------------------------------===// // ZOS Runtime Libcalls //===----------------------------------------------------------------------===// @@ -1052,3 +1603,12 @@ def zos___LCEL_B : ZOSRuntimeLibcallImpl; def zos___SCRT_B : ZOSRuntimeLibcallImpl; def zos___FCBT_B : ZOSRuntimeLibcallImpl; def zos___LCBT_B : ZOSRuntimeLibcallImpl; + +//===----------------------------------------------------------------------===// +// WebAssembly Runtime Libcalls +//===----------------------------------------------------------------------===// + +// Define the emscripten name for return address helper. +// TODO: when implementing other Wasm backends, make this generic or only do +// this on emscripten depending on what they end up doing. +def emscripten_return_address : RuntimeLibcallImpl; diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index 632bd4d53dbd0..5fccb23e6c5ff 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -25,10 +25,10 @@ static cl::opt static void setAArch64LibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT) { #define LCALLNAMES(A, B, N) \ - Info.setLibcallName(A##N##_RELAX, #B #N "_relax"); \ - Info.setLibcallName(A##N##_ACQ, #B #N "_acq"); \ - Info.setLibcallName(A##N##_REL, #B #N "_rel"); \ - Info.setLibcallName(A##N##_ACQ_REL, #B #N "_acq_rel"); + Info.setLibcallImpl(A##N##_RELAX, B##N##_relax); \ + Info.setLibcallImpl(A##N##_ACQ, B##N##_acq); \ + Info.setLibcallImpl(A##N##_REL, B##N##_rel); \ + Info.setLibcallImpl(A##N##_ACQ_REL, B##N##_acq_rel); #define LCALLNAME4(A, B) \ LCALLNAMES(A, B, 1) \ LCALLNAMES(A, B, 2) LCALLNAMES(A, B, 4) LCALLNAMES(A, B, 8) @@ -38,21 +38,20 @@ static void setAArch64LibcallNames(RuntimeLibcallsInfo &Info, LCALLNAMES(A, B, 4) LCALLNAMES(A, B, 8) LCALLNAMES(A, B, 16) if (TT.isWindowsArm64EC()) { - LCALLNAME5(RTLIB::OUTLINE_ATOMIC_CAS, #__aarch64_cas) - LCALLNAME4(RTLIB::OUTLINE_ATOMIC_SWP, #__aarch64_swp) - LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDADD, #__aarch64_ldadd) - LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDSET, #__aarch64_ldset) - LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDCLR, #__aarch64_ldclr) - LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDEOR, #__aarch64_ldeor) + LCALLNAME5(RTLIB::OUTLINE_ATOMIC_CAS, RTLIB::arm64ec___aarch64_cas) + LCALLNAME4(RTLIB::OUTLINE_ATOMIC_SWP, RTLIB::arm64ec___aarch64_swp) + LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDADD, RTLIB::arm64ec___aarch64_ldadd) + LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDSET, RTLIB::arm64ec___aarch64_ldset) + LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDCLR, RTLIB::arm64ec___aarch64_ldclr) + LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDEOR, RTLIB::arm64ec___aarch64_ldeor) } else { - LCALLNAME5(RTLIB::OUTLINE_ATOMIC_CAS, __aarch64_cas) - LCALLNAME4(RTLIB::OUTLINE_ATOMIC_SWP, __aarch64_swp) - LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDADD, __aarch64_ldadd) - LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDSET, __aarch64_ldset) - LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDCLR, __aarch64_ldclr) - LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDEOR, __aarch64_ldeor) + LCALLNAME5(RTLIB::OUTLINE_ATOMIC_CAS, RTLIB::__aarch64_cas) + LCALLNAME4(RTLIB::OUTLINE_ATOMIC_SWP, RTLIB::__aarch64_swp) + LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDADD, RTLIB::__aarch64_ldadd) + LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDSET, RTLIB::__aarch64_ldset) + LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDCLR, RTLIB::__aarch64_ldclr) + LCALLNAME4(RTLIB::OUTLINE_ATOMIC_LDEOR, RTLIB::__aarch64_ldeor) } - #undef LCALLNAMES #undef LCALLNAME4 #undef LCALLNAME5 @@ -75,33 +74,33 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, if (TT.isOSWindows()) { const struct { const RTLIB::Libcall Op; - const char *const Name; + const RTLIB::LibcallImpl Impl; const CallingConv::ID CC; } LibraryCalls[] = { - {RTLIB::SDIVREM_I32, "__rt_sdiv", CallingConv::ARM_AAPCS}, - {RTLIB::SDIVREM_I64, "__rt_sdiv64", CallingConv::ARM_AAPCS}, - {RTLIB::UDIVREM_I32, "__rt_udiv", CallingConv::ARM_AAPCS}, - {RTLIB::UDIVREM_I64, "__rt_udiv64", CallingConv::ARM_AAPCS}, + {RTLIB::SDIVREM_I32, RTLIB::__rt_sdiv, CallingConv::ARM_AAPCS}, + {RTLIB::SDIVREM_I64, RTLIB::__rt_sdiv64, CallingConv::ARM_AAPCS}, + {RTLIB::UDIVREM_I32, RTLIB::__rt_udiv, CallingConv::ARM_AAPCS}, + {RTLIB::UDIVREM_I64, RTLIB::__rt_udiv64, CallingConv::ARM_AAPCS}, }; for (const auto &LC : LibraryCalls) { - Info.setLibcallName(LC.Op, LC.Name); + Info.setLibcallImpl(LC.Op, LC.Impl); Info.setLibcallCallingConv(LC.Op, LC.CC); } } else { const struct { const RTLIB::Libcall Op; - const char *const Name; + const RTLIB::LibcallImpl Impl; const CallingConv::ID CC; } LibraryCalls[] = { - {RTLIB::SDIVREM_I32, "__aeabi_idivmod", CallingConv::ARM_AAPCS}, - {RTLIB::SDIVREM_I64, "__aeabi_ldivmod", CallingConv::ARM_AAPCS}, - {RTLIB::UDIVREM_I32, "__aeabi_uidivmod", CallingConv::ARM_AAPCS}, - {RTLIB::UDIVREM_I64, "__aeabi_uldivmod", CallingConv::ARM_AAPCS}, + {RTLIB::SDIVREM_I32, RTLIB::__aeabi_idivmod, CallingConv::ARM_AAPCS}, + {RTLIB::SDIVREM_I64, RTLIB::__aeabi_ldivmod, CallingConv::ARM_AAPCS}, + {RTLIB::UDIVREM_I32, RTLIB::__aeabi_uidivmod, CallingConv::ARM_AAPCS}, + {RTLIB::UDIVREM_I64, RTLIB::__aeabi_uldivmod, CallingConv::ARM_AAPCS}, }; for (const auto &LC : LibraryCalls) { - Info.setLibcallName(LC.Op, LC.Name); + Info.setLibcallImpl(LC.Op, LC.Impl); Info.setLibcallCallingConv(LC.Op, LC.CC); } } @@ -110,29 +109,29 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, if (TT.isOSWindows()) { static const struct { const RTLIB::Libcall Op; - const char *const Name; + const RTLIB::LibcallImpl Impl; const CallingConv::ID CC; } LibraryCalls[] = { - {RTLIB::FPTOSINT_F32_I64, "__stoi64", CallingConv::ARM_AAPCS_VFP}, - {RTLIB::FPTOSINT_F64_I64, "__dtoi64", CallingConv::ARM_AAPCS_VFP}, - {RTLIB::FPTOUINT_F32_I64, "__stou64", CallingConv::ARM_AAPCS_VFP}, - {RTLIB::FPTOUINT_F64_I64, "__dtou64", CallingConv::ARM_AAPCS_VFP}, - {RTLIB::SINTTOFP_I64_F32, "__i64tos", CallingConv::ARM_AAPCS_VFP}, - {RTLIB::SINTTOFP_I64_F64, "__i64tod", CallingConv::ARM_AAPCS_VFP}, - {RTLIB::UINTTOFP_I64_F32, "__u64tos", CallingConv::ARM_AAPCS_VFP}, - {RTLIB::UINTTOFP_I64_F64, "__u64tod", CallingConv::ARM_AAPCS_VFP}, + {RTLIB::FPTOSINT_F32_I64, RTLIB::__stoi64, CallingConv::ARM_AAPCS_VFP}, + {RTLIB::FPTOSINT_F64_I64, RTLIB::__dtoi64, CallingConv::ARM_AAPCS_VFP}, + {RTLIB::FPTOUINT_F32_I64, RTLIB::__stou64, CallingConv::ARM_AAPCS_VFP}, + {RTLIB::FPTOUINT_F64_I64, RTLIB::__dtou64, CallingConv::ARM_AAPCS_VFP}, + {RTLIB::SINTTOFP_I64_F32, RTLIB::__i64tos, CallingConv::ARM_AAPCS_VFP}, + {RTLIB::SINTTOFP_I64_F64, RTLIB::__i64tod, CallingConv::ARM_AAPCS_VFP}, + {RTLIB::UINTTOFP_I64_F32, RTLIB::__u64tos, CallingConv::ARM_AAPCS_VFP}, + {RTLIB::UINTTOFP_I64_F64, RTLIB::__u64tod, CallingConv::ARM_AAPCS_VFP}, }; for (const auto &LC : LibraryCalls) { - Info.setLibcallName(LC.Op, LC.Name); + Info.setLibcallImpl(LC.Op, LC.Impl); Info.setLibcallCallingConv(LC.Op, LC.CC); } } // Use divmod compiler-rt calls for iOS 5.0 and later. if (TT.isOSBinFormatMachO() && (!TT.isiOS() || !TT.isOSVersionLT(5, 0))) { - Info.setLibcallName(RTLIB::SDIVREM_I32, "__divmodsi4"); - Info.setLibcallName(RTLIB::UDIVREM_I32, "__udivmodsi4"); + Info.setLibcallImpl(RTLIB::SDIVREM_I32, RTLIB::__divmodsi4); + Info.setLibcallImpl(RTLIB::UDIVREM_I32, RTLIB::__udivmodsi4); } } @@ -140,99 +139,99 @@ static void setMSP430Libcalls(RuntimeLibcallsInfo &Info, const Triple &TT) { // EABI Libcalls - EABI Section 6.2 const struct { const RTLIB::Libcall Op; - const char *const Name; + const RTLIB::LibcallImpl Impl; } LibraryCalls[] = { // Floating point conversions - EABI Table 6 - {RTLIB::FPROUND_F64_F32, "__mspabi_cvtdf"}, - {RTLIB::FPEXT_F32_F64, "__mspabi_cvtfd"}, + {RTLIB::FPROUND_F64_F32, RTLIB::__mspabi_cvtdf}, + {RTLIB::FPEXT_F32_F64, RTLIB::__mspabi_cvtfd}, // The following is NOT implemented in libgcc - //{ RTLIB::FPTOSINT_F64_I16, "__mspabi_fixdi" }, - {RTLIB::FPTOSINT_F64_I32, "__mspabi_fixdli"}, - {RTLIB::FPTOSINT_F64_I64, "__mspabi_fixdlli"}, + //{ RTLIB::FPTOSINT_F64_I16, RTLIB::__mspabi_fixdi }, + {RTLIB::FPTOSINT_F64_I32, RTLIB::__mspabi_fixdli}, + {RTLIB::FPTOSINT_F64_I64, RTLIB::__mspabi_fixdlli}, // The following is NOT implemented in libgcc - //{ RTLIB::FPTOUINT_F64_I16, "__mspabi_fixdu" }, - {RTLIB::FPTOUINT_F64_I32, "__mspabi_fixdul"}, - {RTLIB::FPTOUINT_F64_I64, "__mspabi_fixdull"}, + //{ RTLIB::FPTOUINT_F64_I16, RTLIB::__mspabi_fixdu }, + {RTLIB::FPTOUINT_F64_I32, RTLIB::__mspabi_fixdul}, + {RTLIB::FPTOUINT_F64_I64, RTLIB::__mspabi_fixdull}, // The following is NOT implemented in libgcc - //{ RTLIB::FPTOSINT_F32_I16, "__mspabi_fixfi" }, - {RTLIB::FPTOSINT_F32_I32, "__mspabi_fixfli"}, - {RTLIB::FPTOSINT_F32_I64, "__mspabi_fixflli"}, + //{ RTLIB::FPTOSINT_F32_I16, RTLIB::__mspabi_fixfi }, + {RTLIB::FPTOSINT_F32_I32, RTLIB::__mspabi_fixfli}, + {RTLIB::FPTOSINT_F32_I64, RTLIB::__mspabi_fixflli}, // The following is NOT implemented in libgcc - //{ RTLIB::FPTOUINT_F32_I16, "__mspabi_fixfu" }, - {RTLIB::FPTOUINT_F32_I32, "__mspabi_fixful"}, - {RTLIB::FPTOUINT_F32_I64, "__mspabi_fixfull"}, + //{ RTLIB::FPTOUINT_F32_I16, RTLIB::__mspabi_fixfu }, + {RTLIB::FPTOUINT_F32_I32, RTLIB::__mspabi_fixful}, + {RTLIB::FPTOUINT_F32_I64, RTLIB::__mspabi_fixfull}, // TODO The following IS implemented in libgcc - //{ RTLIB::SINTTOFP_I16_F64, "__mspabi_fltid" }, - {RTLIB::SINTTOFP_I32_F64, "__mspabi_fltlid"}, + //{ RTLIB::SINTTOFP_I16_F64, RTLIB::__mspabi_fltid }, + {RTLIB::SINTTOFP_I32_F64, RTLIB::__mspabi_fltlid}, // TODO The following IS implemented in libgcc but is not in the EABI - {RTLIB::SINTTOFP_I64_F64, "__mspabi_fltllid"}, + {RTLIB::SINTTOFP_I64_F64, RTLIB::__mspabi_fltllid}, // TODO The following IS implemented in libgcc - //{ RTLIB::UINTTOFP_I16_F64, "__mspabi_fltud" }, - {RTLIB::UINTTOFP_I32_F64, "__mspabi_fltuld"}, + //{ RTLIB::UINTTOFP_I16_F64, RTLIB::__mspabi_fltud }, + {RTLIB::UINTTOFP_I32_F64, RTLIB::__mspabi_fltuld}, // The following IS implemented in libgcc but is not in the EABI - {RTLIB::UINTTOFP_I64_F64, "__mspabi_fltulld"}, + {RTLIB::UINTTOFP_I64_F64, RTLIB::__mspabi_fltulld}, // TODO The following IS implemented in libgcc - //{ RTLIB::SINTTOFP_I16_F32, "__mspabi_fltif" }, - {RTLIB::SINTTOFP_I32_F32, "__mspabi_fltlif"}, + //{ RTLIB::SINTTOFP_I16_F32, RTLIB::__mspabi_fltif }, + {RTLIB::SINTTOFP_I32_F32, RTLIB::__mspabi_fltlif}, // TODO The following IS implemented in libgcc but is not in the EABI - {RTLIB::SINTTOFP_I64_F32, "__mspabi_fltllif"}, + {RTLIB::SINTTOFP_I64_F32, RTLIB::__mspabi_fltllif}, // TODO The following IS implemented in libgcc - //{ RTLIB::UINTTOFP_I16_F32, "__mspabi_fltuf" }, - {RTLIB::UINTTOFP_I32_F32, "__mspabi_fltulf"}, + //{ RTLIB::UINTTOFP_I16_F32, RTLIB::__mspabi_fltuf }, + {RTLIB::UINTTOFP_I32_F32, RTLIB::__mspabi_fltulf}, // The following IS implemented in libgcc but is not in the EABI - {RTLIB::UINTTOFP_I64_F32, "__mspabi_fltullf"}, + {RTLIB::UINTTOFP_I64_F32, RTLIB::__mspabi_fltullf}, // Floating point comparisons - EABI Table 7 - {RTLIB::OEQ_F64, "__mspabi_cmpd"}, - {RTLIB::UNE_F64, "__mspabi_cmpd"}, - {RTLIB::OGE_F64, "__mspabi_cmpd"}, - {RTLIB::OLT_F64, "__mspabi_cmpd"}, - {RTLIB::OLE_F64, "__mspabi_cmpd"}, - {RTLIB::OGT_F64, "__mspabi_cmpd"}, - {RTLIB::OEQ_F32, "__mspabi_cmpf"}, - {RTLIB::UNE_F32, "__mspabi_cmpf"}, - {RTLIB::OGE_F32, "__mspabi_cmpf"}, - {RTLIB::OLT_F32, "__mspabi_cmpf"}, - {RTLIB::OLE_F32, "__mspabi_cmpf"}, - {RTLIB::OGT_F32, "__mspabi_cmpf"}, + {RTLIB::OEQ_F64, RTLIB::__mspabi_cmpd__oeq}, + {RTLIB::UNE_F64, RTLIB::__mspabi_cmpd__une}, + {RTLIB::OGE_F64, RTLIB::__mspabi_cmpd__oge}, + {RTLIB::OLT_F64, RTLIB::__mspabi_cmpd__olt}, + {RTLIB::OLE_F64, RTLIB::__mspabi_cmpd__ole}, + {RTLIB::OGT_F64, RTLIB::__mspabi_cmpd__ogt}, + {RTLIB::OEQ_F32, RTLIB::__mspabi_cmpf__oeq}, + {RTLIB::UNE_F32, RTLIB::__mspabi_cmpf__une}, + {RTLIB::OGE_F32, RTLIB::__mspabi_cmpf__oge}, + {RTLIB::OLT_F32, RTLIB::__mspabi_cmpf__olt}, + {RTLIB::OLE_F32, RTLIB::__mspabi_cmpf__ole}, + {RTLIB::OGT_F32, RTLIB::__mspabi_cmpf__ogt}, // Floating point arithmetic - EABI Table 8 - {RTLIB::ADD_F64, "__mspabi_addd"}, - {RTLIB::ADD_F32, "__mspabi_addf"}, - {RTLIB::DIV_F64, "__mspabi_divd"}, - {RTLIB::DIV_F32, "__mspabi_divf"}, - {RTLIB::MUL_F64, "__mspabi_mpyd"}, - {RTLIB::MUL_F32, "__mspabi_mpyf"}, - {RTLIB::SUB_F64, "__mspabi_subd"}, - {RTLIB::SUB_F32, "__mspabi_subf"}, + {RTLIB::ADD_F64, RTLIB::__mspabi_addd}, + {RTLIB::ADD_F32, RTLIB::__mspabi_addf}, + {RTLIB::DIV_F64, RTLIB::__mspabi_divd}, + {RTLIB::DIV_F32, RTLIB::__mspabi_divf}, + {RTLIB::MUL_F64, RTLIB::__mspabi_mpyd}, + {RTLIB::MUL_F32, RTLIB::__mspabi_mpyf}, + {RTLIB::SUB_F64, RTLIB::__mspabi_subd}, + {RTLIB::SUB_F32, RTLIB::__mspabi_subf}, // The following are NOT implemented in libgcc - // { RTLIB::NEG_F64, "__mspabi_negd" }, - // { RTLIB::NEG_F32, "__mspabi_negf" }, + // { RTLIB::NEG_F64, RTLIB::__mspabi_negd }, + // { RTLIB::NEG_F32, RTLIB::__mspabi_negf }, // Universal Integer Operations - EABI Table 9 - {RTLIB::SDIV_I16, "__mspabi_divi"}, - {RTLIB::SDIV_I32, "__mspabi_divli"}, - {RTLIB::SDIV_I64, "__mspabi_divlli"}, - {RTLIB::UDIV_I16, "__mspabi_divu"}, - {RTLIB::UDIV_I32, "__mspabi_divul"}, - {RTLIB::UDIV_I64, "__mspabi_divull"}, - {RTLIB::SREM_I16, "__mspabi_remi"}, - {RTLIB::SREM_I32, "__mspabi_remli"}, - {RTLIB::SREM_I64, "__mspabi_remlli"}, - {RTLIB::UREM_I16, "__mspabi_remu"}, - {RTLIB::UREM_I32, "__mspabi_remul"}, - {RTLIB::UREM_I64, "__mspabi_remull"}, + {RTLIB::SDIV_I16, RTLIB::__mspabi_divi}, + {RTLIB::SDIV_I32, RTLIB::__mspabi_divli}, + {RTLIB::SDIV_I64, RTLIB::__mspabi_divlli}, + {RTLIB::UDIV_I16, RTLIB::__mspabi_divu}, + {RTLIB::UDIV_I32, RTLIB::__mspabi_divul}, + {RTLIB::UDIV_I64, RTLIB::__mspabi_divull}, + {RTLIB::SREM_I16, RTLIB::__mspabi_remi}, + {RTLIB::SREM_I32, RTLIB::__mspabi_remli}, + {RTLIB::SREM_I64, RTLIB::__mspabi_remlli}, + {RTLIB::UREM_I16, RTLIB::__mspabi_remu}, + {RTLIB::UREM_I32, RTLIB::__mspabi_remul}, + {RTLIB::UREM_I64, RTLIB::__mspabi_remull}, // Bitwise Operations - EABI Table 10 // TODO: __mspabi_[srli/srai/slli] ARE implemented in libgcc - {RTLIB::SRL_I32, "__mspabi_srll"}, - {RTLIB::SRA_I32, "__mspabi_sral"}, - {RTLIB::SHL_I32, "__mspabi_slll"}, + {RTLIB::SRL_I32, RTLIB::__mspabi_srll}, + {RTLIB::SRA_I32, RTLIB::__mspabi_sral}, + {RTLIB::SHL_I32, RTLIB::__mspabi_slll}, // __mspabi_[srlll/srall/sllll/rlli/rlll] are NOT implemented in libgcc }; for (const auto &LC : LibraryCalls) - Info.setLibcallName(LC.Op, LC.Name); + Info.setLibcallImpl(LC.Op, LC.Impl); // Several of the runtime library functions use a special calling conv Info.setLibcallCallingConv(RTLIB::UDIV_I64, CallingConv::MSP430_BUILTIN); @@ -286,72 +285,70 @@ void RuntimeLibcallsInfo::initSoftFloatCmpLibcallPredicates() { static void setLongDoubleIsF128Libm(RuntimeLibcallsInfo &Info, bool FiniteOnlyFuncs = false) { - Info.setLibcallName(RTLIB::REM_F128, "fmodf128"); - Info.setLibcallName(RTLIB::FMA_F128, "fmaf128"); - Info.setLibcallName(RTLIB::SQRT_F128, "sqrtf128"); - Info.setLibcallName(RTLIB::CBRT_F128, "cbrtf128"); - Info.setLibcallName(RTLIB::LOG_F128, "logf128"); - Info.setLibcallName(RTLIB::LOG2_F128, "log2f128"); - Info.setLibcallName(RTLIB::LOG10_F128, "log10f128"); - Info.setLibcallName(RTLIB::EXP_F128, "expf128"); - Info.setLibcallName(RTLIB::EXP2_F128, "exp2f128"); - Info.setLibcallName(RTLIB::EXP10_F128, "exp10f128"); - Info.setLibcallName(RTLIB::SIN_F128, "sinf128"); - Info.setLibcallName(RTLIB::COS_F128, "cosf128"); - Info.setLibcallName(RTLIB::TAN_F128, "tanf128"); - Info.setLibcallName(RTLIB::SINCOS_F128, "sincosf128"); - Info.setLibcallName(RTLIB::ASIN_F128, "asinf128"); - Info.setLibcallName(RTLIB::ACOS_F128, "acosf128"); - Info.setLibcallName(RTLIB::ATAN_F128, "atanf128"); - Info.setLibcallName(RTLIB::ATAN2_F128, "atan2f128"); - Info.setLibcallName(RTLIB::SINH_F128, "sinhf128"); - Info.setLibcallName(RTLIB::COSH_F128, "coshf128"); - Info.setLibcallName(RTLIB::TANH_F128, "tanhf128"); - Info.setLibcallName(RTLIB::POW_F128, "powf128"); - Info.setLibcallName(RTLIB::CEIL_F128, "ceilf128"); - Info.setLibcallName(RTLIB::TRUNC_F128, "truncf128"); - Info.setLibcallName(RTLIB::RINT_F128, "rintf128"); - Info.setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintf128"); - Info.setLibcallName(RTLIB::ROUND_F128, "roundf128"); - Info.setLibcallName(RTLIB::ROUNDEVEN_F128, "roundevenf128"); - Info.setLibcallName(RTLIB::FLOOR_F128, "floorf128"); - Info.setLibcallName(RTLIB::COPYSIGN_F128, "copysignf128"); - Info.setLibcallName(RTLIB::FMIN_F128, "fminf128"); - Info.setLibcallName(RTLIB::FMAX_F128, "fmaxf128"); - Info.setLibcallName(RTLIB::FMINIMUM_F128, "fminimumf128"); - Info.setLibcallName(RTLIB::FMAXIMUM_F128, "fmaximumf128"); - Info.setLibcallName(RTLIB::FMINIMUM_NUM_F128, "fminimum_numf128"); - Info.setLibcallName(RTLIB::FMAXIMUM_NUM_F128, "fmaximum_numf128"); - Info.setLibcallName(RTLIB::LROUND_F128, "lroundf128"); - Info.setLibcallName(RTLIB::LLROUND_F128, "llroundf128"); - Info.setLibcallName(RTLIB::LRINT_F128, "lrintf128"); - Info.setLibcallName(RTLIB::LLRINT_F128, "llrintf128"); - Info.setLibcallName(RTLIB::LDEXP_F128, "ldexpf128"); - Info.setLibcallName(RTLIB::FREXP_F128, "frexpf128"); - Info.setLibcallName(RTLIB::MODF_F128, "modff128"); + Info.setLibcallImpl(RTLIB::REM_F128, RTLIB::fmodf128); + Info.setLibcallImpl(RTLIB::FMA_F128, RTLIB::fmaf128); + Info.setLibcallImpl(RTLIB::SQRT_F128, RTLIB::sqrtf128); + Info.setLibcallImpl(RTLIB::CBRT_F128, RTLIB::cbrtf128); + Info.setLibcallImpl(RTLIB::LOG_F128, RTLIB::logf128); + Info.setLibcallImpl(RTLIB::LOG2_F128, RTLIB::log2f128); + Info.setLibcallImpl(RTLIB::LOG10_F128, RTLIB::log10f128); + Info.setLibcallImpl(RTLIB::EXP_F128, RTLIB::expf128); + Info.setLibcallImpl(RTLIB::EXP2_F128, RTLIB::exp2f128); + Info.setLibcallImpl(RTLIB::EXP10_F128, RTLIB::exp10f128); + Info.setLibcallImpl(RTLIB::SIN_F128, RTLIB::sinf128); + Info.setLibcallImpl(RTLIB::COS_F128, RTLIB::cosf128); + Info.setLibcallImpl(RTLIB::TAN_F128, RTLIB::tanf128); + Info.setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincosf128); + Info.setLibcallImpl(RTLIB::ASIN_F128, RTLIB::asinf128); + Info.setLibcallImpl(RTLIB::ACOS_F128, RTLIB::acosf128); + Info.setLibcallImpl(RTLIB::ATAN_F128, RTLIB::atanf128); + Info.setLibcallImpl(RTLIB::ATAN2_F128, RTLIB::atan2f128); + Info.setLibcallImpl(RTLIB::SINH_F128, RTLIB::sinhf128); + Info.setLibcallImpl(RTLIB::COSH_F128, RTLIB::coshf128); + Info.setLibcallImpl(RTLIB::TANH_F128, RTLIB::tanhf128); + Info.setLibcallImpl(RTLIB::POW_F128, RTLIB::powf128); + Info.setLibcallImpl(RTLIB::CEIL_F128, RTLIB::ceilf128); + Info.setLibcallImpl(RTLIB::TRUNC_F128, RTLIB::truncf128); + Info.setLibcallImpl(RTLIB::RINT_F128, RTLIB::rintf128); + Info.setLibcallImpl(RTLIB::NEARBYINT_F128, RTLIB::nearbyintf128); + Info.setLibcallImpl(RTLIB::ROUND_F128, RTLIB::roundf128); + Info.setLibcallImpl(RTLIB::ROUNDEVEN_F128, RTLIB::roundevenf128); + Info.setLibcallImpl(RTLIB::FLOOR_F128, RTLIB::floorf128); + Info.setLibcallImpl(RTLIB::COPYSIGN_F128, RTLIB::copysignf128); + Info.setLibcallImpl(RTLIB::FMIN_F128, RTLIB::fminf128); + Info.setLibcallImpl(RTLIB::FMAX_F128, RTLIB::fmaxf128); + Info.setLibcallImpl(RTLIB::FMINIMUM_F128, RTLIB::fminimumf128); + Info.setLibcallImpl(RTLIB::FMAXIMUM_F128, RTLIB::fmaximumf128); + Info.setLibcallImpl(RTLIB::FMINIMUM_NUM_F128, RTLIB::fminimum_numf128); + Info.setLibcallImpl(RTLIB::FMAXIMUM_NUM_F128, RTLIB::fmaximum_numf128); + Info.setLibcallImpl(RTLIB::LROUND_F128, RTLIB::lroundf128); + Info.setLibcallImpl(RTLIB::LLROUND_F128, RTLIB::llroundf128); + Info.setLibcallImpl(RTLIB::LRINT_F128, RTLIB::lrintf128); + Info.setLibcallImpl(RTLIB::LLRINT_F128, RTLIB::llrintf128); + Info.setLibcallImpl(RTLIB::LDEXP_F128, RTLIB::ldexpf128); + Info.setLibcallImpl(RTLIB::FREXP_F128, RTLIB::frexpf128); + Info.setLibcallImpl(RTLIB::MODF_F128, RTLIB::modff128); if (FiniteOnlyFuncs) { - Info.setLibcallName(RTLIB::LOG_FINITE_F128, "__logf128_finite"); - Info.setLibcallName(RTLIB::LOG2_FINITE_F128, "__log2f128_finite"); - Info.setLibcallName(RTLIB::LOG10_FINITE_F128, "__log10f128_finite"); - Info.setLibcallName(RTLIB::EXP_FINITE_F128, "__expf128_finite"); - Info.setLibcallName(RTLIB::EXP2_FINITE_F128, "__exp2f128_finite"); - Info.setLibcallName(RTLIB::POW_FINITE_F128, "__powf128_finite"); + Info.setLibcallImpl(RTLIB::LOG_FINITE_F128, RTLIB::__logf128_finite); + Info.setLibcallImpl(RTLIB::LOG2_FINITE_F128, RTLIB::__log2f128_finite); + Info.setLibcallImpl(RTLIB::LOG10_FINITE_F128, RTLIB::__log10f128_finite); + Info.setLibcallImpl(RTLIB::EXP_FINITE_F128, RTLIB::__expf128_finite); + Info.setLibcallImpl(RTLIB::EXP2_FINITE_F128, RTLIB::__exp2f128_finite); + Info.setLibcallImpl(RTLIB::POW_FINITE_F128, RTLIB::__powf128_finite); } else { - Info.setLibcallName(RTLIB::LOG_FINITE_F128, nullptr); - Info.setLibcallName(RTLIB::LOG2_FINITE_F128, nullptr); - Info.setLibcallName(RTLIB::LOG10_FINITE_F128, nullptr); - Info.setLibcallName(RTLIB::EXP_FINITE_F128, nullptr); - Info.setLibcallName(RTLIB::EXP2_FINITE_F128, nullptr); - Info.setLibcallName(RTLIB::POW_FINITE_F128, nullptr); + Info.setLibcallImpl(RTLIB::LOG_FINITE_F128, RTLIB::Unsupported); + Info.setLibcallImpl(RTLIB::LOG2_FINITE_F128, RTLIB::Unsupported); + Info.setLibcallImpl(RTLIB::LOG10_FINITE_F128, RTLIB::Unsupported); + Info.setLibcallImpl(RTLIB::EXP_FINITE_F128, RTLIB::Unsupported); + Info.setLibcallImpl(RTLIB::EXP2_FINITE_F128, RTLIB::Unsupported); + Info.setLibcallImpl(RTLIB::POW_FINITE_F128, RTLIB::Unsupported); } } -void RuntimeLibcallsInfo::initDefaultLibCallNames() { - std::memcpy(LibcallRoutineNames, DefaultLibcallRoutineNames, - sizeof(LibcallRoutineNames)); - static_assert(sizeof(LibcallRoutineNames) == - sizeof(DefaultLibcallRoutineNames), +void RTLIB::RuntimeLibcallsInfo::initDefaultLibCallImpls() { + std::memcpy(LibcallImpls, DefaultLibcallImpls, sizeof(LibcallImpls)); + static_assert(sizeof(LibcallImpls) == sizeof(DefaultLibcallImpls), "libcall array size should match"); } @@ -367,7 +364,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, if (TT.isX86() || TT.isVE()) { if (ExceptionModel == ExceptionHandling::SjLj) - setLibcallName(RTLIB::UNWIND_RESUME, "_Unwind_SjLj_Resume"); + setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume); } if (TT.isPPC()) { @@ -376,12 +373,19 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, // TODO: Do the finite only functions exist? setLongDoubleIsF128Libm(*this, /*FiniteOnlyFuncs=*/false); + // TODO: Tablegen predicate support if (TT.isOSAIX()) { - bool isPPC64 = TT.isPPC64(); - setLibcallName(RTLIB::MEMCPY, nullptr); - setLibcallName(RTLIB::MEMMOVE, isPPC64 ? "___memmove64" : "___memmove"); - setLibcallName(RTLIB::MEMSET, isPPC64 ? "___memset64" : "___memset"); - setLibcallName(RTLIB::BZERO, isPPC64 ? "___bzero64" : "___bzero"); + if (TT.isPPC64()) { + setLibcallImpl(RTLIB::MEMCPY, RTLIB::Unsupported); + setLibcallImpl(RTLIB::MEMMOVE, RTLIB::___memmove64); + setLibcallImpl(RTLIB::MEMSET, RTLIB::___memset64); + setLibcallImpl(RTLIB::BZERO, RTLIB::___bzero64); + } else { + setLibcallImpl(RTLIB::MEMCPY, RTLIB::Unsupported); + setLibcallImpl(RTLIB::MEMMOVE, RTLIB::___memmove); + setLibcallImpl(RTLIB::MEMSET, RTLIB::___memset); + setLibcallImpl(RTLIB::BZERO, RTLIB::___bzero); + } } } @@ -390,27 +394,27 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, // For f16/f32 conversions, Darwin uses the standard naming scheme, // instead of the gnueabi-style __gnu_*_ieee. // FIXME: What about other targets? - setLibcallName(RTLIB::FPEXT_F16_F32, "__extendhfsf2"); - setLibcallName(RTLIB::FPROUND_F32_F16, "__truncsfhf2"); + setLibcallImpl(RTLIB::FPEXT_F16_F32, RTLIB::__extendhfsf2); + setLibcallImpl(RTLIB::FPROUND_F32_F16, RTLIB::__truncsfhf2); // Some darwins have an optimized __bzero/bzero function. switch (TT.getArch()) { case Triple::x86: case Triple::x86_64: if (TT.isMacOSX() && !TT.isMacOSXVersionLT(10, 6)) - setLibcallName(RTLIB::BZERO, "__bzero"); + setLibcallImpl(RTLIB::BZERO, RTLIB::__bzero); break; case Triple::aarch64: case Triple::aarch64_32: - setLibcallName(RTLIB::BZERO, "bzero"); + setLibcallImpl(RTLIB::BZERO, RTLIB::bzero); break; default: break; } if (darwinHasSinCosStret(TT)) { - setLibcallName(RTLIB::SINCOS_STRET_F32, "__sincosf_stret"); - setLibcallName(RTLIB::SINCOS_STRET_F64, "__sincos_stret"); + setLibcallImpl(RTLIB::SINCOS_STRET_F32, RTLIB::__sincosf_stret); + setLibcallImpl(RTLIB::SINCOS_STRET_F64, RTLIB::__sincos_stret); if (TT.isWatchABI()) { setLibcallCallingConv(RTLIB::SINCOS_STRET_F32, CallingConv::ARM_AAPCS_VFP); @@ -422,17 +426,17 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, switch (TT.getOS()) { case Triple::MacOSX: if (TT.isMacOSXVersionLT(10, 9)) { - setLibcallName(RTLIB::EXP10_F32, nullptr); - setLibcallName(RTLIB::EXP10_F64, nullptr); + setLibcallImpl(RTLIB::EXP10_F32, RTLIB::Unsupported); + setLibcallImpl(RTLIB::EXP10_F64, RTLIB::Unsupported); } else { - setLibcallName(RTLIB::EXP10_F32, "__exp10f"); - setLibcallName(RTLIB::EXP10_F64, "__exp10"); + setLibcallImpl(RTLIB::EXP10_F32, RTLIB::__exp10f); + setLibcallImpl(RTLIB::EXP10_F64, RTLIB::__exp10); } break; case Triple::IOS: if (TT.isOSVersionLT(7, 0)) { - setLibcallName(RTLIB::EXP10_F32, nullptr); - setLibcallName(RTLIB::EXP10_F64, nullptr); + setLibcallImpl(RTLIB::EXP10_F32, RTLIB::Unsupported); + setLibcallImpl(RTLIB::EXP10_F64, RTLIB::Unsupported); break; } [[fallthrough]]; @@ -440,59 +444,59 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, case Triple::TvOS: case Triple::WatchOS: case Triple::XROS: - setLibcallName(RTLIB::EXP10_F32, "__exp10f"); - setLibcallName(RTLIB::EXP10_F64, "__exp10"); + setLibcallImpl(RTLIB::EXP10_F32, RTLIB::__exp10f); + setLibcallImpl(RTLIB::EXP10_F64, RTLIB::__exp10); break; default: break; } } else if (TT.getOS() == Triple::BridgeOS) { // TODO: BridgeOS should be included in isOSDarwin. - setLibcallName(RTLIB::EXP10_F32, "__exp10f"); - setLibcallName(RTLIB::EXP10_F64, "__exp10"); + setLibcallImpl(RTLIB::EXP10_F32, RTLIB::__exp10f); + setLibcallImpl(RTLIB::EXP10_F64, RTLIB::__exp10); } if (hasSinCos(TT)) { - setLibcallName(RTLIB::SINCOS_F32, "sincosf"); - setLibcallName(RTLIB::SINCOS_F64, "sincos"); - setLibcallName(RTLIB::SINCOS_F80, "sincosl"); - setLibcallName(RTLIB::SINCOS_F128, "sincosl"); - setLibcallName(RTLIB::SINCOS_PPCF128, "sincosl"); + setLibcallImpl(RTLIB::SINCOS_F32, RTLIB::sincosf); + setLibcallImpl(RTLIB::SINCOS_F64, RTLIB::sincos); + setLibcallImpl(RTLIB::SINCOS_F80, RTLIB::sincos_f80); + setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincos_f128); + setLibcallImpl(RTLIB::SINCOS_PPCF128, RTLIB::sincos_ppcf128); } if (TT.isPS()) { - setLibcallName(RTLIB::SINCOS_F32, "sincosf"); - setLibcallName(RTLIB::SINCOS_F64, "sincos"); + setLibcallImpl(RTLIB::SINCOS_F32, RTLIB::sincosf); + setLibcallImpl(RTLIB::SINCOS_F64, RTLIB::sincos); } if (TT.isOSOpenBSD()) { - setLibcallName(RTLIB::STACKPROTECTOR_CHECK_FAIL, nullptr); + setLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL, RTLIB::Unsupported); } if (TT.isOSWindows() && !TT.isOSCygMing()) { - setLibcallName(RTLIB::LDEXP_F32, nullptr); - setLibcallName(RTLIB::LDEXP_F80, nullptr); - setLibcallName(RTLIB::LDEXP_F128, nullptr); - setLibcallName(RTLIB::LDEXP_PPCF128, nullptr); - - setLibcallName(RTLIB::FREXP_F32, nullptr); - setLibcallName(RTLIB::FREXP_F80, nullptr); - setLibcallName(RTLIB::FREXP_F128, nullptr); - setLibcallName(RTLIB::FREXP_PPCF128, nullptr); + setLibcallImpl(RTLIB::LDEXP_F32, RTLIB::Unsupported); + setLibcallImpl(RTLIB::LDEXP_F80, RTLIB::Unsupported); + setLibcallImpl(RTLIB::LDEXP_F128, RTLIB::Unsupported); + setLibcallImpl(RTLIB::LDEXP_PPCF128, RTLIB::Unsupported); + + setLibcallImpl(RTLIB::FREXP_F32, RTLIB::Unsupported); + setLibcallImpl(RTLIB::FREXP_F80, RTLIB::Unsupported); + setLibcallImpl(RTLIB::FREXP_F128, RTLIB::Unsupported); + setLibcallImpl(RTLIB::FREXP_PPCF128, RTLIB::Unsupported); } // Disable most libcalls on AMDGPU and NVPTX. if (TT.isAMDGPU() || TT.isNVPTX()) { for (RTLIB::Libcall LC : RTLIB::libcalls()) { if (!isAtomicLibCall(LC)) - setLibcallName(LC, nullptr); + setLibcallImpl(LC, RTLIB::Unsupported); } } if (TT.isOSMSVCRT()) { // MSVCRT doesn't have powi; fall back to pow - setLibcallName(RTLIB::POWI_F32, nullptr); - setLibcallName(RTLIB::POWI_F64, nullptr); + setLibcallImpl(RTLIB::POWI_F32, RTLIB::Unsupported); + setLibcallImpl(RTLIB::POWI_F64, RTLIB::Unsupported); } // Setup Windows compiler runtime calls. @@ -500,18 +504,18 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, (TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment())) { static const struct { const RTLIB::Libcall Op; - const char *const Name; + const RTLIB::LibcallImpl Impl; const CallingConv::ID CC; } LibraryCalls[] = { - {RTLIB::SDIV_I64, "_alldiv", CallingConv::X86_StdCall}, - {RTLIB::UDIV_I64, "_aulldiv", CallingConv::X86_StdCall}, - {RTLIB::SREM_I64, "_allrem", CallingConv::X86_StdCall}, - {RTLIB::UREM_I64, "_aullrem", CallingConv::X86_StdCall}, - {RTLIB::MUL_I64, "_allmul", CallingConv::X86_StdCall}, + {RTLIB::SDIV_I64, RTLIB::_alldiv, CallingConv::X86_StdCall}, + {RTLIB::UDIV_I64, RTLIB::_aulldiv, CallingConv::X86_StdCall}, + {RTLIB::SREM_I64, RTLIB::_allrem, CallingConv::X86_StdCall}, + {RTLIB::UREM_I64, RTLIB::_aullrem, CallingConv::X86_StdCall}, + {RTLIB::MUL_I64, RTLIB::_allmul, CallingConv::X86_StdCall}, }; for (const auto &LC : LibraryCalls) { - setLibcallName(LC.Op, LC.Name); + setLibcallImpl(LC.Op, LC.Impl); setLibcallCallingConv(LC.Op, LC.CC); } } @@ -524,28 +528,28 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, setARMLibcallNames(*this, TT, FloatABI, EABIVersion); } else if (TT.getArch() == Triple::ArchType::avr) { // Division rtlib functions (not supported), use divmod functions instead - setLibcallName(RTLIB::SDIV_I8, nullptr); - setLibcallName(RTLIB::SDIV_I16, nullptr); - setLibcallName(RTLIB::SDIV_I32, nullptr); - setLibcallName(RTLIB::UDIV_I8, nullptr); - setLibcallName(RTLIB::UDIV_I16, nullptr); - setLibcallName(RTLIB::UDIV_I32, nullptr); + setLibcallImpl(RTLIB::SDIV_I8, RTLIB::Unsupported); + setLibcallImpl(RTLIB::SDIV_I16, RTLIB::Unsupported); + setLibcallImpl(RTLIB::SDIV_I32, RTLIB::Unsupported); + setLibcallImpl(RTLIB::UDIV_I8, RTLIB::Unsupported); + setLibcallImpl(RTLIB::UDIV_I16, RTLIB::Unsupported); + setLibcallImpl(RTLIB::UDIV_I32, RTLIB::Unsupported); // Modulus rtlib functions (not supported), use divmod functions instead - setLibcallName(RTLIB::SREM_I8, nullptr); - setLibcallName(RTLIB::SREM_I16, nullptr); - setLibcallName(RTLIB::SREM_I32, nullptr); - setLibcallName(RTLIB::UREM_I8, nullptr); - setLibcallName(RTLIB::UREM_I16, nullptr); - setLibcallName(RTLIB::UREM_I32, nullptr); + setLibcallImpl(RTLIB::SREM_I8, RTLIB::Unsupported); + setLibcallImpl(RTLIB::SREM_I16, RTLIB::Unsupported); + setLibcallImpl(RTLIB::SREM_I32, RTLIB::Unsupported); + setLibcallImpl(RTLIB::UREM_I8, RTLIB::Unsupported); + setLibcallImpl(RTLIB::UREM_I16, RTLIB::Unsupported); + setLibcallImpl(RTLIB::UREM_I32, RTLIB::Unsupported); // Division and modulus rtlib functions - setLibcallName(RTLIB::SDIVREM_I8, "__divmodqi4"); - setLibcallName(RTLIB::SDIVREM_I16, "__divmodhi4"); - setLibcallName(RTLIB::SDIVREM_I32, "__divmodsi4"); - setLibcallName(RTLIB::UDIVREM_I8, "__udivmodqi4"); - setLibcallName(RTLIB::UDIVREM_I16, "__udivmodhi4"); - setLibcallName(RTLIB::UDIVREM_I32, "__udivmodsi4"); + setLibcallImpl(RTLIB::SDIVREM_I8, RTLIB::__divmodqi4); + setLibcallImpl(RTLIB::SDIVREM_I16, RTLIB::__divmodhi4); + setLibcallImpl(RTLIB::SDIVREM_I32, RTLIB::__divmodsi4); + setLibcallImpl(RTLIB::UDIVREM_I8, RTLIB::__udivmodqi4); + setLibcallImpl(RTLIB::UDIVREM_I16, RTLIB::__udivmodhi4); + setLibcallImpl(RTLIB::UDIVREM_I32, RTLIB::__udivmodsi4); // Several of the runtime library functions use a special calling conv setLibcallCallingConv(RTLIB::SDIVREM_I8, CallingConv::AVR_BUILTIN); @@ -554,63 +558,64 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, setLibcallCallingConv(RTLIB::UDIVREM_I16, CallingConv::AVR_BUILTIN); // Trigonometric rtlib functions - setLibcallName(RTLIB::SIN_F32, "sin"); - setLibcallName(RTLIB::COS_F32, "cos"); + setLibcallImpl(RTLIB::SIN_F32, RTLIB::avr_sin); + setLibcallImpl(RTLIB::COS_F32, RTLIB::avr_cos); } if (!TT.isWasm()) { // These libcalls are only available in compiler-rt, not libgcc. if (TT.isArch32Bit()) { - setLibcallName(RTLIB::SHL_I128, nullptr); - setLibcallName(RTLIB::SRL_I128, nullptr); - setLibcallName(RTLIB::SRA_I128, nullptr); - setLibcallName(RTLIB::MUL_I128, nullptr); - setLibcallName(RTLIB::MULO_I64, nullptr); + setLibcallImpl(RTLIB::SHL_I128, RTLIB::Unsupported); + setLibcallImpl(RTLIB::SRL_I128, RTLIB::Unsupported); + setLibcallImpl(RTLIB::SRA_I128, RTLIB::Unsupported); + setLibcallImpl(RTLIB::MUL_I128, RTLIB::Unsupported); + setLibcallImpl(RTLIB::MULO_I64, RTLIB::Unsupported); } - setLibcallName(RTLIB::MULO_I128, nullptr); + + setLibcallImpl(RTLIB::MULO_I128, RTLIB::Unsupported); } else { // Define the emscripten name for return address helper. // TODO: when implementing other Wasm backends, make this generic or only do // this on emscripten depending on what they end up doing. - setLibcallName(RTLIB::RETURN_ADDRESS, "emscripten_return_address"); + setLibcallImpl(RTLIB::RETURN_ADDRESS, RTLIB::emscripten_return_address); } if (TT.getArch() == Triple::ArchType::hexagon) { - setLibcallName(RTLIB::SDIV_I32, "__hexagon_divsi3"); - setLibcallName(RTLIB::SDIV_I64, "__hexagon_divdi3"); - setLibcallName(RTLIB::UDIV_I32, "__hexagon_udivsi3"); - setLibcallName(RTLIB::UDIV_I64, "__hexagon_udivdi3"); - setLibcallName(RTLIB::SREM_I32, "__hexagon_modsi3"); - setLibcallName(RTLIB::SREM_I64, "__hexagon_moddi3"); - setLibcallName(RTLIB::UREM_I32, "__hexagon_umodsi3"); - setLibcallName(RTLIB::UREM_I64, "__hexagon_umoddi3"); + setLibcallImpl(RTLIB::SDIV_I32, RTLIB::__hexagon_divsi3); + setLibcallImpl(RTLIB::SDIV_I64, RTLIB::__hexagon_divdi3); + setLibcallImpl(RTLIB::UDIV_I32, RTLIB::__hexagon_udivsi3); + setLibcallImpl(RTLIB::UDIV_I64, RTLIB::__hexagon_udivdi3); + setLibcallImpl(RTLIB::SREM_I32, RTLIB::__hexagon_modsi3); + setLibcallImpl(RTLIB::SREM_I64, RTLIB::__hexagon_moddi3); + setLibcallImpl(RTLIB::UREM_I32, RTLIB::__hexagon_umodsi3); + setLibcallImpl(RTLIB::UREM_I64, RTLIB::__hexagon_umoddi3); const bool FastMath = HexagonEnableFastMathRuntimeCalls; // This is the only fast library function for sqrtd. if (FastMath) - setLibcallName(RTLIB::SQRT_F64, "__hexagon_fast2_sqrtdf2"); + setLibcallImpl(RTLIB::SQRT_F64, RTLIB::__hexagon_fast2_sqrtdf2); // Prefix is: nothing for "slow-math", // "fast2_" for V5+ fast-math double-precision // (actually, keep fast-math and fast-math2 separate for now) if (FastMath) { - setLibcallName(RTLIB::ADD_F64, "__hexagon_fast_adddf3"); - setLibcallName(RTLIB::SUB_F64, "__hexagon_fast_subdf3"); - setLibcallName(RTLIB::MUL_F64, "__hexagon_fast_muldf3"); - setLibcallName(RTLIB::DIV_F64, "__hexagon_fast_divdf3"); - setLibcallName(RTLIB::DIV_F32, "__hexagon_fast_divsf3"); + setLibcallImpl(RTLIB::ADD_F64, RTLIB::__hexagon_fast_adddf3); + setLibcallImpl(RTLIB::SUB_F64, RTLIB::__hexagon_fast_subdf3); + setLibcallImpl(RTLIB::MUL_F64, RTLIB::__hexagon_fast_muldf3); + setLibcallImpl(RTLIB::DIV_F64, RTLIB::__hexagon_fast_divdf3); + setLibcallImpl(RTLIB::DIV_F32, RTLIB::__hexagon_fast_divsf3); } else { - setLibcallName(RTLIB::ADD_F64, "__hexagon_adddf3"); - setLibcallName(RTLIB::SUB_F64, "__hexagon_subdf3"); - setLibcallName(RTLIB::MUL_F64, "__hexagon_muldf3"); - setLibcallName(RTLIB::DIV_F64, "__hexagon_divdf3"); - setLibcallName(RTLIB::DIV_F32, "__hexagon_divsf3"); + setLibcallImpl(RTLIB::ADD_F64, RTLIB::__hexagon_adddf3); + setLibcallImpl(RTLIB::SUB_F64, RTLIB::__hexagon_subdf3); + setLibcallImpl(RTLIB::MUL_F64, RTLIB::__hexagon_muldf3); + setLibcallImpl(RTLIB::DIV_F64, RTLIB::__hexagon_divdf3); + setLibcallImpl(RTLIB::DIV_F32, RTLIB::__hexagon_divsf3); } if (FastMath) - setLibcallName(RTLIB::SQRT_F32, "__hexagon_fast2_sqrtf"); + setLibcallImpl(RTLIB::SQRT_F32, RTLIB::__hexagon_fast2_sqrtf); else - setLibcallName(RTLIB::SQRT_F32, "__hexagon_sqrtf"); + setLibcallImpl(RTLIB::SQRT_F32, RTLIB::__hexagon_sqrtf); } if (TT.getArch() == Triple::ArchType::msp430) diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index adf995cbc9b18..779c98ee4441e 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -1389,8 +1389,14 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) { SmallVector LTO::getRuntimeLibcallSymbols(const Triple &TT) { RTLIB::RuntimeLibcallsInfo Libcalls(TT); SmallVector LibcallSymbols; - copy_if(Libcalls.getLibcallNames(), std::back_inserter(LibcallSymbols), - [](const char *Name) { return Name; }); + ArrayRef LibcallImpls = Libcalls.getLibcallImpls(); + LibcallSymbols.reserve(LibcallImpls.size()); + + for (RTLIB::LibcallImpl Impl : LibcallImpls) { + if (Impl != RTLIB::Unsupported) + LibcallSymbols.push_back(Libcalls.getLibcallImplName(Impl)); + } + return LibcallSymbols; } diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp index 2f25c771a93fa..2579fa37935f0 100644 --- a/llvm/lib/Object/IRSymtab.cpp +++ b/llvm/lib/Object/IRSymtab.cpp @@ -218,9 +218,9 @@ static DenseSet buildPreservedSymbolsSet(const Triple &TT) { std::end(PreservedSymbols)); // FIXME: Do we need to pass in ABI fields from TargetOptions? RTLIB::RuntimeLibcallsInfo Libcalls(TT); - for (const char *Name : Libcalls.getLibcallNames()) { - if (Name) - PreservedSymbolSet.insert(Name); + for (RTLIB::LibcallImpl Impl : Libcalls.getLibcallImpls()) { + if (Impl != RTLIB::Unsupported) + PreservedSymbolSet.insert(Libcalls.getLibcallImplName(Impl)); } return PreservedSymbolSet; } diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 4567081fe78dc..81b535e19bc71 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -524,65 +524,65 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, // clang-format off static const struct { const RTLIB::Libcall Op; - const char * const Name; + const RTLIB::LibcallImpl Impl; const CmpInst::Predicate Cond; } LibraryCalls[] = { // Single-precision floating-point arithmetic. - { RTLIB::ADD_F32, "__addsf3vfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SUB_F32, "__subsf3vfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::MUL_F32, "__mulsf3vfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::DIV_F32, "__divsf3vfp", CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::ADD_F32, RTLIB::__addsf3vfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SUB_F32, RTLIB::__subsf3vfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::MUL_F32, RTLIB::__mulsf3vfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::DIV_F32, RTLIB::__divsf3vfp, CmpInst::BAD_ICMP_PREDICATE }, // Double-precision floating-point arithmetic. - { RTLIB::ADD_F64, "__adddf3vfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SUB_F64, "__subdf3vfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::MUL_F64, "__muldf3vfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::DIV_F64, "__divdf3vfp", CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::ADD_F64, RTLIB::__adddf3vfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SUB_F64, RTLIB::__subdf3vfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::MUL_F64, RTLIB::__muldf3vfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::DIV_F64, RTLIB::__divdf3vfp, CmpInst::BAD_ICMP_PREDICATE }, // Single-precision comparisons. - { RTLIB::OEQ_F32, "__eqsf2vfp", CmpInst::ICMP_NE }, - { RTLIB::UNE_F32, "__nesf2vfp", CmpInst::ICMP_NE }, - { RTLIB::OLT_F32, "__ltsf2vfp", CmpInst::ICMP_NE }, - { RTLIB::OLE_F32, "__lesf2vfp", CmpInst::ICMP_NE }, - { RTLIB::OGE_F32, "__gesf2vfp", CmpInst::ICMP_NE }, - { RTLIB::OGT_F32, "__gtsf2vfp", CmpInst::ICMP_NE }, - { RTLIB::UO_F32, "__unordsf2vfp", CmpInst::ICMP_NE }, + { RTLIB::OEQ_F32, RTLIB::__eqsf2vfp, CmpInst::ICMP_NE }, + { RTLIB::UNE_F32, RTLIB::__nesf2vfp, CmpInst::ICMP_NE }, + { RTLIB::OLT_F32, RTLIB::__ltsf2vfp, CmpInst::ICMP_NE }, + { RTLIB::OLE_F32, RTLIB::__lesf2vfp, CmpInst::ICMP_NE }, + { RTLIB::OGE_F32, RTLIB::__gesf2vfp, CmpInst::ICMP_NE }, + { RTLIB::OGT_F32, RTLIB::__gtsf2vfp, CmpInst::ICMP_NE }, + { RTLIB::UO_F32, RTLIB::__unordsf2vfp, CmpInst::ICMP_NE }, // Double-precision comparisons. - { RTLIB::OEQ_F64, "__eqdf2vfp", CmpInst::ICMP_NE }, - { RTLIB::UNE_F64, "__nedf2vfp", CmpInst::ICMP_NE }, - { RTLIB::OLT_F64, "__ltdf2vfp", CmpInst::ICMP_NE }, - { RTLIB::OLE_F64, "__ledf2vfp", CmpInst::ICMP_NE }, - { RTLIB::OGE_F64, "__gedf2vfp", CmpInst::ICMP_NE }, - { RTLIB::OGT_F64, "__gtdf2vfp", CmpInst::ICMP_NE }, - { RTLIB::UO_F64, "__unorddf2vfp", CmpInst::ICMP_NE }, + { RTLIB::OEQ_F64, RTLIB::__eqdf2vfp, CmpInst::ICMP_NE }, + { RTLIB::UNE_F64, RTLIB::__nedf2vfp, CmpInst::ICMP_NE }, + { RTLIB::OLT_F64, RTLIB::__ltdf2vfp, CmpInst::ICMP_NE }, + { RTLIB::OLE_F64, RTLIB::__ledf2vfp, CmpInst::ICMP_NE }, + { RTLIB::OGE_F64, RTLIB::__gedf2vfp, CmpInst::ICMP_NE }, + { RTLIB::OGT_F64, RTLIB::__gtdf2vfp, CmpInst::ICMP_NE }, + { RTLIB::UO_F64, RTLIB::__unorddf2vfp, 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. - { RTLIB::FPTOSINT_F64_I32, "__fixdfsivfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPTOUINT_F64_I32, "__fixunsdfsivfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPTOSINT_F32_I32, "__fixsfsivfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPTOUINT_F32_I32, "__fixunssfsivfp", CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOSINT_F64_I32, RTLIB::__fixdfsivfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOUINT_F64_I32, RTLIB::__fixunsdfsivfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOSINT_F32_I32, RTLIB::__fixsfsivfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOUINT_F32_I32, RTLIB::__fixunssfsivfp, CmpInst::BAD_ICMP_PREDICATE }, // Conversions between floating types. - { RTLIB::FPROUND_F64_F32, "__truncdfsf2vfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPEXT_F32_F64, "__extendsfdf2vfp", CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPROUND_F64_F32, RTLIB::__truncdfsf2vfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPEXT_F32_F64, RTLIB::__extendsfdf2vfp, CmpInst::BAD_ICMP_PREDICATE }, // 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, "__floatsidfvfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::UINTTOFP_I32_F64, "__floatunssidfvfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SINTTOFP_I32_F32, "__floatsisfvfp", CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::UINTTOFP_I32_F32, "__floatunssisfvfp", CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SINTTOFP_I32_F64, RTLIB::__floatsidfvfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::UINTTOFP_I32_F64, RTLIB::__floatunssidfvfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SINTTOFP_I32_F32, RTLIB::__floatsisfvfp, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::UINTTOFP_I32_F32, RTLIB::__floatunssisfvfp, CmpInst::BAD_ICMP_PREDICATE }, }; // clang-format on for (const auto &LC : LibraryCalls) { - setLibcallName(LC.Op, LC.Name); + setLibcallImpl(LC.Op, LC.Impl); if (LC.Cond != CmpInst::BAD_ICMP_PREDICATE) setCmpLibcallCC(LC.Op, LC.Cond); } @@ -592,97 +592,100 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, // RTLIB if (TM.isAAPCS_ABI() && (TT.isTargetAEABI() || TT.isTargetGNUAEABI() || TT.isTargetMuslAEABI() || TT.isAndroid())) { + // FIXME: This does not depend on the subtarget and should go directly into + // RuntimeLibcalls. This is only here because of missing support for setting + // the calling convention of an implementation. // clang-format off static const struct { const RTLIB::Libcall Op; - const char * const Name; + const RTLIB::LibcallImpl Impl; const CallingConv::ID CC; const CmpInst::Predicate Cond; } LibraryCalls[] = { // Double-precision floating-point arithmetic helper functions // RTABI chapter 4.1.2, Table 2 - { RTLIB::ADD_F64, "__aeabi_dadd", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::DIV_F64, "__aeabi_ddiv", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::MUL_F64, "__aeabi_dmul", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SUB_F64, "__aeabi_dsub", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::ADD_F64, RTLIB::__aeabi_dadd, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::DIV_F64, RTLIB::__aeabi_ddiv, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::MUL_F64, RTLIB::__aeabi_dmul, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SUB_F64, RTLIB::__aeabi_dsub, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, // Double-precision floating-point comparison helper functions // RTABI chapter 4.1.2, Table 3 - { RTLIB::OEQ_F64, "__aeabi_dcmpeq", CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, - { RTLIB::UNE_F64, "__aeabi_dcmpeq", CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ }, - { RTLIB::OLT_F64, "__aeabi_dcmplt", CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, - { RTLIB::OLE_F64, "__aeabi_dcmple", CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, - { RTLIB::OGE_F64, "__aeabi_dcmpge", CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, - { RTLIB::OGT_F64, "__aeabi_dcmpgt", CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, - { RTLIB::UO_F64, "__aeabi_dcmpun", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::OEQ_F64, RTLIB::__aeabi_dcmpeq__ne, CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, + { RTLIB::UNE_F64, RTLIB::__aeabi_dcmpeq__eq, CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ }, + { RTLIB::OLT_F64, RTLIB::__aeabi_dcmplt, CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, + { RTLIB::OLE_F64, RTLIB::__aeabi_dcmple, CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, + { RTLIB::OGE_F64, RTLIB::__aeabi_dcmpge, CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, + { RTLIB::OGT_F64, RTLIB::__aeabi_dcmpgt, CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, + { RTLIB::UO_F64, RTLIB::__aeabi_dcmpun, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, // Single-precision floating-point arithmetic helper functions // RTABI chapter 4.1.2, Table 4 - { RTLIB::ADD_F32, "__aeabi_fadd", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::DIV_F32, "__aeabi_fdiv", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::MUL_F32, "__aeabi_fmul", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SUB_F32, "__aeabi_fsub", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::ADD_F32, RTLIB::__aeabi_fadd, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::DIV_F32, RTLIB::__aeabi_fdiv, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::MUL_F32, RTLIB::__aeabi_fmul, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SUB_F32, RTLIB::__aeabi_fsub, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, // Single-precision floating-point comparison helper functions // RTABI chapter 4.1.2, Table 5 - { RTLIB::OEQ_F32, "__aeabi_fcmpeq", CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, - { RTLIB::UNE_F32, "__aeabi_fcmpeq", CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ }, - { RTLIB::OLT_F32, "__aeabi_fcmplt", CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, - { RTLIB::OLE_F32, "__aeabi_fcmple", CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, - { RTLIB::OGE_F32, "__aeabi_fcmpge", CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, - { RTLIB::OGT_F32, "__aeabi_fcmpgt", CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, - { RTLIB::UO_F32, "__aeabi_fcmpun", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::OEQ_F32, RTLIB::__aeabi_fcmpeq__ne, CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, + { RTLIB::UNE_F32, RTLIB::__aeabi_fcmpeq__eq, CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ }, + { RTLIB::OLT_F32, RTLIB::__aeabi_fcmplt, CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, + { RTLIB::OLE_F32, RTLIB::__aeabi_fcmple, CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, + { RTLIB::OGE_F32, RTLIB::__aeabi_fcmpge, CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, + { RTLIB::OGT_F32, RTLIB::__aeabi_fcmpgt, CallingConv::ARM_AAPCS, CmpInst::ICMP_NE }, + { RTLIB::UO_F32, RTLIB::__aeabi_fcmpun, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, // Floating-point to integer conversions. // RTABI chapter 4.1.2, Table 6 - { RTLIB::FPTOSINT_F64_I32, "__aeabi_d2iz", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPTOUINT_F64_I32, "__aeabi_d2uiz", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPTOSINT_F64_I64, "__aeabi_d2lz", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPTOUINT_F64_I64, "__aeabi_d2ulz", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPTOSINT_F32_I32, "__aeabi_f2iz", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPTOUINT_F32_I32, "__aeabi_f2uiz", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPTOSINT_F32_I64, "__aeabi_f2lz", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPTOUINT_F32_I64, "__aeabi_f2ulz", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOSINT_F64_I32, RTLIB::__aeabi_d2iz, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOUINT_F64_I32, RTLIB::__aeabi_d2uiz, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOSINT_F64_I64, RTLIB::__aeabi_d2lz, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOUINT_F64_I64, RTLIB::__aeabi_d2ulz, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOSINT_F32_I32, RTLIB::__aeabi_f2iz, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOUINT_F32_I32, RTLIB::__aeabi_f2uiz, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOSINT_F32_I64, RTLIB::__aeabi_f2lz, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPTOUINT_F32_I64, RTLIB::__aeabi_f2ulz, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, // Conversions between floating types. // RTABI chapter 4.1.2, Table 7 - { RTLIB::FPROUND_F64_F32, "__aeabi_d2f", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPROUND_F64_F16, "__aeabi_d2h", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::FPEXT_F32_F64, "__aeabi_f2d", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPROUND_F64_F32, RTLIB::__aeabi_d2f, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPROUND_F64_F16, RTLIB::__aeabi_d2h, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::FPEXT_F32_F64, RTLIB::__aeabi_f2d, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, // Integer to floating-point conversions. // RTABI chapter 4.1.2, Table 8 - { RTLIB::SINTTOFP_I32_F64, "__aeabi_i2d", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::UINTTOFP_I32_F64, "__aeabi_ui2d", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SINTTOFP_I64_F64, "__aeabi_l2d", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::UINTTOFP_I64_F64, "__aeabi_ul2d", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SINTTOFP_I32_F32, "__aeabi_i2f", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::UINTTOFP_I32_F32, "__aeabi_ui2f", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SINTTOFP_I64_F32, "__aeabi_l2f", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::UINTTOFP_I64_F32, "__aeabi_ul2f", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SINTTOFP_I32_F64, RTLIB::__aeabi_i2d, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::UINTTOFP_I32_F64, RTLIB::__aeabi_ui2d, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SINTTOFP_I64_F64, RTLIB::__aeabi_l2d, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::UINTTOFP_I64_F64, RTLIB::__aeabi_ul2d, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SINTTOFP_I32_F32, RTLIB::__aeabi_i2f, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::UINTTOFP_I32_F32, RTLIB::__aeabi_ui2f, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SINTTOFP_I64_F32, RTLIB::__aeabi_l2f, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::UINTTOFP_I64_F32, RTLIB::__aeabi_ul2f, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, // Long long helper functions // RTABI chapter 4.2, Table 9 - { RTLIB::MUL_I64, "__aeabi_lmul", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SHL_I64, "__aeabi_llsl", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SRL_I64, "__aeabi_llsr", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SRA_I64, "__aeabi_lasr", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::MUL_I64, RTLIB::__aeabi_lmul, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SHL_I64, RTLIB::__aeabi_llsl, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SRL_I64, RTLIB::__aeabi_llsr, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SRA_I64, RTLIB::__aeabi_lasr, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, // Integer division functions // RTABI chapter 4.3.1 - { RTLIB::SDIV_I8, "__aeabi_idiv", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SDIV_I16, "__aeabi_idiv", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SDIV_I32, "__aeabi_idiv", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::SDIV_I64, "__aeabi_ldivmod", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::UDIV_I8, "__aeabi_uidiv", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::UDIV_I16, "__aeabi_uidiv", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::UDIV_I32, "__aeabi_uidiv", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, - { RTLIB::UDIV_I64, "__aeabi_uldivmod", CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SDIV_I8, RTLIB::__aeabi_idiv__i8, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SDIV_I16, RTLIB::__aeabi_idiv__i16, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SDIV_I32, RTLIB::__aeabi_idiv__i32, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::SDIV_I64, RTLIB::__aeabi_ldivmod, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::UDIV_I8, RTLIB::__aeabi_uidiv__i8, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::UDIV_I16, RTLIB::__aeabi_uidiv__i16, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::UDIV_I32, RTLIB::__aeabi_uidiv__i32, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, + { RTLIB::UDIV_I64, RTLIB::__aeabi_uldivmod, CallingConv::ARM_AAPCS, CmpInst::BAD_ICMP_PREDICATE }, }; // clang-format on for (const auto &LC : LibraryCalls) { - setLibcallName(LC.Op, LC.Name); + setLibcallImpl(LC.Op, LC.Impl); setLibcallCallingConv(LC.Op, LC.CC); if (LC.Cond != CmpInst::BAD_ICMP_PREDICATE) setCmpLibcallCC(LC.Op, LC.Cond); @@ -693,18 +696,18 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, TM.Options.EABIVersion == EABI::EABI5) { static const struct { const RTLIB::Libcall Op; - const char *const Name; + const RTLIB::LibcallImpl Impl; const CallingConv::ID CC; } MemOpsLibraryCalls[] = { // Memory operations // RTABI chapter 4.3.4 - {RTLIB::MEMCPY, "__aeabi_memcpy", CallingConv::ARM_AAPCS}, - {RTLIB::MEMMOVE, "__aeabi_memmove", CallingConv::ARM_AAPCS}, - {RTLIB::MEMSET, "__aeabi_memset", CallingConv::ARM_AAPCS}, + {RTLIB::MEMCPY, RTLIB::__aeabi_memcpy, CallingConv::ARM_AAPCS}, + {RTLIB::MEMMOVE, RTLIB::__aeabi_memmove, CallingConv::ARM_AAPCS}, + {RTLIB::MEMSET, RTLIB::__aeabi_memset, CallingConv::ARM_AAPCS}, }; for (const auto &LC : MemOpsLibraryCalls) { - setLibcallName(LC.Op, LC.Name); + setLibcallImpl(LC.Op, LC.Impl); setLibcallCallingConv(LC.Op, LC.CC); } } @@ -728,23 +731,26 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, // In EABI, these functions have an __aeabi_ prefix, but in GNUEABI they have // a __gnu_ prefix (which is the default). if (TT.isTargetAEABI()) { + // FIXME: This does not depend on the subtarget and should go directly into + // RuntimeLibcalls. This is only here because of missing support for setting + // the calling convention of an implementation. static const struct { const RTLIB::Libcall Op; - const char * const Name; + const RTLIB::LibcallImpl Impl; const CallingConv::ID CC; } LibraryCalls[] = { - { RTLIB::FPROUND_F32_F16, "__aeabi_f2h", CallingConv::ARM_AAPCS }, - { RTLIB::FPROUND_F64_F16, "__aeabi_d2h", CallingConv::ARM_AAPCS }, - { RTLIB::FPEXT_F16_F32, "__aeabi_h2f", CallingConv::ARM_AAPCS }, + {RTLIB::FPROUND_F32_F16, RTLIB::__aeabi_f2h, CallingConv::ARM_AAPCS}, + {RTLIB::FPROUND_F64_F16, RTLIB::__aeabi_d2h, CallingConv::ARM_AAPCS}, + {RTLIB::FPEXT_F16_F32, RTLIB::__aeabi_h2f, CallingConv::ARM_AAPCS}, }; for (const auto &LC : LibraryCalls) { - setLibcallName(LC.Op, LC.Name); + setLibcallImpl(LC.Op, LC.Impl); setLibcallCallingConv(LC.Op, LC.CC); } } else if (!TT.isOSBinFormatMachO()) { - setLibcallName(RTLIB::FPROUND_F32_F16, "__gnu_f2h_ieee"); - setLibcallName(RTLIB::FPEXT_F16_F32, "__gnu_h2f_ieee"); + setLibcallImpl(RTLIB::FPROUND_F32_F16, RTLIB::__gnu_f2h_ieee); + setLibcallImpl(RTLIB::FPEXT_F16_F32, RTLIB::__gnu_h2f_ieee); } if (Subtarget->isThumb1Only()) @@ -1380,7 +1386,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom); setOperationAction(ISD::EH_SJLJ_SETUP_DISPATCH, MVT::Other, Custom); if (Subtarget->useSjLjEH()) - setLibcallName(RTLIB::UNWIND_RESUME, "_Unwind_SjLj_Resume"); + setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume); setOperationAction(ISD::SETCC, MVT::i32, Expand); setOperationAction(ISD::SETCC, MVT::f32, Expand); diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp index c2946de838d77..f8f688c8fbb14 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -151,62 +151,62 @@ MSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM, if (STI.hasHWMult16()) { const struct { const RTLIB::Libcall Op; - const char * const Name; + const RTLIB::LibcallImpl Impl; } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - { RTLIB::MUL_I16, "__mspabi_mpyi_hw" }, - { RTLIB::MUL_I32, "__mspabi_mpyl_hw" }, - { RTLIB::MUL_I64, "__mspabi_mpyll_hw" }, - // TODO The __mspabi_mpysl*_hw functions ARE implemented in libgcc - // TODO The __mspabi_mpyul*_hw functions ARE implemented in libgcc + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::__mspabi_mpyi_hw}, + {RTLIB::MUL_I32, RTLIB::__mspabi_mpyl_hw}, + {RTLIB::MUL_I64, RTLIB::__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) { - setLibcallName(LC.Op, LC.Name); + setLibcallImpl(LC.Op, LC.Impl); } } else if (STI.hasHWMult32()) { const struct { const RTLIB::Libcall Op; - const char * const Name; + const RTLIB::LibcallImpl Impl; } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - { RTLIB::MUL_I16, "__mspabi_mpyi_hw" }, - { RTLIB::MUL_I32, "__mspabi_mpyl_hw32" }, - { RTLIB::MUL_I64, "__mspabi_mpyll_hw32" }, - // TODO The __mspabi_mpysl*_hw32 functions ARE implemented in libgcc - // TODO The __mspabi_mpyul*_hw32 functions ARE implemented in libgcc + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::__mspabi_mpyi_hw}, + {RTLIB::MUL_I32, RTLIB::__mspabi_mpyl_hw32}, + {RTLIB::MUL_I64, RTLIB::__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) { - setLibcallName(LC.Op, LC.Name); + setLibcallImpl(LC.Op, LC.Impl); } } else if (STI.hasHWMultF5()) { const struct { const RTLIB::Libcall Op; - const char * const Name; + const RTLIB::LibcallImpl Impl; } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - { RTLIB::MUL_I16, "__mspabi_mpyi_f5hw" }, - { RTLIB::MUL_I32, "__mspabi_mpyl_f5hw" }, - { RTLIB::MUL_I64, "__mspabi_mpyll_f5hw" }, - // TODO The __mspabi_mpysl*_f5hw functions ARE implemented in libgcc - // TODO The __mspabi_mpyul*_f5hw functions ARE implemented in libgcc + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::__mspabi_mpyi_f5hw}, + {RTLIB::MUL_I32, RTLIB::__mspabi_mpyl_f5hw}, + {RTLIB::MUL_I64, RTLIB::__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) { - setLibcallName(LC.Op, LC.Name); + setLibcallImpl(LC.Op, LC.Impl); } } else { // NoHWMult const struct { const RTLIB::Libcall Op; - const char * const Name; + const RTLIB::LibcallImpl Impl; } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - { RTLIB::MUL_I16, "__mspabi_mpyi" }, - { RTLIB::MUL_I32, "__mspabi_mpyl" }, - { RTLIB::MUL_I64, "__mspabi_mpyll" }, - // The __mspabi_mpysl* functions are NOT implemented in libgcc - // The __mspabi_mpyul* functions are NOT implemented in libgcc + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::__mspabi_mpyi}, + {RTLIB::MUL_I32, RTLIB::__mspabi_mpyl}, + {RTLIB::MUL_I64, RTLIB::__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) { - setLibcallName(LC.Op, LC.Name); + setLibcallImpl(LC.Op, LC.Impl); } setLibcallCallingConv(RTLIB::MUL_I64, CallingConv::MSP430_BUILTIN); } diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp index 4fca1f71fdb57..330cb4e0e206f 100644 --- a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp +++ b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp @@ -33,7 +33,8 @@ static cl::opt DontExpandCondPseudos16( namespace { struct Mips16Libcall { RTLIB::Libcall Libcall; - const char *Name; + RTLIB::LibcallImpl Impl; + const char *Name; // FIXME: Remove this bool operator<(const Mips16Libcall &RHS) const { return std::strcmp(Name, RHS.Name) < 0; @@ -55,41 +56,48 @@ struct Mips16IntrinsicHelperType{ // Libcalls for which no helper is generated. Sorted by name for binary search. static const Mips16Libcall HardFloatLibCalls[] = { - { RTLIB::ADD_F64, "__mips16_adddf3" }, - { RTLIB::ADD_F32, "__mips16_addsf3" }, - { RTLIB::DIV_F64, "__mips16_divdf3" }, - { RTLIB::DIV_F32, "__mips16_divsf3" }, - { RTLIB::OEQ_F64, "__mips16_eqdf2" }, - { RTLIB::OEQ_F32, "__mips16_eqsf2" }, - { RTLIB::FPEXT_F32_F64, "__mips16_extendsfdf2" }, - { RTLIB::FPTOSINT_F64_I32, "__mips16_fix_truncdfsi" }, - { RTLIB::FPTOSINT_F32_I32, "__mips16_fix_truncsfsi" }, - { RTLIB::SINTTOFP_I32_F64, "__mips16_floatsidf" }, - { RTLIB::SINTTOFP_I32_F32, "__mips16_floatsisf" }, - { RTLIB::UINTTOFP_I32_F64, "__mips16_floatunsidf" }, - { RTLIB::UINTTOFP_I32_F32, "__mips16_floatunsisf" }, - { RTLIB::OGE_F64, "__mips16_gedf2" }, - { RTLIB::OGE_F32, "__mips16_gesf2" }, - { RTLIB::OGT_F64, "__mips16_gtdf2" }, - { RTLIB::OGT_F32, "__mips16_gtsf2" }, - { RTLIB::OLE_F64, "__mips16_ledf2" }, - { RTLIB::OLE_F32, "__mips16_lesf2" }, - { RTLIB::OLT_F64, "__mips16_ltdf2" }, - { RTLIB::OLT_F32, "__mips16_ltsf2" }, - { RTLIB::MUL_F64, "__mips16_muldf3" }, - { RTLIB::MUL_F32, "__mips16_mulsf3" }, - { RTLIB::UNE_F64, "__mips16_nedf2" }, - { RTLIB::UNE_F32, "__mips16_nesf2" }, - { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_dc" }, // No associated libcall. - { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_df" }, // No associated libcall. - { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sc" }, // No associated libcall. - { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sf" }, // No associated libcall. - { RTLIB::SUB_F64, "__mips16_subdf3" }, - { RTLIB::SUB_F32, "__mips16_subsf3" }, - { RTLIB::FPROUND_F64_F32, "__mips16_truncdfsf2" }, - { RTLIB::UO_F64, "__mips16_unorddf2" }, - { RTLIB::UO_F32, "__mips16_unordsf2" } -}; + {RTLIB::ADD_F64, RTLIB::__mips16_adddf3, "__mips16_adddf3"}, + {RTLIB::ADD_F32, RTLIB::__mips16_addsf3, "__mips16_addsf3"}, + {RTLIB::DIV_F64, RTLIB::__mips16_divdf3, "__mips16_divdf3"}, + {RTLIB::DIV_F32, RTLIB::__mips16_divsf3, "__mips16_divsf3"}, + {RTLIB::OEQ_F64, RTLIB::__mips16_eqdf2, "__mips16_eqdf2"}, + {RTLIB::OEQ_F32, RTLIB::__mips16_eqsf2, "__mips16_eqsf2"}, + {RTLIB::FPEXT_F32_F64, RTLIB::__mips16_extendsfdf2, "__mips16_extendsfdf2"}, + {RTLIB::FPTOSINT_F64_I32, RTLIB::__mips16_fix_truncdfsi, + "__mips16_fix_truncdfsi"}, + {RTLIB::FPTOSINT_F32_I32, RTLIB::__mips16_fix_truncsfsi, + "__mips16_fix_truncsfsi"}, + {RTLIB::SINTTOFP_I32_F64, RTLIB::__mips16_floatsidf, "__mips16_floatsidf"}, + {RTLIB::SINTTOFP_I32_F32, RTLIB::__mips16_floatsisf, "__mips16_floatsisf"}, + {RTLIB::UINTTOFP_I32_F64, RTLIB::__mips16_floatunsidf, + "__mips16_floatunsidf"}, + {RTLIB::UINTTOFP_I32_F32, RTLIB::__mips16_floatunsisf, + "__mips16_floatunsisf"}, + {RTLIB::OGE_F64, RTLIB::__mips16_gedf2, "__mips16_gedf2"}, + {RTLIB::OGE_F32, RTLIB::__mips16_gesf2, "__mips16_gesf2"}, + {RTLIB::OGT_F64, RTLIB::__mips16_gtdf2, "__mips16_gtdf2"}, + {RTLIB::OGT_F32, RTLIB::__mips16_gtsf2, "__mips16_gtsf2"}, + {RTLIB::OLE_F64, RTLIB::__mips16_ledf2, "__mips16_ledf2"}, + {RTLIB::OLE_F32, RTLIB::__mips16_lesf2, "__mips16_lesf2"}, + {RTLIB::OLT_F64, RTLIB::__mips16_ltdf2, "__mips16_ltdf2"}, + {RTLIB::OLT_F32, RTLIB::__mips16_ltsf2, "__mips16_ltsf2"}, + {RTLIB::MUL_F64, RTLIB::__mips16_muldf3, "__mips16_muldf3"}, + {RTLIB::MUL_F32, RTLIB::__mips16_mulsf3, "__mips16_mulsf3"}, + {RTLIB::UNE_F64, RTLIB::__mips16_nedf2, "__mips16_nedf2"}, + {RTLIB::UNE_F32, RTLIB::__mips16_nesf2, "__mips16_nesf2"}, + {RTLIB::UNKNOWN_LIBCALL, RTLIB::__mips16_ret_dc, + "__mips16_ret_dc"}, // No associated libcall. + {RTLIB::UNKNOWN_LIBCALL, RTLIB::__mips16_ret_df, + "__mips16_ret_df"}, // No associated libcall. + {RTLIB::UNKNOWN_LIBCALL, RTLIB::__mips16_ret_sc, + "__mips16_ret_sc"}, // No associated libcall. + {RTLIB::UNKNOWN_LIBCALL, RTLIB::__mips16_ret_sf, + "__mips16_ret_sf"}, // No associated libcall. + {RTLIB::SUB_F64, RTLIB::__mips16_subdf3, "__mips16_subdf3"}, + {RTLIB::SUB_F32, RTLIB::__mips16_subsf3, "__mips16_subsf3"}, + {RTLIB::FPROUND_F64_F32, RTLIB::__mips16_truncdfsf2, "__mips16_truncdfsf2"}, + {RTLIB::UO_F64, RTLIB::__mips16_unorddf2, "__mips16_unorddf2"}, + {RTLIB::UO_F32, RTLIB::__mips16_unordsf2, "__mips16_unordsf2"}}; static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = { {"__fixunsdfsi", "__mips16_call_stub_2" }, @@ -250,7 +258,7 @@ void Mips16TargetLowering::setMips16HardFloatLibCalls() { assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) && "Array not sorted!"); if (HardFloatLibCalls[I].Libcall != RTLIB::UNKNOWN_LIBCALL) - setLibcallName(HardFloatLibCalls[I].Libcall, HardFloatLibCalls[I].Name); + setLibcallImpl(HardFloatLibCalls[I].Libcall, HardFloatLibCalls[I].Impl); } } @@ -425,7 +433,8 @@ getOpndList(SmallVectorImpl &Ops, // bool LookupHelper = true; if (ExternalSymbolSDNode *S = dyn_cast(CLI.Callee)) { - Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() }; + Mips16Libcall Find = {RTLIB::UNKNOWN_LIBCALL, RTLIB::Unsupported, + S->getSymbol()}; if (llvm::binary_search(HardFloatLibCalls, Find)) LookupHelper = false; @@ -465,8 +474,8 @@ getOpndList(SmallVectorImpl &Ops, } } else if (GlobalAddressSDNode *G = dyn_cast(CLI.Callee)) { - Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, - G->getGlobal()->getName().data() }; + Mips16Libcall Find = {RTLIB::UNKNOWN_LIBCALL, RTLIB::Unsupported, + G->getGlobal()->getName().data()}; if (llvm::binary_search(HardFloatLibCalls, Find)) LookupHelper = false; diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 21ecf3d5ed70e..74cc3b8d7c613 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -1838,16 +1838,16 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, // .umul works for both signed and unsigned setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); - setLibcallName(RTLIB::MUL_I32, ".umul"); + setLibcallImpl(RTLIB::MUL_I32, RTLIB::sparc_umul); setOperationAction(ISD::SDIV, MVT::i32, Expand); - setLibcallName(RTLIB::SDIV_I32, ".div"); + setLibcallImpl(RTLIB::SDIV_I32, RTLIB::sparc_div); setOperationAction(ISD::UDIV, MVT::i32, Expand); - setLibcallName(RTLIB::UDIV_I32, ".udiv"); + setLibcallImpl(RTLIB::UDIV_I32, RTLIB::sparc_udiv); - setLibcallName(RTLIB::SREM_I32, ".rem"); - setLibcallName(RTLIB::UREM_I32, ".urem"); + setLibcallImpl(RTLIB::SREM_I32, RTLIB::sparc_rem); + setLibcallImpl(RTLIB::UREM_I32, RTLIB::sparc_urem); } if (Subtarget->is64Bit()) { @@ -1908,10 +1908,10 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, } if (!Subtarget->is64Bit()) { - setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Q_qtoll"); - setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Q_qtoull"); - setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Q_lltoq"); - setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Q_ulltoq"); + setLibcallImpl(RTLIB::FPTOSINT_F128_I64, RTLIB::_Q_qtoll); + setLibcallImpl(RTLIB::FPTOUINT_F128_I64, RTLIB::_Q_qtoull); + setLibcallImpl(RTLIB::SINTTOFP_I64_F128, RTLIB::_Q_lltoq); + setLibcallImpl(RTLIB::UINTTOFP_I64_F128, RTLIB::_Q_ulltoq); } } else { @@ -1931,41 +1931,41 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, // Setup Runtime library names. if (Subtarget->is64Bit() && !Subtarget->useSoftFloat()) { - setLibcallName(RTLIB::ADD_F128, "_Qp_add"); - setLibcallName(RTLIB::SUB_F128, "_Qp_sub"); - setLibcallName(RTLIB::MUL_F128, "_Qp_mul"); - setLibcallName(RTLIB::DIV_F128, "_Qp_div"); - setLibcallName(RTLIB::SQRT_F128, "_Qp_sqrt"); - setLibcallName(RTLIB::FPTOSINT_F128_I32, "_Qp_qtoi"); - setLibcallName(RTLIB::FPTOUINT_F128_I32, "_Qp_qtoui"); - setLibcallName(RTLIB::SINTTOFP_I32_F128, "_Qp_itoq"); - setLibcallName(RTLIB::UINTTOFP_I32_F128, "_Qp_uitoq"); - setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Qp_qtox"); - setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Qp_qtoux"); - setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Qp_xtoq"); - setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Qp_uxtoq"); - setLibcallName(RTLIB::FPEXT_F32_F128, "_Qp_stoq"); - setLibcallName(RTLIB::FPEXT_F64_F128, "_Qp_dtoq"); - setLibcallName(RTLIB::FPROUND_F128_F32, "_Qp_qtos"); - setLibcallName(RTLIB::FPROUND_F128_F64, "_Qp_qtod"); + setLibcallImpl(RTLIB::ADD_F128, RTLIB::_Qp_add); + setLibcallImpl(RTLIB::SUB_F128, RTLIB::_Qp_sub); + setLibcallImpl(RTLIB::MUL_F128, RTLIB::_Qp_mul); + setLibcallImpl(RTLIB::DIV_F128, RTLIB::_Qp_div); + setLibcallImpl(RTLIB::SQRT_F128, RTLIB::_Qp_sqrt); + setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::_Qp_qtoi); + setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::_Qp_qtoui); + setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::_Qp_itoq); + setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::_Qp_uitoq); + setLibcallImpl(RTLIB::FPTOSINT_F128_I64, RTLIB::_Qp_qtox); + setLibcallImpl(RTLIB::FPTOUINT_F128_I64, RTLIB::_Qp_qtoux); + setLibcallImpl(RTLIB::SINTTOFP_I64_F128, RTLIB::_Qp_xtoq); + setLibcallImpl(RTLIB::UINTTOFP_I64_F128, RTLIB::_Qp_uxtoq); + setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::_Qp_stoq); + setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::_Qp_dtoq); + setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::_Qp_qtos); + setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::_Qp_qtod); } else if (!Subtarget->useSoftFloat()) { - setLibcallName(RTLIB::ADD_F128, "_Q_add"); - setLibcallName(RTLIB::SUB_F128, "_Q_sub"); - setLibcallName(RTLIB::MUL_F128, "_Q_mul"); - setLibcallName(RTLIB::DIV_F128, "_Q_div"); - setLibcallName(RTLIB::SQRT_F128, "_Q_sqrt"); - setLibcallName(RTLIB::FPTOSINT_F128_I32, "_Q_qtoi"); - setLibcallName(RTLIB::FPTOUINT_F128_I32, "_Q_qtou"); - setLibcallName(RTLIB::SINTTOFP_I32_F128, "_Q_itoq"); - setLibcallName(RTLIB::UINTTOFP_I32_F128, "_Q_utoq"); - setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Q_qtoll"); - setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Q_qtoull"); - setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Q_lltoq"); - setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Q_ulltoq"); - setLibcallName(RTLIB::FPEXT_F32_F128, "_Q_stoq"); - setLibcallName(RTLIB::FPEXT_F64_F128, "_Q_dtoq"); - setLibcallName(RTLIB::FPROUND_F128_F32, "_Q_qtos"); - setLibcallName(RTLIB::FPROUND_F128_F64, "_Q_qtod"); + setLibcallImpl(RTLIB::ADD_F128, RTLIB::_Q_add); + setLibcallImpl(RTLIB::SUB_F128, RTLIB::_Q_sub); + setLibcallImpl(RTLIB::MUL_F128, RTLIB::_Q_mul); + setLibcallImpl(RTLIB::DIV_F128, RTLIB::_Q_div); + setLibcallImpl(RTLIB::SQRT_F128, RTLIB::_Q_sqrt); + setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::_Q_qtoi); + setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::_Q_qtou); + setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::_Q_itoq); + setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::_Q_utoq); + setLibcallImpl(RTLIB::FPTOSINT_F128_I64, RTLIB::_Q_qtoll); + setLibcallImpl(RTLIB::FPTOUINT_F128_I64, RTLIB::_Q_qtoull); + setLibcallImpl(RTLIB::SINTTOFP_I64_F128, RTLIB::_Q_lltoq); + setLibcallImpl(RTLIB::UINTTOFP_I64_F128, RTLIB::_Q_ulltoq); + setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::_Q_stoq); + setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::_Q_dtoq); + setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::_Q_qtos); + setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::_Q_qtod); } } diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter.td b/llvm/test/TableGen/RuntimeLibcallEmitter.td index 8f66bedf860c8..d4030dd0a7e95 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter.td @@ -5,12 +5,18 @@ include "llvm/IR/RuntimeLibcallsImpl.td" def SHL_I32 : RuntimeLibcall; def SRL_I64 : RuntimeLibcall; + +def SQRT_F128 : RuntimeLibcall; +def SQRT_F80 : RuntimeLibcall; def BZERO : RuntimeLibcall; // Test default names. let IsDefault = true in { def __ashlsi3 : RuntimeLibcallImpl; def __lshrdi3 : RuntimeLibcallImpl; + + def sqrtl_f128 : RuntimeLibcallImpl; + def sqrtl_f80 : RuntimeLibcallImpl; } // Ignore non-default in initDefaultLibCallNames. @@ -20,21 +26,52 @@ def bzero : RuntimeLibcallImpl; // CHECK: #ifdef GET_RUNTIME_LIBCALL_ENUM // CHECK-NEXT: namespace llvm { // CHECK-NEXT: namespace RTLIB { -// CHECK-NEXT: enum Libcall { +// CHECK-NEXT: enum Libcall : unsigned short { // CHECK-NEXT: BZERO = 0, // CHECK-NEXT: SHL_I32 = 1, -// CHECK-NEXT: SRL_I64 = 2, -// CHECK-NEXT: UNKNOWN_LIBCALL = 3 +// CHECK-NEXT: SQRT_F80 = 2, +// CHECK-NEXT: SQRT_F128 = 3, +// CHECK-NEXT: SRL_I64 = 4, +// CHECK-NEXT: UNKNOWN_LIBCALL = 5 // CHECK-NEXT: }; // CHECK-EMPTY: +// CHECK-NEXT:enum LibcallImpl : unsigned short { +// CHECK-NEXT: Unsupported = 0, +// CHECK-NEXT: __ashlsi3 = 1, // __ashlsi3 +// CHECK-NEXT: __lshrdi3 = 2, // __lshrdi3 +// CHECK-NEXT: bzero = 3, // bzero +// CHECK-NEXT: sqrtl_f80 = 4, // sqrtl +// CHECK-NEXT: sqrtl_f128 = 5, // sqrtl +// CHECK-NEXT: NumLibcallImpls = 6 +// CHECK-NEXT: }; // CHECK-NEXT: } // End namespace RTLIB // CHECK-NEXT: } // End namespace llvm // CHECK-NEXT: #endif // CHECK: #ifdef GET_INIT_RUNTIME_LIBCALL_NAMES -// CHECK-NEXT: const char *const llvm::RTLIB::RuntimeLibcallsInfo::DefaultLibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1] = { -// CHECK-NEXT: nullptr, // RTLIB::BZERO -// CHECK-NEXT: "__ashlsi3", // RTLIB::SHL_I32 -// CHECK-NEXT: "__lshrdi3", // RTLIB::SRL_I64 -// CHECK-NEXT: nullptr // RTLIB::UNKNOWN_LIBCALL +// CHECK-NEXT: const RTLIB::LibcallImpl llvm::RTLIB::RuntimeLibcallsInfo::DefaultLibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = { +// CHECK-NEXT: RTLIB::Unsupported, // RTLIB::BZERO +// CHECK-NEXT: RTLIB::__ashlsi3, // RTLIB::SHL_I32 +// CHECK-NEXT: RTLIB::sqrtl_f80, // RTLIB::SQRT_F80 +// CHECK-NEXT: RTLIB::sqrtl_f128, // RTLIB::SQRT_F128 +// CHECK-NEXT: RTLIB::__lshrdi3, // RTLIB::SRL_I64 +// CHECK-NEXT: RTLIB::Unsupported +// CHECK-NEXT: }; +// CHECK-EMPTY: +// CHECK-NEXT: const char *const llvm::RTLIB::RuntimeLibcallsInfo::LibCallImplNames[RTLIB::NumLibcallImpls] = { +// CHECK-NEXT: nullptr, // RTLIB::Unsupported +// CHECK-NEXT: "__ashlsi3", // RTLIB::__ashlsi3 +// CHECK-NEXT: "__lshrdi3", // RTLIB::__lshrdi3 +// CHECK-NEXT: "bzero", // RTLIB::bzero +// CHECK-NEXT: "sqrtl", // RTLIB::sqrtl_f80 +// CHECK-NEXT: "sqrtl", // RTLIB::sqrtl_f128 +// CHECK-NEXT: }; + +// CHECK: const RTLIB::Libcall llvm::RTLIB::RuntimeLibcallsInfo::ImplToLibcall[RTLIB::NumLibcallImpls] = { +// CHECK-NEXT: RTLIB::UNKNOWN_LIBCALL, // RTLIB::Unsupported +// CHECK-NEXT: RTLIB::SHL_I32, // RTLIB::__ashlsi3 +// CHECK-NEXT: RTLIB::SRL_I64, // RTLIB::__lshrdi3 +// CHECK-NEXT: RTLIB::BZERO, // RTLIB::bzero +// CHECK-NEXT: RTLIB::SQRT_F80, // RTLIB::sqrtl_f80 +// CHECK-NEXT: RTLIB::SQRT_F128, // RTLIB::sqrtl_f128 // CHECK-NEXT: }; diff --git a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp index 2691437e22edb..9d77631862ee5 100644 --- a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp +++ b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp @@ -165,10 +165,10 @@ void RuntimeLibcallEmitter::emitTargetOverrideFunc( // for (const Record *LibCallImpl : LibCallImplList) { for (const RuntimeLibcallImpl &LibCallImpl : LibCallImplList) { const RuntimeLibcall *Provides = LibCallImpl.getProvides(); - OS << " LibcallRoutineNames["; + OS << " LibcallImpls["; Provides->emitEnumEntry(OS); OS << "] = "; - LibCallImpl.emitQuotedLibcallFuncName(OS); + LibCallImpl.emitEnumEntry(OS); OS << ";\n"; } } @@ -180,7 +180,7 @@ void RuntimeLibcallEmitter::emitGetRuntimeLibcallEnum(raw_ostream &OS) const { OS << "#ifdef GET_RUNTIME_LIBCALL_ENUM\n" "namespace llvm {\n" "namespace RTLIB {\n" - "enum Libcall {\n"; + "enum Libcall : unsigned short {\n"; size_t CallTypeEnumVal = 0; for (const RuntimeLibcall &LibCall : RuntimeLibcallDefList) { @@ -192,6 +192,18 @@ void RuntimeLibcallEmitter::emitGetRuntimeLibcallEnum(raw_ostream &OS) const { OS << " UNKNOWN_LIBCALL = " << CallTypeEnumVal << "\n};\n\n" + "enum LibcallImpl : unsigned short {\n" + " Unsupported = 0,\n"; + + // FIXME: Emit this in a different namespace. And maybe use enum class. + size_t LibCallImplEnumVal = 1; + for (const RuntimeLibcallImpl &LibCall : RuntimeLibcallImplDefList) { + OS << " " << LibCall.getName() << " = " << LibCallImplEnumVal++ << ", // " + << LibCall.getLibcallFuncName() << '\n'; + } + + OS << " NumLibcallImpls = " << LibCallImplEnumVal + << "\n};\n" "} // End namespace RTLIB\n" "} // End namespace llvm\n" "#endif\n\n"; @@ -203,16 +215,16 @@ void RuntimeLibcallEmitter::emitWindowsArm64LibCallNameOverrides( OS << "void " "llvm::RTLIB::RuntimeLibcallsInfo::setWindowsArm64LibCallNameOverrides(" ") {\n" - " static const char *const " - "WindowsArm64RoutineNames[RTLIB::UNKNOWN_LIBCALL + 1] = {\n"; + " static const RTLIB::LibcallImpl " + "WindowsArm64RoutineImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {\n"; for (const RuntimeLibcall &LibCall : RuntimeLibcallDefList) { auto I = LibCallToDefaultImpl.find(&LibCall); if (I == LibCallToDefaultImpl.end()) - OS << " nullptr,"; + OS << " RTLIB::Unsupported,"; else { const RuntimeLibcallImpl *LibCallImpl = I->second; assert(LibCallImpl); - OS << " \"#" << LibCallImpl->getLibcallFuncName() << "\","; + OS << " RTLIB::arm64ec_" << LibCallImpl->getName() << ','; } OS << " // "; @@ -220,12 +232,12 @@ void RuntimeLibcallEmitter::emitWindowsArm64LibCallNameOverrides( OS << '\n'; } - OS << " nullptr // RTLIB::UNKNOWN_LIBCALL\n" + OS << " RTLIB::Unsupported // RTLIB::UNKNOWN_LIBCALL\n" " };\n\n" - " std::memcpy(LibcallRoutineNames, WindowsArm64RoutineNames,\n" - " sizeof(LibcallRoutineNames));\n" - " static_assert(sizeof(LibcallRoutineNames) == " - "sizeof(WindowsArm64RoutineNames),\n" + " std::memcpy(LibcallImpls, WindowsArm64RoutineImpls,\n" + " sizeof(LibcallImpls));\n" + " static_assert(sizeof(LibcallImpls) == " + "sizeof(WindowsArm64RoutineImpls),\n" " \"libcall array size should match\");\n" "}\n#endif\n\n"; } @@ -235,19 +247,19 @@ void RuntimeLibcallEmitter::emitGetInitRuntimeLibcallNames( // TODO: Emit libcall names as string offset table. OS << "#ifdef GET_INIT_RUNTIME_LIBCALL_NAMES\n" - "const char *const " + "const RTLIB::LibcallImpl " "llvm::RTLIB::RuntimeLibcallsInfo::" - "DefaultLibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1] = {\n"; + "DefaultLibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {\n"; for (const RuntimeLibcall &LibCall : RuntimeLibcallDefList) { auto I = LibCallToDefaultImpl.find(&LibCall); - if (I == LibCallToDefaultImpl.end()) - OS << " nullptr,"; - else { + if (I == LibCallToDefaultImpl.end()) { + OS << " RTLIB::Unsupported,"; + } else { const RuntimeLibcallImpl *LibCallImpl = I->second; OS << " "; - LibCallImpl->emitQuotedLibcallFuncName(OS); - OS << ','; + LibCallImpl->emitEnumEntry(OS); + OS << ","; } OS << " // "; @@ -255,9 +267,37 @@ void RuntimeLibcallEmitter::emitGetInitRuntimeLibcallNames( OS << '\n'; } - OS << " nullptr // RTLIB::UNKNOWN_LIBCALL\n" + OS << " RTLIB::Unsupported\n" "};\n\n"; + // Emit the implementation names + OS << "const char *const llvm::RTLIB::RuntimeLibcallsInfo::" + "LibCallImplNames[RTLIB::NumLibcallImpls] = {\n" + " nullptr, // RTLIB::Unsupported\n"; + + for (const RuntimeLibcallImpl &LibCallImpl : RuntimeLibcallImplDefList) { + OS << " \"" << LibCallImpl.getLibcallFuncName() << "\", // "; + LibCallImpl.emitEnumEntry(OS); + OS << '\n'; + } + + OS << "};\n\n"; + + // Emit the reverse mapping from implementation libraries to RTLIB::Libcall + OS << "const RTLIB::Libcall llvm::RTLIB::RuntimeLibcallsInfo::" + "ImplToLibcall[RTLIB::NumLibcallImpls] = {\n" + " RTLIB::UNKNOWN_LIBCALL, // RTLIB::Unsupported\n"; + + for (const RuntimeLibcallImpl &LibCallImpl : RuntimeLibcallImplDefList) { + const RuntimeLibcall *Provides = LibCallImpl.getProvides(); + OS << " "; + Provides->emitEnumEntry(OS); + OS << ", // "; + LibCallImpl.emitEnumEntry(OS); + OS << '\n'; + } + OS << "};\n\n"; + std::vector ZOSRuntimeLibcallImplList = getRuntimeLibcallImplSet("ZOSRuntimeLibcallImpl"); emitTargetOverrideFunc(OS, "setZOSLibCallNameOverrides",