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