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