1 | //===--- Mips.h - Declare Mips target feature support -----------*- 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 | // This file declares Mips TargetInfo objects. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H |
14 | #define LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H |
15 | |
16 | #include "OSTargets.h" |
17 | #include "clang/Basic/TargetInfo.h" |
18 | #include "clang/Basic/TargetOptions.h" |
19 | #include "llvm/Support/Compiler.h" |
20 | #include "llvm/TargetParser/Triple.h" |
21 | |
22 | namespace clang { |
23 | namespace targets { |
24 | |
25 | class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { |
26 | void setDataLayout() { |
27 | StringRef Layout; |
28 | |
29 | if (ABI == "o32") |
30 | Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"; |
31 | else if (ABI == "n32") |
32 | Layout = "m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"; |
33 | else if (ABI == "n64") |
34 | Layout = "m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"; |
35 | else |
36 | llvm_unreachable("Invalid ABI"); |
37 | |
38 | if (BigEndian) |
39 | resetDataLayout(DL: ("E-"+ Layout).str()); |
40 | else |
41 | resetDataLayout(DL: ("e-"+ Layout).str()); |
42 | } |
43 | |
44 | std::string CPU; |
45 | bool IsMips16; |
46 | bool IsMicromips; |
47 | bool IsNan2008; |
48 | bool IsAbs2008; |
49 | bool IsSingleFloat; |
50 | bool IsNoABICalls; |
51 | bool CanUseBSDABICalls; |
52 | enum MipsFloatABI { HardFloat, SoftFloat } FloatABI; |
53 | enum DspRevEnum { NoDSP, DSP1, DSP2 } DspRev; |
54 | bool HasMSA; |
55 | bool DisableMadd4; |
56 | bool UseIndirectJumpHazard; |
57 | bool NoOddSpreg; |
58 | |
59 | protected: |
60 | enum FPModeEnum { FPXX, FP32, FP64 } FPMode; |
61 | std::string ABI; |
62 | |
63 | public: |
64 | MipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &) |
65 | : TargetInfo(Triple), IsMips16(false), IsMicromips(false), |
66 | IsNan2008(false), IsAbs2008(false), IsSingleFloat(false), |
67 | IsNoABICalls(false), CanUseBSDABICalls(false), FloatABI(HardFloat), |
68 | DspRev(NoDSP), HasMSA(false), DisableMadd4(false), |
69 | UseIndirectJumpHazard(false), FPMode(FPXX) { |
70 | TheCXXABI.set(TargetCXXABI::GenericMIPS); |
71 | |
72 | if (Triple.isMIPS32()) |
73 | setABI("o32"); |
74 | else if (Triple.isABIN32()) |
75 | setABI("n32"); |
76 | else |
77 | setABI("n64"); |
78 | |
79 | CPU = ABI == "o32"? "mips32r2": "mips64r2"; |
80 | |
81 | CanUseBSDABICalls = Triple.isOSFreeBSD() || |
82 | Triple.isOSOpenBSD(); |
83 | } |
84 | |
85 | bool isIEEE754_2008Default() const { |
86 | return CPU == "mips32r6"|| CPU == "mips64r6"; |
87 | } |
88 | |
89 | enum FPModeEnum getDefaultFPMode() const { |
90 | if (CPU == "mips32r6"|| ABI == "n32"|| ABI == "n64"|| ABI == "64") |
91 | return FP64; |
92 | else if (CPU == "mips1") |
93 | return FP32; |
94 | else |
95 | return FPXX; |
96 | } |
97 | |
98 | bool isNan2008() const override { return IsNan2008; } |
99 | |
100 | bool processorSupportsGPR64() const; |
101 | |
102 | StringRef getABI() const override { return ABI; } |
103 | |
104 | bool setABI(const std::string &Name) override { |
105 | if (Name == "o32") { |
106 | setO32ABITypes(); |
107 | ABI = Name; |
108 | return true; |
109 | } |
110 | |
111 | if (Name == "n32") { |
112 | setN32ABITypes(); |
113 | ABI = Name; |
114 | return true; |
115 | } |
116 | if (Name == "n64") { |
117 | setN64ABITypes(); |
118 | ABI = Name; |
119 | return true; |
120 | } |
121 | return false; |
122 | } |
123 | |
124 | void setO32ABITypes() { |
125 | Int64Type = SignedLongLong; |
126 | IntMaxType = Int64Type; |
127 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
128 | LongDoubleWidth = LongDoubleAlign = 64; |
129 | LongWidth = LongAlign = 32; |
130 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; |
131 | PointerWidth = PointerAlign = 32; |
132 | PtrDiffType = SignedInt; |
133 | SizeType = UnsignedInt; |
134 | SuitableAlign = 64; |
135 | } |
136 | |
137 | void setN32N64ABITypes() { |
138 | LongDoubleWidth = LongDoubleAlign = 128; |
139 | LongDoubleFormat = &llvm::APFloat::IEEEquad(); |
140 | if (getTriple().isOSFreeBSD()) { |
141 | LongDoubleWidth = LongDoubleAlign = 64; |
142 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
143 | } |
144 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; |
145 | SuitableAlign = 128; |
146 | } |
147 | |
148 | void setN64ABITypes() { |
149 | setN32N64ABITypes(); |
150 | if (getTriple().isOSOpenBSD()) { |
151 | Int64Type = SignedLongLong; |
152 | } else { |
153 | Int64Type = SignedLong; |
154 | } |
155 | IntMaxType = Int64Type; |
156 | LongWidth = LongAlign = 64; |
157 | PointerWidth = PointerAlign = 64; |
158 | PtrDiffType = SignedLong; |
159 | SizeType = UnsignedLong; |
160 | } |
161 | |
162 | void setN32ABITypes() { |
163 | setN32N64ABITypes(); |
164 | Int64Type = SignedLongLong; |
165 | IntMaxType = Int64Type; |
166 | LongWidth = LongAlign = 32; |
167 | PointerWidth = PointerAlign = 32; |
168 | PtrDiffType = SignedInt; |
169 | SizeType = UnsignedInt; |
170 | } |
171 | |
172 | bool isValidCPUName(StringRef Name) const override; |
173 | void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; |
174 | |
175 | bool setCPU(const std::string &Name) override { |
176 | CPU = Name; |
177 | return isValidCPUName(Name); |
178 | } |
179 | |
180 | const std::string &getCPU() const { return CPU; } |
181 | bool |
182 | initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, |
183 | StringRef CPU, |
184 | const std::vector<std::string> &FeaturesVec) const override { |
185 | if (CPU.empty()) |
186 | CPU = getCPU(); |
187 | if (CPU == "octeon") |
188 | Features["mips64r2"] = Features[ "cnmips"] = true; |
189 | else if (CPU == "octeon+") |
190 | Features["mips64r2"] = Features[ "cnmips"] = Features[ "cnmipsp"] = true; |
191 | else |
192 | Features[CPU] = true; |
193 | return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec: FeaturesVec); |
194 | } |
195 | |
196 | unsigned getISARev() const; |
197 | |
198 | void getTargetDefines(const LangOptions &Opts, |
199 | MacroBuilder &Builder) const override; |
200 | |
201 | llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override; |
202 | |
203 | bool hasFeature(StringRef Feature) const override; |
204 | |
205 | BuiltinVaListKind getBuiltinVaListKind() const override { |
206 | return TargetInfo::VoidPtrBuiltinVaList; |
207 | } |
208 | |
209 | ArrayRef<const char *> getGCCRegNames() const override { |
210 | static const char *const GCCRegNames[] = { |
211 | // CPU register names |
212 | // Must match second column of GCCRegAliases |
213 | "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", |
214 | "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19", "$20", |
215 | "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$30", |
216 | "$31", |
217 | // Floating point register names |
218 | "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", |
219 | "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", |
220 | "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", |
221 | "$f28", "$f29", "$f30", "$f31", |
222 | // Hi/lo and condition register names |
223 | "hi", "lo", "", "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", |
224 | "$fcc6", "$fcc7", "$ac1hi", "$ac1lo", "$ac2hi", "$ac2lo", "$ac3hi", |
225 | "$ac3lo", |
226 | // MSA register names |
227 | "$w0", "$w1", "$w2", "$w3", "$w4", "$w5", "$w6", "$w7", "$w8", "$w9", |
228 | "$w10", "$w11", "$w12", "$w13", "$w14", "$w15", "$w16", "$w17", "$w18", |
229 | "$w19", "$w20", "$w21", "$w22", "$w23", "$w24", "$w25", "$w26", "$w27", |
230 | "$w28", "$w29", "$w30", "$w31", |
231 | // MSA control register names |
232 | "$msair", "$msacsr", "$msaaccess", "$msasave", "$msamodify", |
233 | "$msarequest", "$msamap", "$msaunmap" |
234 | }; |
235 | return llvm::ArrayRef(GCCRegNames); |
236 | } |
237 | |
238 | bool validateAsmConstraint(const char *&Name, |
239 | TargetInfo::ConstraintInfo &Info) const override { |
240 | switch (*Name) { |
241 | default: |
242 | return false; |
243 | case 'r': // CPU registers. |
244 | case 'd': // Equivalent to "r" unless generating MIPS16 code. |
245 | case 'y': // Equivalent to "r", backward compatibility only. |
246 | case 'c': // $25 for indirect jumps |
247 | case 'l': // lo register |
248 | case 'x': // hilo register pair |
249 | Info.setAllowsRegister(); |
250 | return true; |
251 | case 'f': // floating-point registers. |
252 | Info.setAllowsRegister(); |
253 | return FloatABI != SoftFloat; |
254 | case 'I': // Signed 16-bit constant |
255 | case 'J': // Integer 0 |
256 | case 'K': // Unsigned 16-bit constant |
257 | case 'L': // Signed 32-bit constant, lower 16-bit zeros (for lui) |
258 | case 'M': // Constants not loadable via lui, addiu, or ori |
259 | case 'N': // Constant -1 to -65535 |
260 | case 'O': // A signed 15-bit constant |
261 | case 'P': // A constant between 1 go 65535 |
262 | return true; |
263 | case 'R': // An address that can be used in a non-macro load or store |
264 | Info.setAllowsMemory(); |
265 | return true; |
266 | case 'Z': |
267 | if (Name[1] == 'C') { // An address usable by ll, and sc. |
268 | Info.setAllowsMemory(); |
269 | Name++; // Skip over 'Z'. |
270 | return true; |
271 | } |
272 | return false; |
273 | } |
274 | } |
275 | |
276 | std::string convertConstraint(const char *&Constraint) const override { |
277 | std::string R; |
278 | switch (*Constraint) { |
279 | case 'Z': // Two-character constraint; add "^" hint for later parsing. |
280 | if (Constraint[1] == 'C') { |
281 | R = std::string("^") + std::string(Constraint, 2); |
282 | Constraint++; |
283 | return R; |
284 | } |
285 | break; |
286 | } |
287 | return TargetInfo::convertConstraint(Constraint); |
288 | } |
289 | |
290 | std::string_view getClobbers() const override { |
291 | // In GCC, $1 is not widely used in generated code (it's used only in a few |
292 | // specific situations), so there is no real need for users to add it to |
293 | // the clobbers list if they want to use it in their inline assembly code. |
294 | // |
295 | // In LLVM, $1 is treated as a normal GPR and is always allocatable during |
296 | // code generation, so using it in inline assembly without adding it to the |
297 | // clobbers list can cause conflicts between the inline assembly code and |
298 | // the surrounding generated code. |
299 | // |
300 | // Another problem is that LLVM is allowed to choose $1 for inline assembly |
301 | // operands, which will conflict with the ".set at" assembler option (which |
302 | // we use only for inline assembly, in order to maintain compatibility with |
303 | // GCC) and will also conflict with the user's usage of $1. |
304 | // |
305 | // The easiest way to avoid these conflicts and keep $1 as an allocatable |
306 | // register for generated code is to automatically clobber $1 for all inline |
307 | // assembly code. |
308 | // |
309 | // FIXME: We should automatically clobber $1 only for inline assembly code |
310 | // which actually uses it. This would allow LLVM to use $1 for inline |
311 | // assembly operands if the user's assembly code doesn't use it. |
312 | return "~{$1}"; |
313 | } |
314 | |
315 | bool handleTargetFeatures(std::vector<std::string> &Features, |
316 | DiagnosticsEngine &Diags) override { |
317 | IsMips16 = false; |
318 | IsMicromips = false; |
319 | IsNan2008 = isIEEE754_2008Default(); |
320 | IsAbs2008 = isIEEE754_2008Default(); |
321 | IsSingleFloat = false; |
322 | FloatABI = HardFloat; |
323 | DspRev = NoDSP; |
324 | NoOddSpreg = false; |
325 | FPMode = getDefaultFPMode(); |
326 | bool OddSpregGiven = false; |
327 | bool StrictAlign = false; |
328 | bool FpGiven = false; |
329 | |
330 | for (const auto &Feature : Features) { |
331 | if (Feature == "+single-float") |
332 | IsSingleFloat = true; |
333 | else if (Feature == "+soft-float") |
334 | FloatABI = SoftFloat; |
335 | else if (Feature == "+mips16") |
336 | IsMips16 = true; |
337 | else if (Feature == "+micromips") |
338 | IsMicromips = true; |
339 | else if (Feature == "+mips32r6"|| Feature == "+mips64r6") |
340 | HasUnalignedAccess = true; |
341 | // We cannot be sure that the order of strict-align vs mips32r6. |
342 | // Thus we need an extra variable here. |
343 | else if (Feature == "+strict-align") |
344 | StrictAlign = true; |
345 | else if (Feature == "+dsp") |
346 | DspRev = std::max(a: DspRev, b: DSP1); |
347 | else if (Feature == "+dspr2") |
348 | DspRev = std::max(a: DspRev, b: DSP2); |
349 | else if (Feature == "+msa") |
350 | HasMSA = true; |
351 | else if (Feature == "+nomadd4") |
352 | DisableMadd4 = true; |
353 | else if (Feature == "+fp64") { |
354 | FPMode = FP64; |
355 | FpGiven = true; |
356 | } else if (Feature == "-fp64") { |
357 | FPMode = FP32; |
358 | FpGiven = true; |
359 | } else if (Feature == "+fpxx") { |
360 | FPMode = FPXX; |
361 | FpGiven = true; |
362 | } else if (Feature == "+nan2008") |
363 | IsNan2008 = true; |
364 | else if (Feature == "-nan2008") |
365 | IsNan2008 = false; |
366 | else if (Feature == "+abs2008") |
367 | IsAbs2008 = true; |
368 | else if (Feature == "-abs2008") |
369 | IsAbs2008 = false; |
370 | else if (Feature == "+noabicalls") |
371 | IsNoABICalls = true; |
372 | else if (Feature == "+use-indirect-jump-hazard") |
373 | UseIndirectJumpHazard = true; |
374 | else if (Feature == "+nooddspreg") { |
375 | NoOddSpreg = true; |
376 | OddSpregGiven = false; |
377 | } else if (Feature == "-nooddspreg") { |
378 | NoOddSpreg = false; |
379 | OddSpregGiven = true; |
380 | } |
381 | } |
382 | |
383 | if (FPMode == FPXX && !OddSpregGiven) |
384 | NoOddSpreg = true; |
385 | |
386 | if (StrictAlign) |
387 | HasUnalignedAccess = false; |
388 | |
389 | if (HasMSA && !FpGiven) { |
390 | FPMode = FP64; |
391 | Features.push_back(x: "+fp64"); |
392 | } |
393 | |
394 | setDataLayout(); |
395 | |
396 | return true; |
397 | } |
398 | |
399 | int getEHDataRegisterNumber(unsigned RegNo) const override { |
400 | if (RegNo == 0) |
401 | return 4; |
402 | if (RegNo == 1) |
403 | return 5; |
404 | return -1; |
405 | } |
406 | |
407 | bool isCLZForZeroUndef() const override { return false; } |
408 | |
409 | ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { |
410 | static const TargetInfo::GCCRegAlias O32RegAliases[] = { |
411 | {.Aliases: {"at"}, .Register: "$1"}, {.Aliases: { "v0"}, .Register: "$2"}, {.Aliases: { "v1"}, .Register: "$3"}, |
412 | {.Aliases: {"a0"}, .Register: "$4"}, {.Aliases: { "a1"}, .Register: "$5"}, {.Aliases: { "a2"}, .Register: "$6"}, |
413 | {.Aliases: {"a3"}, .Register: "$7"}, {.Aliases: { "t0"}, .Register: "$8"}, {.Aliases: { "t1"}, .Register: "$9"}, |
414 | {.Aliases: {"t2"}, .Register: "$10"}, {.Aliases: { "t3"}, .Register: "$11"}, {.Aliases: { "t4"}, .Register: "$12"}, |
415 | {.Aliases: {"t5"}, .Register: "$13"}, {.Aliases: { "t6"}, .Register: "$14"}, {.Aliases: { "t7"}, .Register: "$15"}, |
416 | {.Aliases: {"s0"}, .Register: "$16"}, {.Aliases: { "s1"}, .Register: "$17"}, {.Aliases: { "s2"}, .Register: "$18"}, |
417 | {.Aliases: {"s3"}, .Register: "$19"}, {.Aliases: { "s4"}, .Register: "$20"}, {.Aliases: { "s5"}, .Register: "$21"}, |
418 | {.Aliases: {"s6"}, .Register: "$22"}, {.Aliases: { "s7"}, .Register: "$23"}, {.Aliases: { "t8"}, .Register: "$24"}, |
419 | {.Aliases: {"t9"}, .Register: "$25"}, {.Aliases: { "k0"}, .Register: "$26"}, {.Aliases: { "k1"}, .Register: "$27"}, |
420 | {.Aliases: {"gp"}, .Register: "$28"}, {.Aliases: { "sp", "$sp"}, .Register: "$29"}, {.Aliases: { "fp", "$fp"}, .Register: "$30"}, |
421 | {.Aliases: {"ra"}, .Register: "$31"} |
422 | }; |
423 | static const TargetInfo::GCCRegAlias NewABIRegAliases[] = { |
424 | {.Aliases: {"at"}, .Register: "$1"}, {.Aliases: { "v0"}, .Register: "$2"}, {.Aliases: { "v1"}, .Register: "$3"}, |
425 | {.Aliases: {"a0"}, .Register: "$4"}, {.Aliases: { "a1"}, .Register: "$5"}, {.Aliases: { "a2"}, .Register: "$6"}, |
426 | {.Aliases: {"a3"}, .Register: "$7"}, {.Aliases: { "a4"}, .Register: "$8"}, {.Aliases: { "a5"}, .Register: "$9"}, |
427 | {.Aliases: {"a6"}, .Register: "$10"}, {.Aliases: { "a7"}, .Register: "$11"}, {.Aliases: { "t0"}, .Register: "$12"}, |
428 | {.Aliases: {"t1"}, .Register: "$13"}, {.Aliases: { "t2"}, .Register: "$14"}, {.Aliases: { "t3"}, .Register: "$15"}, |
429 | {.Aliases: {"s0"}, .Register: "$16"}, {.Aliases: { "s1"}, .Register: "$17"}, {.Aliases: { "s2"}, .Register: "$18"}, |
430 | {.Aliases: {"s3"}, .Register: "$19"}, {.Aliases: { "s4"}, .Register: "$20"}, {.Aliases: { "s5"}, .Register: "$21"}, |
431 | {.Aliases: {"s6"}, .Register: "$22"}, {.Aliases: { "s7"}, .Register: "$23"}, {.Aliases: { "t8"}, .Register: "$24"}, |
432 | {.Aliases: {"t9"}, .Register: "$25"}, {.Aliases: { "k0"}, .Register: "$26"}, {.Aliases: { "k1"}, .Register: "$27"}, |
433 | {.Aliases: {"gp"}, .Register: "$28"}, {.Aliases: { "sp", "$sp"}, .Register: "$29"}, {.Aliases: { "fp", "$fp"}, .Register: "$30"}, |
434 | {.Aliases: {"ra"}, .Register: "$31"} |
435 | }; |
436 | if (ABI == "o32") |
437 | return llvm::ArrayRef(O32RegAliases); |
438 | return llvm::ArrayRef(NewABIRegAliases); |
439 | } |
440 | |
441 | bool hasInt128Type() const override { |
442 | return (ABI == "n32"|| ABI == "n64") || getTargetOpts().ForceEnableInt128; |
443 | } |
444 | |
445 | unsigned getUnwindWordWidth() const override; |
446 | |
447 | bool validateTarget(DiagnosticsEngine &Diags) const override; |
448 | bool hasBitIntType() const override { return true; } |
449 | |
450 | std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override { |
451 | return std::make_pair(x: 32, y: 32); |
452 | } |
453 | }; |
454 | |
455 | class LLVM_LIBRARY_VISIBILITY WindowsMipsTargetInfo |
456 | : public WindowsTargetInfo<MipsTargetInfo> { |
457 | const llvm::Triple Triple; |
458 | |
459 | public: |
460 | WindowsMipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); |
461 | |
462 | void getVisualStudioDefines(const LangOptions &Opts, |
463 | MacroBuilder &Builder) const; |
464 | |
465 | BuiltinVaListKind getBuiltinVaListKind() const override; |
466 | |
467 | CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; |
468 | }; |
469 | |
470 | // Windows MIPS, MS (C++) ABI |
471 | class LLVM_LIBRARY_VISIBILITY MicrosoftMipsTargetInfo |
472 | : public WindowsMipsTargetInfo { |
473 | public: |
474 | MicrosoftMipsTargetInfo(const llvm::Triple &Triple, |
475 | const TargetOptions &Opts); |
476 | |
477 | void getTargetDefines(const LangOptions &Opts, |
478 | MacroBuilder &Builder) const override; |
479 | }; |
480 | |
481 | // MIPS MinGW target |
482 | class LLVM_LIBRARY_VISIBILITY MinGWMipsTargetInfo |
483 | : public WindowsMipsTargetInfo { |
484 | public: |
485 | MinGWMipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); |
486 | |
487 | void getTargetDefines(const LangOptions &Opts, |
488 | MacroBuilder &Builder) const override; |
489 | }; |
490 | } // namespace targets |
491 | } // namespace clang |
492 | |
493 | #endif // LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H |
494 |
Definitions
- MipsTargetInfo
- setDataLayout
- MipsFloatABI
- DspRevEnum
- FPModeEnum
- MipsTargetInfo
- isIEEE754_2008Default
- getDefaultFPMode
- isNan2008
- getABI
- setABI
- setO32ABITypes
- setN32N64ABITypes
- setN64ABITypes
- setN32ABITypes
- setCPU
- getCPU
- initFeatureMap
- getBuiltinVaListKind
- getGCCRegNames
- validateAsmConstraint
- convertConstraint
- getClobbers
- handleTargetFeatures
- getEHDataRegisterNumber
- isCLZForZeroUndef
- getGCCRegAliases
- hasInt128Type
- hasBitIntType
- hardwareInterferenceSizes
- WindowsMipsTargetInfo
- MicrosoftMipsTargetInfo
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more