Skip to content

Commit ecc6de3

Browse files
committedFeb 24, 2017
[Driver] Move architecture-specific free helper functions to their own files.
This patch moves helper functions that are CPU-specific out of Driver.cpp and to separate implementation files. The new files are named for the architecture, e.g. ARMArch.cpp. The next step after this will be to move OS-specific code, which I expect will include many of the tool implementations, to similarly separate files. Some CPU-specific functions are not being moved just yet. In cases where the only caller is the platform-specific tools, I plan to move them together. An example is Hexagon, where the only caller of the architecture-specific functions are the tools themselves. (I'm happy to revise this choice, it just seems like less churn to me.) This does mean that some functions which were previously static are now exposed through the library header Driver.h. Reviewers: rsmith, javed.absar Subscribers: aemerson, danalbert, srhines, dschuff, jyknight, nemanjai, mgorny, cfe-commits Differential Revision: https://reviews.llvm.org/D30315 llvm-svn: 296056
1 parent 3e0c068 commit ecc6de3

File tree

10 files changed

+1584
-1384
lines changed

10 files changed

+1584
-1384
lines changed
 

‎clang/lib/Driver/Arch/AArch64.cpp

+196
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
//===--- AArch64.cpp - AArch64 (not ARM) Helpers for Tools ------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "Tools.h"
11+
#include "clang/Driver/Driver.h"
12+
#include "clang/Driver/DriverDiagnostic.h"
13+
#include "clang/Driver/Options.h"
14+
#include "llvm/Option/ArgList.h"
15+
#include "llvm/Support/TargetParser.h"
16+
17+
using namespace clang::driver;
18+
using namespace clang::driver::tools;
19+
using namespace clang;
20+
using namespace llvm::opt;
21+
22+
/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
23+
/// targeting. Set \p A to the Arg corresponding to the -mcpu or -mtune
24+
/// arguments if they are provided, or to nullptr otherwise.
25+
std::string aarch64::getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
26+
std::string CPU;
27+
// If we have -mtune or -mcpu, use that.
28+
if ((A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))) {
29+
CPU = StringRef(A->getValue()).lower();
30+
} else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
31+
StringRef Mcpu = A->getValue();
32+
CPU = Mcpu.split("+").first.lower();
33+
}
34+
35+
// Handle CPU name is 'native'.
36+
if (CPU == "native")
37+
return llvm::sys::getHostCPUName();
38+
else if (CPU.size())
39+
return CPU;
40+
41+
// Make sure we pick "cyclone" if -arch is used.
42+
// FIXME: Should this be picked by checking the target triple instead?
43+
if (Args.getLastArg(options::OPT_arch))
44+
return "cyclone";
45+
46+
return "generic";
47+
}
48+
49+
// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
50+
static bool DecodeAArch64Features(const Driver &D, StringRef text,
51+
std::vector<StringRef> &Features) {
52+
SmallVector<StringRef, 8> Split;
53+
text.split(Split, StringRef("+"), -1, false);
54+
55+
for (StringRef Feature : Split) {
56+
StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
57+
if (!FeatureName.empty())
58+
Features.push_back(FeatureName);
59+
else if (Feature == "neon" || Feature == "noneon")
60+
D.Diag(clang::diag::err_drv_no_neon_modifier);
61+
else
62+
return false;
63+
}
64+
return true;
65+
}
66+
67+
// Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
68+
// decode CPU and feature.
69+
static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
70+
std::vector<StringRef> &Features) {
71+
std::pair<StringRef, StringRef> Split = Mcpu.split("+");
72+
CPU = Split.first;
73+
74+
if (CPU == "generic") {
75+
Features.push_back("+neon");
76+
} else {
77+
unsigned ArchKind = llvm::AArch64::parseCPUArch(CPU);
78+
if (!llvm::AArch64::getArchFeatures(ArchKind, Features))
79+
return false;
80+
81+
unsigned Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind);
82+
if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
83+
return false;
84+
}
85+
86+
if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
87+
return false;
88+
89+
return true;
90+
}
91+
92+
static bool
93+
getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
94+
const ArgList &Args,
95+
std::vector<StringRef> &Features) {
96+
std::string MarchLowerCase = March.lower();
97+
std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
98+
99+
unsigned ArchKind = llvm::AArch64::parseArch(Split.first);
100+
if (ArchKind == static_cast<unsigned>(llvm::AArch64::ArchKind::AK_INVALID) ||
101+
!llvm::AArch64::getArchFeatures(ArchKind, Features) ||
102+
(Split.second.size() && !DecodeAArch64Features(D, Split.second, Features)))
103+
return false;
104+
105+
return true;
106+
}
107+
108+
static bool
109+
getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
110+
const ArgList &Args,
111+
std::vector<StringRef> &Features) {
112+
StringRef CPU;
113+
std::string McpuLowerCase = Mcpu.lower();
114+
if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
115+
return false;
116+
117+
return true;
118+
}
119+
120+
static bool
121+
getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
122+
const ArgList &Args,
123+
std::vector<StringRef> &Features) {
124+
std::string MtuneLowerCase = Mtune.lower();
125+
// Handle CPU name is 'native'.
126+
if (MtuneLowerCase == "native")
127+
MtuneLowerCase = llvm::sys::getHostCPUName();
128+
if (MtuneLowerCase == "cyclone") {
129+
Features.push_back("+zcm");
130+
Features.push_back("+zcz");
131+
}
132+
return true;
133+
}
134+
135+
static bool
136+
getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
137+
const ArgList &Args,
138+
std::vector<StringRef> &Features) {
139+
StringRef CPU;
140+
std::vector<StringRef> DecodedFeature;
141+
std::string McpuLowerCase = Mcpu.lower();
142+
if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
143+
return false;
144+
145+
return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
146+
}
147+
148+
void aarch64::getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
149+
std::vector<StringRef> &Features) {
150+
Arg *A;
151+
bool success = true;
152+
// Enable NEON by default.
153+
Features.push_back("+neon");
154+
if ((A = Args.getLastArg(options::OPT_march_EQ)))
155+
success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
156+
else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
157+
success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
158+
else if (Args.hasArg(options::OPT_arch))
159+
success = getAArch64ArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args, A),
160+
Args, Features);
161+
162+
if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)))
163+
success =
164+
getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
165+
else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
166+
success =
167+
getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
168+
else if (success && Args.hasArg(options::OPT_arch))
169+
success = getAArch64MicroArchFeaturesFromMcpu(
170+
D, getAArch64TargetCPU(Args, A), Args, Features);
171+
172+
if (!success)
173+
D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
174+
175+
if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
176+
Features.push_back("-fp-armv8");
177+
Features.push_back("-crypto");
178+
Features.push_back("-neon");
179+
}
180+
181+
// En/disable crc
182+
if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
183+
if (A->getOption().matches(options::OPT_mcrc))
184+
Features.push_back("+crc");
185+
else
186+
Features.push_back("-crc");
187+
}
188+
189+
if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
190+
options::OPT_munaligned_access))
191+
if (A->getOption().matches(options::OPT_mno_unaligned_access))
192+
Features.push_back("+strict-align");
193+
194+
if (Args.hasArg(options::OPT_ffixed_x18))
195+
Features.push_back("+reserve-x18");
196+
}

