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 // MIPS3 is the default for mips64*-unknown-openbsd.
43 if (Triple.isOSOpenBSD())
44 DefMips64CPU = "mips3";
45
46 // MIPS2 is the default for mips(el)?-unknown-freebsd.
47 // MIPS3 is the default for mips64(el)?-unknown-freebsd.
48 if (Triple.isOSFreeBSD()) {
49 DefMips32CPU = "mips2";
50 DefMips64CPU = "mips3";
51 }
52
53 if (Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ,
54 options::OPT_mcpu_EQ))
55 CPUName = A->getValue();
56
57 if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
58 ABIName = A->getValue();
59 // Convert a GNU style Mips ABI name to the name
60 // accepted by LLVM Mips backend.
61 ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
62 .Case("32", "o32")
63 .Case("64", "n64")
64 .Default(ABIName);
65 }
66
67 // Setup default CPU and ABI names.
68 if (CPUName.empty() && ABIName.empty()) {
69 switch (Triple.getArch()) {
70 default:
71 llvm_unreachable("Unexpected triple arch name");
72 case llvm::Triple::mips:
73 case llvm::Triple::mipsel:
74 CPUName = DefMips32CPU;
75 break;
76 case llvm::Triple::mips64:
77 case llvm::Triple::mips64el:
78 CPUName = DefMips64CPU;
79 break;
80 }
81 }
82
83 if (ABIName.empty() && (Triple.getEnvironment() == llvm::Triple::GNUABIN32))
84 ABIName = "n32";
85
86 if (ABIName.empty() &&
87 (Triple.getVendor() == llvm::Triple::MipsTechnologies ||
88 Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
89 ABIName = llvm::StringSwitch<const char *>(CPUName)
90 .Case("mips1", "o32")
91 .Case("mips2", "o32")
92 .Case("mips3", "n64")
93 .Case("mips4", "n64")
94 .Case("mips5", "n64")
95 .Case("mips32", "o32")
96 .Case("mips32r2", "o32")
97 .Case("mips32r3", "o32")
98 .Case("mips32r5", "o32")
99 .Case("mips32r6", "o32")
100 .Case("mips64", "n64")
101 .Case("mips64r2", "n64")
102 .Case("mips64r3", "n64")
103 .Case("mips64r5", "n64")
104 .Case("mips64r6", "n64")
105 .Case("octeon", "n64")
106 .Case("p5600", "o32")
107 .Default("");
108 }
109
110 if (ABIName.empty()) {
111 // Deduce ABI name from the target triple.
112 ABIName = Triple.isMIPS32() ? "o32" : "n64";
113 }
114
115 if (CPUName.empty()) {
116 // Deduce CPU name from ABI name.
117 CPUName = llvm::StringSwitch<const char *>(ABIName)
118 .Case("o32", DefMips32CPU)
119 .Cases("n32", "n64", DefMips64CPU)
120 .Default("");
121 }
122
123 // FIXME: Warn on inconsistent use of -march and -mabi.
124 }
125
getMipsABILibSuffix(const ArgList & Args,const llvm::Triple & Triple)126 std::string mips::getMipsABILibSuffix(const ArgList &Args,
127 const llvm::Triple &Triple) {
128 StringRef CPUName, ABIName;
129 tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
130 return llvm::StringSwitch<std::string>(ABIName)
131 .Case("o32", "")
132 .Case("n32", "32")
133 .Case("n64", "64");
134 }
135
136 // Convert ABI name to the GNU tools acceptable variant.
getGnuCompatibleMipsABIName(StringRef ABI)137 StringRef mips::getGnuCompatibleMipsABIName(StringRef ABI) {
138 return llvm::StringSwitch<llvm::StringRef>(ABI)
139 .Case("o32", "32")
140 .Case("n64", "64")
141 .Default(ABI);
142 }
143
144 // Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
145 // and -mfloat-abi=.
getMipsFloatABI(const Driver & D,const ArgList & Args,const llvm::Triple & Triple)146 mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args,
147 const llvm::Triple &Triple) {
148 mips::FloatABI ABI = mips::FloatABI::Invalid;
149 if (Arg *A =
150 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
151 options::OPT_mfloat_abi_EQ)) {
152 if (A->getOption().matches(options::OPT_msoft_float))
153 ABI = mips::FloatABI::Soft;
154 else if (A->getOption().matches(options::OPT_mhard_float))
155 ABI = mips::FloatABI::Hard;
156 else {
157 ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
158 .Case("soft", mips::FloatABI::Soft)
159 .Case("hard", mips::FloatABI::Hard)
160 .Default(mips::FloatABI::Invalid);
161 if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
162 D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
163 ABI = mips::FloatABI::Hard;
164 }
165 }
166 }
167
168 // If unspecified, choose the default based on the platform.
169 if (ABI == mips::FloatABI::Invalid) {
170 if (Triple.isOSFreeBSD()) {
171 // For FreeBSD, assume "soft" on all flavors of MIPS.
172 ABI = mips::FloatABI::Soft;
173 } else {
174 // Assume "hard", because it's a default value used by gcc.
175 // When we start to recognize specific target MIPS processors,
176 // we will be able to select the default more correctly.
177 ABI = mips::FloatABI::Hard;
178 }
179 }
180
181 assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
182 return ABI;
183 }
184
getMIPSTargetFeatures(const Driver & D,const llvm::Triple & Triple,const ArgList & Args,std::vector<StringRef> & Features)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 bool HasNaN2008Opt = false;
225
226 Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
227 options::OPT_fpic, options::OPT_fno_pic,
228 options::OPT_fPIE, options::OPT_fno_PIE,
229 options::OPT_fpie, options::OPT_fno_pie);
230 if (LastPICArg) {
231 Option O = LastPICArg->getOption();
232 NonPIC =
233 (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
234 O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
235 IsPIC =
236 (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
237 O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie));
238 }
239
240 bool UseAbiCalls = false;
241
242 Arg *ABICallsArg =
243 Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
244 UseAbiCalls =
245 !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls);
246
247 if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) {
248 D.Diag(diag::warn_drv_unsupported_pic_with_mabicalls)
249 << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1);
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 if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
272 if (A->getOption().matches(options::OPT_mxgot))
273 Features.push_back("+xgot");
274 else
275 Features.push_back("-xgot");
276 }
277
278 mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args, Triple);
279 if (FloatABI == mips::FloatABI::Soft) {
280 // FIXME: Note, this is a hack. We need to pass the selected float
281 // mode to the MipsTargetInfoBase to define appropriate macros there.
282 // Now it is the only method.
283 Features.push_back("+soft-float");
284 }
285
286 if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
287 StringRef Val = StringRef(A->getValue());
288 if (Val == "2008") {
289 if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
290 Features.push_back("+nan2008");
291 HasNaN2008Opt = true;
292 } else {
293 Features.push_back("-nan2008");
294 D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
295 }
296 } else if (Val == "legacy") {
297 if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
298 Features.push_back("-nan2008");
299 else {
300 Features.push_back("+nan2008");
301 D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
302 }
303 } else
304 D.Diag(diag::err_drv_unsupported_option_argument)
305 << A->getSpelling() << Val;
306 }
307
308 if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) {
309 StringRef Val = StringRef(A->getValue());
310 if (Val == "2008") {
311 if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
312 Features.push_back("+abs2008");
313 } else {
314 Features.push_back("-abs2008");
315 D.Diag(diag::warn_target_unsupported_abs2008) << CPUName;
316 }
317 } else if (Val == "legacy") {
318 if (mips::getIEEE754Standard(CPUName) & mips::Legacy) {
319 Features.push_back("-abs2008");
320 } else {
321 Features.push_back("+abs2008");
322 D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName;
323 }
324 } else {
325 D.Diag(diag::err_drv_unsupported_option_argument)
326 << A->getSpelling() << Val;
327 }
328 } else if (HasNaN2008Opt) {
329 Features.push_back("+abs2008");
330 }
331
332 AddTargetFeature(Args, Features, options::OPT_msingle_float,
333 options::OPT_mdouble_float, "single-float");
334 AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
335 "mips16");
336 AddTargetFeature(Args, Features, options::OPT_mmicromips,
337 options::OPT_mno_micromips, "micromips");
338 AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
339 "dsp");
340 AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
341 "dspr2");
342 AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
343 "msa");
344
345 // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
346 // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
347 // nooddspreg.
348 if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
349 options::OPT_mfp64)) {
350 if (A->getOption().matches(options::OPT_mfp32))
351 Features.push_back("-fp64");
352 else if (A->getOption().matches(options::OPT_mfpxx)) {
353 Features.push_back("+fpxx");
354 Features.push_back("+nooddspreg");
355 } else
356 Features.push_back("+fp64");
357 } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
358 Features.push_back("+fpxx");
359 Features.push_back("+nooddspreg");
360 } else if (mips::isFP64ADefault(Triple, CPUName)) {
361 Features.push_back("+fp64");
362 Features.push_back("+nooddspreg");
363 }
364
365 AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
366 options::OPT_modd_spreg, "nooddspreg");
367 AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
368 "nomadd4");
369 AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
370 AddTargetFeature(Args, Features, options::OPT_mcrc, options::OPT_mno_crc,
371 "crc");
372 AddTargetFeature(Args, Features, options::OPT_mvirt, options::OPT_mno_virt,
373 "virt");
374 AddTargetFeature(Args, Features, options::OPT_mginv, options::OPT_mno_ginv,
375 "ginv");
376
377 if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
378 StringRef Val = StringRef(A->getValue());
379 if (Val == "hazard") {
380 Arg *B =
381 Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
382 Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
383
384 if (B && B->getOption().matches(options::OPT_mmicromips))
385 D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
386 << "hazard" << "micromips";
387 else if (C && C->getOption().matches(options::OPT_mips16))
388 D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
389 << "hazard" << "mips16";
390 else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
391 Features.push_back("+use-indirect-jump-hazard");
392 else
393 D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
394 << "hazard" << CPUName;
395 } else
396 D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
397 }
398 }
399
getIEEE754Standard(StringRef & CPU)400 mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
401 // Strictly speaking, mips32r2 and mips64r2 do not conform to the
402 // IEEE754-2008 standard. Support for this standard was first introduced
403 // in Release 3. However, other compilers have traditionally allowed it
404 // for Release 2 so we should do the same.
405 return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
406 .Case("mips1", Legacy)
407 .Case("mips2", Legacy)
408 .Case("mips3", Legacy)
409 .Case("mips4", Legacy)
410 .Case("mips5", Legacy)
411 .Case("mips32", Legacy)
412 .Case("mips32r2", Legacy | Std2008)
413 .Case("mips32r3", Legacy | Std2008)
414 .Case("mips32r5", Legacy | Std2008)
415 .Case("mips32r6", Std2008)
416 .Case("mips64", Legacy)
417 .Case("mips64r2", Legacy | Std2008)
418 .Case("mips64r3", Legacy | Std2008)
419 .Case("mips64r5", Legacy | Std2008)
420 .Case("mips64r6", Std2008)
421 .Default(Std2008);
422 }
423
hasCompactBranches(StringRef & CPU)424 bool mips::hasCompactBranches(StringRef &CPU) {
425 // mips32r6 and mips64r6 have compact branches.
426 return llvm::StringSwitch<bool>(CPU)
427 .Case("mips32r6", true)
428 .Case("mips64r6", true)
429 .Default(false);
430 }
431
hasMipsAbiArg(const ArgList & Args,const char * Value)432 bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
433 Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
434 return A && (A->getValue() == StringRef(Value));
435 }
436
isUCLibc(const ArgList & Args)437 bool mips::isUCLibc(const ArgList &Args) {
438 Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
439 return A && A->getOption().matches(options::OPT_muclibc);
440 }
441
isNaN2008(const Driver & D,const ArgList & Args,const llvm::Triple & Triple)442 bool mips::isNaN2008(const Driver &D, const ArgList &Args,
443 const llvm::Triple &Triple) {
444 if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
445 return llvm::StringSwitch<bool>(NaNArg->getValue())
446 .Case("2008", true)
447 .Case("legacy", false)
448 .Default(false);
449
450 // NaN2008 is the default for MIPS32r6/MIPS64r6.
451 return llvm::StringSwitch<bool>(getCPUName(D, Args, Triple))
452 .Cases("mips32r6", "mips64r6", true)
453 .Default(false);
454 }
455
isFP64ADefault(const llvm::Triple & Triple,StringRef CPUName)456 bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
457 if (!Triple.isAndroid())
458 return false;
459
460 // Android MIPS32R6 defaults to FP64A.
461 return llvm::StringSwitch<bool>(CPUName)
462 .Case("mips32r6", true)
463 .Default(false);
464 }
465
isFPXXDefault(const llvm::Triple & Triple,StringRef CPUName,StringRef ABIName,mips::FloatABI FloatABI)466 bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
467 StringRef ABIName, mips::FloatABI FloatABI) {
468 if (ABIName != "32")
469 return false;
470
471 // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
472 // present.
473 if (FloatABI == mips::FloatABI::Soft)
474 return false;
475
476 return llvm::StringSwitch<bool>(CPUName)
477 .Cases("mips2", "mips3", "mips4", "mips5", true)
478 .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
479 .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
480 .Default(false);
481 }
482
shouldUseFPXX(const ArgList & Args,const llvm::Triple & Triple,StringRef CPUName,StringRef ABIName,mips::FloatABI FloatABI)483 bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
484 StringRef CPUName, StringRef ABIName,
485 mips::FloatABI FloatABI) {
486 bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
487
488 // FPXX shouldn't be used if -msingle-float is present.
489 if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
490 options::OPT_mdouble_float))
491 if (A->getOption().matches(options::OPT_msingle_float))
492 UseFPXX = false;
493
494 return UseFPXX;
495 }
496
supportsIndirectJumpHazardBarrier(StringRef & CPU)497 bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
498 // Supporting the hazard barrier method of dealing with indirect
499 // jumps requires MIPSR2 support.
500 return llvm::StringSwitch<bool>(CPU)
501 .Case("mips32r2", true)
502 .Case("mips32r3", true)
503 .Case("mips32r5", true)
504 .Case("mips32r6", true)
505 .Case("mips64r2", true)
506 .Case("mips64r3", true)
507 .Case("mips64r5", true)
508 .Case("mips64r6", true)
509 .Case("octeon", true)
510 .Case("p5600", true)
511 .Default(false);
512 }
513