xref: /freebsd/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/Mips.cpp (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
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 
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   // 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 
126 std::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.
137 StringRef 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=.
146 mips::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 
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   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   if (Arg *A = Args.getLastArg(
345           options::OPT_mstrict_align, options::OPT_mno_strict_align,
346           options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {
347     if (A->getOption().matches(options::OPT_mstrict_align) ||
348         A->getOption().matches(options::OPT_mno_unaligned_access))
349       Features.push_back(Args.MakeArgString("+strict-align"));
350     else
351       Features.push_back(Args.MakeArgString("-strict-align"));
352   }
353 
354   // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
355   // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
356   // nooddspreg.
357   if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
358                                options::OPT_mfp64)) {
359     if (A->getOption().matches(options::OPT_mfp32))
360       Features.push_back("-fp64");
361     else if (A->getOption().matches(options::OPT_mfpxx)) {
362       Features.push_back("+fpxx");
363       Features.push_back("+nooddspreg");
364     } else
365       Features.push_back("+fp64");
366   } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
367     Features.push_back("+fpxx");
368     Features.push_back("+nooddspreg");
369   } else if (mips::isFP64ADefault(Triple, CPUName)) {
370     Features.push_back("+fp64");
371     Features.push_back("+nooddspreg");
372   } else if (Arg *A = Args.getLastArg(options::OPT_mmsa)) {
373     if (A->getOption().matches(options::OPT_mmsa))
374       Features.push_back("+fp64");
375   }
376 
377   AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
378                    options::OPT_modd_spreg, "nooddspreg");
379   AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
380                    "nomadd4");
381   AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
382   AddTargetFeature(Args, Features, options::OPT_mcrc, options::OPT_mno_crc,
383                    "crc");
384   AddTargetFeature(Args, Features, options::OPT_mvirt, options::OPT_mno_virt,
385                    "virt");
386   AddTargetFeature(Args, Features, options::OPT_mginv, options::OPT_mno_ginv,
387                    "ginv");
388 
389   if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
390     StringRef Val = StringRef(A->getValue());
391     if (Val == "hazard") {
392       Arg *B =
393           Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
394       Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
395 
396       if (B && B->getOption().matches(options::OPT_mmicromips))
397         D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
398             << "hazard" << "micromips";
399       else if (C && C->getOption().matches(options::OPT_mips16))
400         D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
401             << "hazard" << "mips16";
402       else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
403         Features.push_back("+use-indirect-jump-hazard");
404       else
405         D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
406             << "hazard" << CPUName;
407     } else
408       D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
409   }
410 }
411 
412 mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
413   // Strictly speaking, mips32r2 and mips64r2 do not conform to the
414   // IEEE754-2008 standard. Support for this standard was first introduced
415   // in Release 3. However, other compilers have traditionally allowed it
416   // for Release 2 so we should do the same.
417   return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
418       .Case("mips1", Legacy)
419       .Case("mips2", Legacy)
420       .Case("mips3", Legacy)
421       .Case("mips4", Legacy)
422       .Case("mips5", Legacy)
423       .Case("mips32", Legacy)
424       .Case("mips32r2", Legacy | Std2008)
425       .Case("mips32r3", Legacy | Std2008)
426       .Case("mips32r5", Legacy | Std2008)
427       .Case("mips32r6", Std2008)
428       .Case("mips64", Legacy)
429       .Case("mips64r2", Legacy | Std2008)
430       .Case("mips64r3", Legacy | Std2008)
431       .Case("mips64r5", Legacy | Std2008)
432       .Case("mips64r6", Std2008)
433       .Default(Std2008);
434 }
435 
436 bool mips::hasCompactBranches(StringRef &CPU) {
437   // mips32r6 and mips64r6 have compact branches.
438   return llvm::StringSwitch<bool>(CPU)
439       .Case("mips32r6", true)
440       .Case("mips64r6", true)
441       .Default(false);
442 }
443 
444 bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
445   Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
446   return A && (A->getValue() == StringRef(Value));
447 }
448 
449 bool mips::isUCLibc(const ArgList &Args) {
450   Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
451   return A && A->getOption().matches(options::OPT_muclibc);
452 }
453 
454 bool mips::isNaN2008(const Driver &D, const ArgList &Args,
455                      const llvm::Triple &Triple) {
456   if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
457     return llvm::StringSwitch<bool>(NaNArg->getValue())
458         .Case("2008", true)
459         .Case("legacy", false)
460         .Default(false);
461 
462   // NaN2008 is the default for MIPS32r6/MIPS64r6.
463   return llvm::StringSwitch<bool>(getCPUName(D, Args, Triple))
464       .Cases("mips32r6", "mips64r6", true)
465       .Default(false);
466 }
467 
468 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
469   if (!Triple.isAndroid())
470     return false;
471 
472   // Android MIPS32R6 defaults to FP64A.
473   return llvm::StringSwitch<bool>(CPUName)
474       .Case("mips32r6", true)
475       .Default(false);
476 }
477 
478 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
479                          StringRef ABIName, mips::FloatABI FloatABI) {
480   if (ABIName != "32")
481     return false;
482 
483   // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
484   // present.
485   if (FloatABI == mips::FloatABI::Soft)
486     return false;
487 
488   return llvm::StringSwitch<bool>(CPUName)
489       .Cases("mips2", "mips3", "mips4", "mips5", true)
490       .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
491       .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
492       .Default(false);
493 }
494 
495 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
496                          StringRef CPUName, StringRef ABIName,
497                          mips::FloatABI FloatABI) {
498   bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
499 
500   // FPXX shouldn't be used if -msingle-float is present.
501   if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
502                                options::OPT_mdouble_float))
503     if (A->getOption().matches(options::OPT_msingle_float))
504       UseFPXX = false;
505   // FP64 should be used for MSA.
506   if (Arg *A = Args.getLastArg(options::OPT_mmsa))
507     if (A->getOption().matches(options::OPT_mmsa))
508       UseFPXX = llvm::StringSwitch<bool>(CPUName)
509                     .Cases("mips32r2", "mips32r3", "mips32r5", false)
510                     .Cases("mips64r2", "mips64r3", "mips64r5", false)
511                     .Default(UseFPXX);
512 
513   return UseFPXX;
514 }
515 
516 bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
517   // Supporting the hazard barrier method of dealing with indirect
518   // jumps requires MIPSR2 support.
519   return llvm::StringSwitch<bool>(CPU)
520       .Case("mips32r2", true)
521       .Case("mips32r3", true)
522       .Case("mips32r5", true)
523       .Case("mips32r6", true)
524       .Case("mips64r2", true)
525       .Case("mips64r3", true)
526       .Case("mips64r5", true)
527       .Case("mips64r6", true)
528       .Case("octeon", true)
529       .Case("p5600", true)
530       .Default(false);
531 }
532