‎clang/lib/Driver/Arch/ARM.cpp

+445
Large diffs are not rendered by default.

‎clang/lib/Driver/Arch/Mips.cpp

+397
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,397 @@
1+
//===--- Mips.cpp - Tools Implementations -----------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "Tools.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+
17+
using namespace clang::driver;
18+
using namespace clang::driver::tools;
19+
using namespace clang;
20+
using namespace llvm::opt;
21+
22+
// Get CPU and ABI names. They are not independent
23+
// so we have to calculate them together.
24+
void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple,
25+
StringRef &CPUName, StringRef &ABIName) {
26+
const char *DefMips32CPU = "mips32r2";
27+
const char *DefMips64CPU = "mips64r2";
28+
29+
// MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the
30+
// default for mips64(el)?-img-linux-gnu.
31+
if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies &&
32+
Triple.getEnvironment() == llvm::Triple::GNU) {
33+
DefMips32CPU = "mips32r6";
34+
DefMips64CPU = "mips64r6";
35+
}
36+
37+
// MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android).
38+
if (Triple.isAndroid()) {
39+
DefMips32CPU = "mips32";
40+
DefMips64CPU = "mips64r6";
41+
}
42+
43+
// MIPS3 is the default for mips64*-unknown-openbsd.
44+
if (Triple.getOS() == llvm::Triple::OpenBSD)
45+
DefMips64CPU = "mips3";
46+
47+
if (Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ,
48+
options::OPT_mcpu_EQ))
49+
CPUName = A->getValue();
50+
51+
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
52+
ABIName = A->getValue();
53+
// Convert a GNU style Mips ABI name to the name
54+
// accepted by LLVM Mips backend.
55+
ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
56+
.Case("32", "o32")
57+
.Case("64", "n64")
58+
.Default(ABIName);
59+
}
60+
61+
// Setup default CPU and ABI names.
62+
if (CPUName.empty() && ABIName.empty()) {
63+
switch (Triple.getArch()) {
64+
default:
65+
llvm_unreachable("Unexpected triple arch name");
66+
case llvm::Triple::mips:
67+
case llvm::Triple::mipsel:
68+
CPUName = DefMips32CPU;
69+
break;
70+
case llvm::Triple::mips64:
71+
case llvm::Triple::mips64el:
72+
CPUName = DefMips64CPU;
73+
break;
74+
}
75+
}
76+
77+
if (ABIName.empty() &&
78+
(Triple.getVendor() == llvm::Triple::MipsTechnologies ||
79+
Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
80+
ABIName = llvm::StringSwitch<const char *>(CPUName)
81+
.Case("mips1", "o32")
82+
.Case("mips2", "o32")
83+
.Case("mips3", "n64")
84+
.Case("mips4", "n64")
85+
.Case("mips5", "n64")
86+
.Case("mips32", "o32")
87+
.Case("mips32r2", "o32")
88+
.Case("mips32r3", "o32")
89+
.Case("mips32r5", "o32")
90+
.Case("mips32r6", "o32")
91+
.Case("mips64", "n64")
92+
.Case("mips64r2", "n64")
93+
.Case("mips64r3", "n64")
94+
.Case("mips64r5", "n64")
95+
.Case("mips64r6", "n64")
96+
.Case("octeon", "n64")
97+
.Case("p5600", "o32")
98+
.Default("");
99+
}
100+
101+
if (ABIName.empty()) {
102+
// Deduce ABI name from the target triple.
103+
if (Triple.getArch() == llvm::Triple::mips ||
104+
Triple.getArch() == llvm::Triple::mipsel)
105+
ABIName = "o32";
106+
else
107+
ABIName = "n64";
108+
}
109+
110+
if (CPUName.empty()) {
111+
// Deduce CPU name from ABI name.
112+
CPUName = llvm::StringSwitch<const char *>(ABIName)
113+
.Case("o32", DefMips32CPU)
114+
.Cases("n32", "n64", DefMips64CPU)
115+
.Default("");
116+
}
117+
118+
// FIXME: Warn on inconsistent use of -march and -mabi.
119+
}
120+
121+
std::string mips::getMipsABILibSuffix(const ArgList &Args,
122+
const llvm::Triple &Triple) {
123+
StringRef CPUName, ABIName;
124+
tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
125+
return llvm::StringSwitch<std::string>(ABIName)
126+
.Case("o32", "")
127+
.Case("n32", "32")
128+
.Case("n64", "64");
129+
}
130+
131+
// Convert ABI name to the GNU tools acceptable variant.
132+
StringRef mips::getGnuCompatibleMipsABIName(StringRef ABI) {
133+
return llvm::StringSwitch<llvm::StringRef>(ABI)
134+
.Case("o32", "32")
135+
.Case("n64", "64")
136+
.Default(ABI);
137+
}
138+
139+
// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
140+
// and -mfloat-abi=.
141+
mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args) {
142+
mips::FloatABI ABI = mips::FloatABI::Invalid;
143+
if (Arg *A =
144+
Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
145+
options::OPT_mfloat_abi_EQ)) {
146+
if (A->getOption().matches(options::OPT_msoft_float))
147+
ABI = mips::FloatABI::Soft;
148+
else if (A->getOption().matches(options::OPT_mhard_float))
149+
ABI = mips::FloatABI::Hard;
150+
else {
151+
ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
152+
.Case("soft", mips::FloatABI::Soft)
153+
.Case("hard", mips::FloatABI::Hard)
154+
.Default(mips::FloatABI::Invalid);
155+
if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
156+
D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
157+
ABI = mips::FloatABI::Hard;
158+
}
159+
}
160+
}
161+
162+
// If unspecified, choose the default based on the platform.
163+
if (ABI == mips::FloatABI::Invalid) {
164+
// Assume "hard", because it's a default value used by gcc.
165+
// When we start to recognize specific target MIPS processors,
166+
// we will be able to select the default more correctly.
167+
ABI = mips::FloatABI::Hard;
168+
}
169+
170+
assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
171+
return ABI;
172+
}
173+
174+
void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
175+
const ArgList &Args,
176+
std::vector<StringRef> &Features) {
177+
StringRef CPUName;
178+
StringRef ABIName;
179+
getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
180+
ABIName = getGnuCompatibleMipsABIName(ABIName);
181+
182+
// Historically, PIC code for MIPS was associated with -mabicalls, a.k.a
183+
// SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI
184+
// extension was developed by Richard Sandiford & Code Sourcery to support
185+
// static code calling PIC code (CPIC). For O32 and N32 this means we have
186+
// several combinations of PIC/static and abicalls. Pure static, static
187+
// with the CPIC extension, and pure PIC code.
188+
189+
// At final link time, O32 and N32 with CPIC will have another section
190+
// added to the binary which contains the stub functions to perform
191+
// any fixups required for PIC code.
192+
193+
// For N64, the situation is more regular: code can either be static
194+
// (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code
195+
// code for N64. Since Clang has already built the relocation model portion
196+
// of the commandline, we pick add +noabicalls feature in the N64 static
197+
// case.
198+
199+
// The is another case to be accounted for: -msym32, which enforces that all
200+
// symbols have 32 bits in size. In this case, N64 can in theory use CPIC
201+
// but it is unsupported.
202+
203+
// The combinations for N64 are:
204+
// a) Static without abicalls and 64bit symbols.
205+
// b) Static with abicalls and 32bit symbols.
206+
// c) PIC with abicalls and 64bit symbols.
207+
208+
// For case (a) we need to add +noabicalls for N64.
209+
210+
bool IsN64 = ABIName == "64";
211+
bool NonPIC = false;
212+
213+
Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
214+
options::OPT_fpic, options::OPT_fno_pic,
215+
options::OPT_fPIE, options::OPT_fno_PIE,
216+
options::OPT_fpie, options::OPT_fno_pie);
217+
if (LastPICArg) {
218+
Option O = LastPICArg->getOption();
219+
NonPIC =
220+
(O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
221+
O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
222+
}
223+
224+
if (IsN64 && NonPIC) {
225+
Features.push_back("+noabicalls");
226+
} else {
227+
AddTargetFeature(Args, Features, options::OPT_mno_abicalls,
228+
options::OPT_mabicalls, "noabicalls");
229+
}
230+
231+
mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args);
232+
if (FloatABI == mips::FloatABI::Soft) {
233+
// FIXME: Note, this is a hack. We need to pass the selected float
234+
// mode to the MipsTargetInfoBase to define appropriate macros there.
235+
// Now it is the only method.
236+
Features.push_back("+soft-float");
237+
}
238+
239+
if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
240+
StringRef Val = StringRef(A->getValue());
241+
if (Val == "2008") {
242+
if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008)
243+
Features.push_back("+nan2008");
244+
else {
245+
Features.push_back("-nan2008");
246+
D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
247+
}
248+
} else if (Val == "legacy") {
249+
if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy)
250+
Features.push_back("-nan2008");
251+
else {
252+
Features.push_back("+nan2008");
253+
D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
254+
}
255+
} else
256+
D.Diag(diag::err_drv_unsupported_option_argument)
257+
<< A->getOption().getName() << Val;
258+
}
259+
260+
AddTargetFeature(Args, Features, options::OPT_msingle_float,
261+
options::OPT_mdouble_float, "single-float");
262+
AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
263+
"mips16");
264+
AddTargetFeature(Args, Features, options::OPT_mmicromips,
265+
options::OPT_mno_micromips, "micromips");
266+
AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
267+
"dsp");
268+
AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
269+
"dspr2");
270+
AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
271+
"msa");
272+
273+
// Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
274+
// pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
275+
// nooddspreg.
276+
if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
277+
options::OPT_mfp64)) {
278+
if (A->getOption().matches(options::OPT_mfp32))
279+
Features.push_back(Args.MakeArgString("-fp64"));
280+
else if (A->getOption().matches(options::OPT_mfpxx)) {
281+
Features.push_back(Args.MakeArgString("+fpxx"));
282+
Features.push_back(Args.MakeArgString("+nooddspreg"));
283+
} else
284+
Features.push_back(Args.MakeArgString("+fp64"));
285+
} else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
286+
Features.push_back(Args.MakeArgString("+fpxx"));
287+
Features.push_back(Args.MakeArgString("+nooddspreg"));
288+
} else if (mips::isFP64ADefault(Triple, CPUName)) {
289+
Features.push_back(Args.MakeArgString("+fp64"));
290+
Features.push_back(Args.MakeArgString("+nooddspreg"));
291+
}
292+
293+
AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
294+
options::OPT_modd_spreg, "nooddspreg");
295+
}
296+
297+
mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
298+
// Strictly speaking, mips32r2 and mips64r2 are NanLegacy-only since Nan2008
299+
// was first introduced in Release 3. However, other compilers have
300+
// traditionally allowed it for Release 2 so we should do the same.
301+
return (NanEncoding)llvm::StringSwitch<int>(CPU)
302+
.Case("mips1", NanLegacy)
303+
.Case("mips2", NanLegacy)
304+
.Case("mips3", NanLegacy)
305+
.Case("mips4", NanLegacy)
306+
.Case("mips5", NanLegacy)
307+
.Case("mips32", NanLegacy)
308+
.Case("mips32r2", NanLegacy | Nan2008)
309+
.Case("mips32r3", NanLegacy | Nan2008)
310+
.Case("mips32r5", NanLegacy | Nan2008)
311+
.Case("mips32r6", Nan2008)
312+
.Case("mips64", NanLegacy)
313+
.Case("mips64r2", NanLegacy | Nan2008)
314+
.Case("mips64r3", NanLegacy | Nan2008)
315+
.Case("mips64r5", NanLegacy | Nan2008)
316+
.Case("mips64r6", Nan2008)
317+
.Default(NanLegacy);
318+
}
319+
320+
bool mips::hasCompactBranches(StringRef &CPU) {
321+
// mips32r6 and mips64r6 have compact branches.
322+
return llvm::StringSwitch<bool>(CPU)
323+
.Case("mips32r6", true)
324+
.Case("mips64r6", true)
325+
.Default(false);
326+
}
327+
328+
bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
329+
Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
330+
return A && (A->getValue() == StringRef(Value));
331+
}
332+
333+
bool mips::isUCLibc(const ArgList &Args) {
334+
Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
335+
return A && A->getOption().matches(options::OPT_muclibc);
336+
}
337+
338+
bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
339+
if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
340+
return llvm::StringSwitch<bool>(NaNArg->getValue())
341+
.Case("2008", true)
342+
.Case("legacy", false)
343+
.Default(false);
344+
345+
// NaN2008 is the default for MIPS32r6/MIPS64r6.
346+
return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
347+
.Cases("mips32r6", "mips64r6", true)
348+
.Default(false);
349+
350+
return false;
351+
}
352+
353+
bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
354+
if (!Triple.isAndroid())
355+
return false;
356+
357+
// Android MIPS32R6 defaults to FP64A.
358+
return llvm::StringSwitch<bool>(CPUName)
359+
.Case("mips32r6", true)
360+
.Default(false);
361+
}
362+
363+
bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
364+
StringRef ABIName, mips::FloatABI FloatABI) {
365+
if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
366+
Triple.getVendor() != llvm::Triple::MipsTechnologies &&
367+
!Triple.isAndroid())
368+
return false;
369+
370+
if (ABIName != "32")
371+
return false;
372+
373+
// FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
374+
// present.
375+
if (FloatABI == mips::FloatABI::Soft)
376+
return false;
377+
378+
return llvm::StringSwitch<bool>(CPUName)
379+
.Cases("mips2", "mips3", "mips4", "mips5", true)
380+
.Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
381+
.Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
382+
.Default(false);
383+
}
384+
385+
bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
386+
StringRef CPUName, StringRef ABIName,
387+
mips::FloatABI FloatABI) {
388+
bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
389+
390+
// FPXX shouldn't be used if -msingle-float is present.
391+
if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
392+
options::OPT_mdouble_float))
393+
if (A->getOption().matches(options::OPT_msingle_float))
394+
UseFPXX = false;
395+
396+
return UseFPXX;
397+
}

