clang 22.0.0git
TargetInfo.cpp
Go to the documentation of this file.
1//===--- TargetInfo.cpp - Information about Target machine ----------------===//
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 implements the TargetInfo interface.
10//
11//===----------------------------------------------------------------------===//
12
19#include "llvm/ADT/APFloat.h"
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/StringExtras.h"
22#include "llvm/Support/ErrorHandling.h"
23#include "llvm/TargetParser/TargetParser.h"
24#include <cstdlib>
25using namespace clang;
26
27static const LangASMap DefaultAddrSpaceMap = {0};
28// The fake address space map must have a distinct entry for each
29// language-specific address space.
31 0, // Default
32 1, // opencl_global
33 3, // opencl_local
34 2, // opencl_constant
35 0, // opencl_private
36 4, // opencl_generic
37 5, // opencl_global_device
38 6, // opencl_global_host
39 7, // cuda_device
40 8, // cuda_constant
41 9, // cuda_shared
42 1, // sycl_global
43 5, // sycl_global_device
44 6, // sycl_global_host
45 3, // sycl_local
46 0, // sycl_private
47 10, // ptr32_sptr
48 11, // ptr32_uptr
49 12, // ptr64
50 13, // hlsl_groupshared
51 14, // hlsl_constant
52 15, // hlsl_private
53 16, // hlsl_device
54 17, // hlsl_input
55 20, // wasm_funcref
56};
57
58// TargetInfo Constructor.
59TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
60 // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or
61 // SPARC. These should be overridden by concrete targets as needed.
62 HasMustTail = true;
63 BigEndian = !T.isLittleEndian();
64 TLSSupported = true;
65 VLASupported = true;
66 NoAsmVariants = false;
67 HasFastHalfType = false;
68 HalfArgsAndReturns = false;
69 HasFloat128 = false;
70 HasIbm128 = false;
71 HasFloat16 = false;
72 HasBFloat16 = false;
73 HasFullBFloat16 = false;
74 HasLongDouble = true;
75 HasFPReturn = true;
76 HasStrictFP = false;
78 BoolWidth = BoolAlign = 8;
80 IntWidth = IntAlign = 32;
81 LongWidth = LongAlign = 32;
83 Int128Align = 128;
84
85 // Fixed point default bit widths
92
93 // Fixed point default integral and fractional bit sizes
94 // We give the _Accum 1 fewer fractional bits than their corresponding _Fract
95 // types by default to have the same number of fractional bits between _Accum
96 // and _Fract types.
99 AccumScale = 15;
100 LongAccumScale = 31;
101
102 SuitableAlign = 64;
104 MinGlobalAlign = 0;
105 // From the glibc documentation, on GNU systems, malloc guarantees 16-byte
106 // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See
107 // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html.
108 // This alignment guarantee also applies to Windows and Android. On Darwin
109 // and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems.
110 if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() ||
111 T.isOHOSFamily())
112 NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;
113 else if (T.isOSDarwin() || T.isOSOpenBSD())
114 NewAlign = 128;
115 else
116 NewAlign = 0; // Infer from basic type alignment.
117 HalfWidth = 16;
118 HalfAlign = 16;
119 FloatWidth = 32;
120 FloatAlign = 32;
121 DoubleWidth = 64;
122 DoubleAlign = 64;
123 LongDoubleWidth = 64;
124 LongDoubleAlign = 64;
125 Float128Align = 128;
126 Ibm128Align = 128;
128 LargeArrayAlign = 0;
130 MaxVectorAlign = 0;
131 MaxTLSAlign = 0;
152 HalfFormat = &llvm::APFloat::IEEEhalf();
153 FloatFormat = &llvm::APFloat::IEEEsingle();
154 DoubleFormat = &llvm::APFloat::IEEEdouble();
155 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
156 Float128Format = &llvm::APFloat::IEEEquad();
157 Ibm128Format = &llvm::APFloat::PPCDoubleDouble();
158 MCountName = "mcount";
159 UserLabelPrefix = "_";
160 RegParmMax = 0;
161 SSERegParmMax = 0;
162 HasAlignMac68kSupport = false;
163 HasBuiltinMSVaList = false;
164 HasAArch64ACLETypes = false;
165 HasRISCVVTypes = false;
167 HasUnalignedAccess = false;
169
170 // Default to no types using fpret.
172
173 // Default to not using fp2ret for __Complex long double
175
176 // Set the C++ ABI based on the triple.
177 TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment() || Triple.isUEFI()
178 ? TargetCXXABI::Microsoft
179 : TargetCXXABI::GenericItanium);
180
181 HasMicrosoftRecordLayout = TheCXXABI.isMicrosoft();
182
183 // Default to an empty address space map.
186
187 // Default to an unknown platform name.
188 PlatformName = "unknown";
189 PlatformMinVersion = VersionTuple();
190
192
193 MaxBitIntWidth.reset();
194}
195
196// Out of line virtual dtor for TargetInfo.
198
199void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) {
200 DataLayoutString = DL.str();
201 UserLabelPrefix = ULP;
202}
203
204bool
206 Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";
207 return false;
208}
209
211 // if this hook is called, the target should override it to return a
212 // non-default scheme
213 llvm::report_fatal_error("not implemented");
214}
215
217 const CFBranchLabelSchemeKind Scheme, DiagnosticsEngine &Diags) const {
219 Diags.Report(diag::err_opt_not_valid_on_target)
220 << (Twine("mcf-branch-label-scheme=") +
222 .str();
223 return false;
224}
225
226bool
228 Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return";
229 return false;
230}
231
232/// getTypeName - Return the user string for the specified integer type enum.
233/// For example, SignedShort -> "short".
235 switch (T) {
236 default: llvm_unreachable("not an integer!");
237 case SignedChar: return "signed char";
238 case UnsignedChar: return "unsigned char";
239 case SignedShort: return "short";
240 case UnsignedShort: return "unsigned short";
241 case SignedInt: return "int";
242 case UnsignedInt: return "unsigned int";
243 case SignedLong: return "long int";
244 case UnsignedLong: return "long unsigned int";
245 case SignedLongLong: return "long long int";
246 case UnsignedLongLong: return "long long unsigned int";
247 }
248}
249
250/// getTypeConstantSuffix - Return the constant suffix for the specified
251/// integer type enum. For example, SignedLong -> "L".
253 switch (T) {
254 default: llvm_unreachable("not an integer!");
255 case SignedChar:
256 case SignedShort:
257 case SignedInt: return "";
258 case SignedLong: return "L";
259 case SignedLongLong: return "LL";
260 case UnsignedChar:
261 if (getCharWidth() < getIntWidth())
262 return "";
263 [[fallthrough]];
264 case UnsignedShort:
265 if (getShortWidth() < getIntWidth())
266 return "";
267 [[fallthrough]];
268 case UnsignedInt: return "U";
269 case UnsignedLong: return "UL";
270 case UnsignedLongLong: return "ULL";
271 }
272}
273
274/// getTypeFormatModifier - Return the printf format modifier for the
275/// specified integer type enum. For example, SignedLong -> "l".
276
278 switch (T) {
279 default: llvm_unreachable("not an integer!");
280 case SignedChar:
281 case UnsignedChar: return "hh";
282 case SignedShort:
283 case UnsignedShort: return "h";
284 case SignedInt:
285 case UnsignedInt: return "";
286 case SignedLong:
287 case UnsignedLong: return "l";
288 case SignedLongLong:
289 case UnsignedLongLong: return "ll";
290 }
291}
292
293/// getTypeWidth - Return the width (in bits) of the specified integer type
294/// enum. For example, SignedInt -> getIntWidth().
296 switch (T) {
297 default: llvm_unreachable("not an integer!");
298 case SignedChar:
299 case UnsignedChar: return getCharWidth();
300 case SignedShort:
301 case UnsignedShort: return getShortWidth();
302 case SignedInt:
303 case UnsignedInt: return getIntWidth();
304 case SignedLong:
305 case UnsignedLong: return getLongWidth();
306 case SignedLongLong:
307 case UnsignedLongLong: return getLongLongWidth();
308 };
309}
310
312 unsigned BitWidth, bool IsSigned) const {
313 if (getCharWidth() == BitWidth)
314 return IsSigned ? SignedChar : UnsignedChar;
315 if (getShortWidth() == BitWidth)
316 return IsSigned ? SignedShort : UnsignedShort;
317 if (getIntWidth() == BitWidth)
318 return IsSigned ? SignedInt : UnsignedInt;
319 if (getLongWidth() == BitWidth)
320 return IsSigned ? SignedLong : UnsignedLong;
321 if (getLongLongWidth() == BitWidth)
322 return IsSigned ? SignedLongLong : UnsignedLongLong;
323 return NoInt;
324}
325
327 bool IsSigned) const {
328 if (getCharWidth() >= BitWidth)
329 return IsSigned ? SignedChar : UnsignedChar;
330 if (getShortWidth() >= BitWidth)
331 return IsSigned ? SignedShort : UnsignedShort;
332 if (getIntWidth() >= BitWidth)
333 return IsSigned ? SignedInt : UnsignedInt;
334 if (getLongWidth() >= BitWidth)
335 return IsSigned ? SignedLong : UnsignedLong;
336 if (getLongLongWidth() >= BitWidth)
337 return IsSigned ? SignedLongLong : UnsignedLongLong;
338 return NoInt;
339}
340
342 FloatModeKind ExplicitType) const {
343 if (getHalfWidth() == BitWidth)
344 return FloatModeKind::Half;
345 if (getFloatWidth() == BitWidth)
347 if (getDoubleWidth() == BitWidth)
349
350 switch (BitWidth) {
351 case 96:
352 if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended())
354 break;
355 case 128:
356 // The caller explicitly asked for an IEEE compliant type but we still
357 // have to check if the target supports it.
358 if (ExplicitType == FloatModeKind::Float128)
361 if (ExplicitType == FloatModeKind::Ibm128)
364 if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() ||
365 &getLongDoubleFormat() == &llvm::APFloat::IEEEquad())
367 if (hasFloat128Type())
369 break;
370 }
371
373}
374
375/// getTypeAlign - Return the alignment (in bits) of the specified integer type
376/// enum. For example, SignedInt -> getIntAlign().
378 switch (T) {
379 default: llvm_unreachable("not an integer!");
380 case SignedChar:
381 case UnsignedChar: return getCharAlign();
382 case SignedShort:
383 case UnsignedShort: return getShortAlign();
384 case SignedInt:
385 case UnsignedInt: return getIntAlign();
386 case SignedLong:
387 case UnsignedLong: return getLongAlign();
388 case SignedLongLong:
389 case UnsignedLongLong: return getLongLongAlign();
390 };
391}
392
393/// isTypeSigned - Return whether an integer types is signed. Returns true if
394/// the type is signed; false otherwise.
396 switch (T) {
397 default: llvm_unreachable("not an integer!");
398 case SignedChar:
399 case SignedShort:
400 case SignedInt:
401 case SignedLong:
402 case SignedLongLong:
403 return true;
404 case UnsignedChar:
405 case UnsignedShort:
406 case UnsignedInt:
407 case UnsignedLong:
408 case UnsignedLongLong:
409 return false;
410 };
411}
412
413/// adjust - Set forced language options.
414/// Apply changes to the target information with respect to certain
415/// language options which change the target configuration and adjust
416/// the language based on the target options where applicable.
418 const TargetInfo *Aux) {
419 if (Opts.NoBitFieldTypeAlign)
421
422 switch (Opts.WCharSize) {
423 default: llvm_unreachable("invalid wchar_t width");
424 case 0: break;
425 case 1: WCharType = Opts.WCharIsSigned ? SignedChar : UnsignedChar; break;
426 case 2: WCharType = Opts.WCharIsSigned ? SignedShort : UnsignedShort; break;
427 case 4: WCharType = Opts.WCharIsSigned ? SignedInt : UnsignedInt; break;
428 }
429
430 if (Opts.AlignDouble) {
432 LongDoubleAlign = 64;
433 }
434
435 // HLSL explicitly defines the sizes and formats of some data types, and we
436 // need to conform to those regardless of what architecture you are targeting.
437 if (Opts.HLSL) {
438 BoolWidth = BoolAlign = 32;
439 LongWidth = LongAlign = 64;
440 if (!Opts.NativeHalfType) {
441 HalfFormat = &llvm::APFloat::IEEEsingle();
442 HalfWidth = HalfAlign = 32;
443 }
444 }
445
446 if (Opts.OpenCL) {
447 // OpenCL C requires specific widths for types, irrespective of
448 // what these normally are for the target.
449 // We also define long long and long double here, although the
450 // OpenCL standard only mentions these as "reserved".
451 ShortWidth = ShortAlign = 16;
452 IntWidth = IntAlign = 32;
453 LongWidth = LongAlign = 64;
455 HalfWidth = HalfAlign = 16;
456 FloatWidth = FloatAlign = 32;
457
458 // Embedded 32-bit targets (OpenCL EP) might have double C type
459 // defined as float. Let's not override this as it might lead
460 // to generating illegal code that uses 64bit doubles.
461 if (DoubleWidth != FloatWidth) {
463 DoubleFormat = &llvm::APFloat::IEEEdouble();
464 }
466
467 unsigned MaxPointerWidth = getMaxPointerWidth();
468 assert(MaxPointerWidth == 32 || MaxPointerWidth == 64);
469 bool Is32BitArch = MaxPointerWidth == 32;
470 SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;
471 PtrDiffType = Is32BitArch ? SignedInt : SignedLong;
472 IntPtrType = Is32BitArch ? SignedInt : SignedLong;
473
476
477 HalfFormat = &llvm::APFloat::IEEEhalf();
478 FloatFormat = &llvm::APFloat::IEEEsingle();
479 LongDoubleFormat = &llvm::APFloat::IEEEquad();
480
481 // OpenCL C v3.0 s6.7.5 - The generic address space requires support for
482 // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space
483 // feature
484 // OpenCL C v3.0 s6.2.1 - OpenCL pipes require support of OpenCL C 2.0
485 // or later and __opencl_c_pipes feature
486 // FIXME: These language options are also defined in setLangDefaults()
487 // for OpenCL C 2.0 but with no access to target capabilities. Target
488 // should be immutable once created and thus these language options need
489 // to be defined only once.
490 if (Opts.getOpenCLCompatibleVersion() == 300) {
491 const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts();
492 Opts.OpenCLGenericAddressSpace = hasFeatureEnabled(
493 OpenCLFeaturesMap, "__opencl_c_generic_address_space");
494 Opts.OpenCLPipes =
495 hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes");
496 Opts.Blocks =
497 hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_device_enqueue");
498 }
499 }
500
501 if (Opts.DoubleSize) {
502 if (Opts.DoubleSize == 32) {
503 DoubleWidth = 32;
504 LongDoubleWidth = 32;
505 DoubleFormat = &llvm::APFloat::IEEEsingle();
506 LongDoubleFormat = &llvm::APFloat::IEEEsingle();
507 } else if (Opts.DoubleSize == 64) {
508 DoubleWidth = 64;
509 LongDoubleWidth = 64;
510 DoubleFormat = &llvm::APFloat::IEEEdouble();
511 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
512 }
513 }
514
515 if (Opts.LongDoubleSize) {
516 if (Opts.LongDoubleSize == DoubleWidth) {
520 } else if (Opts.LongDoubleSize == 128) {
522 LongDoubleFormat = &llvm::APFloat::IEEEquad();
523 } else if (Opts.LongDoubleSize == 80) {
524 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
525 if (getTriple().isWindowsMSVCEnvironment()) {
526 LongDoubleWidth = 128;
527 LongDoubleAlign = 128;
528 } else { // Linux
529 if (getTriple().getArch() == llvm::Triple::x86) {
530 LongDoubleWidth = 96;
531 LongDoubleAlign = 32;
532 } else {
533 LongDoubleWidth = 128;
534 LongDoubleAlign = 128;
535 }
536 }
537 }
538 }
539
540 if (Opts.NewAlignOverride)
541 NewAlign = Opts.NewAlignOverride * getCharWidth();
542
543 // Each unsigned fixed point type has the same number of fractional bits as
544 // its corresponding signed type.
545 PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint;
546 CheckFixedPointBits();
547
548 if (Opts.ProtectParens && !checkArithmeticFenceSupported()) {
549 Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens";
550 Opts.ProtectParens = false;
551 }
552
553 if (Opts.MaxBitIntWidth)
554 MaxBitIntWidth = static_cast<unsigned>(Opts.MaxBitIntWidth);
555
556 if (Opts.FakeAddressSpaceMap)
558
559 // Check if it's CUDA device compilation; ensure layout consistency with host.
560 if (Opts.CUDA && Opts.CUDAIsDevice && Aux && !HasMicrosoftRecordLayout)
562}
563
565 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
566 const std::vector<std::string> &FeatureVec) const {
567 for (StringRef Name : FeatureVec) {
568 if (Name.empty())
569 continue;
570 // Apply the feature via the target.
571 if (Name[0] != '+' && Name[0] != '-')
572 Diags.Report(diag::warn_fe_backend_invalid_feature_flag) << Name;
573 else
574 setFeatureEnabled(Features, Name.substr(1), Name[0] == '+');
575 }
576 return true;
577}
578
581 if (Features == "default")
582 return Ret;
583 SmallVector<StringRef, 1> AttrFeatures;
584 Features.split(AttrFeatures, ",");
585
586 // Grab the various features and prepend a "+" to turn on the feature to
587 // the backend and add them to our existing set of features.
588 for (auto &Feature : AttrFeatures) {
589 // Go ahead and trim whitespace rather than either erroring or
590 // accepting it weirdly.
591 Feature = Feature.trim();
592
593 // TODO: Support the fpmath option. It will require checking
594 // overall feature validity for the function with the rest of the
595 // attributes on the function.
596 if (Feature.starts_with("fpmath="))
597 continue;
598
599 if (Feature.starts_with("branch-protection=")) {
600 Ret.BranchProtection = Feature.split('=').second.trim();
601 continue;
602 }
603
604 // While we're here iterating check for a different target cpu.
605 if (Feature.starts_with("arch=")) {
606 if (!Ret.CPU.empty())
607 Ret.Duplicate = "arch=";
608 else
609 Ret.CPU = Feature.split("=").second.trim();
610 } else if (Feature.starts_with("tune=")) {
611 if (!Ret.Tune.empty())
612 Ret.Duplicate = "tune=";
613 else
614 Ret.Tune = Feature.split("=").second.trim();
615 } else if (Feature.starts_with("no-"))
616 Ret.Features.push_back("-" + Feature.split("-").second.str());
617 else
618 Ret.Features.push_back("+" + Feature.str());
619 }
620 return Ret;
621}
622
624TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
625 if (getCXXABI() != TargetCXXABI::Microsoft &&
626 (ClangABICompat4 || getTriple().isPS4()))
627 return CCK_ClangABI4OrPS4;
628 return CCK_Default;
629}
630
632 const LangOptions &LangOpts) const {
633 if (getCXXABI() == TargetCXXABI::Microsoft &&
634 LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver21)
635 return true;
636 return false;
637}
638
640 return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15;
641}
642
644 auto &Opts = getSupportedOpenCLOpts();
645 if (!hasFeatureEnabled(Opts, "cl_khr_fp64") ||
646 !hasFeatureEnabled(Opts, "__opencl_c_fp64")) {
647 setFeatureEnabled(Opts, "__opencl_c_ext_fp64_global_atomic_add", false);
648 setFeatureEnabled(Opts, "__opencl_c_ext_fp64_local_atomic_add", false);
649 setFeatureEnabled(Opts, "__opencl_c_ext_fp64_global_atomic_min_max", false);
650 setFeatureEnabled(Opts, "__opencl_c_ext_fp64_local_atomic_min_max", false);
651 }
652}
653
655 switch (TK) {
656 case OCLTK_Image:
657 case OCLTK_Pipe:
659
660 case OCLTK_Sampler:
662
663 default:
664 return LangAS::Default;
665 }
666}
667
668//===----------------------------------------------------------------------===//
669
670
671static StringRef removeGCCRegisterPrefix(StringRef Name) {
672 if (Name[0] == '%' || Name[0] == '#')
673 Name = Name.substr(1);
674
675 return Name;
676}
677
678/// isValidClobber - Returns whether the passed in string is
679/// a valid clobber in an inline asm statement. This is used by
680/// Sema.
681bool TargetInfo::isValidClobber(StringRef Name) const {
682 return (isValidGCCRegisterName(Name) || Name == "memory" || Name == "cc" ||
683 Name == "unwind");
684}
685
686/// isValidGCCRegisterName - Returns whether the passed in string
687/// is a valid register name according to GCC. This is used by Sema for
688/// inline asm statements.
689bool TargetInfo::isValidGCCRegisterName(StringRef Name) const {
690 if (Name.empty())
691 return false;
692
693 // Get rid of any register prefix.
694 Name = removeGCCRegisterPrefix(Name);
695 if (Name.empty())
696 return false;
697
699
700 // If we have a number it maps to an entry in the register name array.
701 if (isDigit(Name[0])) {
702 unsigned n;
703 if (!Name.getAsInteger(0, n))
704 return n < Names.size();
705 }
706
707 // Check register names.
708 if (llvm::is_contained(Names, Name))
709 return true;
710
711 // Check any additional names that we have.
712 for (const AddlRegName &ARN : getGCCAddlRegNames())
713 for (const char *AN : ARN.Names) {
714 if (!AN)
715 break;
716 // Make sure the register that the additional name is for is within
717 // the bounds of the register names from above.
718 if (AN == Name && ARN.RegNum < Names.size())
719 return true;
720 }
721
722 // Now check aliases.
723 for (const GCCRegAlias &GRA : getGCCRegAliases())
724 for (const char *A : GRA.Aliases) {
725 if (!A)
726 break;
727 if (A == Name)
728 return true;
729 }
730
731 return false;
732}
733
735 bool ReturnCanonical) const {
736 assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
737
738 // Get rid of any register prefix.
739 Name = removeGCCRegisterPrefix(Name);
740
742
743 // First, check if we have a number.
744 if (isDigit(Name[0])) {
745 unsigned n;
746 if (!Name.getAsInteger(0, n)) {
747 assert(n < Names.size() && "Out of bounds register number!");
748 return Names[n];
749 }
750 }
751
752 // Check any additional names that we have.
753 for (const AddlRegName &ARN : getGCCAddlRegNames())
754 for (const char *AN : ARN.Names) {
755 if (!AN)
756 break;
757 // Make sure the register that the additional name is for is within
758 // the bounds of the register names from above.
759 if (AN == Name && ARN.RegNum < Names.size())
760 return ReturnCanonical ? Names[ARN.RegNum] : Name;
761 }
762
763 // Now check aliases.
764 for (const GCCRegAlias &RA : getGCCRegAliases())
765 for (const char *A : RA.Aliases) {
766 if (!A)
767 break;
768 if (A == Name)
769 return RA.Register;
770 }
771
772 return Name;
773}
774
776 const char *Name = Info.getConstraintStr().c_str();
777 // An output constraint must start with '=' or '+'
778 if (*Name != '=' && *Name != '+')
779 return false;
780
781 if (*Name == '+')
782 Info.setIsReadWrite();
783
784 Name++;
785 while (*Name) {
786 switch (*Name) {
787 default:
788 if (!validateAsmConstraint(Name, Info)) {
789 // FIXME: We temporarily return false
790 // so we can add more constraints as we hit it.
791 // Eventually, an unknown constraint should just be treated as 'g'.
792 return false;
793 }
794 break;
795 case '&': // early clobber.
796 Info.setEarlyClobber();
797 break;
798 case '%': // commutative.
799 // FIXME: Check that there is a another register after this one.
800 break;
801 case 'r': // general register.
802 Info.setAllowsRegister();
803 break;
804 case 'm': // memory operand.
805 case 'o': // offsetable memory operand.
806 case 'V': // non-offsetable memory operand.
807 case '<': // autodecrement memory operand.
808 case '>': // autoincrement memory operand.
809 Info.setAllowsMemory();
810 break;
811 case 'g': // general register, memory operand or immediate integer.
812 case 'X': // any operand.
813 Info.setAllowsRegister();
814 Info.setAllowsMemory();
815 break;
816 case ',': // multiple alternative constraint. Pass it.
817 // Handle additional optional '=' or '+' modifiers.
818 if (Name[1] == '=' || Name[1] == '+')
819 Name++;
820 break;
821 case '#': // Ignore as constraint.
822 while (Name[1] && Name[1] != ',')
823 Name++;
824 break;
825 case '?': // Disparage slightly code.
826 case '!': // Disparage severely.
827 case '*': // Ignore for choosing register preferences.
828 case 'i': // Ignore i,n,E,F as output constraints (match from the other
829 // chars)
830 case 'n':
831 case 'E':
832 case 'F':
833 break; // Pass them.
834 }
835
836 Name++;
837 }
838
839 // Early clobber with a read-write constraint which doesn't permit registers
840 // is invalid.
841 if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister())
842 return false;
843
844 // If a constraint allows neither memory nor register operands it contains
845 // only modifiers. Reject it.
846 return Info.allowsMemory() || Info.allowsRegister();
847}
848
849bool TargetInfo::resolveSymbolicName(const char *&Name,
850 ArrayRef<ConstraintInfo> OutputConstraints,
851 unsigned &Index) const {
852 assert(*Name == '[' && "Symbolic name did not start with '['");
853 Name++;
854 const char *Start = Name;
855 while (*Name && *Name != ']')
856 Name++;
857
858 if (!*Name) {
859 // Missing ']'
860 return false;
861 }
862
863 std::string SymbolicName(Start, Name - Start);
864
865 for (Index = 0; Index != OutputConstraints.size(); ++Index)
866 if (SymbolicName == OutputConstraints[Index].getName())
867 return true;
868
869 return false;
870}
871
873 MutableArrayRef<ConstraintInfo> OutputConstraints,
874 ConstraintInfo &Info) const {
875 const char *Name = Info.ConstraintStr.c_str();
876
877 if (!*Name)
878 return false;
879
880 while (*Name) {
881 switch (*Name) {
882 default:
883 // Check if we have a matching constraint
884 if (*Name >= '0' && *Name <= '9') {
885 const char *DigitStart = Name;
886 while (Name[1] >= '0' && Name[1] <= '9')
887 Name++;
888 const char *DigitEnd = Name;
889 unsigned i;
890 if (StringRef(DigitStart, DigitEnd - DigitStart + 1)
891 .getAsInteger(10, i))
892 return false;
893
894 // Check if matching constraint is out of bounds.
895 if (i >= OutputConstraints.size()) return false;
896
897 // A number must refer to an output only operand.
898 if (OutputConstraints[i].isReadWrite())
899 return false;
900
901 // If the constraint is already tied, it must be tied to the
902 // same operand referenced to by the number.
903 if (Info.hasTiedOperand() && Info.getTiedOperand() != i)
904 return false;
905
906 // The constraint should have the same info as the respective
907 // output constraint.
908 Info.setTiedOperand(i, OutputConstraints[i]);
909 } else if (!validateAsmConstraint(Name, Info)) {
910 // FIXME: This error return is in place temporarily so we can
911 // add more constraints as we hit it. Eventually, an unknown
912 // constraint should just be treated as 'g'.
913 return false;
914 }
915 break;
916 case '[': {
917 unsigned Index = 0;
918 if (!resolveSymbolicName(Name, OutputConstraints, Index))
919 return false;
920
921 // If the constraint is already tied, it must be tied to the
922 // same operand referenced to by the number.
923 if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)
924 return false;
925
926 // A number must refer to an output only operand.
927 if (OutputConstraints[Index].isReadWrite())
928 return false;
929
930 Info.setTiedOperand(Index, OutputConstraints[Index]);
931 break;
932 }
933 case '%': // commutative
934 // FIXME: Fail if % is used with the last operand.
935 break;
936 case 'i': // immediate integer.
937 break;
938 case 'n': // immediate integer with a known value.
940 break;
941 case 'I': // Various constant constraints with target-specific meanings.
942 case 'J':
943 case 'K':
944 case 'L':
945 case 'M':
946 case 'N':
947 case 'O':
948 case 'P':
949 if (!validateAsmConstraint(Name, Info))
950 return false;
951 break;
952 case 'r': // general register.
953 Info.setAllowsRegister();
954 break;
955 case 'm': // memory operand.
956 case 'o': // offsettable memory operand.
957 case 'V': // non-offsettable memory operand.
958 case '<': // autodecrement memory operand.
959 case '>': // autoincrement memory operand.
960 Info.setAllowsMemory();
961 break;
962 case 'g': // general register, memory operand or immediate integer.
963 case 'X': // any operand.
964 Info.setAllowsRegister();
965 Info.setAllowsMemory();
966 break;
967 case 'E': // immediate floating point.
968 case 'F': // immediate floating point.
969 case 'p': // address operand.
970 break;
971 case ',': // multiple alternative constraint. Ignore comma.
972 break;
973 case '#': // Ignore as constraint.
974 while (Name[1] && Name[1] != ',')
975 Name++;
976 break;
977 case '?': // Disparage slightly code.
978 case '!': // Disparage severely.
979 case '*': // Ignore for choosing register preferences.
980 break; // Pass them.
981 }
982
983 Name++;
984 }
985
986 return true;
987}
988
989bool TargetInfo::validatePointerAuthKey(const llvm::APSInt &value) const {
990 return false;
991}
992
993void TargetInfo::CheckFixedPointBits() const {
994 // Check that the number of fractional and integral bits (and maybe sign) can
995 // fit into the bits given for a fixed point type.
997 assert(AccumScale + getAccumIBits() + 1 <= AccumWidth);
1004
1005 assert(getShortFractScale() + 1 <= ShortFractWidth);
1006 assert(getFractScale() + 1 <= FractWidth);
1007 assert(getLongFractScale() + 1 <= LongFractWidth);
1009 assert(getUnsignedFractScale() <= FractWidth);
1011
1012 // Each unsigned fract type has either the same number of fractional bits
1013 // as, or one more fractional bit than, its corresponding signed fract type.
1016 assert(getFractScale() == getUnsignedFractScale() ||
1020
1021 // When arranged in order of increasing rank (see 6.3.1.3a), the number of
1022 // fractional bits is nondecreasing for each of the following sets of
1023 // fixed-point types:
1024 // - signed fract types
1025 // - unsigned fract types
1026 // - signed accum types
1027 // - unsigned accum types.
1028 assert(getLongFractScale() >= getFractScale() &&
1035
1036 // When arranged in order of increasing rank (see 6.3.1.3a), the number of
1037 // integral bits is nondecreasing for each of the following sets of
1038 // fixed-point types:
1039 // - signed accum types
1040 // - unsigned accum types
1041 assert(getLongAccumIBits() >= getAccumIBits() &&
1045
1046 // Each signed accum type has at least as many integral bits as its
1047 // corresponding unsigned accum type.
1049 assert(getAccumIBits() >= getUnsignedAccumIBits());
1051}
1052
1054 auto *Target = static_cast<TransferrableTargetInfo*>(this);
1055 auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);
1056 *Target = *Src;
1057}
1058
1059std::string
1061 SmallVectorImpl<ConstraintInfo> *OutCons) const {
1062 std::string Result;
1063
1064 for (const char *I = Constraint.begin(), *E = Constraint.end(); I < E; I++) {
1065 switch (*I) {
1066 default:
1068 break;
1069 // Ignore these
1070 case '*':
1071 case '?':
1072 case '!':
1073 case '=': // Will see this and the following in mult-alt constraints.
1074 case '+':
1075 break;
1076 case '#': // Ignore the rest of the constraint alternative.
1077 while (I + 1 != E && I[1] != ',')
1078 I++;
1079 break;
1080 case '&':
1081 case '%':
1082 Result += *I;
1083 while (I + 1 != E && I[1] == *I)
1084 I++;
1085 break;
1086 case ',':
1087 Result += "|";
1088 break;
1089 case 'g':
1090 Result += "imr";
1091 break;
1092 case '[': {
1093 assert(OutCons &&
1094 "Must pass output names to constraints with a symbolic name");
1095 unsigned Index;
1096 bool ResolveResult = resolveSymbolicName(I, *OutCons, Index);
1097 assert(ResolveResult && "Could not resolve symbolic name");
1098 (void)ResolveResult;
1099 Result += llvm::utostr(Index);
1100 break;
1101 }
1102 }
1103 }
1104 return Result;
1105}
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
static const LangASMap DefaultAddrSpaceMap
static StringRef removeGCCRegisterPrefix(StringRef Name)
static const LangASMap FakeAddrSpaceMap
Defines the clang::LangOptions interface.
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:232
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
virtual bool validatePointerAuthKey(const llvm::APSInt &value) const
Determine whether the given pointer-authentication key is valid.
unsigned getUnsignedLongFractScale() const
getUnsignedLongFractScale - Return the number of fractional bits in a 'unsigned long _Fract' type.
Definition TargetInfo.h:668
bool validateInputConstraint(MutableArrayRef< ConstraintInfo > OutputConstraints, ConstraintInfo &info) const
virtual ~TargetInfo()
bool resolveSymbolicName(const char *&Name, ArrayRef< ConstraintInfo > OutputConstraints, unsigned &Index) const
void copyAuxTarget(const TargetInfo *Aux)
Copy type and layout related info.
TargetInfo(const llvm::Triple &T)
virtual bool checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const
Check if the target supports CFProtection return.
unsigned getShortWidth() const
getShortWidth/Align - Return the size of 'signed short' and 'unsigned short' for this target,...
Definition TargetInfo.h:523
unsigned getUnsignedAccumScale() const
getUnsignedAccumScale/IBits - Return the number of fractional/integral bits in a 'unsigned _Accum' ty...
Definition TargetInfo.h:622
unsigned getIntAlign() const
Definition TargetInfo.h:529
virtual ArrayRef< AddlRegName > getGCCAddlRegNames() const
unsigned getUnsignedAccumIBits() const
Definition TargetInfo.h:625
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
const LangASMap * AddrSpaceMap
Definition TargetInfo.h:259
const char * UserLabelPrefix
Definition TargetInfo.h:254
bool HasMicrosoftRecordLayout
Definition TargetInfo.h:294
unsigned getUnsignedFractScale() const
getUnsignedFractScale - Return the number of fractional bits in a 'unsigned _Fract' type.
Definition TargetInfo.h:662
virtual bool checkCFBranchLabelSchemeSupported(const CFBranchLabelSchemeKind Scheme, DiagnosticsEngine &Diags) const
unsigned getLongAlign() const
Definition TargetInfo.h:534
virtual IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const
Return the smallest integer type with at least the specified width.
unsigned getLongLongAlign() const
Definition TargetInfo.h:539
virtual bool hasFeatureEnabled(const llvm::StringMap< bool > &Features, StringRef Name) const
Check if target has a given feature enabled.
virtual CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const
Get the target default CFBranchLabelScheme scheme.
void resetDataLayout(StringRef DL, const char *UserLabelPrefix="")
unsigned char RegParmMax
Definition TargetInfo.h:256
virtual ArrayRef< const char * > getGCCRegNames() const =0
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
unsigned getLongFractScale() const
getLongFractScale - Return the number of fractional bits in a 'signed long _Fract' type.
Definition TargetInfo.h:651
static bool isTypeSigned(IntType T)
Returns true if the type is signed; false otherwise.
std::optional< unsigned > MaxBitIntWidth
Definition TargetInfo.h:290
virtual void setFeatureEnabled(llvm::StringMap< bool > &Features, StringRef Name, bool Enabled) const
Enable or disable a specific target feature; the feature name must be valid.
unsigned getAccumIBits() const
Definition TargetInfo.h:600
virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const
std::string simplifyConstraint(StringRef Constraint, SmallVectorImpl< ConstraintInfo > *OutCons=nullptr) const
VersionTuple PlatformMinVersion
Definition TargetInfo.h:262
unsigned getIntWidth() const
getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target,...
Definition TargetInfo.h:528
const char * MCountName
Definition TargetInfo.h:255
unsigned getShortAccumIBits() const
Definition TargetInfo.h:593
unsigned getFloatWidth() const
getFloatWidth/Align/Format - Return the size/align/format of 'float'.
Definition TargetInfo.h:789
virtual ArrayRef< GCCRegAlias > getGCCRegAliases() const =0
StringRef getNormalizedGCCRegisterName(StringRef Name, bool ReturnCanonical=false) const
Returns the "normalized" GCC register name.
unsigned getLongAccumIBits() const
Definition TargetInfo.h:605
FloatModeKind getRealTypeByWidth(unsigned BitWidth, FloatModeKind ExplicitType) const
Return floating point type with specified width.
virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const
Return integer type with specified width.
unsigned getHalfWidth() const
getHalfWidth/Align/Format - Return the size/align/format of 'half'.
Definition TargetInfo.h:784
unsigned char SSERegParmMax
Definition TargetInfo.h:256
unsigned HasUnalignedAccess
Definition TargetInfo.h:284
virtual void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, const TargetInfo *Aux)
Set forced language options.
unsigned char MaxAtomicPromoteWidth
Definition TargetInfo.h:252
virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const
Get address space for OpenCL type.
static const char * getTypeName(IntType T)
Return the user string for the specified integer type enum.
unsigned getCharAlign() const
Definition TargetInfo.h:519
unsigned RealTypeUsesObjCFPRetMask
Definition TargetInfo.h:267
unsigned MaxOpenCLWorkGroupSize
Definition TargetInfo.h:288
unsigned getLongLongWidth() const
getLongLongWidth/Align - Return the size of 'signed long long' and 'unsigned long long' for this targ...
Definition TargetInfo.h:538
virtual bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const =0
llvm::StringMap< bool > & getSupportedOpenCLOpts()
Get supported OpenCL extensions and optional core features.
StringRef PlatformName
Definition TargetInfo.h:261
bool UseAddrSpaceMapMangling
Specify if mangling based on address space map should be used or not for language specific address sp...
Definition TargetInfo.h:383
virtual void setDependentOpenCLOpts()
Set features that depend on other features.
unsigned ComplexLongDoubleUsesFP2Ret
Definition TargetInfo.h:269
virtual bool hasIbm128Type() const
Determine whether the __ibm128 type is supported on this target.
Definition TargetInfo.h:730
unsigned getUnsignedShortAccumIBits() const
Definition TargetInfo.h:614
std::string DataLayoutString
Definition TargetInfo.h:253
unsigned getUnsignedLongAccumScale() const
getUnsignedLongAccumScale/IBits - Return the number of fractional/integral bits in a 'unsigned long _...
Definition TargetInfo.h:632
virtual bool hasFloat128Type() const
Determine whether the __float128 type is supported on this target.
Definition TargetInfo.h:715
unsigned getUnsignedLongAccumIBits() const
Definition TargetInfo.h:635
unsigned getUnsignedShortFractScale() const
getUnsignedShortFractScale - Return the number of fractional bits in a 'unsigned short _Fract' type.
Definition TargetInfo.h:655
unsigned HasAlignMac68kSupport
Definition TargetInfo.h:265
const llvm::fltSemantics & getLongDoubleFormat() const
Definition TargetInfo.h:807
bool validateOutputConstraint(ConstraintInfo &Info) const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
const char * getTypeConstantSuffix(IntType T) const
Return the constant suffix for the specified integer type enum.
unsigned getDoubleWidth() const
getDoubleWidth/Align/Format - Return the size/align/format of 'double'.
Definition TargetInfo.h:799
virtual bool checkArithmeticFenceSupported() const
Controls if __arithmetic_fence is supported in the targeted backend.
unsigned HasAArch64ACLETypes
Definition TargetInfo.h:275
bool isValidClobber(StringRef Name) const
Returns whether the passed in string is a valid clobber in an inline asm statement.
virtual bool areDefaultedSMFStillPOD(const LangOptions &) const
Controls whether explicitly defaulted (= default) special member functions disqualify something from ...
unsigned getCharWidth() const
Definition TargetInfo.h:518
unsigned HasRISCVVTypes
Definition TargetInfo.h:278
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
Definition TargetInfo.h:533
unsigned getFractScale() const
getFractScale - Return the number of fractional bits in a 'signed _Fract' type.
Definition TargetInfo.h:647
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
virtual bool checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const
Check if the target supports CFProtection branch.
virtual std::string convertConstraint(const char *&Constraint) const
unsigned char MaxAtomicInlineWidth
Definition TargetInfo.h:252
unsigned AllowAMDGPUUnsafeFPAtomics
Definition TargetInfo.h:281
unsigned getShortFractScale() const
getShortFractScale - Return the number of fractional bits in a 'signed short _Fract' type.
Definition TargetInfo.h:643
virtual uint64_t getMaxPointerWidth() const
Return the maximum width of pointers on this target.
Definition TargetInfo.h:497
TargetCXXABI TheCXXABI
Definition TargetInfo.h:257
unsigned ARMCDECoprocMask
Definition TargetInfo.h:286
static const char * getTypeFormatModifier(IntType T)
Return the printf format modifier for the specified integer type enum.
unsigned getUnsignedShortAccumScale() const
getUnsignedShortAccumScale/IBits - Return the number of fractional/integral bits in a 'unsigned short...
Definition TargetInfo.h:611
unsigned HasBuiltinMSVaList
Definition TargetInfo.h:272
unsigned getTypeAlign(IntType T) const
Return the alignment (in bits) of the specified integer type enum.
unsigned getShortAlign() const
Definition TargetInfo.h:524
virtual bool callGlobalDeleteInDeletingDtor(const LangOptions &) const
Controls whether global operator delete is called by the deleting destructor or at the point where de...
virtual bool isValidGCCRegisterName(StringRef Name) const
Returns whether the passed in string is a valid register name according to GCC.
Defines the clang::TargetInfo interface.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
OpenCLTypeKind
OpenCL type kinds.
Definition TargetInfo.h:212
@ OCLTK_Image
Definition TargetInfo.h:216
@ OCLTK_Sampler
Definition TargetInfo.h:220
@ OCLTK_Pipe
Definition TargetInfo.h:217
@ Result
The result type of a method or function.
Definition TypeBase.h:905
const FunctionProtoType * T
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
Definition CharInfo.h:114
LangAS
Defines the address space values used by the address space qualifier of QualType.
static const char * getCFBranchLabelSchemeFlagVal(const CFBranchLabelSchemeKind Scheme)
FloatModeKind
Definition TargetInfo.h:75
unsigned[(unsigned) LangAS::FirstTargetAddressSpace] LangASMap
The type of a lookup table which maps from language-specific address spaces to target-specific ones.
Contains information gathered from parsing the contents of TargetAttr.
Definition TargetInfo.h:60
const std::string & getConstraintStr() const
void setTiedOperand(unsigned N, ConstraintInfo &Output)
Indicate that this is an input operand that is tied to the specified output operand.
bool hasTiedOperand() const
Return true if this input operand is a matching constraint that ties it to an output operand.
void setRequiresImmediate(int Min, int Max)
Fields controlling how types are laid out in memory; these may need to be copied for targets like AMD...
Definition TargetInfo.h:89
const llvm::fltSemantics * DoubleFormat
Definition TargetInfo.h:143
unsigned UseZeroLengthBitfieldAlignment
Whether zero length bitfields (e.g., int : 0;) force alignment of the next bitfield.
Definition TargetInfo.h:187
unsigned UseExplicitBitFieldAlignment
Whether explicit bit field alignment attributes are honored.
Definition TargetInfo.h:196
IntType
===-— Target Data Type Query Methods ----------------------------—===//
Definition TargetInfo.h:146
const llvm::fltSemantics * LongDoubleFormat
Definition TargetInfo.h:143
unsigned ZeroLengthBitfieldBoundary
If non-zero, specifies a fixed alignment value for bitfields that follow zero length bitfield,...
Definition TargetInfo.h:200
const llvm::fltSemantics * Float128Format
Definition TargetInfo.h:143
unsigned LargestOverSizedBitfieldContainer
The largest container size which should be used for an over-sized bitfield, in bits.
Definition TargetInfo.h:204
unsigned UseLeadingZeroLengthBitfield
Whether zero length bitfield alignment is respected if they are the leading members.
Definition TargetInfo.h:192
unsigned UseBitFieldTypeAlignment
Control whether the alignment of bit-field types is respected when laying out structures.
Definition TargetInfo.h:178
unsigned MaxAlignedAttribute
If non-zero, specifies a maximum alignment to truncate alignment specified in the aligned attribute o...
Definition TargetInfo.h:208
const llvm::fltSemantics * Ibm128Format
Definition TargetInfo.h:143
const llvm::fltSemantics * FloatFormat
Definition TargetInfo.h:142
const llvm::fltSemantics * HalfFormat
Definition TargetInfo.h:142
unsigned UseSignedCharForObjCBool
Whether Objective-C's built-in boolean type should be signed char.
Definition TargetInfo.h:170
unsigned char DefaultAlignForAttributeAligned
Definition TargetInfo.h:134