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"
12#include "clang/Driver/DriverDiagnostic.h"
13#include "clang/Driver/Options.h"
14#include "llvm/ADT/StringSwitch.h"
15#include "llvm/Option/ArgList.h"
16
17using namespace clang::driver;
18using namespace clang::driver::tools;
19using namespace clang;
20using namespace llvm::opt;
21
22// Get CPU and ABI names. They are not independent
23// so we have to calculate them together.
24void 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  // MIPS3 is the default for mips64*-unknown-openbsd.
43  if (Triple.isOSOpenBSD())
44    DefMips64CPU = "mips3";
45
46  // MIPS2 is the default for mips(el)?-unknown-freebsd.
47  // MIPS3 is the default for mips64(el)?-unknown-freebsd.
48  if (Triple.isOSFreeBSD()) {
49    DefMips32CPU = "mips2";
50    DefMips64CPU = "mips3";
51  }
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() && (Triple.getEnvironment() == llvm::Triple::GNUABIN32))
84    ABIName = "n32";
85
86  if (ABIName.empty() &&
87      (Triple.getVendor() == llvm::Triple::MipsTechnologies ||
88       Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
89    ABIName = llvm::StringSwitch<const char *>(CPUName)
90                  .Case("mips1", "o32")
91                  .Case("mips2", "o32")
92                  .Case("mips3", "n64")
93                  .Case("mips4", "n64")
94                  .Case("mips5", "n64")
95                  .Case("mips32", "o32")
96                  .Case("mips32r2", "o32")
97                  .Case("mips32r3", "o32")
98                  .Case("mips32r5", "o32")
99                  .Case("mips32r6", "o32")
100                  .Case("mips64", "n64")
101                  .Case("mips64r2", "n64")
102                  .Case("mips64r3", "n64")
103                  .Case("mips64r5", "n64")
104                  .Case("mips64r6", "n64")
105                  .Case("octeon", "n64")
106                  .Case("p5600", "o32")
107                  .Default("");
108  }
109
110  if (ABIName.empty()) {
111    // Deduce ABI name from the target triple.
112    ABIName = Triple.isMIPS32() ? "o32" : "n64";
113  }
114
115  if (CPUName.empty()) {
116    // Deduce CPU name from ABI name.
117    CPUName = llvm::StringSwitch<const char *>(ABIName)
118                  .Case("o32", DefMips32CPU)
119                  .Cases("n32", "n64", DefMips64CPU)
120                  .Default("");
121  }
122
123  // FIXME: Warn on inconsistent use of -march and -mabi.
124}
125
126std::string mips::getMipsABILibSuffix(const ArgList &Args,
127                                      const llvm::Triple &Triple) {
128  StringRef CPUName, ABIName;
129  tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
130  return llvm::StringSwitch<std::string>(ABIName)
131      .Case("o32", "")
132      .Case("n32", "32")
133      .Case("n64", "64");
134}
135
136// Convert ABI name to the GNU tools acceptable variant.
137StringRef mips::getGnuCompatibleMipsABIName(StringRef ABI) {
138  return llvm::StringSwitch<llvm::StringRef>(ABI)
139      .Case("o32", "32")
140      .Case("n64", "64")
141      .Default(ABI);
142}
143
144// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
145// and -mfloat-abi=.
146mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args,
147                                     const llvm::Triple &Triple) {
148  mips::FloatABI ABI = mips::FloatABI::Invalid;
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    if (Triple.isOSFreeBSD()) {
171      // For FreeBSD, assume "soft" on all flavors of MIPS.
172      ABI = mips::FloatABI::Soft;
173    } else {
174      // Assume "hard", because it's a default value used by gcc.
175      // When we start to recognize specific target MIPS processors,
176      // we will be able to select the default more correctly.
177      ABI = mips::FloatABI::Hard;
178    }
179  }
180
181  assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
182  return ABI;
183}
184
185void 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  bool HasNaN2008Opt = false;
225
226  Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
227                                    options::OPT_fpic, options::OPT_fno_pic,
228                                    options::OPT_fPIE, options::OPT_fno_PIE,
229                                    options::OPT_fpie, options::OPT_fno_pie);
230  if (LastPICArg) {
231    Option O = LastPICArg->getOption();
232    NonPIC =
233        (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
234         O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
235    IsPIC =
236        (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
237         O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie));
238  }
239
240  bool UseAbiCalls = false;
241
242  Arg *ABICallsArg =
243      Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
244  UseAbiCalls =
245      !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls);
246
247  if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) {
248    D.Diag(diag::warn_drv_unsupported_pic_with_mabicalls)
249        << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1);
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
271  if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
272    if (A->getOption().matches(options::OPT_mxgot))
273      Features.push_back("+xgot");
274    else
275      Features.push_back("-xgot");
276  }
277
278  mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args, Triple);
279  if (FloatABI == mips::FloatABI::Soft) {
280    // FIXME: Note, this is a hack. We need to pass the selected float
281    // mode to the MipsTargetInfoBase to define appropriate macros there.
282    // Now it is the only method.
283    Features.push_back("+soft-float");
284  }
285
286  if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
287    StringRef Val = StringRef(A->getValue());
288    if (Val == "2008") {
289      if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
290        Features.push_back("+nan2008");
291        HasNaN2008Opt = true;
292      } else {
293        Features.push_back("-nan2008");
294        D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
295      }
296    } else if (Val == "legacy") {
297      if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
298        Features.push_back("-nan2008");
299      else {
300        Features.push_back("+nan2008");
301        D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
302      }
303    } else
304      D.Diag(diag::err_drv_unsupported_option_argument)
305          << A->getSpelling() << Val;
306  }
307
308  if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) {
309    StringRef Val = StringRef(A->getValue());
310    if (Val == "2008") {
311      if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
312        Features.push_back("+abs2008");
313      } else {
314        Features.push_back("-abs2008");
315        D.Diag(diag::warn_target_unsupported_abs2008) << CPUName;
316      }
317    } else if (Val == "legacy") {
318      if (mips::getIEEE754Standard(CPUName) & mips::Legacy) {
319        Features.push_back("-abs2008");
320      } else {
321        Features.push_back("+abs2008");
322        D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName;
323      }
324    } else {
325      D.Diag(diag::err_drv_unsupported_option_argument)
326          << A->getSpelling() << Val;
327    }
328  } else if (HasNaN2008Opt) {
329    Features.push_back("+abs2008");
330  }
331
332  AddTargetFeature(Args, Features, options::OPT_msingle_float,
333                   options::OPT_mdouble_float, "single-float");
334  AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
335                   "mips16");
336  AddTargetFeature(Args, Features, options::OPT_mmicromips,
337                   options::OPT_mno_micromips, "micromips");
338  AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
339                   "dsp");
340  AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
341                   "dspr2");
342  AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
343                   "msa");
344
345  // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
346  // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
347  // nooddspreg.
348  if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
349                               options::OPT_mfp64)) {
350    if (A->getOption().matches(options::OPT_mfp32))
351      Features.push_back("-fp64");
352    else if (A->getOption().matches(options::OPT_mfpxx)) {
353      Features.push_back("+fpxx");
354      Features.push_back("+nooddspreg");
355    } else
356      Features.push_back("+fp64");
357  } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
358    Features.push_back("+fpxx");
359    Features.push_back("+nooddspreg");
360  } else if (mips::isFP64ADefault(Triple, CPUName)) {
361    Features.push_back("+fp64");
362    Features.push_back("+nooddspreg");
363  }
364
365  AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
366                   options::OPT_modd_spreg, "nooddspreg");
367  AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
368                   "nomadd4");
369  AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
370  AddTargetFeature(Args, Features, options::OPT_mcrc, options::OPT_mno_crc,
371                   "crc");
372  AddTargetFeature(Args, Features, options::OPT_mvirt, options::OPT_mno_virt,
373                   "virt");
374  AddTargetFeature(Args, Features, options::OPT_mginv, options::OPT_mno_ginv,
375                   "ginv");
376
377  if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
378    StringRef Val = StringRef(A->getValue());
379    if (Val == "hazard") {
380      Arg *B =
381          Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
382      Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
383
384      if (B && B->getOption().matches(options::OPT_mmicromips))
385        D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
386            << "hazard" << "micromips";
387      else if (C && C->getOption().matches(options::OPT_mips16))
388        D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
389            << "hazard" << "mips16";
390      else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
391        Features.push_back("+use-indirect-jump-hazard");
392      else
393        D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
394            << "hazard" << CPUName;
395    } else
396      D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
397  }
398}
399
400mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
401  // Strictly speaking, mips32r2 and mips64r2 do not conform to the
402  // IEEE754-2008 standard. Support for this standard was first introduced
403  // in Release 3. However, other compilers have traditionally allowed it
404  // for Release 2 so we should do the same.
405  return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
406      .Case("mips1", Legacy)
407      .Case("mips2", Legacy)
408      .Case("mips3", Legacy)
409      .Case("mips4", Legacy)
410      .Case("mips5", Legacy)
411      .Case("mips32", Legacy)
412      .Case("mips32r2", Legacy | Std2008)
413      .Case("mips32r3", Legacy | Std2008)
414      .Case("mips32r5", Legacy | Std2008)
415      .Case("mips32r6", Std2008)
416      .Case("mips64", Legacy)
417      .Case("mips64r2", Legacy | Std2008)
418      .Case("mips64r3", Legacy | Std2008)
419      .Case("mips64r5", Legacy | Std2008)
420      .Case("mips64r6", Std2008)
421      .Default(Std2008);
422}
423
424bool mips::hasCompactBranches(StringRef &CPU) {
425  // mips32r6 and mips64r6 have compact branches.
426  return llvm::StringSwitch<bool>(CPU)
427      .Case("mips32r6", true)
428      .Case("mips64r6", true)
429      .Default(false);
430}
431
432bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
433  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
434  return A && (A->getValue() == StringRef(Value));
435}
436
437bool mips::isUCLibc(const ArgList &Args) {
438  Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
439  return A && A->getOption().matches(options::OPT_muclibc);
440}
441
442bool mips::isNaN2008(const Driver &D, const ArgList &Args,
443                     const llvm::Triple &Triple) {
444  if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
445    return llvm::StringSwitch<bool>(NaNArg->getValue())
446        .Case("2008", true)
447        .Case("legacy", false)
448        .Default(false);
449
450  // NaN2008 is the default for MIPS32r6/MIPS64r6.
451  return llvm::StringSwitch<bool>(getCPUName(D, Args, Triple))
452      .Cases("mips32r6", "mips64r6", true)
453      .Default(false);
454}
455
456bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
457  if (!Triple.isAndroid())
458    return false;
459
460  // Android MIPS32R6 defaults to FP64A.
461  return llvm::StringSwitch<bool>(CPUName)
462      .Case("mips32r6", true)
463      .Default(false);
464}
465
466bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
467                         StringRef ABIName, mips::FloatABI FloatABI) {
468  if (ABIName != "32")
469    return false;
470
471  // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
472  // present.
473  if (FloatABI == mips::FloatABI::Soft)
474    return false;
475
476  return llvm::StringSwitch<bool>(CPUName)
477      .Cases("mips2", "mips3", "mips4", "mips5", true)
478      .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
479      .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
480      .Default(false);
481}
482
483bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
484                         StringRef CPUName, StringRef ABIName,
485                         mips::FloatABI FloatABI) {
486  bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
487
488  // FPXX shouldn't be used if -msingle-float is present.
489  if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
490                               options::OPT_mdouble_float))
491    if (A->getOption().matches(options::OPT_msingle_float))
492      UseFPXX = false;
493
494  return UseFPXX;
495}
496
497bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
498  // Supporting the hazard barrier method of dealing with indirect
499  // jumps requires MIPSR2 support.
500  return llvm::StringSwitch<bool>(CPU)
501      .Case("mips32r2", true)
502      .Case("mips32r3", true)
503      .Case("mips32r5", true)
504      .Case("mips32r6", true)
505      .Case("mips64r2", true)
506      .Case("mips64r3", true)
507      .Case("mips64r5", true)
508      .Case("mips64r6", true)
509      .Case("octeon", true)
510      .Case("p5600", true)
511      .Default(false);
512}
513