‎clang/lib/Driver/Arch/PPC.cpp

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
//===--- PPC.cpp - PPC Helpers for Tools ------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "Tools.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+
17+
using namespace clang::driver;
18+
using namespace clang::driver::tools;
19+
using namespace clang;
20+
using namespace llvm::opt;
21+
22+
/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
23+
std::string ppc::getPPCTargetCPU(const ArgList &Args) {
24+
if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {
25+
StringRef CPUName = A->getValue();
26+
27+
if (CPUName == "native") {
28+
std::string CPU = llvm::sys::getHostCPUName();
29+
if (!CPU.empty() && CPU != "generic")
30+
return CPU;
31+
else
32+
return "";
33+
}
34+
35+
return llvm::StringSwitch<const char *>(CPUName)
36+
.Case("common", "generic")
37+
.Case("440", "440")
38+
.Case("440fp", "440")
39+
.Case("450", "450")
40+
.Case("601", "601")
41+
.Case("602", "602")
42+
.Case("603", "603")
43+
.Case("603e", "603e")
44+
.Case("603ev", "603ev")
45+
.Case("604", "604")
46+
.Case("604e", "604e")
47+
.Case("620", "620")
48+
.Case("630", "pwr3")
49+
.Case("G3", "g3")
50+
.Case("7400", "7400")
51+
.Case("G4", "g4")
52+
.Case("7450", "7450")
53+
.Case("G4+", "g4+")
54+
.Case("750", "750")
55+
.Case("970", "970")
56+
.Case("G5", "g5")
57+
.Case("a2", "a2")
58+
.Case("a2q", "a2q")
59+
.Case("e500mc", "e500mc")
60+
.Case("e5500", "e5500")
61+
.Case("power3", "pwr3")
62+
.Case("power4", "pwr4")
63+
.Case("power5", "pwr5")
64+
.Case("power5x", "pwr5x")
65+
.Case("power6", "pwr6")
66+
.Case("power6x", "pwr6x")
67+
.Case("power7", "pwr7")
68+
.Case("power8", "pwr8")
69+
.Case("power9", "pwr9")
70+
.Case("pwr3", "pwr3")
71+
.Case("pwr4", "pwr4")
72+
.Case("pwr5", "pwr5")
73+
.Case("pwr5x", "pwr5x")
74+
.Case("pwr6", "pwr6")
75+
.Case("pwr6x", "pwr6x")
76+
.Case("pwr7", "pwr7")
77+
.Case("pwr8", "pwr8")
78+
.Case("pwr9", "pwr9")
79+
.Case("powerpc", "ppc")
80+
.Case("powerpc64", "ppc64")
81+
.Case("powerpc64le", "ppc64le")
82+
.Default("");
83+
}
84+
85+
return "";
86+
}
87+
88+
void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
89+
const ArgList &Args,
90+
std::vector<StringRef> &Features) {
91+
handleTargetFeaturesGroup(Args, Features, options::OPT_m_ppc_Features_Group);
92+
93+
ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
94+
if (FloatABI == ppc::FloatABI::Soft)
95+
Features.push_back("-hard-float");
96+
97+
// Altivec is a bit weird, allow overriding of the Altivec feature here.
98+
AddTargetFeature(Args, Features, options::OPT_faltivec,
99+
options::OPT_fno_altivec, "altivec");
100+
}
101+
102+
ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) {
103+
ppc::FloatABI ABI = ppc::FloatABI::Invalid;
104+
if (Arg *A =
105+
Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
106+
options::OPT_mfloat_abi_EQ)) {
107+
if (A->getOption().matches(options::OPT_msoft_float))
108+
ABI = ppc::FloatABI::Soft;
109+
else if (A->getOption().matches(options::OPT_mhard_float))
110+
ABI = ppc::FloatABI::Hard;
111+
else {
112+
ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue())
113+
.Case("soft", ppc::FloatABI::Soft)
114+
.Case("hard", ppc::FloatABI::Hard)
115+
.Default(ppc::FloatABI::Invalid);
116+
if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
117+
D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
118+
ABI = ppc::FloatABI::Hard;
119+
}
120+
}
121+
}
122+
123+
// If unspecified, choose the default based on the platform.
124+
if (ABI == ppc::FloatABI::Invalid) {
125+
ABI = ppc::FloatABI::Hard;
126+
}
127+
128+
return ABI;
129+
}
130+
131+
bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
132+
Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
133+
return A && (A->getValue() == StringRef(Value));
134+
}

