/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- PPC.cpp - PPC Helpers for Tools ------------------------*- 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 "PPC.h" |
10 | | #include "ToolChains/CommonArgs.h" |
11 | | #include "clang/Driver/Driver.h" |
12 | | #include "clang/Driver/DriverDiagnostic.h" |
13 | | #include "clang/Driver/Options.h" |
14 | | #include "llvm/ADT/StringSwitch.h" |
15 | | #include "llvm/Option/ArgList.h" |
16 | | #include "llvm/Support/Host.h" |
17 | | |
18 | | using namespace clang::driver; |
19 | | using namespace clang::driver::tools; |
20 | | using namespace clang; |
21 | | using namespace llvm::opt; |
22 | | |
23 | | /// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting. |
24 | 496 | std::string ppc::getPPCTargetCPU(const ArgList &Args) { |
25 | 496 | if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) { |
26 | 106 | StringRef CPUName = A->getValue(); |
27 | | |
28 | 106 | if (CPUName == "native") { |
29 | 1 | std::string CPU = std::string(llvm::sys::getHostCPUName()); |
30 | 1 | if (!CPU.empty() && CPU != "generic") |
31 | 1 | return CPU; |
32 | 0 | else |
33 | 0 | return ""; |
34 | 105 | } |
35 | | |
36 | 105 | return llvm::StringSwitch<const char *>(CPUName) |
37 | 105 | .Case("common", "generic") |
38 | 105 | .Case("440", "440") |
39 | 105 | .Case("440fp", "440") |
40 | 105 | .Case("450", "450") |
41 | 105 | .Case("601", "601") |
42 | 105 | .Case("602", "602") |
43 | 105 | .Case("603", "603") |
44 | 105 | .Case("603e", "603e") |
45 | 105 | .Case("603ev", "603ev") |
46 | 105 | .Case("604", "604") |
47 | 105 | .Case("604e", "604e") |
48 | 105 | .Case("620", "620") |
49 | 105 | .Case("630", "pwr3") |
50 | 105 | .Case("G3", "g3") |
51 | 105 | .Case("7400", "7400") |
52 | 105 | .Case("G4", "g4") |
53 | 105 | .Case("7450", "7450") |
54 | 105 | .Case("G4+", "g4+") |
55 | 105 | .Case("750", "750") |
56 | 105 | .Case("8548", "e500") |
57 | 105 | .Case("970", "970") |
58 | 105 | .Case("G5", "g5") |
59 | 105 | .Case("a2", "a2") |
60 | 105 | .Case("e500", "e500") |
61 | 105 | .Case("e500mc", "e500mc") |
62 | 105 | .Case("e5500", "e5500") |
63 | 105 | .Case("power3", "pwr3") |
64 | 105 | .Case("power4", "pwr4") |
65 | 105 | .Case("power5", "pwr5") |
66 | 105 | .Case("power5x", "pwr5x") |
67 | 105 | .Case("power6", "pwr6") |
68 | 105 | .Case("power6x", "pwr6x") |
69 | 105 | .Case("power7", "pwr7") |
70 | 105 | .Case("power8", "pwr8") |
71 | 105 | .Case("power9", "pwr9") |
72 | 105 | .Case("power10", "pwr10") |
73 | 105 | .Case("future", "future") |
74 | 105 | .Case("pwr3", "pwr3") |
75 | 105 | .Case("pwr4", "pwr4") |
76 | 105 | .Case("pwr5", "pwr5") |
77 | 105 | .Case("pwr5x", "pwr5x") |
78 | 105 | .Case("pwr6", "pwr6") |
79 | 105 | .Case("pwr6x", "pwr6x") |
80 | 105 | .Case("pwr7", "pwr7") |
81 | 105 | .Case("pwr8", "pwr8") |
82 | 105 | .Case("pwr9", "pwr9") |
83 | 105 | .Case("pwr10", "pwr10") |
84 | 105 | .Case("powerpc", "ppc") |
85 | 105 | .Case("powerpc64", "ppc64") |
86 | 105 | .Case("powerpc64le", "ppc64le") |
87 | 105 | .Default(""); |
88 | 105 | } |
89 | | |
90 | 390 | return ""; |
91 | 390 | } |
92 | | |
93 | 12 | const char *ppc::getPPCAsmModeForCPU(StringRef Name) { |
94 | 12 | return llvm::StringSwitch<const char *>(Name) |
95 | 12 | .Case("pwr7", "-mpower7") |
96 | 12 | .Case("power7", "-mpower7") |
97 | 12 | .Case("pwr8", "-mpower8") |
98 | 12 | .Case("power8", "-mpower8") |
99 | 12 | .Case("ppc64le", "-mpower8") |
100 | 12 | .Case("pwr9", "-mpower9") |
101 | 12 | .Case("power9", "-mpower9") |
102 | 12 | .Case("pwr10", "-mpower10") |
103 | 12 | .Case("power10", "-mpower10") |
104 | 12 | .Default("-many"); |
105 | 12 | } |
106 | | |
107 | | void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple, |
108 | | const ArgList &Args, |
109 | 484 | std::vector<StringRef> &Features) { |
110 | 484 | if (Triple.getSubArch() == llvm::Triple::PPCSubArch_spe) |
111 | 2 | Features.push_back("+spe"); |
112 | | |
113 | 484 | handleTargetFeaturesGroup(Args, Features, options::OPT_m_ppc_Features_Group); |
114 | | |
115 | 484 | ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args); |
116 | 484 | if (FloatABI == ppc::FloatABI::Soft) |
117 | 9 | Features.push_back("-hard-float"); |
118 | | |
119 | 484 | ppc::ReadGOTPtrMode ReadGOT = ppc::getPPCReadGOTPtrMode(D, Triple, Args); |
120 | 484 | if (ReadGOT == ppc::ReadGOTPtrMode::SecurePlt) |
121 | 29 | Features.push_back("+secure-plt"); |
122 | 484 | } |
123 | | |
124 | | ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple, |
125 | 484 | const ArgList &Args) { |
126 | 484 | if (Args.getLastArg(options::OPT_msecure_plt)) |
127 | 1 | return ppc::ReadGOTPtrMode::SecurePlt; |
128 | 483 | if ((Triple.isOSFreeBSD() && Triple.getOSMajorVersion() >= 1316 ) || |
129 | 476 | Triple.isOSNetBSD() || Triple.isOSOpenBSD()467 || Triple.isMusl()462 ) |
130 | 28 | return ppc::ReadGOTPtrMode::SecurePlt; |
131 | 455 | else |
132 | 455 | return ppc::ReadGOTPtrMode::Bss; |
133 | 483 | } |
134 | | |
135 | 932 | ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) { |
136 | 932 | ppc::FloatABI ABI = ppc::FloatABI::Invalid; |
137 | 932 | if (Arg *A = |
138 | 26 | Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, |
139 | 26 | options::OPT_mfloat_abi_EQ)) { |
140 | 26 | if (A->getOption().matches(options::OPT_msoft_float)) |
141 | 12 | ABI = ppc::FloatABI::Soft; |
142 | 14 | else if (A->getOption().matches(options::OPT_mhard_float)) |
143 | 4 | ABI = ppc::FloatABI::Hard; |
144 | 10 | else { |
145 | 10 | ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue()) |
146 | 10 | .Case("soft", ppc::FloatABI::Soft) |
147 | 10 | .Case("hard", ppc::FloatABI::Hard) |
148 | 10 | .Default(ppc::FloatABI::Invalid); |
149 | 10 | if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()2 ) { |
150 | 2 | D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); |
151 | 2 | ABI = ppc::FloatABI::Hard; |
152 | 2 | } |
153 | 10 | } |
154 | 26 | } |
155 | | |
156 | | // If unspecified, choose the default based on the platform. |
157 | 932 | if (ABI == ppc::FloatABI::Invalid) { |
158 | 906 | ABI = ppc::FloatABI::Hard; |
159 | 906 | } |
160 | | |
161 | 932 | return ABI; |
162 | 932 | } |
163 | | |
164 | 92 | bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) { |
165 | 92 | Arg *A = Args.getLastArg(options::OPT_mabi_EQ); |
166 | 92 | return A && (A->getValue() == StringRef(Value))18 ; |
167 | 92 | } |