1*0fca6ea1SDimitry Andric //===- RuntimeLibcalls.cpp - Interface for runtime libcalls -----*- C++ -*-===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric 9*0fca6ea1SDimitry Andric #include "llvm/IR/RuntimeLibcalls.h" 10*0fca6ea1SDimitry Andric 11*0fca6ea1SDimitry Andric using namespace llvm; 12*0fca6ea1SDimitry Andric using namespace RTLIB; 13*0fca6ea1SDimitry Andric 14*0fca6ea1SDimitry Andric /// Set default libcall names. If a target wants to opt-out of a libcall it 15*0fca6ea1SDimitry Andric /// should be placed here. 16*0fca6ea1SDimitry Andric void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) { 17*0fca6ea1SDimitry Andric std::fill(std::begin(LibcallRoutineNames), std::end(LibcallRoutineNames), 18*0fca6ea1SDimitry Andric nullptr); 19*0fca6ea1SDimitry Andric 20*0fca6ea1SDimitry Andric #define HANDLE_LIBCALL(code, name) setLibcallName(RTLIB::code, name); 21*0fca6ea1SDimitry Andric #include "llvm/IR/RuntimeLibcalls.def" 22*0fca6ea1SDimitry Andric #undef HANDLE_LIBCALL 23*0fca6ea1SDimitry Andric 24*0fca6ea1SDimitry Andric // Initialize calling conventions to their default. 25*0fca6ea1SDimitry Andric for (int LC = 0; LC < RTLIB::UNKNOWN_LIBCALL; ++LC) 26*0fca6ea1SDimitry Andric setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C); 27*0fca6ea1SDimitry Andric 28*0fca6ea1SDimitry Andric // Use the f128 variants of math functions on x86_64 29*0fca6ea1SDimitry Andric if (TT.getArch() == Triple::ArchType::x86_64 && TT.isGNUEnvironment()) { 30*0fca6ea1SDimitry Andric setLibcallName(RTLIB::REM_F128, "fmodf128"); 31*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FMA_F128, "fmaf128"); 32*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SQRT_F128, "sqrtf128"); 33*0fca6ea1SDimitry Andric setLibcallName(RTLIB::CBRT_F128, "cbrtf128"); 34*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LOG_F128, "logf128"); 35*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LOG_FINITE_F128, "__logf128_finite"); 36*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LOG2_F128, "log2f128"); 37*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LOG2_FINITE_F128, "__log2f128_finite"); 38*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LOG10_F128, "log10f128"); 39*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LOG10_FINITE_F128, "__log10f128_finite"); 40*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP_F128, "expf128"); 41*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP_FINITE_F128, "__expf128_finite"); 42*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP2_F128, "exp2f128"); 43*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP2_FINITE_F128, "__exp2f128_finite"); 44*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP10_F128, "exp10f128"); 45*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SIN_F128, "sinf128"); 46*0fca6ea1SDimitry Andric setLibcallName(RTLIB::COS_F128, "cosf128"); 47*0fca6ea1SDimitry Andric setLibcallName(RTLIB::TAN_F128, "tanf128"); 48*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINCOS_F128, "sincosf128"); 49*0fca6ea1SDimitry Andric setLibcallName(RTLIB::ASIN_F128, "asinf128"); 50*0fca6ea1SDimitry Andric setLibcallName(RTLIB::ACOS_F128, "acosf128"); 51*0fca6ea1SDimitry Andric setLibcallName(RTLIB::ATAN_F128, "atanf128"); 52*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINH_F128, "sinhf128"); 53*0fca6ea1SDimitry Andric setLibcallName(RTLIB::COSH_F128, "coshf128"); 54*0fca6ea1SDimitry Andric setLibcallName(RTLIB::TANH_F128, "tanhf128"); 55*0fca6ea1SDimitry Andric setLibcallName(RTLIB::POW_F128, "powf128"); 56*0fca6ea1SDimitry Andric setLibcallName(RTLIB::POW_FINITE_F128, "__powf128_finite"); 57*0fca6ea1SDimitry Andric setLibcallName(RTLIB::CEIL_F128, "ceilf128"); 58*0fca6ea1SDimitry Andric setLibcallName(RTLIB::TRUNC_F128, "truncf128"); 59*0fca6ea1SDimitry Andric setLibcallName(RTLIB::RINT_F128, "rintf128"); 60*0fca6ea1SDimitry Andric setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintf128"); 61*0fca6ea1SDimitry Andric setLibcallName(RTLIB::ROUND_F128, "roundf128"); 62*0fca6ea1SDimitry Andric setLibcallName(RTLIB::ROUNDEVEN_F128, "roundevenf128"); 63*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FLOOR_F128, "floorf128"); 64*0fca6ea1SDimitry Andric setLibcallName(RTLIB::COPYSIGN_F128, "copysignf128"); 65*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FMIN_F128, "fminf128"); 66*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FMAX_F128, "fmaxf128"); 67*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LROUND_F128, "lroundf128"); 68*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LLROUND_F128, "llroundf128"); 69*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LRINT_F128, "lrintf128"); 70*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LLRINT_F128, "llrintf128"); 71*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LDEXP_F128, "ldexpf128"); 72*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FREXP_F128, "frexpf128"); 73*0fca6ea1SDimitry Andric } 74*0fca6ea1SDimitry Andric 75*0fca6ea1SDimitry Andric // For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf". 76*0fca6ea1SDimitry Andric if (TT.isPPC()) { 77*0fca6ea1SDimitry Andric setLibcallName(RTLIB::ADD_F128, "__addkf3"); 78*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SUB_F128, "__subkf3"); 79*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MUL_F128, "__mulkf3"); 80*0fca6ea1SDimitry Andric setLibcallName(RTLIB::DIV_F128, "__divkf3"); 81*0fca6ea1SDimitry Andric setLibcallName(RTLIB::POWI_F128, "__powikf2"); 82*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPEXT_F32_F128, "__extendsfkf2"); 83*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPEXT_F64_F128, "__extenddfkf2"); 84*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPROUND_F128_F32, "__trunckfsf2"); 85*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPROUND_F128_F64, "__trunckfdf2"); 86*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPTOSINT_F128_I32, "__fixkfsi"); 87*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPTOSINT_F128_I64, "__fixkfdi"); 88*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPTOSINT_F128_I128, "__fixkfti"); 89*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPTOUINT_F128_I32, "__fixunskfsi"); 90*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPTOUINT_F128_I64, "__fixunskfdi"); 91*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPTOUINT_F128_I128, "__fixunskfti"); 92*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINTTOFP_I32_F128, "__floatsikf"); 93*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINTTOFP_I64_F128, "__floatdikf"); 94*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINTTOFP_I128_F128, "__floattikf"); 95*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UINTTOFP_I32_F128, "__floatunsikf"); 96*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UINTTOFP_I64_F128, "__floatundikf"); 97*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UINTTOFP_I128_F128, "__floatuntikf"); 98*0fca6ea1SDimitry Andric setLibcallName(RTLIB::OEQ_F128, "__eqkf2"); 99*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UNE_F128, "__nekf2"); 100*0fca6ea1SDimitry Andric setLibcallName(RTLIB::OGE_F128, "__gekf2"); 101*0fca6ea1SDimitry Andric setLibcallName(RTLIB::OLT_F128, "__ltkf2"); 102*0fca6ea1SDimitry Andric setLibcallName(RTLIB::OLE_F128, "__lekf2"); 103*0fca6ea1SDimitry Andric setLibcallName(RTLIB::OGT_F128, "__gtkf2"); 104*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UO_F128, "__unordkf2"); 105*0fca6ea1SDimitry Andric } 106*0fca6ea1SDimitry Andric 107*0fca6ea1SDimitry Andric // A few names are different on particular architectures or environments. 108*0fca6ea1SDimitry Andric if (TT.isOSDarwin()) { 109*0fca6ea1SDimitry Andric // For f16/f32 conversions, Darwin uses the standard naming scheme, 110*0fca6ea1SDimitry Andric // instead of the gnueabi-style __gnu_*_ieee. 111*0fca6ea1SDimitry Andric // FIXME: What about other targets? 112*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPEXT_F16_F32, "__extendhfsf2"); 113*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPROUND_F32_F16, "__truncsfhf2"); 114*0fca6ea1SDimitry Andric 115*0fca6ea1SDimitry Andric // Some darwins have an optimized __bzero/bzero function. 116*0fca6ea1SDimitry Andric switch (TT.getArch()) { 117*0fca6ea1SDimitry Andric case Triple::x86: 118*0fca6ea1SDimitry Andric case Triple::x86_64: 119*0fca6ea1SDimitry Andric if (TT.isMacOSX() && !TT.isMacOSXVersionLT(10, 6)) 120*0fca6ea1SDimitry Andric setLibcallName(RTLIB::BZERO, "__bzero"); 121*0fca6ea1SDimitry Andric break; 122*0fca6ea1SDimitry Andric case Triple::aarch64: 123*0fca6ea1SDimitry Andric case Triple::aarch64_32: 124*0fca6ea1SDimitry Andric setLibcallName(RTLIB::BZERO, "bzero"); 125*0fca6ea1SDimitry Andric break; 126*0fca6ea1SDimitry Andric default: 127*0fca6ea1SDimitry Andric break; 128*0fca6ea1SDimitry Andric } 129*0fca6ea1SDimitry Andric 130*0fca6ea1SDimitry Andric if (darwinHasSinCos(TT)) { 131*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINCOS_STRET_F32, "__sincosf_stret"); 132*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINCOS_STRET_F64, "__sincos_stret"); 133*0fca6ea1SDimitry Andric if (TT.isWatchABI()) { 134*0fca6ea1SDimitry Andric setLibcallCallingConv(RTLIB::SINCOS_STRET_F32, 135*0fca6ea1SDimitry Andric CallingConv::ARM_AAPCS_VFP); 136*0fca6ea1SDimitry Andric setLibcallCallingConv(RTLIB::SINCOS_STRET_F64, 137*0fca6ea1SDimitry Andric CallingConv::ARM_AAPCS_VFP); 138*0fca6ea1SDimitry Andric } 139*0fca6ea1SDimitry Andric } 140*0fca6ea1SDimitry Andric 141*0fca6ea1SDimitry Andric switch (TT.getOS()) { 142*0fca6ea1SDimitry Andric case Triple::MacOSX: 143*0fca6ea1SDimitry Andric if (TT.isMacOSXVersionLT(10, 9)) { 144*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP10_F32, nullptr); 145*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP10_F64, nullptr); 146*0fca6ea1SDimitry Andric } else { 147*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP10_F32, "__exp10f"); 148*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP10_F64, "__exp10"); 149*0fca6ea1SDimitry Andric } 150*0fca6ea1SDimitry Andric break; 151*0fca6ea1SDimitry Andric case Triple::IOS: 152*0fca6ea1SDimitry Andric if (TT.isOSVersionLT(7, 0)) { 153*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP10_F32, nullptr); 154*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP10_F64, nullptr); 155*0fca6ea1SDimitry Andric break; 156*0fca6ea1SDimitry Andric } 157*0fca6ea1SDimitry Andric [[fallthrough]]; 158*0fca6ea1SDimitry Andric case Triple::TvOS: 159*0fca6ea1SDimitry Andric case Triple::WatchOS: 160*0fca6ea1SDimitry Andric case Triple::XROS: 161*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP10_F32, "__exp10f"); 162*0fca6ea1SDimitry Andric setLibcallName(RTLIB::EXP10_F64, "__exp10"); 163*0fca6ea1SDimitry Andric break; 164*0fca6ea1SDimitry Andric default: 165*0fca6ea1SDimitry Andric break; 166*0fca6ea1SDimitry Andric } 167*0fca6ea1SDimitry Andric } else { 168*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPEXT_F16_F32, "__gnu_h2f_ieee"); 169*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FPROUND_F32_F16, "__gnu_f2h_ieee"); 170*0fca6ea1SDimitry Andric } 171*0fca6ea1SDimitry Andric 172*0fca6ea1SDimitry Andric if (TT.isGNUEnvironment() || TT.isOSFuchsia() || 173*0fca6ea1SDimitry Andric (TT.isAndroid() && !TT.isAndroidVersionLT(9))) { 174*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINCOS_F32, "sincosf"); 175*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINCOS_F64, "sincos"); 176*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINCOS_F80, "sincosl"); 177*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINCOS_F128, "sincosl"); 178*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINCOS_PPCF128, "sincosl"); 179*0fca6ea1SDimitry Andric } 180*0fca6ea1SDimitry Andric 181*0fca6ea1SDimitry Andric if (TT.isPS()) { 182*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINCOS_F32, "sincosf"); 183*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SINCOS_F64, "sincos"); 184*0fca6ea1SDimitry Andric } 185*0fca6ea1SDimitry Andric 186*0fca6ea1SDimitry Andric if (TT.isOSOpenBSD()) { 187*0fca6ea1SDimitry Andric setLibcallName(RTLIB::STACKPROTECTOR_CHECK_FAIL, nullptr); 188*0fca6ea1SDimitry Andric } 189*0fca6ea1SDimitry Andric 190*0fca6ea1SDimitry Andric if (TT.isOSWindows() && !TT.isOSCygMing()) { 191*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LDEXP_F32, nullptr); 192*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LDEXP_F80, nullptr); 193*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LDEXP_F128, nullptr); 194*0fca6ea1SDimitry Andric setLibcallName(RTLIB::LDEXP_PPCF128, nullptr); 195*0fca6ea1SDimitry Andric 196*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FREXP_F32, nullptr); 197*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FREXP_F80, nullptr); 198*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FREXP_F128, nullptr); 199*0fca6ea1SDimitry Andric setLibcallName(RTLIB::FREXP_PPCF128, nullptr); 200*0fca6ea1SDimitry Andric } 201*0fca6ea1SDimitry Andric 202*0fca6ea1SDimitry Andric if (TT.isAArch64()) { 203*0fca6ea1SDimitry Andric if (TT.isOSMSVCRT()) { 204*0fca6ea1SDimitry Andric // MSVCRT doesn't have powi; fall back to pow 205*0fca6ea1SDimitry Andric setLibcallName(RTLIB::POWI_F32, nullptr); 206*0fca6ea1SDimitry Andric setLibcallName(RTLIB::POWI_F64, nullptr); 207*0fca6ea1SDimitry Andric } 208*0fca6ea1SDimitry Andric } 209*0fca6ea1SDimitry Andric 210*0fca6ea1SDimitry Andric // Disable most libcalls on AMDGPU. 211*0fca6ea1SDimitry Andric if (TT.isAMDGPU()) { 212*0fca6ea1SDimitry Andric for (int I = 0; I < RTLIB::UNKNOWN_LIBCALL; ++I) { 213*0fca6ea1SDimitry Andric if (I < RTLIB::ATOMIC_LOAD || I > RTLIB::ATOMIC_FETCH_NAND_16) 214*0fca6ea1SDimitry Andric setLibcallName(static_cast<RTLIB::Libcall>(I), nullptr); 215*0fca6ea1SDimitry Andric } 216*0fca6ea1SDimitry Andric } 217*0fca6ea1SDimitry Andric 218*0fca6ea1SDimitry Andric // Disable most libcalls on NVPTX. 219*0fca6ea1SDimitry Andric if (TT.isNVPTX()) { 220*0fca6ea1SDimitry Andric for (int I = 0; I < RTLIB::UNKNOWN_LIBCALL; ++I) 221*0fca6ea1SDimitry Andric if (I < RTLIB::ATOMIC_LOAD || I > RTLIB::ATOMIC_FETCH_NAND_16) 222*0fca6ea1SDimitry Andric setLibcallName(static_cast<RTLIB::Libcall>(I), nullptr); 223*0fca6ea1SDimitry Andric } 224*0fca6ea1SDimitry Andric 225*0fca6ea1SDimitry Andric if (TT.isARM() || TT.isThumb()) { 226*0fca6ea1SDimitry Andric // These libcalls are not available in 32-bit. 227*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SHL_I128, nullptr); 228*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRL_I128, nullptr); 229*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRA_I128, nullptr); 230*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MUL_I128, nullptr); 231*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I64, nullptr); 232*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I128, nullptr); 233*0fca6ea1SDimitry Andric 234*0fca6ea1SDimitry Andric if (TT.isOSMSVCRT()) { 235*0fca6ea1SDimitry Andric // MSVCRT doesn't have powi; fall back to pow 236*0fca6ea1SDimitry Andric setLibcallName(RTLIB::POWI_F32, nullptr); 237*0fca6ea1SDimitry Andric setLibcallName(RTLIB::POWI_F64, nullptr); 238*0fca6ea1SDimitry Andric } 239*0fca6ea1SDimitry Andric } 240*0fca6ea1SDimitry Andric 241*0fca6ea1SDimitry Andric if (TT.getArch() == Triple::ArchType::avr) { 242*0fca6ea1SDimitry Andric // Division rtlib functions (not supported), use divmod functions instead 243*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SDIV_I8, nullptr); 244*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SDIV_I16, nullptr); 245*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SDIV_I32, nullptr); 246*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UDIV_I8, nullptr); 247*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UDIV_I16, nullptr); 248*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UDIV_I32, nullptr); 249*0fca6ea1SDimitry Andric 250*0fca6ea1SDimitry Andric // Modulus rtlib functions (not supported), use divmod functions instead 251*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SREM_I8, nullptr); 252*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SREM_I16, nullptr); 253*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SREM_I32, nullptr); 254*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UREM_I8, nullptr); 255*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UREM_I16, nullptr); 256*0fca6ea1SDimitry Andric setLibcallName(RTLIB::UREM_I32, nullptr); 257*0fca6ea1SDimitry Andric } 258*0fca6ea1SDimitry Andric 259*0fca6ea1SDimitry Andric if (TT.getArch() == Triple::ArchType::hexagon) { 260*0fca6ea1SDimitry Andric // These cause problems when the shift amount is non-constant. 261*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SHL_I128, nullptr); 262*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRL_I128, nullptr); 263*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRA_I128, nullptr); 264*0fca6ea1SDimitry Andric } 265*0fca6ea1SDimitry Andric 266*0fca6ea1SDimitry Andric if (TT.isLoongArch()) { 267*0fca6ea1SDimitry Andric if (!TT.isLoongArch64()) { 268*0fca6ea1SDimitry Andric // Set libcalls. 269*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MUL_I128, nullptr); 270*0fca6ea1SDimitry Andric // The MULO libcall is not part of libgcc, only compiler-rt. 271*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I64, nullptr); 272*0fca6ea1SDimitry Andric } 273*0fca6ea1SDimitry Andric // The MULO libcall is not part of libgcc, only compiler-rt. 274*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I128, nullptr); 275*0fca6ea1SDimitry Andric } 276*0fca6ea1SDimitry Andric 277*0fca6ea1SDimitry Andric if (TT.isMIPS32()) { 278*0fca6ea1SDimitry Andric // These libcalls are not available in 32-bit. 279*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SHL_I128, nullptr); 280*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRL_I128, nullptr); 281*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRA_I128, nullptr); 282*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MUL_I128, nullptr); 283*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I64, nullptr); 284*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I128, nullptr); 285*0fca6ea1SDimitry Andric } 286*0fca6ea1SDimitry Andric 287*0fca6ea1SDimitry Andric if (TT.isPPC()) { 288*0fca6ea1SDimitry Andric if (!TT.isPPC64()) { 289*0fca6ea1SDimitry Andric // These libcalls are not available in 32-bit. 290*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SHL_I128, nullptr); 291*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRL_I128, nullptr); 292*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRA_I128, nullptr); 293*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MUL_I128, nullptr); 294*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I64, nullptr); 295*0fca6ea1SDimitry Andric } 296*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I128, nullptr); 297*0fca6ea1SDimitry Andric } 298*0fca6ea1SDimitry Andric 299*0fca6ea1SDimitry Andric if (TT.isRISCV32()) { 300*0fca6ea1SDimitry Andric // These libcalls are not available in 32-bit. 301*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SHL_I128, nullptr); 302*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRL_I128, nullptr); 303*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRA_I128, nullptr); 304*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MUL_I128, nullptr); 305*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I64, nullptr); 306*0fca6ea1SDimitry Andric } 307*0fca6ea1SDimitry Andric 308*0fca6ea1SDimitry Andric if (TT.isSPARC()) { 309*0fca6ea1SDimitry Andric if (!TT.isSPARC64()) { 310*0fca6ea1SDimitry Andric // These libcalls are not available in 32-bit. 311*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I64, nullptr); 312*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MUL_I128, nullptr); 313*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SHL_I128, nullptr); 314*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRL_I128, nullptr); 315*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRA_I128, nullptr); 316*0fca6ea1SDimitry Andric } 317*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I128, nullptr); 318*0fca6ea1SDimitry Andric } 319*0fca6ea1SDimitry Andric 320*0fca6ea1SDimitry Andric if (TT.isSystemZ()) { 321*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRL_I128, nullptr); 322*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SHL_I128, nullptr); 323*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRA_I128, nullptr); 324*0fca6ea1SDimitry Andric } 325*0fca6ea1SDimitry Andric 326*0fca6ea1SDimitry Andric if (TT.isX86()) { 327*0fca6ea1SDimitry Andric if (TT.getArch() == Triple::ArchType::x86) { 328*0fca6ea1SDimitry Andric // These libcalls are not available in 32-bit. 329*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SHL_I128, nullptr); 330*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRL_I128, nullptr); 331*0fca6ea1SDimitry Andric setLibcallName(RTLIB::SRA_I128, nullptr); 332*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MUL_I128, nullptr); 333*0fca6ea1SDimitry Andric // The MULO libcall is not part of libgcc, only compiler-rt. 334*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I64, nullptr); 335*0fca6ea1SDimitry Andric } 336*0fca6ea1SDimitry Andric 337*0fca6ea1SDimitry Andric // The MULO libcall is not part of libgcc, only compiler-rt. 338*0fca6ea1SDimitry Andric setLibcallName(RTLIB::MULO_I128, nullptr); 339*0fca6ea1SDimitry Andric 340*0fca6ea1SDimitry Andric if (TT.isOSMSVCRT()) { 341*0fca6ea1SDimitry Andric // MSVCRT doesn't have powi; fall back to pow 342*0fca6ea1SDimitry Andric setLibcallName(RTLIB::POWI_F32, nullptr); 343*0fca6ea1SDimitry Andric setLibcallName(RTLIB::POWI_F64, nullptr); 344*0fca6ea1SDimitry Andric } 345*0fca6ea1SDimitry Andric } 346*0fca6ea1SDimitry Andric } 347