‎clang/lib/Driver/Arch/Sparc.cpp

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//===--- Sparc.cpp - Tools Implementations ----------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "Tools.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+
17+
using namespace clang::driver;
18+
using namespace clang::driver::tools;
19+
using namespace clang;
20+
using namespace llvm::opt;
21+
22+
const char *sparc::getSparcAsmModeForCPU(StringRef Name,
23+
const llvm::Triple &Triple) {
24+
if (Triple.getArch() == llvm::Triple::sparcv9) {
25+
return llvm::StringSwitch<const char *>(Name)
26+
.Case("niagara", "-Av9b")
27+
.Case("niagara2", "-Av9b")
28+
.Case("niagara3", "-Av9d")
29+
.Case("niagara4", "-Av9d")
30+
.Default("-Av9");
31+
} else {
32+
return llvm::StringSwitch<const char *>(Name)
33+
.Case("v8", "-Av8")
34+
.Case("supersparc", "-Av8")
35+
.Case("sparclite", "-Asparclite")
36+
.Case("f934", "-Asparclite")
37+
.Case("hypersparc", "-Av8")
38+
.Case("sparclite86x", "-Asparclite")
39+
.Case("sparclet", "-Asparclet")
40+
.Case("tsc701", "-Asparclet")
41+
.Case("v9", "-Av8plus")
42+
.Case("ultrasparc", "-Av8plus")
43+
.Case("ultrasparc3", "-Av8plus")
44+
.Case("niagara", "-Av8plusb")
45+
.Case("niagara2", "-Av8plusb")
46+
.Case("niagara3", "-Av8plusd")
47+
.Case("niagara4", "-Av8plusd")
48+
.Case("leon2", "-Av8")
49+
.Case("at697e", "-Av8")
50+
.Case("at697f", "-Av8")
51+
.Case("leon3", "-Av8")
52+
.Case("ut699", "-Av8")
53+
.Case("gr712rc", "-Av8")
54+
.Case("leon4", "-Av8")
55+
.Case("gr740", "-Av8")
56+
.Default("-Av8");
57+
}
58+
}
59+
60+
sparc::FloatABI sparc::getSparcFloatABI(const Driver &D,
61+
const ArgList &Args) {
62+
sparc::FloatABI ABI = sparc::FloatABI::Invalid;
63+
if (Arg *A = Args.getLastArg(clang::driver::options::OPT_msoft_float,
64+
options::OPT_mhard_float,
65+
options::OPT_mfloat_abi_EQ)) {
66+
if (A->getOption().matches(clang::driver::options::OPT_msoft_float))
67+
ABI = sparc::FloatABI::Soft;
68+
else if (A->getOption().matches(options::OPT_mhard_float))
69+
ABI = sparc::FloatABI::Hard;
70+
else {
71+
ABI = llvm::StringSwitch<sparc::FloatABI>(A->getValue())
72+
.Case("soft", sparc::FloatABI::Soft)
73+
.Case("hard", sparc::FloatABI::Hard)
74+
.Default(sparc::FloatABI::Invalid);
75+
if (ABI == sparc::FloatABI::Invalid &&
76+
!StringRef(A->getValue()).empty()) {
77+
D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
78+
ABI = sparc::FloatABI::Hard;
79+
}
80+
}
81+
}
82+
83+
// If unspecified, choose the default based on the platform.
84+
// Only the hard-float ABI on Sparc is standardized, and it is the
85+
// default. GCC also supports a nonstandard soft-float ABI mode, also
86+
// implemented in LLVM. However as this is not standard we set the default
87+
// to be hard-float.
88+
if (ABI == sparc::FloatABI::Invalid) {
89+
ABI = sparc::FloatABI::Hard;
90+
}
91+
92+
return ABI;
93+
}
94+
95+
void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args,
96+
std::vector<StringRef> &Features) {
97+
sparc::FloatABI FloatABI = sparc::getSparcFloatABI(D, Args);
98+
if (FloatABI == sparc::FloatABI::Soft)
99+
Features.push_back("+soft-float");
100+
}

