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