1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "clang/Basic/TargetInfo.h" |
14 | #include "clang/Basic/AddressSpaces.h" |
15 | #include "clang/Basic/CharInfo.h" |
16 | #include "clang/Basic/Diagnostic.h" |
17 | #include "clang/Basic/LangOptions.h" |
18 | #include "llvm/ADT/APFloat.h" |
19 | #include "llvm/ADT/STLExtras.h" |
20 | #include "llvm/Support/ErrorHandling.h" |
21 | #include "llvm/Support/TargetParser.h" |
22 | #include <cstdlib> |
23 | using namespace clang; |
24 | |
25 | static const LangASMap DefaultAddrSpaceMap = {0}; |
26 | |
27 | |
28 | TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { |
29 | |
30 | |
31 | BigEndian = !T.isLittleEndian(); |
32 | TLSSupported = true; |
33 | VLASupported = true; |
34 | NoAsmVariants = false; |
35 | HasLegalHalfType = false; |
36 | HasFloat128 = false; |
37 | HasFloat16 = false; |
38 | PointerWidth = PointerAlign = 32; |
39 | BoolWidth = BoolAlign = 8; |
40 | IntWidth = IntAlign = 32; |
41 | LongWidth = LongAlign = 32; |
42 | LongLongWidth = LongLongAlign = 64; |
43 | |
44 | |
45 | ShortAccumWidth = ShortAccumAlign = 16; |
46 | AccumWidth = AccumAlign = 32; |
47 | LongAccumWidth = LongAccumAlign = 64; |
48 | ShortFractWidth = ShortFractAlign = 8; |
49 | FractWidth = FractAlign = 16; |
50 | LongFractWidth = LongFractAlign = 32; |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | PaddingOnUnsignedFixedPoint = false; |
57 | ShortAccumScale = 7; |
58 | AccumScale = 15; |
59 | LongAccumScale = 31; |
60 | |
61 | SuitableAlign = 64; |
62 | DefaultAlignForAttributeAligned = 128; |
63 | MinGlobalAlign = 0; |
64 | |
65 | |
66 | |
67 | |
68 | if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid()) |
69 | NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0; |
70 | else |
71 | NewAlign = 0; |
72 | HalfWidth = 16; |
73 | HalfAlign = 16; |
74 | FloatWidth = 32; |
75 | FloatAlign = 32; |
76 | DoubleWidth = 64; |
77 | DoubleAlign = 64; |
78 | LongDoubleWidth = 64; |
79 | LongDoubleAlign = 64; |
80 | Float128Align = 128; |
81 | LargeArrayMinWidth = 0; |
82 | LargeArrayAlign = 0; |
83 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; |
84 | MaxVectorAlign = 0; |
85 | MaxTLSAlign = 0; |
86 | SimdDefaultAlign = 0; |
87 | SizeType = UnsignedLong; |
88 | PtrDiffType = SignedLong; |
89 | IntMaxType = SignedLongLong; |
90 | IntPtrType = SignedLong; |
91 | WCharType = SignedInt; |
92 | WIntType = SignedInt; |
93 | Char16Type = UnsignedShort; |
94 | Char32Type = UnsignedInt; |
95 | Int64Type = SignedLongLong; |
96 | SigAtomicType = SignedInt; |
97 | ProcessIDType = SignedInt; |
98 | UseSignedCharForObjCBool = true; |
99 | UseBitFieldTypeAlignment = true; |
100 | UseZeroLengthBitfieldAlignment = false; |
101 | UseExplicitBitFieldAlignment = true; |
102 | ZeroLengthBitfieldBoundary = 0; |
103 | HalfFormat = &llvm::APFloat::IEEEhalf(); |
104 | FloatFormat = &llvm::APFloat::IEEEsingle(); |
105 | DoubleFormat = &llvm::APFloat::IEEEdouble(); |
106 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
107 | Float128Format = &llvm::APFloat::IEEEquad(); |
108 | MCountName = "mcount"; |
109 | RegParmMax = 0; |
110 | SSERegParmMax = 0; |
111 | HasAlignMac68kSupport = false; |
112 | HasBuiltinMSVaList = false; |
113 | IsRenderScriptTarget = false; |
114 | |
115 | |
116 | RealTypeUsesObjCFPRet = 0; |
117 | |
118 | |
119 | ComplexLongDoubleUsesFP2Ret = false; |
120 | |
121 | |
122 | TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment() |
123 | ? TargetCXXABI::Microsoft |
124 | : TargetCXXABI::GenericItanium); |
125 | |
126 | |
127 | AddrSpaceMap = &DefaultAddrSpaceMap; |
128 | UseAddrSpaceMapMangling = false; |
129 | |
130 | |
131 | PlatformName = "unknown"; |
132 | PlatformMinVersion = VersionTuple(); |
133 | } |
134 | |
135 | |
136 | TargetInfo::~TargetInfo() {} |
137 | |
138 | bool |
139 | TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const { |
140 | Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch"; |
141 | return false; |
142 | } |
143 | |
144 | bool |
145 | TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const { |
146 | Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return"; |
147 | return false; |
148 | } |
149 | |
150 | |
151 | |
152 | const char *TargetInfo::getTypeName(IntType T) { |
153 | switch (T) { |
154 | default: llvm_unreachable("not an integer!"); |
155 | case SignedChar: return "signed char"; |
156 | case UnsignedChar: return "unsigned char"; |
157 | case SignedShort: return "short"; |
158 | case UnsignedShort: return "unsigned short"; |
159 | case SignedInt: return "int"; |
160 | case UnsignedInt: return "unsigned int"; |
161 | case SignedLong: return "long int"; |
162 | case UnsignedLong: return "long unsigned int"; |
163 | case SignedLongLong: return "long long int"; |
164 | case UnsignedLongLong: return "long long unsigned int"; |
165 | } |
166 | } |
167 | |
168 | |
169 | |
170 | const char *TargetInfo::getTypeConstantSuffix(IntType T) const { |
171 | switch (T) { |
172 | default: llvm_unreachable("not an integer!"); |
173 | case SignedChar: |
174 | case SignedShort: |
175 | case SignedInt: return ""; |
176 | case SignedLong: return "L"; |
177 | case SignedLongLong: return "LL"; |
178 | case UnsignedChar: |
179 | if (getCharWidth() < getIntWidth()) |
180 | return ""; |
181 | LLVM_FALLTHROUGH; |
182 | case UnsignedShort: |
183 | if (getShortWidth() < getIntWidth()) |
184 | return ""; |
185 | LLVM_FALLTHROUGH; |
186 | case UnsignedInt: return "U"; |
187 | case UnsignedLong: return "UL"; |
188 | case UnsignedLongLong: return "ULL"; |
189 | } |
190 | } |
191 | |
192 | |
193 | |
194 | |
195 | const char *TargetInfo::getTypeFormatModifier(IntType T) { |
196 | switch (T) { |
197 | default: llvm_unreachable("not an integer!"); |
198 | case SignedChar: |
199 | case UnsignedChar: return "hh"; |
200 | case SignedShort: |
201 | case UnsignedShort: return "h"; |
202 | case SignedInt: |
203 | case UnsignedInt: return ""; |
204 | case SignedLong: |
205 | case UnsignedLong: return "l"; |
206 | case SignedLongLong: |
207 | case UnsignedLongLong: return "ll"; |
208 | } |
209 | } |
210 | |
211 | |
212 | |
213 | unsigned TargetInfo::getTypeWidth(IntType T) const { |
214 | switch (T) { |
215 | default: llvm_unreachable("not an integer!"); |
216 | case SignedChar: |
217 | case UnsignedChar: return getCharWidth(); |
218 | case SignedShort: |
219 | case UnsignedShort: return getShortWidth(); |
220 | case SignedInt: |
221 | case UnsignedInt: return getIntWidth(); |
222 | case SignedLong: |
223 | case UnsignedLong: return getLongWidth(); |
224 | case SignedLongLong: |
225 | case UnsignedLongLong: return getLongLongWidth(); |
226 | }; |
227 | } |
228 | |
229 | TargetInfo::IntType TargetInfo::getIntTypeByWidth( |
230 | unsigned BitWidth, bool IsSigned) const { |
231 | if (getCharWidth() == BitWidth) |
232 | return IsSigned ? SignedChar : UnsignedChar; |
233 | if (getShortWidth() == BitWidth) |
234 | return IsSigned ? SignedShort : UnsignedShort; |
235 | if (getIntWidth() == BitWidth) |
236 | return IsSigned ? SignedInt : UnsignedInt; |
237 | if (getLongWidth() == BitWidth) |
238 | return IsSigned ? SignedLong : UnsignedLong; |
239 | if (getLongLongWidth() == BitWidth) |
240 | return IsSigned ? SignedLongLong : UnsignedLongLong; |
241 | return NoInt; |
242 | } |
243 | |
244 | TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth, |
245 | bool IsSigned) const { |
246 | if (getCharWidth() >= BitWidth) |
247 | return IsSigned ? SignedChar : UnsignedChar; |
248 | if (getShortWidth() >= BitWidth) |
249 | return IsSigned ? SignedShort : UnsignedShort; |
250 | if (getIntWidth() >= BitWidth) |
251 | return IsSigned ? SignedInt : UnsignedInt; |
252 | if (getLongWidth() >= BitWidth) |
253 | return IsSigned ? SignedLong : UnsignedLong; |
254 | if (getLongLongWidth() >= BitWidth) |
255 | return IsSigned ? SignedLongLong : UnsignedLongLong; |
256 | return NoInt; |
257 | } |
258 | |
259 | TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const { |
260 | if (getFloatWidth() == BitWidth) |
261 | return Float; |
262 | if (getDoubleWidth() == BitWidth) |
263 | return Double; |
264 | |
265 | switch (BitWidth) { |
266 | case 96: |
267 | if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended()) |
268 | return LongDouble; |
269 | break; |
270 | case 128: |
271 | if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() || |
272 | &getLongDoubleFormat() == &llvm::APFloat::IEEEquad()) |
273 | return LongDouble; |
274 | if (hasFloat128Type()) |
275 | return Float128; |
276 | break; |
277 | } |
278 | |
279 | return NoFloat; |
280 | } |
281 | |
282 | |
283 | |
284 | unsigned TargetInfo::getTypeAlign(IntType T) const { |
285 | switch (T) { |
286 | default: llvm_unreachable("not an integer!"); |
287 | case SignedChar: |
288 | case UnsignedChar: return getCharAlign(); |
289 | case SignedShort: |
290 | case UnsignedShort: return getShortAlign(); |
291 | case SignedInt: |
292 | case UnsignedInt: return getIntAlign(); |
293 | case SignedLong: |
294 | case UnsignedLong: return getLongAlign(); |
295 | case SignedLongLong: |
296 | case UnsignedLongLong: return getLongLongAlign(); |
297 | }; |
298 | } |
299 | |
300 | |
301 | |
302 | bool TargetInfo::isTypeSigned(IntType T) { |
303 | switch (T) { |
304 | default: llvm_unreachable("not an integer!"); |
305 | case SignedChar: |
306 | case SignedShort: |
307 | case SignedInt: |
308 | case SignedLong: |
309 | case SignedLongLong: |
310 | return true; |
311 | case UnsignedChar: |
312 | case UnsignedShort: |
313 | case UnsignedInt: |
314 | case UnsignedLong: |
315 | case UnsignedLongLong: |
316 | return false; |
317 | }; |
318 | } |
319 | |
320 | |
321 | |
322 | |
323 | |
324 | void TargetInfo::adjust(LangOptions &Opts) { |
325 | if (Opts.NoBitFieldTypeAlign) |
326 | UseBitFieldTypeAlignment = false; |
327 | |
328 | switch (Opts.WCharSize) { |
329 | default: llvm_unreachable("invalid wchar_t width"); |
330 | case 0: break; |
331 | case 1: WCharType = Opts.WCharIsSigned ? SignedChar : UnsignedChar; break; |
332 | case 2: WCharType = Opts.WCharIsSigned ? SignedShort : UnsignedShort; break; |
333 | case 4: WCharType = Opts.WCharIsSigned ? SignedInt : UnsignedInt; break; |
334 | } |
335 | |
336 | if (Opts.AlignDouble) { |
337 | DoubleAlign = LongLongAlign = 64; |
338 | LongDoubleAlign = 64; |
339 | } |
340 | |
341 | if (Opts.OpenCL) { |
342 | |
343 | |
344 | |
345 | |
346 | IntWidth = IntAlign = 32; |
347 | LongWidth = LongAlign = 64; |
348 | LongLongWidth = LongLongAlign = 128; |
349 | HalfWidth = HalfAlign = 16; |
350 | FloatWidth = FloatAlign = 32; |
351 | |
352 | |
353 | |
354 | |
355 | if (DoubleWidth != FloatWidth) { |
356 | DoubleWidth = DoubleAlign = 64; |
357 | DoubleFormat = &llvm::APFloat::IEEEdouble(); |
358 | } |
359 | LongDoubleWidth = LongDoubleAlign = 128; |
360 | |
361 | unsigned MaxPointerWidth = getMaxPointerWidth(); |
362 | assert(MaxPointerWidth == 32 || MaxPointerWidth == 64); |
363 | bool Is32BitArch = MaxPointerWidth == 32; |
364 | SizeType = Is32BitArch ? UnsignedInt : UnsignedLong; |
365 | PtrDiffType = Is32BitArch ? SignedInt : SignedLong; |
366 | IntPtrType = Is32BitArch ? SignedInt : SignedLong; |
367 | |
368 | IntMaxType = SignedLongLong; |
369 | Int64Type = SignedLong; |
370 | |
371 | HalfFormat = &llvm::APFloat::IEEEhalf(); |
372 | FloatFormat = &llvm::APFloat::IEEEsingle(); |
373 | LongDoubleFormat = &llvm::APFloat::IEEEquad(); |
374 | } |
375 | |
376 | if (Opts.NewAlignOverride) |
377 | NewAlign = Opts.NewAlignOverride * getCharWidth(); |
378 | |
379 | |
380 | |
381 | PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint; |
382 | CheckFixedPointBits(); |
383 | } |
384 | |
385 | bool TargetInfo::initFeatureMap( |
386 | llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, |
387 | const std::vector<std::string> &FeatureVec) const { |
388 | for (const auto &F : FeatureVec) { |
389 | StringRef Name = F; |
390 | |
391 | bool Enabled = Name[0] == '+'; |
392 | setFeatureEnabled(Features, Name.substr(1), Enabled); |
393 | } |
394 | return true; |
395 | } |
396 | |
397 | TargetInfo::CallingConvKind |
398 | TargetInfo::getCallingConvKind(bool ClangABICompat4) const { |
399 | if (getCXXABI() != TargetCXXABI::Microsoft && |
400 | (ClangABICompat4 || getTriple().getOS() == llvm::Triple::PS4)) |
401 | return CCK_ClangABI4OrPS4; |
402 | return CCK_Default; |
403 | } |
404 | |
405 | LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const { |
406 | switch (TK) { |
407 | case OCLTK_Image: |
408 | case OCLTK_Pipe: |
409 | return LangAS::opencl_global; |
410 | |
411 | case OCLTK_Sampler: |
412 | return LangAS::opencl_constant; |
413 | |
414 | default: |
415 | return LangAS::Default; |
416 | } |
417 | } |
418 | |
419 | |
420 | |
421 | |
422 | static StringRef removeGCCRegisterPrefix(StringRef Name) { |
423 | if (Name[0] == '%' || Name[0] == '#') |
424 | Name = Name.substr(1); |
425 | |
426 | return Name; |
427 | } |
428 | |
429 | |
430 | |
431 | |
432 | bool TargetInfo::isValidClobber(StringRef Name) const { |
433 | return (isValidGCCRegisterName(Name) || |
434 | Name == "memory" || Name == "cc"); |
435 | } |
436 | |
437 | |
438 | |
439 | |
440 | bool TargetInfo::isValidGCCRegisterName(StringRef Name) const { |
441 | if (Name.empty()) |
442 | return false; |
443 | |
444 | |
445 | Name = removeGCCRegisterPrefix(Name); |
446 | if (Name.empty()) |
447 | return false; |
448 | |
449 | ArrayRef<const char *> Names = getGCCRegNames(); |
450 | |
451 | |
452 | if (isDigit(Name[0])) { |
453 | unsigned n; |
454 | if (!Name.getAsInteger(0, n)) |
455 | return n < Names.size(); |
456 | } |
457 | |
458 | |
459 | if (llvm::is_contained(Names, Name)) |
460 | return true; |
461 | |
462 | |
463 | for (const AddlRegName &ARN : getGCCAddlRegNames()) |
464 | for (const char *AN : ARN.Names) { |
465 | if (!AN) |
466 | break; |
467 | |
468 | |
469 | if (AN == Name && ARN.RegNum < Names.size()) |
470 | return true; |
471 | } |
472 | |
473 | |
474 | for (const GCCRegAlias &GRA : getGCCRegAliases()) |
475 | for (const char *A : GRA.Aliases) { |
476 | if (!A) |
477 | break; |
478 | if (A == Name) |
479 | return true; |
480 | } |
481 | |
482 | return false; |
483 | } |
484 | |
485 | StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name, |
486 | bool ReturnCanonical) const { |
487 | (0) . __assert_fail ("isValidGCCRegisterName(Name) && \"Invalid register passed in\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 487, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isValidGCCRegisterName(Name) && "Invalid register passed in"); |
488 | |
489 | |
490 | Name = removeGCCRegisterPrefix(Name); |
491 | |
492 | ArrayRef<const char *> Names = getGCCRegNames(); |
493 | |
494 | |
495 | if (isDigit(Name[0])) { |
496 | unsigned n; |
497 | if (!Name.getAsInteger(0, n)) { |
498 | (0) . __assert_fail ("n < Names.size() && \"Out of bounds register number!\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 498, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(n < Names.size() && "Out of bounds register number!"); |
499 | return Names[n]; |
500 | } |
501 | } |
502 | |
503 | |
504 | for (const AddlRegName &ARN : getGCCAddlRegNames()) |
505 | for (const char *AN : ARN.Names) { |
506 | if (!AN) |
507 | break; |
508 | |
509 | |
510 | if (AN == Name && ARN.RegNum < Names.size()) |
511 | return ReturnCanonical ? Names[ARN.RegNum] : Name; |
512 | } |
513 | |
514 | |
515 | for (const GCCRegAlias &RA : getGCCRegAliases()) |
516 | for (const char *A : RA.Aliases) { |
517 | if (!A) |
518 | break; |
519 | if (A == Name) |
520 | return RA.Register; |
521 | } |
522 | |
523 | return Name; |
524 | } |
525 | |
526 | bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const { |
527 | const char *Name = Info.getConstraintStr().c_str(); |
528 | |
529 | if (*Name != '=' && *Name != '+') |
530 | return false; |
531 | |
532 | if (*Name == '+') |
533 | Info.setIsReadWrite(); |
534 | |
535 | Name++; |
536 | while (*Name) { |
537 | switch (*Name) { |
538 | default: |
539 | if (!validateAsmConstraint(Name, Info)) { |
540 | |
541 | |
542 | |
543 | return false; |
544 | } |
545 | break; |
546 | case '&': |
547 | Info.setEarlyClobber(); |
548 | break; |
549 | case '%': |
550 | |
551 | break; |
552 | case 'r': |
553 | Info.setAllowsRegister(); |
554 | break; |
555 | case 'm': |
556 | case 'o': |
557 | case 'V': |
558 | case '<': |
559 | case '>': |
560 | Info.setAllowsMemory(); |
561 | break; |
562 | case 'g': |
563 | case 'X': |
564 | Info.setAllowsRegister(); |
565 | Info.setAllowsMemory(); |
566 | break; |
567 | case ',': |
568 | |
569 | if (Name[1] == '=' || Name[1] == '+') |
570 | Name++; |
571 | break; |
572 | case '#': |
573 | while (Name[1] && Name[1] != ',') |
574 | Name++; |
575 | break; |
576 | case '?': |
577 | case '!': |
578 | case '*': |
579 | case 'i': |
580 | |
581 | case 'n': |
582 | case 'E': |
583 | case 'F': |
584 | break; |
585 | } |
586 | |
587 | Name++; |
588 | } |
589 | |
590 | |
591 | |
592 | if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister()) |
593 | return false; |
594 | |
595 | |
596 | |
597 | return Info.allowsMemory() || Info.allowsRegister(); |
598 | } |
599 | |
600 | bool TargetInfo::resolveSymbolicName(const char *&Name, |
601 | ArrayRef<ConstraintInfo> OutputConstraints, |
602 | unsigned &Index) const { |
603 | (0) . __assert_fail ("*Name == '[' && \"Symbolic name did not start with '['\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 603, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(*Name == '[' && "Symbolic name did not start with '['"); |
604 | Name++; |
605 | const char *Start = Name; |
606 | while (*Name && *Name != ']') |
607 | Name++; |
608 | |
609 | if (!*Name) { |
610 | |
611 | return false; |
612 | } |
613 | |
614 | std::string SymbolicName(Start, Name - Start); |
615 | |
616 | for (Index = 0; Index != OutputConstraints.size(); ++Index) |
617 | if (SymbolicName == OutputConstraints[Index].getName()) |
618 | return true; |
619 | |
620 | return false; |
621 | } |
622 | |
623 | bool TargetInfo::validateInputConstraint( |
624 | MutableArrayRef<ConstraintInfo> OutputConstraints, |
625 | ConstraintInfo &Info) const { |
626 | const char *Name = Info.ConstraintStr.c_str(); |
627 | |
628 | if (!*Name) |
629 | return false; |
630 | |
631 | while (*Name) { |
632 | switch (*Name) { |
633 | default: |
634 | |
635 | if (*Name >= '0' && *Name <= '9') { |
636 | const char *DigitStart = Name; |
637 | while (Name[1] >= '0' && Name[1] <= '9') |
638 | Name++; |
639 | const char *DigitEnd = Name; |
640 | unsigned i; |
641 | if (StringRef(DigitStart, DigitEnd - DigitStart + 1) |
642 | .getAsInteger(10, i)) |
643 | return false; |
644 | |
645 | |
646 | if (i >= OutputConstraints.size()) return false; |
647 | |
648 | |
649 | if (OutputConstraints[i].isReadWrite()) |
650 | return false; |
651 | |
652 | |
653 | |
654 | if (Info.hasTiedOperand() && Info.getTiedOperand() != i) |
655 | return false; |
656 | |
657 | |
658 | |
659 | Info.setTiedOperand(i, OutputConstraints[i]); |
660 | } else if (!validateAsmConstraint(Name, Info)) { |
661 | |
662 | |
663 | |
664 | return false; |
665 | } |
666 | break; |
667 | case '[': { |
668 | unsigned Index = 0; |
669 | if (!resolveSymbolicName(Name, OutputConstraints, Index)) |
670 | return false; |
671 | |
672 | |
673 | |
674 | if (Info.hasTiedOperand() && Info.getTiedOperand() != Index) |
675 | return false; |
676 | |
677 | |
678 | if (OutputConstraints[Index].isReadWrite()) |
679 | return false; |
680 | |
681 | Info.setTiedOperand(Index, OutputConstraints[Index]); |
682 | break; |
683 | } |
684 | case '%': |
685 | |
686 | break; |
687 | case 'i': |
688 | break; |
689 | case 'n': |
690 | Info.setRequiresImmediate(); |
691 | break; |
692 | case 'I': |
693 | case 'J': |
694 | case 'K': |
695 | case 'L': |
696 | case 'M': |
697 | case 'N': |
698 | case 'O': |
699 | case 'P': |
700 | if (!validateAsmConstraint(Name, Info)) |
701 | return false; |
702 | break; |
703 | case 'r': |
704 | Info.setAllowsRegister(); |
705 | break; |
706 | case 'm': |
707 | case 'o': |
708 | case 'V': |
709 | case '<': |
710 | case '>': |
711 | Info.setAllowsMemory(); |
712 | break; |
713 | case 'g': |
714 | case 'X': |
715 | Info.setAllowsRegister(); |
716 | Info.setAllowsMemory(); |
717 | break; |
718 | case 'E': |
719 | case 'F': |
720 | case 'p': |
721 | break; |
722 | case ',': |
723 | break; |
724 | case '#': |
725 | while (Name[1] && Name[1] != ',') |
726 | Name++; |
727 | break; |
728 | case '?': |
729 | case '!': |
730 | case '*': |
731 | break; |
732 | } |
733 | |
734 | Name++; |
735 | } |
736 | |
737 | return true; |
738 | } |
739 | |
740 | void TargetInfo::CheckFixedPointBits() const { |
741 | |
742 | |
743 | assert(ShortAccumScale + getShortAccumIBits() + 1 <= ShortAccumWidth); |
744 | assert(AccumScale + getAccumIBits() + 1 <= AccumWidth); |
745 | assert(LongAccumScale + getLongAccumIBits() + 1 <= LongAccumWidth); |
746 | assert(getUnsignedShortAccumScale() + getUnsignedShortAccumIBits() <= |
747 | ShortAccumWidth); |
748 | assert(getUnsignedAccumScale() + getUnsignedAccumIBits() <= AccumWidth); |
749 | assert(getUnsignedLongAccumScale() + getUnsignedLongAccumIBits() <= |
750 | LongAccumWidth); |
751 | |
752 | assert(getShortFractScale() + 1 <= ShortFractWidth); |
753 | assert(getFractScale() + 1 <= FractWidth); |
754 | assert(getLongFractScale() + 1 <= LongFractWidth); |
755 | assert(getUnsignedShortFractScale() <= ShortFractWidth); |
756 | assert(getUnsignedFractScale() <= FractWidth); |
757 | assert(getUnsignedLongFractScale() <= LongFractWidth); |
758 | |
759 | |
760 | |
761 | assert(getShortFractScale() == getUnsignedShortFractScale() || |
762 | getShortFractScale() == getUnsignedShortFractScale() - 1); |
763 | assert(getFractScale() == getUnsignedFractScale() || |
764 | getFractScale() == getUnsignedFractScale() - 1); |
765 | assert(getLongFractScale() == getUnsignedLongFractScale() || |
766 | getLongFractScale() == getUnsignedLongFractScale() - 1); |
767 | |
768 | |
769 | |
770 | |
771 | |
772 | |
773 | |
774 | |
775 | = getFractScale() && getFractScale() >= getShortFractScale()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 776, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getLongFractScale() >= getFractScale() && |
776 | = getFractScale() && getFractScale() >= getShortFractScale()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 776, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> getFractScale() >= getShortFractScale()); |
777 | = getUnsignedFractScale() && getUnsignedFractScale() >= getUnsignedShortFractScale()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 778, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getUnsignedLongFractScale() >= getUnsignedFractScale() && |
778 | = getUnsignedFractScale() && getUnsignedFractScale() >= getUnsignedShortFractScale()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 778, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> getUnsignedFractScale() >= getUnsignedShortFractScale()); |
779 | = AccumScale && AccumScale >= ShortAccumScale", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 779, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LongAccumScale >= AccumScale && AccumScale >= ShortAccumScale); |
780 | = getUnsignedAccumScale() && getUnsignedAccumScale() >= getUnsignedShortAccumScale()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 781, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getUnsignedLongAccumScale() >= getUnsignedAccumScale() && |
781 | = getUnsignedAccumScale() && getUnsignedAccumScale() >= getUnsignedShortAccumScale()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 781, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> getUnsignedAccumScale() >= getUnsignedShortAccumScale()); |
782 | |
783 | |
784 | |
785 | |
786 | |
787 | |
788 | = getAccumIBits() && getAccumIBits() >= getShortAccumIBits()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 789, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getLongAccumIBits() >= getAccumIBits() && |
789 | = getAccumIBits() && getAccumIBits() >= getShortAccumIBits()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 789, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> getAccumIBits() >= getShortAccumIBits()); |
790 | = getUnsignedAccumIBits() && getUnsignedAccumIBits() >= getUnsignedShortAccumIBits()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 791, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getUnsignedLongAccumIBits() >= getUnsignedAccumIBits() && |
791 | = getUnsignedAccumIBits() && getUnsignedAccumIBits() >= getUnsignedShortAccumIBits()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 791, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> getUnsignedAccumIBits() >= getUnsignedShortAccumIBits()); |
792 | |
793 | |
794 | |
795 | = getUnsignedShortAccumIBits()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 795, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getShortAccumIBits() >= getUnsignedShortAccumIBits()); |
796 | = getUnsignedAccumIBits()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 796, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getAccumIBits() >= getUnsignedAccumIBits()); |
797 | = getUnsignedLongAccumIBits()", "/home/seafit/code_projects/clang_source/clang/lib/Basic/TargetInfo.cpp", 797, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getLongAccumIBits() >= getUnsignedLongAccumIBits()); |
798 | } |
799 | |
800 | void TargetInfo::copyAuxTarget(const TargetInfo *Aux) { |
801 | auto *Target = static_cast<TransferrableTargetInfo*>(this); |
802 | auto *Src = static_cast<const TransferrableTargetInfo*>(Aux); |
803 | *Target = *Src; |
804 | } |
805 | |