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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "PPCLinux.h" |
10 | #include "clang/Driver/Driver.h" |
11 | #include "clang/Driver/Options.h" |
12 | #include "llvm/Support/FileSystem.h" |
13 | #include "llvm/Support/Path.h" |
14 | |
15 | using namespace clang::driver; |
16 | using namespace clang::driver::toolchains; |
17 | using namespace llvm::opt; |
18 | using namespace llvm::sys; |
19 | |
20 | // Glibc older than 2.32 doesn't fully support IEEE float128. Here we check |
21 | // glibc version by looking at dynamic linker name. |
22 | static bool GlibcSupportsFloat128(const std::string &Linker) { |
23 | llvm::SmallVector<char, 16> Path; |
24 | |
25 | // Resolve potential symlinks to linker. |
26 | if (fs::real_path(path: Linker, output&: Path)) |
27 | return false; |
28 | llvm::StringRef LinkerName = |
29 | path::filename(path: llvm::StringRef(Path.data(), Path.size())); |
30 | |
31 | // Since glibc 2.34, the installed .so file is not symlink anymore. But we can |
32 | // still safely assume it's newer than 2.32. |
33 | if (LinkerName.starts_with(Prefix: "ld64.so" )) |
34 | return true; |
35 | |
36 | if (!LinkerName.starts_with(Prefix: "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 | |
45 | PPCLinuxToolChain::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::DiagID: warn_drv_unsupported_float_abi_by_lib) << ABIName; |
56 | } |
57 | } |
58 | |
59 | void PPCLinuxToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
60 | ArgStringList &CC1Args) const { |
61 | if (!DriverArgs.hasArg(clang::driver::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(path&: P, a: "include" , b: "ppc_wrappers" ); |
66 | addSystemInclude(DriverArgs, CC1Args, Path: P); |
67 | } |
68 | |
69 | Linux::AddClangSystemIncludeArgs(DriverArgs, CC1Args); |
70 | } |
71 | |
72 | bool 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 | |
84 | bool 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(RHSMajor: 12, RHSMinor: 1, RHSPatch: 0)); |
98 | |
99 | std::string Linker = Linux::getDynamicLinker(Args); |
100 | return GlibcSupportsFloat128(Linker: (Twine(D.DyldPrefix) + Linker).str()) && |
101 | !(D.CCCIsCXX() && HasUnsupportedCXXLib); |
102 | } |
103 | |