clang  7.0.0svn
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.isGNUEnvironment()) {
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  bool UseAbiCalls = false;
231 
232  Arg *ABICallsArg =
233  Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
234  UseAbiCalls =
235  !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls);
236 
237  if (UseAbiCalls && IsN64 && NonPIC) {
238  D.Diag(diag::warn_drv_unsupported_abicalls);
239  UseAbiCalls = false;
240  }
241 
242  if (!UseAbiCalls)
243  Features.push_back("+noabicalls");
244  else
245  Features.push_back("-noabicalls");
246 
247  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
248  options::OPT_mno_long_calls)) {
249  if (A->getOption().matches(options::OPT_mno_long_calls))
250  Features.push_back("-long-calls");
251  else if (!UseAbiCalls)
252  Features.push_back("+long-calls");
253  else
254  D.Diag(diag::warn_drv_unsupported_longcalls) << (ABICallsArg ? 0 : 1);
255  }
256 
258  if (FloatABI == mips::FloatABI::Soft) {
259  // FIXME: Note, this is a hack. We need to pass the selected float
260  // mode to the MipsTargetInfoBase to define appropriate macros there.
261  // Now it is the only method.
262  Features.push_back("+soft-float");
263  }
264 
265  if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
266  StringRef Val = StringRef(A->getValue());
267  if (Val == "2008") {
269  Features.push_back("+nan2008");
270  else {
271  Features.push_back("-nan2008");
272  D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
273  }
274  } else if (Val == "legacy") {
275  if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
276  Features.push_back("-nan2008");
277  else {
278  Features.push_back("+nan2008");
279  D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
280  }
281  } else
282  D.Diag(diag::err_drv_unsupported_option_argument)
283  << A->getOption().getName() << Val;
284  }
285 
286  if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) {
287  StringRef Val = StringRef(A->getValue());
288  if (Val == "2008") {
289  if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
290  Features.push_back("+abs2008");
291  } else {
292  Features.push_back("-abs2008");
293  D.Diag(diag::warn_target_unsupported_abs2008) << CPUName;
294  }
295  } else if (Val == "legacy") {
296  if (mips::getIEEE754Standard(CPUName) & mips::Legacy) {
297  Features.push_back("-abs2008");
298  } else {
299  Features.push_back("+abs2008");
300  D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName;
301  }
302  } else {
303  D.Diag(diag::err_drv_unsupported_option_argument)
304  << A->getOption().getName() << Val;
305  }
306  }
307 
308  AddTargetFeature(Args, Features, options::OPT_msingle_float,
309  options::OPT_mdouble_float, "single-float");
310  AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
311  "mips16");
312  AddTargetFeature(Args, Features, options::OPT_mmicromips,
313  options::OPT_mno_micromips, "micromips");
314  AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
315  "dsp");
316  AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
317  "dspr2");
318  AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
319  "msa");
320 
321  // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
322  // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
323  // nooddspreg.
324  if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
325  options::OPT_mfp64)) {
326  if (A->getOption().matches(options::OPT_mfp32))
327  Features.push_back("-fp64");
328  else if (A->getOption().matches(options::OPT_mfpxx)) {
329  Features.push_back("+fpxx");
330  Features.push_back("+nooddspreg");
331  } else
332  Features.push_back("+fp64");
333  } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
334  Features.push_back("+fpxx");
335  Features.push_back("+nooddspreg");
336  } else if (mips::isFP64ADefault(Triple, CPUName)) {
337  Features.push_back("+fp64");
338  Features.push_back("+nooddspreg");
339  }
340 
341  AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
342  options::OPT_modd_spreg, "nooddspreg");
343  AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
344  "nomadd4");
345  AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
346 
347  if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
348  StringRef Val = StringRef(A->getValue());
349  if (Val == "hazard") {
350  Arg *B =
351  Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
352  Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
353 
354  if (B && B->getOption().matches(options::OPT_mmicromips))
355  D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
356  << "hazard" << "micromips";
357  else if (C && C->getOption().matches(options::OPT_mips16))
358  D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
359  << "hazard" << "mips16";
360  else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
361  Features.push_back("+use-indirect-jump-hazard");
362  else
363  D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
364  << "hazard" << CPUName;
365  } else
366  D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
367  }
368 }
369 
371  // Strictly speaking, mips32r2 and mips64r2 do not conform to the
372  // IEEE754-2008 standard. Support for this standard was first introduced
373  // in Release 3. However, other compilers have traditionally allowed it
374  // for Release 2 so we should do the same.
375  return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
376  .Case("mips1", Legacy)
377  .Case("mips2", Legacy)
378  .Case("mips3", Legacy)
379  .Case("mips4", Legacy)
380  .Case("mips5", Legacy)
381  .Case("mips32", Legacy)
382  .Case("mips32r2", Legacy | Std2008)
383  .Case("mips32r3", Legacy | Std2008)
384  .Case("mips32r5", Legacy | Std2008)
385  .Case("mips32r6", Std2008)
386  .Case("mips64", Legacy)
387  .Case("mips64r2", Legacy | Std2008)
388  .Case("mips64r3", Legacy | Std2008)
389  .Case("mips64r5", Legacy | Std2008)
390  .Case("mips64r6", Std2008)
391  .Default(Std2008);
392 }
393 
394 bool mips::hasCompactBranches(StringRef &CPU) {
395  // mips32r6 and mips64r6 have compact branches.
396  return llvm::StringSwitch<bool>(CPU)
397  .Case("mips32r6", true)
398  .Case("mips64r6", true)
399  .Default(false);
400 }
401 
402 bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
403  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
404  return A && (A->getValue() == StringRef(Value));
405 }
406 
407 bool mips::isUCLibc(const ArgList &Args) {
408  Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
409  return A && A->getOption().matches(options::OPT_muclibc);
410 }
411 
412 bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
413  if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
414  return llvm::StringSwitch<bool>(NaNArg->getValue())
415  .Case("2008", true)
416  .Case("legacy", false)
417  .Default(false);
418 
419  // NaN2008 is the default for MIPS32r6/MIPS64r6.
420  return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
421  .Cases("mips32r6", "mips64r6", true)
422  .Default(false);
423 
424  return false;
425 }
426 
427 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
428  if (!Triple.isAndroid())
429  return false;
430 
431  // Android MIPS32R6 defaults to FP64A.
432  return llvm::StringSwitch<bool>(CPUName)
433  .Case("mips32r6", true)
434  .Default(false);
435 }
436 
437 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
438  StringRef ABIName, mips::FloatABI FloatABI) {
439  if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
440  Triple.getVendor() != llvm::Triple::MipsTechnologies &&
441  !Triple.isAndroid())
442  return false;
443 
444  if (ABIName != "32")
445  return false;
446 
447  // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
448  // present.
449  if (FloatABI == mips::FloatABI::Soft)
450  return false;
451 
452  return llvm::StringSwitch<bool>(CPUName)
453  .Cases("mips2", "mips3", "mips4", "mips5", true)
454  .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
455  .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
456  .Default(false);
457 }
458 
459 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
460  StringRef CPUName, StringRef ABIName,
462  bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
463 
464  // FPXX shouldn't be used if -msingle-float is present.
465  if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
466  options::OPT_mdouble_float))
467  if (A->getOption().matches(options::OPT_msingle_float))
468  UseFPXX = false;
469 
470  return UseFPXX;
471 }
472 
474  // Supporting the hazard barrier method of dealing with indirect
475  // jumps requires MIPSR2 support.
476  return llvm::StringSwitch<bool>(CPU)
477  .Case("mips32r2", true)
478  .Case("mips32r3", true)
479  .Case("mips32r5", true)
480  .Case("mips32r6", true)
481  .Case("mips64r2", true)
482  .Case("mips64r3", true)
483  .Case("mips64r5", true)
484  .Case("mips64r6", true)
485  .Case("octeon", true)
486  .Case("p5600", true)
487  .Default(false);
488 }
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:110
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)
IEEE754Standard getIEEE754Standard(StringRef &CPU)
Definition: Mips.cpp:370
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:59
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:437
bool supportsIndirectJumpHazardBarrier(StringRef &CPU)
Definition: Mips.cpp:473
Dataflow Directional Tag Classes.
bool hasCompactBranches(StringRef &CPU)
Definition: Mips.cpp:394
StringRef getGnuCompatibleMipsABIName(StringRef ABI)
Definition: Mips.cpp:138
bool isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName)
Definition: Mips.cpp:427
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)