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