clang  6.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 
349  // Strictly speaking, mips32r2 and mips64r2 do not conform to the
350  // IEEE754-2008 standard. Support for this standard was first introduced
351  // in Release 3. However, other compilers have traditionally allowed it
352  // for Release 2 so we should do the same.
353  return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
354  .Case("mips1", Legacy)
355  .Case("mips2", Legacy)
356  .Case("mips3", Legacy)
357  .Case("mips4", Legacy)
358  .Case("mips5", Legacy)
359  .Case("mips32", Legacy)
360  .Case("mips32r2", Legacy | Std2008)
361  .Case("mips32r3", Legacy | Std2008)
362  .Case("mips32r5", Legacy | Std2008)
363  .Case("mips32r6", Std2008)
364  .Case("mips64", Legacy)
365  .Case("mips64r2", Legacy | Std2008)
366  .Case("mips64r3", Legacy | Std2008)
367  .Case("mips64r5", Legacy | Std2008)
368  .Case("mips64r6", Std2008)
369  .Default(Std2008);
370 }
371 
372 bool mips::hasCompactBranches(StringRef &CPU) {
373  // mips32r6 and mips64r6 have compact branches.
374  return llvm::StringSwitch<bool>(CPU)
375  .Case("mips32r6", true)
376  .Case("mips64r6", true)
377  .Default(false);
378 }
379 
380 bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
381  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
382  return A && (A->getValue() == StringRef(Value));
383 }
384 
385 bool mips::isUCLibc(const ArgList &Args) {
386  Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
387  return A && A->getOption().matches(options::OPT_muclibc);
388 }
389 
390 bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
391  if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
392  return llvm::StringSwitch<bool>(NaNArg->getValue())
393  .Case("2008", true)
394  .Case("legacy", false)
395  .Default(false);
396 
397  // NaN2008 is the default for MIPS32r6/MIPS64r6.
398  return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
399  .Cases("mips32r6", "mips64r6", true)
400  .Default(false);
401 
402  return false;
403 }
404 
405 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
406  if (!Triple.isAndroid())
407  return false;
408 
409  // Android MIPS32R6 defaults to FP64A.
410  return llvm::StringSwitch<bool>(CPUName)
411  .Case("mips32r6", true)
412  .Default(false);
413 }
414 
415 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
416  StringRef ABIName, mips::FloatABI FloatABI) {
417  if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
418  Triple.getVendor() != llvm::Triple::MipsTechnologies &&
419  !Triple.isAndroid())
420  return false;
421 
422  if (ABIName != "32")
423  return false;
424 
425  // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
426  // present.
427  if (FloatABI == mips::FloatABI::Soft)
428  return false;
429 
430  return llvm::StringSwitch<bool>(CPUName)
431  .Cases("mips2", "mips3", "mips4", "mips5", true)
432  .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
433  .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
434  .Default(false);
435 }
436 
437 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
438  StringRef CPUName, StringRef ABIName,
440  bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
441 
442  // FPXX shouldn't be used if -msingle-float is present.
443  if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
444  options::OPT_mdouble_float))
445  if (A->getOption().matches(options::OPT_msingle_float))
446  UseFPXX = false;
447 
448  return UseFPXX;
449 }
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)
IEEE754Standard getIEEE754Standard(StringRef &CPU)
Definition: Mips.cpp:348
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:415
Dataflow Directional Tag Classes.
bool hasCompactBranches(StringRef &CPU)
Definition: Mips.cpp:372
StringRef getGnuCompatibleMipsABIName(StringRef ABI)
Definition: Mips.cpp:138
bool isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName)
Definition: Mips.cpp:405
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)