‎clang/lib/Driver/Arch/SystemZ.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===--- SystemZ.cpp - SystemZ Helpers for Tools ----------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "Tools.h"
11+
#include "clang/Driver/Options.h"
12+
#include "llvm/Option/ArgList.h"
13+
14+
using namespace clang::driver;
15+
using namespace clang::driver::tools;
16+
using namespace clang;
17+
using namespace llvm::opt;
18+
19+
const char *systemz::getSystemZTargetCPU(const ArgList &Args) {
20+
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ))
21+
return A->getValue();
22+
return "z10";
23+
}
24+
25+
void systemz::getSystemZTargetFeatures(const ArgList &Args,
26+
std::vector<StringRef> &Features) {
27+
// -m(no-)htm overrides use of the transactional-execution facility.
28+
if (Arg *A = Args.getLastArg(options::OPT_mhtm, options::OPT_mno_htm)) {
29+
if (A->getOption().matches(options::OPT_mhtm))
30+
Features.push_back("+transactional-execution");
31+
else
32+
Features.push_back("-transactional-execution");
33+
}
34+
// -m(no-)vx overrides use of the vector facility.
35+
if (Arg *A = Args.getLastArg(options::OPT_mvx, options::OPT_mno_vx)) {
36+
if (A->getOption().matches(options::OPT_mvx))
37+
Features.push_back("+vector");
38+
else
39+
Features.push_back("-vector");
40+
}
41+
}

