brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · 672ebd5 Raw
103 lines · cpp
1//===-- PPCLinux.cpp - PowerPC ToolChain Implementations --------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "PPCLinux.h"10#include "clang/Driver/Driver.h"11#include "clang/Options/Options.h"12#include "llvm/Support/FileSystem.h"13#include "llvm/Support/Path.h"14 15using namespace clang::driver;16using namespace clang::driver::toolchains;17using namespace llvm::opt;18using namespace llvm::sys;19 20// Glibc older than 2.32 doesn't fully support IEEE float128. Here we check21// glibc version by looking at dynamic linker name.22static bool GlibcSupportsFloat128(const std::string &Linker) {23  llvm::SmallVector<char, 16> Path;24 25  // Resolve potential symlinks to linker.26  if (fs::real_path(Linker, Path))27    return false;28  llvm::StringRef LinkerName =29      path::filename(llvm::StringRef(Path.data(), Path.size()));30 31  // Since glibc 2.34, the installed .so file is not symlink anymore. But we can32  // still safely assume it's newer than 2.32.33  if (LinkerName.starts_with("ld64.so"))34    return true;35 36  if (!LinkerName.starts_with("ld-2."))37    return false;38  unsigned Minor = (LinkerName[5] - '0') * 10 + (LinkerName[6] - '0');39  if (Minor < 32)40    return false;41 42  return true;43}44 45PPCLinuxToolChain::PPCLinuxToolChain(const Driver &D,46                                     const llvm::Triple &Triple,47                                     const llvm::opt::ArgList &Args)48    : Linux(D, Triple, Args) {49  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {50    StringRef ABIName = A->getValue();51 52    if ((ABIName == "ieeelongdouble" &&53         !SupportIEEEFloat128(D, Triple, Args)) ||54        (ABIName == "ibmlongdouble" && !supportIBMLongDouble(D, Args)))55      D.Diag(diag::warn_drv_unsupported_float_abi_by_lib) << ABIName;56  }57}58 59void PPCLinuxToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,60                                                  ArgStringList &CC1Args) const {61  if (!DriverArgs.hasArg(options::OPT_nostdinc) &&62      !DriverArgs.hasArg(options::OPT_nobuiltininc)) {63    const Driver &D = getDriver();64    SmallString<128> P(D.ResourceDir);65    llvm::sys::path::append(P, "include", "ppc_wrappers");66    addSystemInclude(DriverArgs, CC1Args, P);67  }68 69  Linux::AddClangSystemIncludeArgs(DriverArgs, CC1Args);70}71 72bool PPCLinuxToolChain::supportIBMLongDouble(73    const Driver &D, const llvm::opt::ArgList &Args) const {74  if (Args.hasArg(options::OPT_nostdlib, options::OPT_nostdlibxx))75    return true;76 77  CXXStdlibType StdLib = ToolChain::GetCXXStdlibType(Args);78  if (StdLib == CST_Libstdcxx)79    return true;80 81  return StdLib == CST_Libcxx && !defaultToIEEELongDouble();82}83 84bool PPCLinuxToolChain::SupportIEEEFloat128(85    const Driver &D, const llvm::Triple &Triple,86    const llvm::opt::ArgList &Args) const {87  if (!Triple.isLittleEndian() || !Triple.isPPC64())88    return false;89 90  if (Args.hasArg(options::OPT_nostdlib, options::OPT_nostdlibxx))91    return true;92 93  CXXStdlibType StdLib = ToolChain::GetCXXStdlibType(Args);94  bool HasUnsupportedCXXLib =95      (StdLib == CST_Libcxx && !defaultToIEEELongDouble()) ||96      (StdLib == CST_Libstdcxx &&97       GCCInstallation.getVersion().isOlderThan(12, 1, 0));98 99  std::string Linker = Linux::getDynamicLinker(Args);100  return GlibcSupportsFloat128((Twine(D.DyldPrefix) + Linker).str()) &&101         !(D.CCCIsCXX() && HasUnsupportedCXXLib);102}103