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