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  // 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
132std::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.
143StringRef 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=.
152mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args,
153                                     const llvm::Triple &Triple) {
154  mips::FloatABI ABI = mips::FloatABI::Invalid;
155  if (Arg *A =
156          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
157                          options::OPT_mfloat_abi_EQ)) {
158    if (A->getOption().matches(options::OPT_msoft_float))
159      ABI = mips::FloatABI::Soft;
160    else if (A->getOption().matches(options::OPT_mhard_float))
161      ABI = mips::FloatABI::Hard;
162    else {
163      ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
164                .Case("soft", mips::FloatABI::Soft)
165                .Case("hard", mips::FloatABI::Hard)
166                .Default(mips::FloatABI::Invalid);
167      if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
168        D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
169        ABI = mips::FloatABI::Hard;
170      }
171    }
172  }
173
174  // If unspecified, choose the default based on the platform.
175  if (ABI == mips::FloatABI::Invalid) {
176    if (Triple.isOSFreeBSD()) {
177      // For FreeBSD, assume "soft" on all flavors of MIPS.
178      ABI = mips::FloatABI::Soft;
179    } else {
180      // Assume "hard", because it's a default value used by gcc.
181      // When we start to recognize specific target MIPS processors,
182      // we will be able to select the default more correctly.
183      ABI = mips::FloatABI::Hard;
184    }
185  }
186
187  assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
188  return ABI;
189}
190
191void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
192                                 const ArgList &Args,
193                                 std::vector<StringRef> &Features) {
194  StringRef CPUName;
195  StringRef ABIName;
196  getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
197  ABIName = getGnuCompatibleMipsABIName(ABIName);
198
199  // Historically, PIC code for MIPS was associated with -mabicalls, a.k.a
200  // SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI
201  // extension was developed by Richard Sandiford & Code Sourcery to support
202  // static code calling PIC code (CPIC). For O32 and N32 this means we have
203  // several combinations of PIC/static and abicalls. Pure static, static
204  // with the CPIC extension, and pure PIC code.
205
206  // At final link time, O32 and N32 with CPIC will have another section
207  // added to the binary which contains the stub functions to perform
208  // any fixups required for PIC code.
209
210  // For N64, the situation is more regular: code can either be static
211  // (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code
212  // code for N64. Since Clang has already built the relocation model portion
213  // of the commandline, we pick add +noabicalls feature in the N64 static
214  // case.
215
216  // The is another case to be accounted for: -msym32, which enforces that all
217  // symbols have 32 bits in size. In this case, N64 can in theory use CPIC
218  // but it is unsupported.
219
220  // The combinations for N64 are:
221  // a) Static without abicalls and 64bit symbols.
222  // b) Static with abicalls and 32bit symbols.
223  // c) PIC with abicalls and 64bit symbols.
224
225  // For case (a) we need to add +noabicalls for N64.
226
227  bool IsN64 = ABIName == "64";
228  bool IsPIC = false;
229  bool NonPIC = false;
230
231  Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
232                                    options::OPT_fpic, options::OPT_fno_pic,
233                                    options::OPT_fPIE, options::OPT_fno_PIE,
234                                    options::OPT_fpie, options::OPT_fno_pie);
235  if (LastPICArg) {
236    Option O = LastPICArg->getOption();
237    NonPIC =
238        (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
239         O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
240    IsPIC =
241        (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
242         O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie));
243  }
244
245  bool UseAbiCalls = false;
246
247  Arg *ABICallsArg =
248      Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
249  UseAbiCalls =
250      !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls);
251
252  if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) {
253    D.Diag(diag::warn_drv_unsupported_pic_with_mabicalls)
254        << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1);
255  }
256
257  if (ABICallsArg && !UseAbiCalls && IsPIC) {
258    D.Diag(diag::err_drv_unsupported_noabicalls_pic);
259  }
260
261  if (!UseAbiCalls)
262    Features.push_back("+noabicalls");
263  else
264    Features.push_back("-noabicalls");
265
266  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
267                               options::OPT_mno_long_calls)) {
268    if (A->getOption().matches(options::OPT_mno_long_calls))
269      Features.push_back("-long-calls");
270    else if (!UseAbiCalls)
271      Features.push_back("+long-calls");
272    else
273      D.Diag(diag::warn_drv_unsupported_longcalls) << (ABICallsArg ? 0 : 1);
274  }
275
276  if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
277    if (A->getOption().matches(options::OPT_mxgot))
278      Features.push_back("+xgot");
279    else
280      Features.push_back("-xgot");
281  }
282
283  mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args, Triple);
284  if (FloatABI == mips::FloatABI::Soft) {
285    // FIXME: Note, this is a hack. We need to pass the selected float
286    // mode to the MipsTargetInfoBase to define appropriate macros there.
287    // Now it is the only method.
288    Features.push_back("+soft-float");
289  }
290
291  if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
292    StringRef Val = StringRef(A->getValue());
293    if (Val == "2008") {
294      if (mips::getIEEE754Standard(CPUName) & mips::Std2008)
295        Features.push_back("+nan2008");
296      else {
297        Features.push_back("-nan2008");
298        D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
299      }
300    } else if (Val == "legacy") {
301      if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
302        Features.push_back("-nan2008");
303      else {
304        Features.push_back("+nan2008");
305        D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
306      }
307    } else
308      D.Diag(diag::err_drv_unsupported_option_argument)
309          << A->getOption().getName() << Val;
310  }
311
312  if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) {
313    StringRef Val = StringRef(A->getValue());
314    if (Val == "2008") {
315      if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
316        Features.push_back("+abs2008");
317      } else {
318        Features.push_back("-abs2008");
319        D.Diag(diag::warn_target_unsupported_abs2008) << CPUName;
320      }
321    } else if (Val == "legacy") {
322      if (mips::getIEEE754Standard(CPUName) & mips::Legacy) {
323        Features.push_back("-abs2008");
324      } else {
325        Features.push_back("+abs2008");
326        D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName;
327      }
328    } else {
329      D.Diag(diag::err_drv_unsupported_option_argument)
330          << A->getOption().getName() << Val;
331    }
332  }
333
334  AddTargetFeature(Args, Features, options::OPT_msingle_float,
335                   options::OPT_mdouble_float, "single-float");
336  AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
337                   "mips16");
338  AddTargetFeature(Args, Features, options::OPT_mmicromips,
339                   options::OPT_mno_micromips, "micromips");
340  AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
341                   "dsp");
342  AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
343                   "dspr2");
344  AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
345                   "msa");
346
347  // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
348  // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
349  // nooddspreg.
350  if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
351                               options::OPT_mfp64)) {
352    if (A->getOption().matches(options::OPT_mfp32))
353      Features.push_back("-fp64");
354    else if (A->getOption().matches(options::OPT_mfpxx)) {
355      Features.push_back("+fpxx");
356      Features.push_back("+nooddspreg");
357    } else
358      Features.push_back("+fp64");
359  } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
360    Features.push_back("+fpxx");
361    Features.push_back("+nooddspreg");
362  } else if (mips::isFP64ADefault(Triple, CPUName)) {
363    Features.push_back("+fp64");
364    Features.push_back("+nooddspreg");
365  }
366
367  AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
368                   options::OPT_modd_spreg, "nooddspreg");
369  AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
370                   "nomadd4");
371  AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
372  AddTargetFeature(Args, Features, options::OPT_mcrc, options::OPT_mno_crc,
373                   "crc");
374  AddTargetFeature(Args, Features, options::OPT_mvirt, options::OPT_mno_virt,
375                   "virt");
376  AddTargetFeature(Args, Features, options::OPT_mginv, options::OPT_mno_ginv,
377                   "ginv");
378
379  if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
380    StringRef Val = StringRef(A->getValue());
381    if (Val == "hazard") {
382      Arg *B =
383          Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
384      Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
385
386      if (B && B->getOption().matches(options::OPT_mmicromips))
387        D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
388            << "hazard" << "micromips";
389      else if (C && C->getOption().matches(options::OPT_mips16))
390        D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
391            << "hazard" << "mips16";
392      else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
393        Features.push_back("+use-indirect-jump-hazard");
394      else
395        D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
396            << "hazard" << CPUName;
397    } else
398      D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
399  }
400}
401
402mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
403  // Strictly speaking, mips32r2 and mips64r2 do not conform to the
404  // IEEE754-2008 standard. Support for this standard was first introduced
405  // in Release 3. However, other compilers have traditionally allowed it
406  // for Release 2 so we should do the same.
407  return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
408      .Case("mips1", Legacy)
409      .Case("mips2", Legacy)
410      .Case("mips3", Legacy)
411      .Case("mips4", Legacy)
412      .Case("mips5", Legacy)
413      .Case("mips32", Legacy)
414      .Case("mips32r2", Legacy | Std2008)
415      .Case("mips32r3", Legacy | Std2008)
416      .Case("mips32r5", Legacy | Std2008)
417      .Case("mips32r6", Std2008)
418      .Case("mips64", Legacy)
419      .Case("mips64r2", Legacy | Std2008)
420      .Case("mips64r3", Legacy | Std2008)
421      .Case("mips64r5", Legacy | Std2008)
422      .Case("mips64r6", Std2008)
423      .Default(Std2008);
424}
425
426bool mips::hasCompactBranches(StringRef &CPU) {
427  // mips32r6 and mips64r6 have compact branches.
428  return llvm::StringSwitch<bool>(CPU)
429      .Case("mips32r6", true)
430      .Case("mips64r6", true)
431      .Default(false);
432}
433
434bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
435  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
436  return A && (A->getValue() == StringRef(Value));
437}
438
439bool mips::isUCLibc(const ArgList &Args) {
440  Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
441  return A && A->getOption().matches(options::OPT_muclibc);
442}
443
444bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
445  if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
446    return llvm::StringSwitch<bool>(NaNArg->getValue())
447        .Case("2008", true)
448        .Case("legacy", false)
449        .Default(false);
450
451  // NaN2008 is the default for MIPS32r6/MIPS64r6.
452  return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
453      .Cases("mips32r6", "mips64r6", true)
454      .Default(false);
455
456  return false;
457}
458
459bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
460  if (!Triple.isAndroid())
461    return false;
462
463  // Android MIPS32R6 defaults to FP64A.
464  return llvm::StringSwitch<bool>(CPUName)
465      .Case("mips32r6", true)
466      .Default(false);
467}
468
469bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
470                         StringRef ABIName, mips::FloatABI FloatABI) {
471  if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
472      Triple.getVendor() != llvm::Triple::MipsTechnologies &&
473      !Triple.isAndroid())
474    return false;
475
476  if (ABIName != "32")
477    return false;
478
479  // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
480  // present.
481  if (FloatABI == mips::FloatABI::Soft)
482    return false;
483
484  return llvm::StringSwitch<bool>(CPUName)
485      .Cases("mips2", "mips3", "mips4", "mips5", true)
486      .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
487      .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
488      .Default(false);
489}
490
491bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
492                         StringRef CPUName, StringRef ABIName,
493                         mips::FloatABI FloatABI) {
494  bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
495
496  // FPXX shouldn't be used if -msingle-float is present.
497  if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
498                               options::OPT_mdouble_float))
499    if (A->getOption().matches(options::OPT_msingle_float))
500      UseFPXX = false;
501
502  return UseFPXX;
503}
504
505bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
506  // Supporting the hazard barrier method of dealing with indirect
507  // jumps requires MIPSR2 support.
508  return llvm::StringSwitch<bool>(CPU)
509      .Case("mips32r2", true)
510      .Case("mips32r3", true)
511      .Case("mips32r5", true)
512      .Case("mips32r6", true)
513      .Case("mips64r2", true)
514      .Case("mips64r3", true)
515      .Case("mips64r5", true)
516      .Case("mips64r6", true)
517      .Case("octeon", true)
518      .Case("p5600", true)
519      .Default(false);
520}
521