xref: /freebsd/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/Mips.cpp (revision 7ef62cebc2f965b0f640263e179276928885e33d)
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   // 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,
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 
191 void 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->getSpelling() << 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->getSpelling() << 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 
402 mips::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 
426 bool 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 
434 bool 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 
439 bool 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 
444 bool mips::isNaN2008(const Driver &D, const ArgList &Args,
445                      const llvm::Triple &Triple) {
446   if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
447     return llvm::StringSwitch<bool>(NaNArg->getValue())
448         .Case("2008", true)
449         .Case("legacy", false)
450         .Default(false);
451 
452   // NaN2008 is the default for MIPS32r6/MIPS64r6.
453   return llvm::StringSwitch<bool>(getCPUName(D, Args, Triple))
454       .Cases("mips32r6", "mips64r6", true)
455       .Default(false);
456 }
457 
458 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
459   if (!Triple.isAndroid())
460     return false;
461 
462   // Android MIPS32R6 defaults to FP64A.
463   return llvm::StringSwitch<bool>(CPUName)
464       .Case("mips32r6", true)
465       .Default(false);
466 }
467 
468 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
469                          StringRef ABIName, mips::FloatABI FloatABI) {
470   if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
471       Triple.getVendor() != llvm::Triple::MipsTechnologies &&
472       !Triple.isAndroid())
473     return false;
474 
475   if (ABIName != "32")
476     return false;
477 
478   // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
479   // present.
480   if (FloatABI == mips::FloatABI::Soft)
481     return false;
482 
483   return llvm::StringSwitch<bool>(CPUName)
484       .Cases("mips2", "mips3", "mips4", "mips5", true)
485       .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
486       .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
487       .Default(false);
488 }
489 
490 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
491                          StringRef CPUName, StringRef ABIName,
492                          mips::FloatABI FloatABI) {
493   bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
494 
495   // FPXX shouldn't be used if -msingle-float is present.
496   if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
497                                options::OPT_mdouble_float))
498     if (A->getOption().matches(options::OPT_msingle_float))
499       UseFPXX = false;
500 
501   return UseFPXX;
502 }
503 
504 bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
505   // Supporting the hazard barrier method of dealing with indirect
506   // jumps requires MIPSR2 support.
507   return llvm::StringSwitch<bool>(CPU)
508       .Case("mips32r2", true)
509       .Case("mips32r3", true)
510       .Case("mips32r5", true)
511       .Case("mips32r6", true)
512       .Case("mips64r2", true)
513       .Case("mips64r3", true)
514       .Case("mips64r5", true)
515       .Case("mips64r6", true)
516       .Case("octeon", true)
517       .Case("p5600", true)
518       .Default(false);
519 }
520