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