‎clang/lib/Driver/Arch/X86.cpp

+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
//===--- X86.cpp - X86 Helpers for Tools ------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "Tools.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+
17+
using namespace clang::driver;
18+
using namespace clang::driver::tools;
19+
using namespace clang;
20+
using namespace llvm::opt;
21+
22+
const char *x86::getX86TargetCPU(const ArgList &Args,
23+
const llvm::Triple &Triple) {
24+
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
25+
if (StringRef(A->getValue()) != "native") {
26+
if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
27+
return "core-avx2";
28+
29+
return A->getValue();
30+
}
31+
32+
// FIXME: Reject attempts to use -march=native unless the target matches
33+
// the host.
34+
//
35+
// FIXME: We should also incorporate the detected target features for use
36+
// with -native.
37+
std::string CPU = llvm::sys::getHostCPUName();
38+
if (!CPU.empty() && CPU != "generic")
39+
return Args.MakeArgString(CPU);
40+
}
41+
42+
if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
43+
// Mapping built by referring to X86TargetInfo::getDefaultFeatures().
44+
StringRef Arch = A->getValue();
45+
const char *CPU;
46+
if (Triple.getArch() == llvm::Triple::x86) {
47+
CPU = llvm::StringSwitch<const char *>(Arch)
48+
.Case("IA32", "i386")
49+
.Case("SSE", "pentium3")
50+
.Case("SSE2", "pentium4")
51+
.Case("AVX", "sandybridge")
52+
.Case("AVX2", "haswell")
53+
.Default(nullptr);
54+
} else {
55+
CPU = llvm::StringSwitch<const char *>(Arch)
56+
.Case("AVX", "sandybridge")
57+
.Case("AVX2", "haswell")
58+
.Default(nullptr);
59+
}
60+
if (CPU)
61+
return CPU;
62+
}
63+
64+
// Select the default CPU if none was given (or detection failed).
65+
66+
if (Triple.getArch() != llvm::Triple::x86_64 &&
67+
Triple.getArch() != llvm::Triple::x86)
68+
return nullptr; // This routine is only handling x86 targets.
69+
70+
bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
71+
72+
// FIXME: Need target hooks.
73+
if (Triple.isOSDarwin()) {
74+
if (Triple.getArchName() == "x86_64h")
75+
return "core-avx2";
76+
// macosx10.12 drops support for all pre-Penryn Macs.
77+
// Simulators can still run on 10.11 though, like Xcode.
78+
if (Triple.isMacOSX() && !Triple.isOSVersionLT(10, 12))
79+
return "penryn";
80+
// The oldest x86_64 Macs have core2/Merom; the oldest x86 Macs have Yonah.
81+
return Is64Bit ? "core2" : "yonah";
82+
}
83+
84+
// Set up default CPU name for PS4 compilers.
85+
if (Triple.isPS4CPU())
86+
return "btver2";
87+
88+
// On Android use targets compatible with gcc
89+
if (Triple.isAndroid())
90+
return Is64Bit ? "x86-64" : "i686";
91+
92+
// Everything else goes to x86-64 in 64-bit mode.
93+
if (Is64Bit)
94+
return "x86-64";
95+
96+
switch (Triple.getOS()) {
97+
case llvm::Triple::FreeBSD:
98+
case llvm::Triple::NetBSD:
99+
case llvm::Triple::OpenBSD:
100+
return "i486";
101+
case llvm::Triple::Haiku:
102+
return "i586";
103+
case llvm::Triple::Bitrig:
104+
return "i686";
105+
default:
106+
// Fallback to p4.
107+
return "pentium4";
108+
}
109+
}
110+
111+
void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
112+
const ArgList &Args,
113+
std::vector<StringRef> &Features) {
114+
// If -march=native, autodetect the feature list.
115+
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
116+
if (StringRef(A->getValue()) == "native") {
117+
llvm::StringMap<bool> HostFeatures;
118+
if (llvm::sys::getHostCPUFeatures(HostFeatures))
119+
for (auto &F : HostFeatures)
120+
Features.push_back(
121+
Args.MakeArgString((F.second ? "+" : "-") + F.first()));
122+
}
123+
}
124+
125+
if (Triple.getArchName() == "x86_64h") {
126+
// x86_64h implies quite a few of the more modern subtarget features
127+
// for Haswell class CPUs, but not all of them. Opt-out of a few.
128+
Features.push_back("-rdrnd");
129+
Features.push_back("-aes");
130+
Features.push_back("-pclmul");
131+
Features.push_back("-rtm");
132+
Features.push_back("-hle");
133+
Features.push_back("-fsgsbase");
134+
}
135+
136+
const llvm::Triple::ArchType ArchType = Triple.getArch();
137+
// Add features to be compatible with gcc for Android.
138+
if (Triple.isAndroid()) {
139+
if (ArchType == llvm::Triple::x86_64) {
140+
Features.push_back("+sse4.2");
141+
Features.push_back("+popcnt");
142+
} else
143+
Features.push_back("+ssse3");
144+
}
145+
146+
// Set features according to the -arch flag on MSVC.
147+
if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
148+
StringRef Arch = A->getValue();
149+
bool ArchUsed = false;
150+
// First, look for flags that are shared in x86 and x86-64.
151+
if (ArchType == llvm::Triple::x86_64 || ArchType == llvm::Triple::x86) {
152+
if (Arch == "AVX" || Arch == "AVX2") {
153+
ArchUsed = true;
154+
Features.push_back(Args.MakeArgString("+" + Arch.lower()));
155+
}
156+
}
157+
// Then, look for x86-specific flags.
158+
if (ArchType == llvm::Triple::x86) {
159+
if (Arch == "IA32") {
160+
ArchUsed = true;
161+
} else if (Arch == "SSE" || Arch == "SSE2") {
162+
ArchUsed = true;
163+
Features.push_back(Args.MakeArgString("+" + Arch.lower()));
164+
}
165+
}
166+
if (!ArchUsed)
167+
D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args);
168+
}
169+
170+
// Now add any that the user explicitly requested on the command line,
171+
// which may override the defaults.
172+
handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group);
173+
}

