clang  9.0.0svn
Mips.cpp
Go to the documentation of this file.
1 //===--- Mips.cpp - Tools Implementations -----------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Mips.h"
10 #include "ToolChains/CommonArgs.h"
11 #include "clang/Driver/Driver.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.isGNUEnvironment()) {
33  DefMips32CPU = "mips32r6";
34  DefMips64CPU = "mips64r6";
35  }
36 
37  if (Triple.getSubArch() == llvm::Triple::MipsSubArch_r6) {
38  DefMips32CPU = "mips32r6";
39  DefMips64CPU = "mips64r6";
40  }
41 
42  // MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android).
43  if (Triple.isAndroid()) {
44  DefMips32CPU = "mips32";
45  DefMips64CPU = "mips64r6";
46  }
47 
48  // MIPS3 is the default for mips64*-unknown-openbsd.
49  if (Triple.isOSOpenBSD())
50  DefMips64CPU = "mips3";
51 
52  // MIPS2 is the default for mips(el)?-unknown-freebsd.
53  // MIPS3 is the default for mips64(el)?-unknown-freebsd.
54  if (Triple.isOSFreeBSD()) {
55  DefMips32CPU = "mips2";
56  DefMips64CPU = "mips3";
57  }
58 
59  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ,
60  options::OPT_mcpu_EQ))
61  CPUName = A->getValue();
62 
63  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
64  ABIName = A->getValue();
65  // Convert a GNU style Mips ABI name to the name
66  // accepted by LLVM Mips backend.
67  ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
68  .Case("32", "o32")
69  .Case("64", "n64")
70  .Default(ABIName);
71  }
72 
73  // Setup default CPU and ABI names.
74  if (CPUName.empty() && ABIName.empty()) {
75  switch (Triple.getArch()) {
76  default:
77  llvm_unreachable("Unexpected triple arch name");
78  case llvm::Triple::mips:
79  case llvm::Triple::mipsel:
80  CPUName = DefMips32CPU;
81  break;
82  case llvm::Triple::mips64:
83  case llvm::Triple::mips64el:
84  CPUName = DefMips64CPU;
85  break;
86  }
87  }
88 
89  if (ABIName.empty() && (Triple.getEnvironment() == llvm::Triple::GNUABIN32))
90  ABIName = "n32";
91 
92  if (ABIName.empty() &&
93  (Triple.getVendor() == llvm::Triple::MipsTechnologies ||
94  Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
95  ABIName = llvm::StringSwitch<const char *>(CPUName)
96  .Case("mips1", "o32")
97  .Case("mips2", "o32")
98  .Case("mips3", "n64")
99  .Case("mips4", "n64")
100  .Case("mips5", "n64")
101  .Case("mips32", "o32")
102  .Case("mips32r2", "o32")
103  .Case("mips32r3", "o32")
104  .Case("mips32r5", "o32")
105  .Case("mips32r6", "o32")
106  .Case("mips64", "n64")
107  .Case("mips64r2", "n64")
108  .Case("mips64r3", "n64")
109  .Case("mips64r5", "n64")
110  .Case("mips64r6", "n64")
111  .Case("octeon", "n64")
112  .Case("p5600", "o32")
113  .Default("");
114  }
115 
116  if (ABIName.empty()) {
117  // Deduce ABI name from the target triple.
118  ABIName = Triple.isMIPS32() ? "o32" : "n64";
119  }
120 
121  if (CPUName.empty()) {
122  // Deduce CPU name from ABI name.
123  CPUName = llvm::StringSwitch<const char *>(ABIName)
124  .Case("o32", DefMips32CPU)
125  .Cases("n32", "n64", DefMips64CPU)
126  .Default("");
127  }
128 
129  // FIXME: Warn on inconsistent use of -march and -mabi.
130 }
131 
132 std::string mips::getMipsABILibSuffix(const ArgList &Args,
133  const llvm::Triple &Triple) {
134  StringRef CPUName, ABIName;
135  tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
136  return llvm::StringSwitch<std::string>(ABIName)
137  .Case("o32", "")
138  .Case("n32", "32")
139  .Case("n64", "64");
140 }
141 
142 // Convert ABI name to the GNU tools acceptable variant.
143 StringRef mips::getGnuCompatibleMipsABIName(StringRef ABI) {
144  return llvm::StringSwitch<llvm::StringRef>(ABI)
145  .Case("o32", "32")
146  .Case("n64", "64")
147  .Default(ABI);
148 }
149 
150 // Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
151 // and -mfloat-abi=.
152 mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args) {
154  if (Arg *A =
155  Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
156  options::OPT_mfloat_abi_EQ)) {
157  if (A->getOption().matches(options::OPT_msoft_float))
158  ABI = mips::FloatABI::Soft;
159  else if (A->getOption().matches(options::OPT_mhard_float))
160  ABI = mips::FloatABI::Hard;
161  else {
162  ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
163  .Case("soft", mips::FloatABI::Soft)
164  .Case("hard", mips::FloatABI::Hard)
165  .Default(mips::FloatABI::Invalid);
166  if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
167  D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
168  ABI = mips::FloatABI::Hard;
169  }
170  }
171  }
172 
173  // If unspecified, choose the default based on the platform.
174  if (ABI == mips::FloatABI::Invalid) {
175  // Assume "hard", because it's a default value used by gcc.
176  // When we start to recognize specific target MIPS processors,
177  // we will be able to select the default more correctly.
178  ABI = mips::FloatABI::Hard;
179  }
180 
181  assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
182  return ABI;
183 }
184 
185 void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
186  const ArgList &Args,
187  std::vector<StringRef> &Features) {
188  StringRef CPUName;
189  StringRef ABIName;
190  getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
191  ABIName = getGnuCompatibleMipsABIName(ABIName);
192 
193  // Historically, PIC code for MIPS was associated with -mabicalls, a.k.a
194  // SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI
195  // extension was developed by Richard Sandiford & Code Sourcery to support
196  // static code calling PIC code (CPIC). For O32 and N32 this means we have
197  // several combinations of PIC/static and abicalls. Pure static, static
198  // with the CPIC extension, and pure PIC code.
199 
200  // At final link time, O32 and N32 with CPIC will have another section
201  // added to the binary which contains the stub functions to perform
202  // any fixups required for PIC code.
203 
204  // For N64, the situation is more regular: code can either be static
205  // (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code
206  // code for N64. Since Clang has already built the relocation model portion
207  // of the commandline, we pick add +noabicalls feature in the N64 static
208  // case.
209 
210  // The is another case to be accounted for: -msym32, which enforces that all
211  // symbols have 32 bits in size. In this case, N64 can in theory use CPIC
212  // but it is unsupported.
213 
214  // The combinations for N64 are:
215  // a) Static without abicalls and 64bit symbols.
216  // b) Static with abicalls and 32bit symbols.
217  // c) PIC with abicalls and 64bit symbols.
218 
219  // For case (a) we need to add +noabicalls for N64.
220 
221  bool IsN64 = ABIName == "64";
222  bool IsPIC = false;
223  bool NonPIC = false;
224 
225  Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
226  options::OPT_fpic, options::OPT_fno_pic,
227  options::OPT_fPIE, options::OPT_fno_PIE,
228  options::OPT_fpie, options::OPT_fno_pie);
229  if (LastPICArg) {
230  Option O = LastPICArg->getOption();
231  NonPIC =
232  (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
233  O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
234  IsPIC =
235  (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
236  O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie));
237  }
238 
239  bool UseAbiCalls = false;
240 
241  Arg *ABICallsArg =
242  Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
243  UseAbiCalls =
244  !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls);
245 
246  if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) {
247  D.Diag(diag::warn_drv_unsupported_pic_with_mabicalls)
248  << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1);
249  }
250 
251  if (ABICallsArg && !UseAbiCalls && IsPIC) {
252  D.Diag(diag::err_drv_unsupported_noabicalls_pic);
253  }
254 
255  if (!UseAbiCalls)
256  Features.push_back("+noabicalls");
257  else
258  Features.push_back("-noabicalls");
259 
260  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
261  options::OPT_mno_long_calls)) {
262  if (A->getOption().matches(options::OPT_mno_long_calls))
263  Features.push_back("-long-calls");
264  else if (!UseAbiCalls)
265  Features.push_back("+long-calls");
266  else
267  D.Diag(diag::warn_drv_unsupported_longcalls) << (ABICallsArg ? 0 : 1);
268  }
269 
271  if (FloatABI == mips::FloatABI::Soft) {
272  // FIXME: Note, this is a hack. We need to pass the selected float
273  // mode to the MipsTargetInfoBase to define appropriate macros there.
274  // Now it is the only method.
275  Features.push_back("+soft-float");
276  }
277 
278  if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
279  StringRef Val = StringRef(A->getValue());
280  if (Val == "2008") {
282  Features.push_back("+nan2008");
283  else {
284  Features.push_back("-nan2008");
285  D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
286  }
287  } else if (Val == "legacy") {
288  if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
289  Features.push_back("-nan2008");
290  else {
291  Features.push_back("+nan2008");
292  D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
293  }
294  } else
295  D.Diag(diag::err_drv_unsupported_option_argument)
296  << A->getOption().getName() << Val;
297  }
298 
299  if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) {
300  StringRef Val = StringRef(A->getValue());
301  if (Val == "2008") {
302  if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
303  Features.push_back("+abs2008");
304  } else {
305  Features.push_back("-abs2008");
306  D.Diag(diag::warn_target_unsupported_abs2008) << CPUName;
307  }
308  } else if (Val == "legacy") {
309  if (mips::getIEEE754Standard(CPUName) & mips::Legacy) {
310  Features.push_back("-abs2008");
311  } else {
312  Features.push_back("+abs2008");
313  D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName;
314  }
315  } else {
316  D.Diag(diag::err_drv_unsupported_option_argument)
317  << A->getOption().getName() << Val;
318  }
319  }
320 
321  AddTargetFeature(Args, Features, options::OPT_msingle_float,
322  options::OPT_mdouble_float, "single-float");
323  AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
324  "mips16");
325  AddTargetFeature(Args, Features, options::OPT_mmicromips,
326  options::OPT_mno_micromips, "micromips");
327  AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
328  "dsp");
329  AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
330  "dspr2");
331  AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
332  "msa");
333 
334  // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
335  // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
336  // nooddspreg.
337  if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
338  options::OPT_mfp64)) {
339  if (A->getOption().matches(options::OPT_mfp32))
340  Features.push_back("-fp64");
341  else if (A->getOption().matches(options::OPT_mfpxx)) {
342  Features.push_back("+fpxx");
343  Features.push_back("+nooddspreg");
344  } else
345  Features.push_back("+fp64");
346  } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
347  Features.push_back("+fpxx");
348  Features.push_back("+nooddspreg");
349  } else if (mips::isFP64ADefault(Triple, CPUName)) {
350  Features.push_back("+fp64");
351  Features.push_back("+nooddspreg");
352  }
353 
354  AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
355  options::OPT_modd_spreg, "nooddspreg");
356  AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
357  "nomadd4");
358  AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
359  AddTargetFeature(Args, Features, options::OPT_mcrc, options::OPT_mno_crc,
360  "crc");
361  AddTargetFeature(Args, Features, options::OPT_mvirt, options::OPT_mno_virt,
362  "virt");
363  AddTargetFeature(Args, Features, options::OPT_mginv, options::OPT_mno_ginv,
364  "ginv");
365 
366  if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
367  StringRef Val = StringRef(A->getValue());
368  if (Val == "hazard") {
369  Arg *B =
370  Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
371  Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
372 
373  if (B && B->getOption().matches(options::OPT_mmicromips))
374  D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
375  << "hazard" << "micromips";
376  else if (C && C->getOption().matches(options::OPT_mips16))
377  D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
378  << "hazard" << "mips16";
379  else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
380  Features.push_back("+use-indirect-jump-hazard");
381  else
382  D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
383  << "hazard" << CPUName;
384  } else
385  D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
386  }
387 }
388 
390  // Strictly speaking, mips32r2 and mips64r2 do not conform to the
391  // IEEE754-2008 standard. Support for this standard was first introduced
392  // in Release 3. However, other compilers have traditionally allowed it
393  // for Release 2 so we should do the same.
394  return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
395  .Case("mips1", Legacy)
396  .Case("mips2", Legacy)
397  .Case("mips3", Legacy)
398  .Case("mips4", Legacy)
399  .Case("mips5", Legacy)
400  .Case("mips32", Legacy)
401  .Case("mips32r2", Legacy | Std2008)
402  .Case("mips32r3", Legacy | Std2008)
403  .Case("mips32r5", Legacy | Std2008)
404  .Case("mips32r6", Std2008)
405  .Case("mips64", Legacy)
406  .Case("mips64r2", Legacy | Std2008)
407  .Case("mips64r3", Legacy | Std2008)
408  .Case("mips64r5", Legacy | Std2008)
409  .Case("mips64r6", Std2008)
410  .Default(Std2008);
411 }
412 
413 bool mips::hasCompactBranches(StringRef &CPU) {
414  // mips32r6 and mips64r6 have compact branches.
415  return llvm::StringSwitch<bool>(CPU)
416  .Case("mips32r6", true)
417  .Case("mips64r6", true)
418  .Default(false);
419 }
420 
421 bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
422  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
423  return A && (A->getValue() == StringRef(Value));
424 }
425 
426 bool mips::isUCLibc(const ArgList &Args) {
427  Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
428  return A && A->getOption().matches(options::OPT_muclibc);
429 }
430 
431 bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
432  if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
433  return llvm::StringSwitch<bool>(NaNArg->getValue())
434  .Case("2008", true)
435  .Case("legacy", false)
436  .Default(false);
437 
438  // NaN2008 is the default for MIPS32r6/MIPS64r6.
439  return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
440  .Cases("mips32r6", "mips64r6", true)
441  .Default(false);
442 
443  return false;
444 }
445 
446 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
447  if (!Triple.isAndroid())
448  return false;
449 
450  // Android MIPS32R6 defaults to FP64A.
451  return llvm::StringSwitch<bool>(CPUName)
452  .Case("mips32r6", true)
453  .Default(false);
454 }
455 
456 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
457  StringRef ABIName, mips::FloatABI FloatABI) {
458  if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
459  Triple.getVendor() != llvm::Triple::MipsTechnologies &&
460  !Triple.isAndroid())
461  return false;
462 
463  if (ABIName != "32")
464  return false;
465 
466  // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
467  // present.
468  if (FloatABI == mips::FloatABI::Soft)
469  return false;
470 
471  return llvm::StringSwitch<bool>(CPUName)
472  .Cases("mips2", "mips3", "mips4", "mips5", true)
473  .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
474  .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
475  .Default(false);
476 }
477 
478 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
479  StringRef CPUName, StringRef ABIName,
481  bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
482 
483  // FPXX shouldn't be used if -msingle-float is present.
484  if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
485  options::OPT_mdouble_float))
486  if (A->getOption().matches(options::OPT_msingle_float))
487  UseFPXX = false;
488 
489  return UseFPXX;
490 }
491 
493  // Supporting the hazard barrier method of dealing with indirect
494  // jumps requires MIPSR2 support.
495  return llvm::StringSwitch<bool>(CPU)
496  .Case("mips32r2", true)
497  .Case("mips32r3", true)
498  .Case("mips32r5", true)
499  .Case("mips32r6", true)
500  .Case("mips64r2", true)
501  .Case("mips64r3", true)
502  .Case("mips64r5", true)
503  .Case("mips64r6", true)
504  .Case("octeon", true)
505  .Case("p5600", true)
506  .Default(false);
507 }
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:108
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:389
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:57
bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value)
mips::FloatABI getMipsFloatABI(const Driver &D, const llvm::opt::ArgList &Args)
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:456
bool supportsIndirectJumpHazardBarrier(StringRef &CPU)
Definition: Mips.cpp:492
Dataflow Directional Tag Classes.
bool hasCompactBranches(StringRef &CPU)
Definition: Mips.cpp:413
StringRef getGnuCompatibleMipsABIName(StringRef ABI)
Definition: Mips.cpp:143
bool isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName)
Definition: Mips.cpp:446
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)