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.
getMipsCPUAndABI(const ArgList & Args,const llvm::Triple & Triple,StringRef & CPUName,StringRef & ABIName)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 
getMipsABILibSuffix(const ArgList & Args,const llvm::Triple & Triple)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.
getGnuCompatibleMipsABIName(StringRef ABI)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=.
getMipsFloatABI(const Driver & D,const ArgList & Args,const llvm::Triple & Triple)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 
getMIPSTargetFeatures(const Driver & D,const llvm::Triple & Triple,const ArgList & Args,std::vector<StringRef> & Features)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->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 
getIEEE754Standard(StringRef & CPU)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 
hasCompactBranches(StringRef & CPU)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 
hasMipsAbiArg(const ArgList & Args,const char * Value)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 
isUCLibc(const ArgList & Args)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 
isNaN2008(const ArgList & Args,const llvm::Triple & Triple)444 bool 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 
isFP64ADefault(const llvm::Triple & Triple,StringRef CPUName)457 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
458   if (!Triple.isAndroid())
459     return false;
460 
461   // Android MIPS32R6 defaults to FP64A.
462   return llvm::StringSwitch<bool>(CPUName)
463       .Case("mips32r6", true)
464       .Default(false);
465 }
466 
isFPXXDefault(const llvm::Triple & Triple,StringRef CPUName,StringRef ABIName,mips::FloatABI FloatABI)467 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
468                          StringRef ABIName, mips::FloatABI FloatABI) {
469   if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
470       Triple.getVendor() != llvm::Triple::MipsTechnologies &&
471       !Triple.isAndroid())
472     return false;
473 
474   if (ABIName != "32")
475     return false;
476 
477   // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
478   // present.
479   if (FloatABI == mips::FloatABI::Soft)
480     return false;
481 
482   return llvm::StringSwitch<bool>(CPUName)
483       .Cases("mips2", "mips3", "mips4", "mips5", true)
484       .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
485       .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
486       .Default(false);
487 }
488 
shouldUseFPXX(const ArgList & Args,const llvm::Triple & Triple,StringRef CPUName,StringRef ABIName,mips::FloatABI FloatABI)489 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
490                          StringRef CPUName, StringRef ABIName,
491                          mips::FloatABI FloatABI) {
492   bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
493 
494   // FPXX shouldn't be used if -msingle-float is present.
495   if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
496                                options::OPT_mdouble_float))
497     if (A->getOption().matches(options::OPT_msingle_float))
498       UseFPXX = false;
499 
500   return UseFPXX;
501 }
502 
supportsIndirectJumpHazardBarrier(StringRef & CPU)503 bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
504   // Supporting the hazard barrier method of dealing with indirect
505   // jumps requires MIPSR2 support.
506   return llvm::StringSwitch<bool>(CPU)
507       .Case("mips32r2", true)
508       .Case("mips32r3", true)
509       .Case("mips32r5", true)
510       .Case("mips32r6", true)
511       .Case("mips64r2", true)
512       .Case("mips64r3", true)
513       .Case("mips64r5", true)
514       .Case("mips64r6", true)
515       .Case("octeon", true)
516       .Case("p5600", true)
517       .Default(false);
518 }
519