1 //===-- llvm/TargetParser/Triple.h - Target triple helper class--*- 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 #ifndef LLVM_TARGETPARSER_TRIPLE_H
10 #define LLVM_TARGETPARSER_TRIPLE_H
11 
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/Support/VersionTuple.h"
14 
15 // Some system headers or GCC predefined macros conflict with identifiers in
16 // this file.  Undefine them here.
17 #undef NetBSD
18 #undef mips
19 #undef sparc
20 
21 namespace llvm {
22 
23 /// Triple - Helper class for working with autoconf configuration names. For
24 /// historical reasons, we also call these 'triples' (they used to contain
25 /// exactly three fields).
26 ///
27 /// Configuration names are strings in the canonical form:
28 ///   ARCHITECTURE-VENDOR-OPERATING_SYSTEM
29 /// or
30 ///   ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT
31 ///
32 /// This class is used for clients which want to support arbitrary
33 /// configuration names, but also want to implement certain special
34 /// behavior for particular configurations. This class isolates the mapping
35 /// from the components of the configuration name to well known IDs.
36 ///
37 /// At its core the Triple class is designed to be a wrapper for a triple
38 /// string; the constructor does not change or normalize the triple string.
39 /// Clients that need to handle the non-canonical triples that users often
40 /// specify should use the normalize method.
41 ///
42 /// See autoconf/config.guess for a glimpse into what configuration names
43 /// look like in practice.
44 class Triple {
45 public:
46   enum ArchType {
47     UnknownArch,
48 
49     arm,            // ARM (little endian): arm, armv.*, xscale
50     armeb,          // ARM (big endian): armeb
51     aarch64,        // AArch64 (little endian): aarch64
52     aarch64_be,     // AArch64 (big endian): aarch64_be
53     aarch64_32,     // AArch64 (little endian) ILP32: aarch64_32
54     arc,            // ARC: Synopsys ARC
55     avr,            // AVR: Atmel AVR microcontroller
56     bpfel,          // eBPF or extended BPF or 64-bit BPF (little endian)
57     bpfeb,          // eBPF or extended BPF or 64-bit BPF (big endian)
58     csky,           // CSKY: csky
59     dxil,           // DXIL 32-bit DirectX bytecode
60     hexagon,        // Hexagon: hexagon
61     loongarch32,    // LoongArch (32-bit): loongarch32
62     loongarch64,    // LoongArch (64-bit): loongarch64
63     m68k,           // M68k: Motorola 680x0 family
64     mips,           // MIPS: mips, mipsallegrex, mipsr6
65     mipsel,         // MIPSEL: mipsel, mipsallegrexe, mipsr6el
66     mips64,         // MIPS64: mips64, mips64r6, mipsn32, mipsn32r6
67     mips64el,       // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el
68     msp430,         // MSP430: msp430
69     ppc,            // PPC: powerpc
70     ppcle,          // PPCLE: powerpc (little endian)
71     ppc64,          // PPC64: powerpc64, ppu
72     ppc64le,        // PPC64LE: powerpc64le
73     r600,           // R600: AMD GPUs HD2XXX - HD6XXX
74     amdgcn,         // AMDGCN: AMD GCN GPUs
75     riscv32,        // RISC-V (32-bit): riscv32
76     riscv64,        // RISC-V (64-bit): riscv64
77     sparc,          // Sparc: sparc
78     sparcv9,        // Sparcv9: Sparcv9
79     sparcel,        // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant
80     systemz,        // SystemZ: s390x
81     tce,            // TCE (http://tce.cs.tut.fi/): tce
82     tcele,          // TCE little endian (http://tce.cs.tut.fi/): tcele
83     thumb,          // Thumb (little endian): thumb, thumbv.*
84     thumbeb,        // Thumb (big endian): thumbeb
85     x86,            // X86: i[3-9]86
86     x86_64,         // X86-64: amd64, x86_64
87     xcore,          // XCore: xcore
88     xtensa,         // Tensilica: Xtensa
89     nvptx,          // NVPTX: 32-bit
90     nvptx64,        // NVPTX: 64-bit
91     le32,           // le32: generic little-endian 32-bit CPU (PNaCl)
92     le64,           // le64: generic little-endian 64-bit CPU (PNaCl)
93     amdil,          // AMDIL
94     amdil64,        // AMDIL with 64-bit pointers
95     hsail,          // AMD HSAIL
96     hsail64,        // AMD HSAIL with 64-bit pointers
97     spir,           // SPIR: standard portable IR for OpenCL 32-bit version
98     spir64,         // SPIR: standard portable IR for OpenCL 64-bit version
99     spirv,          // SPIR-V with logical memory layout.
100     spirv32,        // SPIR-V with 32-bit pointers
101     spirv64,        // SPIR-V with 64-bit pointers
102     kalimba,        // Kalimba: generic kalimba
103     shave,          // SHAVE: Movidius vector VLIW processors
104     lanai,          // Lanai: Lanai 32-bit
105     wasm32,         // WebAssembly with 32-bit pointers
106     wasm64,         // WebAssembly with 64-bit pointers
107     renderscript32, // 32-bit RenderScript
108     renderscript64, // 64-bit RenderScript
109     ve,             // NEC SX-Aurora Vector Engine
110     LastArchType = ve
111   };
112   enum SubArchType {
113     NoSubArch,
114 
115     ARMSubArch_v9_5a,
116     ARMSubArch_v9_4a,
117     ARMSubArch_v9_3a,
118     ARMSubArch_v9_2a,
119     ARMSubArch_v9_1a,
120     ARMSubArch_v9,
121     ARMSubArch_v8_9a,
122     ARMSubArch_v8_8a,
123     ARMSubArch_v8_7a,
124     ARMSubArch_v8_6a,
125     ARMSubArch_v8_5a,
126     ARMSubArch_v8_4a,
127     ARMSubArch_v8_3a,
128     ARMSubArch_v8_2a,
129     ARMSubArch_v8_1a,
130     ARMSubArch_v8,
131     ARMSubArch_v8r,
132     ARMSubArch_v8m_baseline,
133     ARMSubArch_v8m_mainline,
134     ARMSubArch_v8_1m_mainline,
135     ARMSubArch_v7,
136     ARMSubArch_v7em,
137     ARMSubArch_v7m,
138     ARMSubArch_v7s,
139     ARMSubArch_v7k,
140     ARMSubArch_v7ve,
141     ARMSubArch_v6,
142     ARMSubArch_v6m,
143     ARMSubArch_v6k,
144     ARMSubArch_v6t2,
145     ARMSubArch_v5,
146     ARMSubArch_v5te,
147     ARMSubArch_v4t,
148 
149     AArch64SubArch_arm64e,
150     AArch64SubArch_arm64ec,
151 
152     KalimbaSubArch_v3,
153     KalimbaSubArch_v4,
154     KalimbaSubArch_v5,
155 
156     MipsSubArch_r6,
157 
158     PPCSubArch_spe,
159 
160     // SPIR-V sub-arch corresponds to its version.
161     SPIRVSubArch_v10,
162     SPIRVSubArch_v11,
163     SPIRVSubArch_v12,
164     SPIRVSubArch_v13,
165     SPIRVSubArch_v14,
166     SPIRVSubArch_v15,
167     SPIRVSubArch_v16,
168   };
169   enum VendorType {
170     UnknownVendor,
171 
172     Apple,
173     PC,
174     SCEI,
175     Freescale,
176     IBM,
177     ImaginationTechnologies,
178     MipsTechnologies,
179     NVIDIA,
180     CSR,
181     AMD,
182     Mesa,
183     SUSE,
184     OpenEmbedded,
185     LastVendorType = OpenEmbedded
186   };
187   enum OSType {
188     UnknownOS,
189 
190     Darwin,
191     DragonFly,
192     FreeBSD,
193     Fuchsia,
194     IOS,
195     KFreeBSD,
196     Linux,
197     Lv2, // PS3
198     MacOSX,
199     NetBSD,
200     OpenBSD,
201     Solaris,
202     UEFI,
203     Win32,
204     ZOS,
205     Haiku,
206     RTEMS,
207     NaCl, // Native Client
208     AIX,
209     CUDA,   // NVIDIA CUDA
210     NVCL,   // NVIDIA OpenCL
211     AMDHSA, // AMD HSA Runtime
212     PS4,
213     PS5,
214     ELFIAMCU,
215     TvOS,      // Apple tvOS
216     WatchOS,   // Apple watchOS
217     BridgeOS,  // Apple bridgeOS
218     DriverKit, // Apple DriverKit
219     XROS,      // Apple XROS
220     Mesa3D,
221     AMDPAL,     // AMD PAL Runtime
222     HermitCore, // HermitCore Unikernel/Multikernel
223     Hurd,       // GNU/Hurd
224     WASI,       // Experimental WebAssembly OS
225     Emscripten,
226     ShaderModel, // DirectX ShaderModel
227     LiteOS,
228     Serenity,
229     Vulkan, // Vulkan SPIR-V
230     LastOSType = Vulkan
231   };
232   enum EnvironmentType {
233     UnknownEnvironment,
234 
235     GNU,
236     GNUABIN32,
237     GNUABI64,
238     GNUEABI,
239     GNUEABIHF,
240     GNUF32,
241     GNUF64,
242     GNUSF,
243     GNUX32,
244     GNUILP32,
245     CODE16,
246     EABI,
247     EABIHF,
248     Android,
249     Musl,
250     MuslEABI,
251     MuslEABIHF,
252     MuslX32,
253 
254     // As in wasm64-unknown-unknown-nativeandroid.
255     // Turns off 64->32 function pointer cast on indirect
256     // lookup and compiles varargs calls using intrinsics
257     // for varargs allocation:
258     NativeAndroid,
259 
260     MSVC,
261     Itanium,
262     Cygnus,
263     CoreCLR,
264     Simulator, // Simulator variants of other systems, e.g., Apple's iOS
265     MacABI, // Mac Catalyst variant of Apple's iOS deployment target.
266 
267     // Shader Stages
268     // The order of these values matters, and must be kept in sync with the
269     // language options enum in Clang. The ordering is enforced in
270     // static_asserts in Triple.cpp and in Clang.
271     Pixel,
272     Vertex,
273     Geometry,
274     Hull,
275     Domain,
276     Compute,
277     Library,
278     RayGeneration,
279     Intersection,
280     AnyHit,
281     ClosestHit,
282     Miss,
283     Callable,
284     Mesh,
285     Amplification,
286     OpenCL,
287     OpenHOS,
288 
289     LastEnvironmentType = OpenHOS
290   };
291   enum ObjectFormatType {
292     UnknownObjectFormat,
293 
294     COFF,
295     DXContainer,
296     ELF,
297     GOFF,
298     MachO,
299     SPIRV,
300     Wasm,
301     XCOFF,
302   };
303 
304 private:
305   std::string Data;
306 
307   /// The parsed arch type.
308   ArchType Arch{};
309 
310   /// The parsed subarchitecture type.
311   SubArchType SubArch{};
312 
313   /// The parsed vendor type.
314   VendorType Vendor{};
315 
316   /// The parsed OS type.
317   OSType OS{};
318 
319   /// The parsed Environment type.
320   EnvironmentType Environment{};
321 
322   /// The object format type.
323   ObjectFormatType ObjectFormat{};
324 
325 public:
326   /// @name Constructors
327   /// @{
328 
329   /// Default constructor is the same as an empty string and leaves all
330   /// triple fields unknown.
331   Triple() = default;
332 
333   explicit Triple(const Twine &Str);
334   Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
335   Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
336          const Twine &EnvironmentStr);
337 
338   bool operator==(const Triple &Other) const {
339     return Arch == Other.Arch && SubArch == Other.SubArch &&
340            Vendor == Other.Vendor && OS == Other.OS &&
341            Environment == Other.Environment &&
342            ObjectFormat == Other.ObjectFormat;
343   }
344 
345   bool operator!=(const Triple &Other) const {
346     return !(*this == Other);
347   }
348 
349   /// @}
350   /// @name Normalization
351   /// @{
352 
353   /// Turn an arbitrary machine specification into the canonical triple form (or
354   /// something sensible that the Triple class understands if nothing better can
355   /// reasonably be done).  In particular, it handles the common case in which
356   /// otherwise valid components are in the wrong order.
357   static std::string normalize(StringRef Str);
358 
359   /// Return the normalized form of this triple's string.
normalize()360   std::string normalize() const { return normalize(Data); }
361 
362   /// @}
363   /// @name Typed Component Access
364   /// @{
365 
366   /// Get the parsed architecture type of this triple.
getArch()367   ArchType getArch() const { return Arch; }
368 
369   /// get the parsed subarchitecture type for this triple.
getSubArch()370   SubArchType getSubArch() const { return SubArch; }
371 
372   /// Get the parsed vendor type of this triple.
getVendor()373   VendorType getVendor() const { return Vendor; }
374 
375   /// Get the parsed operating system type of this triple.
getOS()376   OSType getOS() const { return OS; }
377 
378   /// Does this triple have the optional environment (fourth) component?
hasEnvironment()379   bool hasEnvironment() const {
380     return getEnvironmentName() != "";
381   }
382 
383   /// Get the parsed environment type of this triple.
getEnvironment()384   EnvironmentType getEnvironment() const { return Environment; }
385 
386   /// Parse the version number from the OS name component of the
387   /// triple, if present.
388   ///
389   /// For example, "fooos1.2.3" would return (1, 2, 3).
390   VersionTuple getEnvironmentVersion() const;
391 
392   /// Get the object format for this triple.
getObjectFormat()393   ObjectFormatType getObjectFormat() const { return ObjectFormat; }
394 
395   /// Parse the version number from the OS name component of the triple, if
396   /// present.
397   ///
398   /// For example, "fooos1.2.3" would return (1, 2, 3).
399   VersionTuple getOSVersion() const;
400 
401   /// Return just the major version number, this is specialized because it is a
402   /// common query.
getOSMajorVersion()403   unsigned getOSMajorVersion() const { return getOSVersion().getMajor(); }
404 
405   /// Parse the version number as with getOSVersion and then translate generic
406   /// "darwin" versions to the corresponding OS X versions.  This may also be
407   /// called with IOS triples but the OS X version number is just set to a
408   /// constant 10.4.0 in that case.  Returns true if successful.
409   bool getMacOSXVersion(VersionTuple &Version) const;
410 
411   /// Parse the version number as with getOSVersion.  This should only be called
412   /// with IOS or generic triples.
413   VersionTuple getiOSVersion() const;
414 
415   /// Parse the version number as with getOSVersion.  This should only be called
416   /// with WatchOS or generic triples.
417   VersionTuple getWatchOSVersion() const;
418 
419   /// Parse the version number as with getOSVersion.
420   VersionTuple getDriverKitVersion() const;
421 
422   /// Parse the Vulkan version number from the OSVersion and SPIR-V version
423   /// (SubArch).  This should only be called with Vulkan SPIR-V triples.
424   VersionTuple getVulkanVersion() const;
425 
426   /// @}
427   /// @name Direct Component Access
428   /// @{
429 
str()430   const std::string &str() const { return Data; }
431 
getTriple()432   const std::string &getTriple() const { return Data; }
433 
434   /// Get the architecture (first) component of the triple.
435   StringRef getArchName() const;
436 
437   /// Get the vendor (second) component of the triple.
438   StringRef getVendorName() const;
439 
440   /// Get the operating system (third) component of the triple.
441   StringRef getOSName() const;
442 
443   /// Get the optional environment (fourth) component of the triple, or "" if
444   /// empty.
445   StringRef getEnvironmentName() const;
446 
447   /// Get the operating system and optional environment components as a single
448   /// string (separated by a '-' if the environment component is present).
449   StringRef getOSAndEnvironmentName() const;
450 
451   /// Get the version component of the environment component as a single
452   /// string (the version after the environment).
453   ///
454   /// For example, "fooos1.2.3" would return "1.2.3".
455   StringRef getEnvironmentVersionString() const;
456 
457   /// @}
458   /// @name Convenience Predicates
459   /// @{
460 
461   /// Returns the pointer width of this architecture.
462   static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch);
463 
464   /// Returns the pointer width of this architecture.
getArchPointerBitWidth()465   unsigned getArchPointerBitWidth() const {
466     return getArchPointerBitWidth(getArch());
467   }
468 
469   /// Test whether the architecture is 64-bit
470   ///
471   /// Note that this tests for 64-bit pointer width, and nothing else. Note
472   /// that we intentionally expose only three predicates, 64-bit, 32-bit, and
473   /// 16-bit. The inner details of pointer width for particular architectures
474   /// is not summed up in the triple, and so only a coarse grained predicate
475   /// system is provided.
476   bool isArch64Bit() const;
477 
478   /// Test whether the architecture is 32-bit
479   ///
480   /// Note that this tests for 32-bit pointer width, and nothing else.
481   bool isArch32Bit() const;
482 
483   /// Test whether the architecture is 16-bit
484   ///
485   /// Note that this tests for 16-bit pointer width, and nothing else.
486   bool isArch16Bit() const;
487 
488   /// Helper function for doing comparisons against version numbers included in
489   /// the target triple.
490   bool isOSVersionLT(unsigned Major, unsigned Minor = 0,
491                      unsigned Micro = 0) const {
492     if (Minor == 0) {
493       return getOSVersion() < VersionTuple(Major);
494     }
495     if (Micro == 0) {
496       return getOSVersion() < VersionTuple(Major, Minor);
497     }
498     return getOSVersion() < VersionTuple(Major, Minor, Micro);
499   }
500 
isOSVersionLT(const Triple & Other)501   bool isOSVersionLT(const Triple &Other) const {
502     return getOSVersion() < Other.getOSVersion();
503   }
504 
505   /// Comparison function for checking OS X version compatibility, which handles
506   /// supporting skewed version numbering schemes used by the "darwin" triples.
507   bool isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
508                          unsigned Micro = 0) const;
509 
510   /// Is this a Mac OS X triple. For legacy reasons, we support both "darwin"
511   /// and "osx" as OS X triples.
isMacOSX()512   bool isMacOSX() const {
513     return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
514   }
515 
516   /// Is this an iOS triple.
517   /// Note: This identifies tvOS as a variant of iOS. If that ever
518   /// changes, i.e., if the two operating systems diverge or their version
519   /// numbers get out of sync, that will need to be changed.
520   /// watchOS has completely different version numbers so it is not included.
isiOS()521   bool isiOS() const {
522     return getOS() == Triple::IOS || isTvOS();
523   }
524 
525   /// Is this an Apple tvOS triple.
isTvOS()526   bool isTvOS() const {
527     return getOS() == Triple::TvOS;
528   }
529 
530   /// Is this an Apple watchOS triple.
isWatchOS()531   bool isWatchOS() const {
532     return getOS() == Triple::WatchOS;
533   }
534 
isWatchABI()535   bool isWatchABI() const {
536     return getSubArch() == Triple::ARMSubArch_v7k;
537   }
538 
539   /// Is this an Apple XROS triple.
isXROS()540   bool isXROS() const { return getOS() == Triple::XROS; }
541 
542   /// Is this an Apple DriverKit triple.
isDriverKit()543   bool isDriverKit() const { return getOS() == Triple::DriverKit; }
544 
isOSzOS()545   bool isOSzOS() const { return getOS() == Triple::ZOS; }
546 
547   /// Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
isOSDarwin()548   bool isOSDarwin() const {
549     return isMacOSX() || isiOS() || isWatchOS() || isDriverKit() || isXROS();
550   }
551 
isSimulatorEnvironment()552   bool isSimulatorEnvironment() const {
553     return getEnvironment() == Triple::Simulator;
554   }
555 
isMacCatalystEnvironment()556   bool isMacCatalystEnvironment() const {
557     return getEnvironment() == Triple::MacABI;
558   }
559 
560   /// Returns true for targets that run on a macOS machine.
isTargetMachineMac()561   bool isTargetMachineMac() const {
562     return isMacOSX() || (isOSDarwin() && (isSimulatorEnvironment() ||
563                                            isMacCatalystEnvironment()));
564   }
565 
isOSNetBSD()566   bool isOSNetBSD() const {
567     return getOS() == Triple::NetBSD;
568   }
569 
isOSOpenBSD()570   bool isOSOpenBSD() const {
571     return getOS() == Triple::OpenBSD;
572   }
573 
isOSFreeBSD()574   bool isOSFreeBSD() const {
575     return getOS() == Triple::FreeBSD;
576   }
577 
isOSFuchsia()578   bool isOSFuchsia() const {
579     return getOS() == Triple::Fuchsia;
580   }
581 
isOSDragonFly()582   bool isOSDragonFly() const { return getOS() == Triple::DragonFly; }
583 
isOSSolaris()584   bool isOSSolaris() const {
585     return getOS() == Triple::Solaris;
586   }
587 
isOSIAMCU()588   bool isOSIAMCU() const {
589     return getOS() == Triple::ELFIAMCU;
590   }
591 
isOSUnknown()592   bool isOSUnknown() const { return getOS() == Triple::UnknownOS; }
593 
isGNUEnvironment()594   bool isGNUEnvironment() const {
595     EnvironmentType Env = getEnvironment();
596     return Env == Triple::GNU || Env == Triple::GNUABIN32 ||
597            Env == Triple::GNUABI64 || Env == Triple::GNUEABI ||
598            Env == Triple::GNUEABIHF || Env == Triple::GNUF32 ||
599            Env == Triple::GNUF64 || Env == Triple::GNUSF ||
600            Env == Triple::GNUX32;
601   }
602 
603   /// Tests whether the OS is Haiku.
isOSHaiku()604   bool isOSHaiku() const {
605     return getOS() == Triple::Haiku;
606   }
607 
608   /// Tests whether the OS is UEFI.
isUEFI()609   bool isUEFI() const {
610     return getOS() == Triple::UEFI;
611   }
612 
613   /// Tests whether the OS is Windows.
isOSWindows()614   bool isOSWindows() const {
615     return getOS() == Triple::Win32;
616   }
617 
618   /// Checks if the environment is MSVC.
isKnownWindowsMSVCEnvironment()619   bool isKnownWindowsMSVCEnvironment() const {
620     return isOSWindows() && getEnvironment() == Triple::MSVC;
621   }
622 
623   /// Checks if the environment could be MSVC.
isWindowsMSVCEnvironment()624   bool isWindowsMSVCEnvironment() const {
625     return isKnownWindowsMSVCEnvironment() ||
626            (isOSWindows() && getEnvironment() == Triple::UnknownEnvironment);
627   }
628 
629   // Checks if we're using the Windows Arm64EC ABI.
isWindowsArm64EC()630   bool isWindowsArm64EC() const {
631     return getArch() == Triple::aarch64 &&
632            getSubArch() == Triple::AArch64SubArch_arm64ec;
633   }
634 
isWindowsCoreCLREnvironment()635   bool isWindowsCoreCLREnvironment() const {
636     return isOSWindows() && getEnvironment() == Triple::CoreCLR;
637   }
638 
isWindowsItaniumEnvironment()639   bool isWindowsItaniumEnvironment() const {
640     return isOSWindows() && getEnvironment() == Triple::Itanium;
641   }
642 
isWindowsCygwinEnvironment()643   bool isWindowsCygwinEnvironment() const {
644     return isOSWindows() && getEnvironment() == Triple::Cygnus;
645   }
646 
isWindowsGNUEnvironment()647   bool isWindowsGNUEnvironment() const {
648     return isOSWindows() && getEnvironment() == Triple::GNU;
649   }
650 
651   /// Tests for either Cygwin or MinGW OS
isOSCygMing()652   bool isOSCygMing() const {
653     return isWindowsCygwinEnvironment() || isWindowsGNUEnvironment();
654   }
655 
656   /// Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
isOSMSVCRT()657   bool isOSMSVCRT() const {
658     return isWindowsMSVCEnvironment() || isWindowsGNUEnvironment() ||
659            isWindowsItaniumEnvironment();
660   }
661 
662   /// Tests whether the OS is NaCl (Native Client)
isOSNaCl()663   bool isOSNaCl() const {
664     return getOS() == Triple::NaCl;
665   }
666 
667   /// Tests whether the OS is Linux.
isOSLinux()668   bool isOSLinux() const {
669     return getOS() == Triple::Linux;
670   }
671 
672   /// Tests whether the OS is kFreeBSD.
isOSKFreeBSD()673   bool isOSKFreeBSD() const {
674     return getOS() == Triple::KFreeBSD;
675   }
676 
677   /// Tests whether the OS is Hurd.
isOSHurd()678   bool isOSHurd() const {
679     return getOS() == Triple::Hurd;
680   }
681 
682   /// Tests whether the OS is WASI.
isOSWASI()683   bool isOSWASI() const {
684     return getOS() == Triple::WASI;
685   }
686 
687   /// Tests whether the OS is Emscripten.
isOSEmscripten()688   bool isOSEmscripten() const {
689     return getOS() == Triple::Emscripten;
690   }
691 
692   /// Tests whether the OS uses glibc.
isOSGlibc()693   bool isOSGlibc() const {
694     return (getOS() == Triple::Linux || getOS() == Triple::KFreeBSD ||
695             getOS() == Triple::Hurd) &&
696            !isAndroid();
697   }
698 
699   /// Tests whether the OS is AIX.
isOSAIX()700   bool isOSAIX() const {
701     return getOS() == Triple::AIX;
702   }
703 
isOSSerenity()704   bool isOSSerenity() const {
705     return getOS() == Triple::Serenity;
706   }
707 
708   /// Tests whether the OS uses the ELF binary format.
isOSBinFormatELF()709   bool isOSBinFormatELF() const {
710     return getObjectFormat() == Triple::ELF;
711   }
712 
713   /// Tests whether the OS uses the COFF binary format.
isOSBinFormatCOFF()714   bool isOSBinFormatCOFF() const {
715     return getObjectFormat() == Triple::COFF;
716   }
717 
718   /// Tests whether the OS uses the GOFF binary format.
isOSBinFormatGOFF()719   bool isOSBinFormatGOFF() const { return getObjectFormat() == Triple::GOFF; }
720 
721   /// Tests whether the environment is MachO.
isOSBinFormatMachO()722   bool isOSBinFormatMachO() const {
723     return getObjectFormat() == Triple::MachO;
724   }
725 
726   /// Tests whether the OS uses the Wasm binary format.
isOSBinFormatWasm()727   bool isOSBinFormatWasm() const {
728     return getObjectFormat() == Triple::Wasm;
729   }
730 
731   /// Tests whether the OS uses the XCOFF binary format.
isOSBinFormatXCOFF()732   bool isOSBinFormatXCOFF() const {
733     return getObjectFormat() == Triple::XCOFF;
734   }
735 
736   /// Tests whether the OS uses the DXContainer binary format.
isOSBinFormatDXContainer()737   bool isOSBinFormatDXContainer() const {
738     return getObjectFormat() == Triple::DXContainer;
739   }
740 
741   /// Tests whether the target is the PS4 platform.
isPS4()742   bool isPS4() const {
743     return getArch() == Triple::x86_64 &&
744            getVendor() == Triple::SCEI &&
745            getOS() == Triple::PS4;
746   }
747 
748   /// Tests whether the target is the PS5 platform.
isPS5()749   bool isPS5() const {
750     return getArch() == Triple::x86_64 &&
751       getVendor() == Triple::SCEI &&
752       getOS() == Triple::PS5;
753   }
754 
755   /// Tests whether the target is the PS4 or PS5 platform.
isPS()756   bool isPS() const { return isPS4() || isPS5(); }
757 
758   /// Tests whether the target is Android
isAndroid()759   bool isAndroid() const { return getEnvironment() == Triple::Android; }
760 
isAndroidVersionLT(unsigned Major)761   bool isAndroidVersionLT(unsigned Major) const {
762     assert(isAndroid() && "Not an Android triple!");
763 
764     VersionTuple Version = getEnvironmentVersion();
765 
766     // 64-bit targets did not exist before API level 21 (Lollipop).
767     if (isArch64Bit() && Version.getMajor() < 21)
768       return VersionTuple(21) < VersionTuple(Major);
769 
770     return Version < VersionTuple(Major);
771   }
772 
773   /// Tests whether the environment is musl-libc
isMusl()774   bool isMusl() const {
775     return getEnvironment() == Triple::Musl ||
776            getEnvironment() == Triple::MuslEABI ||
777            getEnvironment() == Triple::MuslEABIHF ||
778            getEnvironment() == Triple::MuslX32 ||
779            getEnvironment() == Triple::OpenHOS || isOSLiteOS();
780   }
781 
782   /// Tests whether the target is OHOS
783   /// LiteOS default enviroment is also OHOS, but omited on triple.
isOHOSFamily()784   bool isOHOSFamily() const { return isOpenHOS() || isOSLiteOS(); }
785 
isOpenHOS()786   bool isOpenHOS() const { return getEnvironment() == Triple::OpenHOS; }
787 
isOSLiteOS()788   bool isOSLiteOS() const { return getOS() == Triple::LiteOS; }
789 
isNativeAndroid()790   bool isNativeAndroid() const { return getEnvironment() == Triple::NativeAndroid; }
791 
792   /// Tests whether the target is DXIL.
isDXIL()793   bool isDXIL() const {
794     return getArch() == Triple::dxil;
795   }
796 
isShaderModelOS()797   bool isShaderModelOS() const {
798     return getOS() == Triple::ShaderModel;
799   }
800 
isVulkanOS()801   bool isVulkanOS() const { return getOS() == Triple::Vulkan; }
802 
isShaderStageEnvironment()803   bool isShaderStageEnvironment() const {
804     EnvironmentType Env = getEnvironment();
805     return Env == Triple::Pixel || Env == Triple::Vertex ||
806            Env == Triple::Geometry || Env == Triple::Hull ||
807            Env == Triple::Domain || Env == Triple::Compute ||
808            Env == Triple::Library || Env == Triple::RayGeneration ||
809            Env == Triple::Intersection || Env == Triple::AnyHit ||
810            Env == Triple::ClosestHit || Env == Triple::Miss ||
811            Env == Triple::Callable || Env == Triple::Mesh ||
812            Env == Triple::Amplification;
813   }
814 
815   /// Tests whether the target is SPIR (32- or 64-bit).
isSPIR()816   bool isSPIR() const {
817     return getArch() == Triple::spir || getArch() == Triple::spir64;
818   }
819 
820   /// Tests whether the target is SPIR-V (32/64-bit/Logical).
isSPIRV()821   bool isSPIRV() const {
822     return getArch() == Triple::spirv32 || getArch() == Triple::spirv64 ||
823            getArch() == Triple::spirv;
824   }
825 
826   /// Tests whether the target is SPIR-V Logical
isSPIRVLogical()827   bool isSPIRVLogical() const {
828     return getArch() == Triple::spirv;
829   }
830 
831   /// Tests whether the target is NVPTX (32- or 64-bit).
isNVPTX()832   bool isNVPTX() const {
833     return getArch() == Triple::nvptx || getArch() == Triple::nvptx64;
834   }
835 
836   /// Tests whether the target is AMDGCN
isAMDGCN()837   bool isAMDGCN() const { return getArch() == Triple::amdgcn; }
838 
isAMDGPU()839   bool isAMDGPU() const {
840     return getArch() == Triple::r600 || getArch() == Triple::amdgcn;
841   }
842 
843   /// Tests whether the target is Thumb (little and big endian).
isThumb()844   bool isThumb() const {
845     return getArch() == Triple::thumb || getArch() == Triple::thumbeb;
846   }
847 
848   /// Tests whether the target is ARM (little and big endian).
isARM()849   bool isARM() const {
850     return getArch() == Triple::arm || getArch() == Triple::armeb;
851   }
852 
853   /// Tests whether the target supports the EHABI exception
854   /// handling standard.
isTargetEHABICompatible()855   bool isTargetEHABICompatible() const {
856     return (isARM() || isThumb()) &&
857            (getEnvironment() == Triple::EABI ||
858             getEnvironment() == Triple::GNUEABI ||
859             getEnvironment() == Triple::MuslEABI ||
860             getEnvironment() == Triple::EABIHF ||
861             getEnvironment() == Triple::GNUEABIHF ||
862             getEnvironment() == Triple::OpenHOS ||
863             getEnvironment() == Triple::MuslEABIHF || isAndroid()) &&
864            isOSBinFormatELF();
865   }
866 
867   /// Tests whether the target is T32.
isArmT32()868   bool isArmT32() const {
869     switch (getSubArch()) {
870     case Triple::ARMSubArch_v8m_baseline:
871     case Triple::ARMSubArch_v7s:
872     case Triple::ARMSubArch_v7k:
873     case Triple::ARMSubArch_v7ve:
874     case Triple::ARMSubArch_v6:
875     case Triple::ARMSubArch_v6m:
876     case Triple::ARMSubArch_v6k:
877     case Triple::ARMSubArch_v6t2:
878     case Triple::ARMSubArch_v5:
879     case Triple::ARMSubArch_v5te:
880     case Triple::ARMSubArch_v4t:
881       return false;
882     default:
883       return true;
884     }
885   }
886 
887   /// Tests whether the target is an M-class.
isArmMClass()888   bool isArmMClass() const {
889     switch (getSubArch()) {
890     case Triple::ARMSubArch_v6m:
891     case Triple::ARMSubArch_v7m:
892     case Triple::ARMSubArch_v7em:
893     case Triple::ARMSubArch_v8m_mainline:
894     case Triple::ARMSubArch_v8m_baseline:
895     case Triple::ARMSubArch_v8_1m_mainline:
896       return true;
897     default:
898       return false;
899     }
900   }
901 
902   /// Tests whether the target is AArch64 (little and big endian).
isAArch64()903   bool isAArch64() const {
904     return getArch() == Triple::aarch64 || getArch() == Triple::aarch64_be ||
905            getArch() == Triple::aarch64_32;
906   }
907 
908   /// Tests whether the target is AArch64 and pointers are the size specified by
909   /// \p PointerWidth.
isAArch64(int PointerWidth)910   bool isAArch64(int PointerWidth) const {
911     assert(PointerWidth == 64 || PointerWidth == 32);
912     if (!isAArch64())
913       return false;
914     return getArch() == Triple::aarch64_32 ||
915                    getEnvironment() == Triple::GNUILP32
916                ? PointerWidth == 32
917                : PointerWidth == 64;
918   }
919 
920   /// Tests whether the target is 32-bit LoongArch.
isLoongArch32()921   bool isLoongArch32() const { return getArch() == Triple::loongarch32; }
922 
923   /// Tests whether the target is 64-bit LoongArch.
isLoongArch64()924   bool isLoongArch64() const { return getArch() == Triple::loongarch64; }
925 
926   /// Tests whether the target is LoongArch (32- and 64-bit).
isLoongArch()927   bool isLoongArch() const { return isLoongArch32() || isLoongArch64(); }
928 
929   /// Tests whether the target is MIPS 32-bit (little and big endian).
isMIPS32()930   bool isMIPS32() const {
931     return getArch() == Triple::mips || getArch() == Triple::mipsel;
932   }
933 
934   /// Tests whether the target is MIPS 64-bit (little and big endian).
isMIPS64()935   bool isMIPS64() const {
936     return getArch() == Triple::mips64 || getArch() == Triple::mips64el;
937   }
938 
939   /// Tests whether the target is MIPS (little and big endian, 32- or 64-bit).
isMIPS()940   bool isMIPS() const {
941     return isMIPS32() || isMIPS64();
942   }
943 
944   /// Tests whether the target is PowerPC (32- or 64-bit LE or BE).
isPPC()945   bool isPPC() const {
946     return getArch() == Triple::ppc || getArch() == Triple::ppc64 ||
947            getArch() == Triple::ppcle || getArch() == Triple::ppc64le;
948   }
949 
950   /// Tests whether the target is 32-bit PowerPC (little and big endian).
isPPC32()951   bool isPPC32() const {
952     return getArch() == Triple::ppc || getArch() == Triple::ppcle;
953   }
954 
955   /// Tests whether the target is 64-bit PowerPC (little and big endian).
isPPC64()956   bool isPPC64() const {
957     return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le;
958   }
959 
960   /// Tests whether the target 64-bit PowerPC big endian ABI is ELFv2.
isPPC64ELFv2ABI()961   bool isPPC64ELFv2ABI() const {
962     return (getArch() == Triple::ppc64 &&
963             ((getOS() == Triple::FreeBSD &&
964               (getOSMajorVersion() >= 13 || getOSVersion().empty())) ||
965              getOS() == Triple::OpenBSD || isMusl()));
966   }
967 
968   /// Tests whether the target 32-bit PowerPC uses Secure PLT.
isPPC32SecurePlt()969   bool isPPC32SecurePlt() const {
970     return ((getArch() == Triple::ppc || getArch() == Triple::ppcle) &&
971             ((getOS() == Triple::FreeBSD &&
972               (getOSMajorVersion() >= 13 || getOSVersion().empty())) ||
973              getOS() == Triple::NetBSD || getOS() == Triple::OpenBSD ||
974              isMusl()));
975   }
976 
977   /// Tests whether the target is 32-bit RISC-V.
isRISCV32()978   bool isRISCV32() const { return getArch() == Triple::riscv32; }
979 
980   /// Tests whether the target is 64-bit RISC-V.
isRISCV64()981   bool isRISCV64() const { return getArch() == Triple::riscv64; }
982 
983   /// Tests whether the target is RISC-V (32- and 64-bit).
isRISCV()984   bool isRISCV() const { return isRISCV32() || isRISCV64(); }
985 
986   /// Tests whether the target is 32-bit SPARC (little and big endian).
isSPARC32()987   bool isSPARC32() const {
988     return getArch() == Triple::sparc || getArch() == Triple::sparcel;
989   }
990 
991   /// Tests whether the target is 64-bit SPARC (big endian).
isSPARC64()992   bool isSPARC64() const { return getArch() == Triple::sparcv9; }
993 
994   /// Tests whether the target is SPARC.
isSPARC()995   bool isSPARC() const { return isSPARC32() || isSPARC64(); }
996 
997   /// Tests whether the target is SystemZ.
isSystemZ()998   bool isSystemZ() const {
999     return getArch() == Triple::systemz;
1000   }
1001 
1002   /// Tests whether the target is x86 (32- or 64-bit).
isX86()1003   bool isX86() const {
1004     return getArch() == Triple::x86 || getArch() == Triple::x86_64;
1005   }
1006 
1007   /// Tests whether the target is VE
isVE()1008   bool isVE() const {
1009     return getArch() == Triple::ve;
1010   }
1011 
1012   /// Tests whether the target is wasm (32- and 64-bit).
isWasm()1013   bool isWasm() const {
1014     return getArch() == Triple::wasm32 || getArch() == Triple::wasm64;
1015   }
1016 
1017   // Tests whether the target is CSKY
isCSKY()1018   bool isCSKY() const {
1019     return getArch() == Triple::csky;
1020   }
1021 
1022   /// Tests whether the target is the Apple "arm64e" AArch64 subarch.
isArm64e()1023   bool isArm64e() const {
1024     return getArch() == Triple::aarch64 &&
1025            getSubArch() == Triple::AArch64SubArch_arm64e;
1026   }
1027 
1028   /// Tests whether the target is X32.
isX32()1029   bool isX32() const {
1030     EnvironmentType Env = getEnvironment();
1031     return Env == Triple::GNUX32 || Env == Triple::MuslX32;
1032   }
1033 
1034   /// Tests whether the target is eBPF.
isBPF()1035   bool isBPF() const {
1036     return getArch() == Triple::bpfel || getArch() == Triple::bpfeb;
1037   }
1038 
1039   /// Tests whether the target supports comdat
supportsCOMDAT()1040   bool supportsCOMDAT() const {
1041     return !(isOSBinFormatMachO() || isOSBinFormatXCOFF() ||
1042              isOSBinFormatDXContainer());
1043   }
1044 
1045   /// Tests whether the target uses emulated TLS as default.
1046   ///
1047   /// Note: Android API level 29 (10) introduced ELF TLS.
hasDefaultEmulatedTLS()1048   bool hasDefaultEmulatedTLS() const {
1049     return (isAndroid() && isAndroidVersionLT(29)) || isOSOpenBSD() ||
1050            isWindowsCygwinEnvironment() || isOHOSFamily();
1051   }
1052 
1053   /// True if the target supports both general-dynamic and TLSDESC, and TLSDESC
1054   /// is enabled by default.
hasDefaultTLSDESC()1055   bool hasDefaultTLSDESC() const { return isAndroid() && isRISCV64(); }
1056 
1057   /// Tests whether the target uses -data-sections as default.
hasDefaultDataSections()1058   bool hasDefaultDataSections() const {
1059     return isOSBinFormatXCOFF() || isWasm();
1060   }
1061 
1062   /// Tests if the environment supports dllimport/export annotations.
hasDLLImportExport()1063   bool hasDLLImportExport() const { return isOSWindows() || isPS(); }
1064 
1065   /// @}
1066   /// @name Mutators
1067   /// @{
1068 
1069   /// Set the architecture (first) component of the triple to a known type.
1070   void setArch(ArchType Kind, SubArchType SubArch = NoSubArch);
1071 
1072   /// Set the vendor (second) component of the triple to a known type.
1073   void setVendor(VendorType Kind);
1074 
1075   /// Set the operating system (third) component of the triple to a known type.
1076   void setOS(OSType Kind);
1077 
1078   /// Set the environment (fourth) component of the triple to a known type.
1079   void setEnvironment(EnvironmentType Kind);
1080 
1081   /// Set the object file format.
1082   void setObjectFormat(ObjectFormatType Kind);
1083 
1084   /// Set all components to the new triple \p Str.
1085   void setTriple(const Twine &Str);
1086 
1087   /// Set the architecture (first) component of the triple by name.
1088   void setArchName(StringRef Str);
1089 
1090   /// Set the vendor (second) component of the triple by name.
1091   void setVendorName(StringRef Str);
1092 
1093   /// Set the operating system (third) component of the triple by name.
1094   void setOSName(StringRef Str);
1095 
1096   /// Set the optional environment (fourth) component of the triple by name.
1097   void setEnvironmentName(StringRef Str);
1098 
1099   /// Set the operating system and optional environment components with a single
1100   /// string.
1101   void setOSAndEnvironmentName(StringRef Str);
1102 
1103   /// @}
1104   /// @name Helpers to build variants of a particular triple.
1105   /// @{
1106 
1107   /// Form a triple with a 32-bit variant of the current architecture.
1108   ///
1109   /// This can be used to move across "families" of architectures where useful.
1110   ///
1111   /// \returns A new triple with a 32-bit architecture or an unknown
1112   ///          architecture if no such variant can be found.
1113   llvm::Triple get32BitArchVariant() const;
1114 
1115   /// Form a triple with a 64-bit variant of the current architecture.
1116   ///
1117   /// This can be used to move across "families" of architectures where useful.
1118   ///
1119   /// \returns A new triple with a 64-bit architecture or an unknown
1120   ///          architecture if no such variant can be found.
1121   llvm::Triple get64BitArchVariant() const;
1122 
1123   /// Form a triple with a big endian variant of the current architecture.
1124   ///
1125   /// This can be used to move across "families" of architectures where useful.
1126   ///
1127   /// \returns A new triple with a big endian architecture or an unknown
1128   ///          architecture if no such variant can be found.
1129   llvm::Triple getBigEndianArchVariant() const;
1130 
1131   /// Form a triple with a little endian variant of the current architecture.
1132   ///
1133   /// This can be used to move across "families" of architectures where useful.
1134   ///
1135   /// \returns A new triple with a little endian architecture or an unknown
1136   ///          architecture if no such variant can be found.
1137   llvm::Triple getLittleEndianArchVariant() const;
1138 
1139   /// Tests whether the target triple is little endian.
1140   ///
1141   /// \returns true if the triple is little endian, false otherwise.
1142   bool isLittleEndian() const;
1143 
1144   /// Test whether target triples are compatible.
1145   bool isCompatibleWith(const Triple &Other) const;
1146 
1147   /// Merge target triples.
1148   std::string merge(const Triple &Other) const;
1149 
1150   /// Some platforms have different minimum supported OS versions that
1151   /// varies by the architecture specified in the triple. This function
1152   /// returns the minimum supported OS version for this triple if one an exists,
1153   /// or an invalid version tuple if this triple doesn't have one.
1154   VersionTuple getMinimumSupportedOSVersion() const;
1155 
1156   /// @}
1157   /// @name Static helpers for IDs.
1158   /// @{
1159 
1160   /// Get the canonical name for the \p Kind architecture.
1161   static StringRef getArchTypeName(ArchType Kind);
1162 
1163   /// Get the architecture name based on \p Kind and \p SubArch.
1164   static StringRef getArchName(ArchType Kind, SubArchType SubArch = NoSubArch);
1165 
1166   /// Get the "prefix" canonical name for the \p Kind architecture. This is the
1167   /// prefix used by the architecture specific builtins, and is suitable for
1168   /// passing to \see Intrinsic::getIntrinsicForClangBuiltin().
1169   ///
1170   /// \return - The architecture prefix, or 0 if none is defined.
1171   static StringRef getArchTypePrefix(ArchType Kind);
1172 
1173   /// Get the canonical name for the \p Kind vendor.
1174   static StringRef getVendorTypeName(VendorType Kind);
1175 
1176   /// Get the canonical name for the \p Kind operating system.
1177   static StringRef getOSTypeName(OSType Kind);
1178 
1179   /// Get the canonical name for the \p Kind environment.
1180   static StringRef getEnvironmentTypeName(EnvironmentType Kind);
1181 
1182   /// Get the name for the \p Object format.
1183   static StringRef getObjectFormatTypeName(ObjectFormatType ObjectFormat);
1184 
1185   /// @}
1186   /// @name Static helpers for converting alternate architecture names.
1187   /// @{
1188 
1189   /// The canonical type for the given LLVM architecture name (e.g., "x86").
1190   static ArchType getArchTypeForLLVMName(StringRef Str);
1191 
1192   /// @}
1193 
1194   /// Returns a canonicalized OS version number for the specified OS.
1195   static VersionTuple getCanonicalVersionForOS(OSType OSKind,
1196                                                const VersionTuple &Version);
1197 };
1198 
1199 } // End llvm namespace
1200 
1201 
1202 #endif
1203