‎clang/lib/Driver/CMakeLists.txt

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,22 @@ endif()
1010

1111
add_clang_library(clangDriver
1212
Action.cpp
13+
Arch/AArch64.cpp
14+
Arch/ARM.cpp
15+
Arch/Mips.cpp
16+
Arch/PPC.cpp
17+
Arch/Sparc.cpp
18+
Arch/SystemZ.cpp
19+
Arch/X86.cpp
1320
Compilation.cpp
1421
CrossWindowsToolChain.cpp
1522
Distro.cpp
1623
Driver.cpp
1724
DriverOptions.cpp
1825
Job.cpp
26+
MSVCToolChain.cpp
1927
MinGWToolChain.cpp
2028
Multilib.cpp
21-
MSVCToolChain.cpp
2229
Phases.cpp
2330
SanitizerArgs.cpp
2431
Tool.cpp

‎clang/lib/Driver/Tools.cpp

+33-1,383
Large diffs are not rendered by default.

‎clang/lib/Driver/Tools.h

+57
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,23 @@ class Compiler;
3838
}
3939

4040
using llvm::opt::ArgStringList;
41+
using llvm::opt::ArgList;
4142

4243
SmallString<128> getCompilerRT(const ToolChain &TC,
4344
const llvm::opt::ArgList &Args,
4445
StringRef Component, bool Shared = false);
4546

