xref: /freebsd/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/Mips.cpp (revision 6966ac055c3b7a39266fb982493330df7a097997)
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   mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args, Triple);
277   if (FloatABI == mips::FloatABI::Soft) {
278     // FIXME: Note, this is a hack. We need to pass the selected float
279     // mode to the MipsTargetInfoBase to define appropriate macros there.
280     // Now it is the only method.
281     Features.push_back("+soft-float");
282   }
283 
284   if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
285     StringRef Val = StringRef(A->getValue());
286     if (Val == "2008") {
287       if (mips::getIEEE754Standard(CPUName) & mips::Std2008)
288         Features.push_back("+nan2008");
289       else {
290         Features.push_back("-nan2008");
291         D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
292       }
293     } else if (Val == "legacy") {
294       if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
295         Features.push_back("-nan2008");
296       else {
297         Features.push_back("+nan2008");
298         D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
299       }
300     } else
301       D.Diag(diag::err_drv_unsupported_option_argument)
302           << A->getOption().getName() << Val;
303   }
304 
305   if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) {
306     StringRef Val = StringRef(A->getValue());
307     if (Val == "2008") {
308       if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
309         Features.push_back("+abs2008");
310       } else {
311         Features.push_back("-abs2008");
312         D.Diag(diag::warn_target_unsupported_abs2008) << CPUName;
313       }
314     } else if (Val == "legacy") {
315       if (mips::getIEEE754Standard(CPUName) & mips::Legacy) {
316         Features.push_back("-abs2008");
317       } else {
318         Features.push_back("+abs2008");
319         D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName;
320       }
321     } else {
322       D.Diag(diag::err_drv_unsupported_option_argument)
323           << A->getOption().getName() << Val;
324     }
325   }
326 
327   AddTargetFeature(Args, Features, options::OPT_msingle_float,
328                    options::OPT_mdouble_float, "single-float");
329   AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
330                    "mips16");
331   AddTargetFeature(Args, Features, options::OPT_mmicromips,
332                    options::OPT_mno_micromips, "micromips");
333   AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
334                    "dsp");
335   AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
336                    "dspr2");
337   AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
338                    "msa");
339 
340   // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
341   // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
342   // nooddspreg.
343   if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
344                                options::OPT_mfp64)) {
345     if (A->getOption().matches(options::OPT_mfp32))
346       Features.push_back("-fp64");
347     else if (A->getOption().matches(options::OPT_mfpxx)) {
348       Features.push_back("+fpxx");
349       Features.push_back("+nooddspreg");
350     } else
351       Features.push_back("+fp64");
352   } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
353     Features.push_back("+fpxx");
354     Features.push_back("+nooddspreg");
355   } else if (mips::isFP64ADefault(Triple, CPUName)) {
356     Features.push_back("+fp64");
357     Features.push_back("+nooddspreg");
358   }
359 
360   AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
361                    options::OPT_modd_spreg, "nooddspreg");
362   AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
363                    "nomadd4");
364   AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
365   AddTargetFeature(Args, Features, options::OPT_mcrc, options::OPT_mno_crc,
366                    "crc");
367   AddTargetFeature(Args, Features, options::OPT_mvirt, options::OPT_mno_virt,
368                    "virt");
369   AddTargetFeature(Args, Features, options::OPT_mginv, options::OPT_mno_ginv,
370                    "ginv");
371 
372   if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
373     StringRef Val = StringRef(A->getValue());
374     if (Val == "hazard") {
375       Arg *B =
376           Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
377       Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
378 
379       if (B && B->getOption().matches(options::OPT_mmicromips))
380         D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
381             << "hazard" << "micromips";
382       else if (C && C->getOption().matches(options::OPT_mips16))
383         D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
384             << "hazard" << "mips16";
385       else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
386         Features.push_back("+use-indirect-jump-hazard");
387       else
388         D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
389             << "hazard" << CPUName;
390     } else
391       D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
392   }
393 }
394 
395 mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
396   // Strictly speaking, mips32r2 and mips64r2 do not conform to the
397   // IEEE754-2008 standard. Support for this standard was first introduced
398   // in Release 3. However, other compilers have traditionally allowed it
399   // for Release 2 so we should do the same.
400   return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
401       .Case("mips1", Legacy)
402       .Case("mips2", Legacy)
403       .Case("mips3", Legacy)
404       .Case("mips4", Legacy)
405       .Case("mips5", Legacy)
406       .Case("mips32", Legacy)
407       .Case("mips32r2", Legacy | Std2008)
408       .Case("mips32r3", Legacy | Std2008)
409       .Case("mips32r5", Legacy | Std2008)
410       .Case("mips32r6", Std2008)
411       .Case("mips64", Legacy)
412       .Case("mips64r2", Legacy | Std2008)
413       .Case("mips64r3", Legacy | Std2008)
414       .Case("mips64r5", Legacy | Std2008)
415       .Case("mips64r6", Std2008)
416       .Default(Std2008);
417 }
418 
419 bool mips::hasCompactBranches(StringRef &CPU) {
420   // mips32r6 and mips64r6 have compact branches.
421   return llvm::StringSwitch<bool>(CPU)
422       .Case("mips32r6", true)
423       .Case("mips64r6", true)
424       .Default(false);
425 }
426 
427 bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
428   Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
429   return A && (A->getValue() == StringRef(Value));
430 }
431 
432 bool mips::isUCLibc(const ArgList &Args) {
433   Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
434   return A && A->getOption().matches(options::OPT_muclibc);
435 }
436 
437 bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
438   if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
439     return llvm::StringSwitch<bool>(NaNArg->getValue())
440         .Case("2008", true)
441         .Case("legacy", false)
442         .Default(false);
443 
444   // NaN2008 is the default for MIPS32r6/MIPS64r6.
445   return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
446       .Cases("mips32r6", "mips64r6", true)
447       .Default(false);
448 
449   return false;
450 }
451 
452 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
453   if (!Triple.isAndroid())
454     return false;
455 
456   // Android MIPS32R6 defaults to FP64A.
457   return llvm::StringSwitch<bool>(CPUName)
458       .Case("mips32r6", true)
459       .Default(false);
460 }
461 
462 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
463                          StringRef ABIName, mips::FloatABI FloatABI) {
464   if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
465       Triple.getVendor() != llvm::Triple::MipsTechnologies &&
466       !Triple.isAndroid())
467     return false;
468 
469   if (ABIName != "32")
470     return false;
471 
472   // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
473   // present.
474   if (FloatABI == mips::FloatABI::Soft)
475     return false;
476 
477   return llvm::StringSwitch<bool>(CPUName)
478       .Cases("mips2", "mips3", "mips4", "mips5", true)
479       .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
480       .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
481       .Default(false);
482 }
483 
484 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
485                          StringRef CPUName, StringRef ABIName,
486                          mips::FloatABI FloatABI) {
487   bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
488 
489   // FPXX shouldn't be used if -msingle-float is present.
490   if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
491                                options::OPT_mdouble_float))
492     if (A->getOption().matches(options::OPT_msingle_float))
493       UseFPXX = false;
494 
495   return UseFPXX;
496 }
497 
498 bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
499   // Supporting the hazard barrier method of dealing with indirect
500   // jumps requires MIPSR2 support.
501   return llvm::StringSwitch<bool>(CPU)
502       .Case("mips32r2", true)
503       .Case("mips32r3", true)
504       .Case("mips32r5", true)
505       .Case("mips32r6", true)
506       .Case("mips64r2", true)
507       .Case("mips64r3", true)
508       .Case("mips64r5", true)
509       .Case("mips64r6", true)
510       .Case("octeon", true)
511       .Case("p5600", true)
512       .Default(false);
513 }
514