Index: lib/CodeGen/TargetLoweringBase.cpp =================================================================== --- lib/CodeGen/TargetLoweringBase.cpp +++ lib/CodeGen/TargetLoweringBase.cpp @@ -123,6 +123,34 @@ for (int LC = 0; LC < RTLIB::UNKNOWN_LIBCALL; ++LC) setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C); + // For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf". + if (TT.getArch() == Triple::ppc || TT.isPPC64()) { + setLibcallName(RTLIB::ADD_F128, "__addkf3"); + setLibcallName(RTLIB::SUB_F128, "__subkf3"); + setLibcallName(RTLIB::MUL_F128, "__mulkf3"); + setLibcallName(RTLIB::DIV_F128, "__divkf3"); + setLibcallName(RTLIB::FPEXT_F32_F128, "__extendsfkf2"); + setLibcallName(RTLIB::FPEXT_F64_F128, "__extenddfkf2"); + setLibcallName(RTLIB::FPROUND_F128_F32, "__trunckfsf2"); + setLibcallName(RTLIB::FPROUND_F128_F64, "__trunckfdf2"); + setLibcallName(RTLIB::FPTOSINT_F128_I32, "__fixkfsi"); + setLibcallName(RTLIB::FPTOSINT_F128_I64, "__fixkfdi"); + setLibcallName(RTLIB::FPTOUINT_F128_I32, "__fixunskfsi"); + setLibcallName(RTLIB::FPTOUINT_F128_I64, "__fixunskfdi"); + setLibcallName(RTLIB::SINTTOFP_I32_F128, "__floatsikf"); + setLibcallName(RTLIB::SINTTOFP_I64_F128, "__floatdikf"); + setLibcallName(RTLIB::UINTTOFP_I32_F128, "__floatunsikf"); + setLibcallName(RTLIB::UINTTOFP_I64_F128, "__floatundikf"); + setLibcallName(RTLIB::OEQ_F128, "__eqkf2"); + setLibcallName(RTLIB::UNE_F128, "__nekf2"); + setLibcallName(RTLIB::OGE_F128, "__gekf2"); + setLibcallName(RTLIB::OLT_F128, "__ltkf2"); + setLibcallName(RTLIB::OLE_F128, "__lekf2"); + setLibcallName(RTLIB::OGT_F128, "__gtkf2"); + setLibcallName(RTLIB::UO_F128, "__unordkf2"); + setLibcallName(RTLIB::O_F128, "__unordkf2"); + } + // A few names are different on particular architectures or environments. if (TT.isOSDarwin()) { // For f16/f32 conversions, Darwin uses the standard naming scheme, instead Index: test/CodeGen/PowerPC/fp128-libcalls.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/fp128-libcalls.ll @@ -0,0 +1,164 @@ +; RUN: llc < %s -O2 -mtriple=powerpc-linux-musl | FileCheck %s +; RUN: llc < %s -O2 -mtriple=powerpc64-linux-musl | FileCheck %s +; RUN: llc < %s -O2 -mtriple=powerpc64le-linux-musl | FileCheck %s + +define fp128 @addkf3(fp128 %a, fp128 %b) { +; CHECK-LABEL: addkf3: +; CHECK: __addkf3 + %1 = fadd fp128 %a, %b + ret fp128 %1 +} + +define fp128 @subkf3(fp128 %a, fp128 %b) { +; CHECK-LABEL: subkf3: +; CHECK: __subkf3 + %1 = fsub fp128 %a, %b + ret fp128 %1 +} + +define fp128 @mulkf3(fp128 %a, fp128 %b) { +; CHECK-LABEL: mulkf3: +; CHECK: __mulkf3 + %1 = fmul fp128 %a, %b + ret fp128 %1 +} + +define fp128 @divkf3(fp128 %a, fp128 %b) { +; CHECK-LABEL: divkf3: +; CHECK: __divkf3 + %1 = fdiv fp128 %a, %b + ret fp128 %1 +} + +define fp128 @extendsfkf2(float %a) { +; CHECK-LABEL: extendsfkf2: +; CHECK: __extendsfkf2 + %1 = fpext float %a to fp128 + ret fp128 %1 +} + +define fp128 @extenddfkf2(double %a) { +; CHECK-LABEL: extenddfkf2: +; CHECK: __extenddfkf2 + %1 = fpext double %a to fp128 + ret fp128 %1 +} + +define float @trunckfsf2(fp128 %a) { +; CHECK-LABEL: trunckfsf2: +; CHECK: __trunckfsf2 + %1 = fptrunc fp128 %a to float + ret float %1 +} + +define double @trunckfdf2(fp128 %a) { +; CHECK-LABEL: trunckfdf2: +; CHECK: __trunckfdf2 + %1 = fptrunc fp128 %a to double + ret double %1 +} + +define i32 @fixkfsi(fp128 %a) { +; CHECK-LABEL: fixkfsi: +; CHECK: __fixkfsi + %1 = fptosi fp128 %a to i32 + ret i32 %1 +} + +define i64 @fixkfdi(fp128 %a) { +; CHECK-LABEL: fixkfdi: +; CHECK: __fixkfdi + %1 = fptosi fp128 %a to i64 + ret i64 %1 +} + +define i32 @fixunskfsi(fp128 %a) { +; CHECK-LABEL: fixunskfsi: +; CHECK: __fixunskfsi + %1 = fptoui fp128 %a to i32 + ret i32 %1 +} + +define i64 @fixunskfdi(fp128 %a) { +; CHECK-LABEL: fixunskfdi: +; CHECK: __fixunskfdi + %1 = fptoui fp128 %a to i64 + ret i64 %1 +} + +define fp128 @floatsikf(i32 %a) { +; CHECK-LABEL: floatsikf: +; CHECK: __floatsikf + %1 = sitofp i32 %a to fp128 + ret fp128 %1 +} + +define fp128 @floatdikf(i64 %a) { +; CHECK-LABEL: floatdikf: +; CHECK: __floatdikf + %1 = sitofp i64 %a to fp128 + ret fp128 %1 +} + +define fp128 @floatunsikf(i32 %a) { +; CHECK-LABEL: floatunsikf: +; CHECK: __floatunsikf + %1 = uitofp i32 %a to fp128 + ret fp128 %1 +} + +define fp128 @floatundikf(i64 %a) { +; CHECK-LABEL: floatundikf: +; CHECK: __floatundikf + %1 = uitofp i64 %a to fp128 + ret fp128 %1 +} + +define i1 @test_eqkf2(fp128 %a, fp128 %b) { +; CHECK-LABEL: test_eqkf2: +; CHECK: __eqkf2 + %1 = fcmp oeq fp128 %a, %b + ret i1 %1 +} + +define i1 @test_nekf2(fp128 %a, fp128 %b) { +; CHECK-LABEL: test_nekf2: +; CHECK: __nekf2 + %1 = fcmp une fp128 %a, %b + ret i1 %1 +} + +define i1 @test_gekf2(fp128 %a, fp128 %b) { +; CHECK-LABEL: test_gekf2: +; CHECK: __gekf2 + %1 = fcmp oge fp128 %a, %b + ret i1 %1 +} + +define i1 @test_ltkf2(fp128 %a, fp128 %b) { +; CHECK-LABEL: test_ltkf2: +; CHECK: __ltkf2 + %1 = fcmp olt fp128 %a, %b + ret i1 %1 +} + +define i1 @test_lekf2(fp128 %a, fp128 %b) { +; CHECK-LABEL: test_lekf2: +; CHECK: __lekf2 + %1 = fcmp ole fp128 %a, %b + ret i1 %1 +} + +define i1 @test_gtkf2(fp128 %a, fp128 %b) { +; CHECK-LABEL: test_gtkf2: +; CHECK: __gtkf2 + %1 = fcmp ogt fp128 %a, %b + ret i1 %1 +} + +define i1 @test_unordkf2(fp128 %a, fp128 %b) { +; CHECK-LABEL: test_unordkf2: +; CHECK: __unordkf2 + %1 = fcmp uno fp128 %a, %b + ret i1 %1 +}