47+
std::string getCPUName(const ArgList &Args, const llvm::Triple &T,
48+
bool FromAs = false);
49+
50+
void AddTargetFeature(const ArgList &Args, std::vector<StringRef> &Features,
51+
llvm::opt::OptSpecifier OnOpt,
52+
llvm::opt::OptSpecifier OffOpt, StringRef FeatureName);
53+
54+
void handleTargetFeaturesGroup(const ArgList &Args,
55+
std::vector<StringRef> &Features,
56+
llvm::opt::OptSpecifier Group);
57+
4658
/// \brief Clang compiler tool.
4759
class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
4860
public:
@@ -321,6 +333,11 @@ bool hasCompactBranches(StringRef &CPU);
321333
void getMipsCPUAndABI(const llvm::opt::ArgList &Args,
322334
const llvm::Triple &Triple, StringRef &CPUName,
323335
StringRef &ABIName);
336+
void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
337+
const ArgList &Args,
338+
std::vector<StringRef> &Features);
339+
StringRef getGnuCompatibleMipsABIName(StringRef ABI);
340+
mips::FloatABI getMipsFloatABI(const Driver &D, const ArgList &Args);
324341
std::string getMipsABILibSuffix(const llvm::opt::ArgList &Args,
325342
const llvm::Triple &Triple);
326343
bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value);
@@ -332,6 +349,7 @@ bool isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
332349
bool shouldUseFPXX(const llvm::opt::ArgList &Args, const llvm::Triple &Triple,
333350
StringRef CPUName, StringRef ABIName,
334351
mips::FloatABI FloatABI);
352+
335353
} // end namespace mips
336354

337355
namespace ppc {
@@ -803,8 +821,23 @@ enum class FloatABI {
803821
};
804822

805823
FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args);
824+
825+
bool useAAPCSForMachO(const llvm::Triple &T);
826+
void getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
827+
llvm::StringRef &CPU, bool FromAs = false);
828+
void getARMTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
829+
const ArgList &Args, ArgStringList &CmdArgs,
830+
std::vector<StringRef> &Features, bool ForAS);
831+
int getARMSubArchVersionNumber(const llvm::Triple &Triple);
832+
bool isARMMProfile(const llvm::Triple &Triple);
806833
} // end namespace arm
807834

835+
namespace aarch64 {
836+
void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
837+
std::vector<StringRef> &Features);
838+
std::string getAArch64TargetCPU(const ArgList &Args, llvm::opt::Arg *&A);
839+
} // end namespace aarch64
840+
808841
namespace ppc {
809842
enum class FloatABI {
810843
Invalid,
@@ -813,6 +846,11 @@ enum class FloatABI {
813846
};
814847

815848
FloatABI getPPCFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
849+
850+
std::string getPPCTargetCPU(const ArgList &Args);
851+
void getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
852+
const ArgList &Args,
853+
std::vector<StringRef> &Features);
816854
} // end namespace ppc
817855

818856
namespace sparc {
@@ -823,6 +861,11 @@ enum class FloatABI {
823861
};
824862

825863
FloatABI getSparcFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
864+
865+
void getSparcTargetFeatures(const Driver &D, const ArgList &Args,
866+
std::vector<StringRef> &Features);
867+
const char *getSparcAsmModeForCPU(StringRef Name,
868+
const llvm::Triple &Triple);
826869
} // end namespace sparc
827870

828871
namespace XCore {
@@ -1003,6 +1046,20 @@ class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
10031046
};
10041047
} // end namespace AVR
10051048

1049+
namespace systemz {
1050+
const char *getSystemZTargetCPU(const ArgList &Args);
1051+
void getSystemZTargetFeatures(const ArgList &Args,
1052+
std::vector<StringRef> &Features);
1053+
} // end namespace systemz
1054+
1055+
namespace x86 {
1056+
const char *getX86TargetCPU(const ArgList &Args,
1057+
const llvm::Triple &Triple);
1058+
void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
1059+
const ArgList &Args,
1060+
std::vector<StringRef> &Features);
1061+
} // end namespace x86
1062+
10061063
} // end namespace tools
10071064
} // end namespace driver
10081065
} // end namespace clang

0 commit comments

Comments
 (0)
Please sign in to comment.