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