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     DriverKit,  // Apple DriverKit
218     XROS,       // Apple XROS
219     Mesa3D,
220     AMDPAL,     // AMD PAL Runtime
221     HermitCore, // HermitCore Unikernel/Multikernel
222     Hurd,       // GNU/Hurd
223     WASI,       // Experimental WebAssembly OS
224     Emscripten,
225     ShaderModel, // DirectX ShaderModel
226     LiteOS,
227     Serenity,
228     Vulkan,      // Vulkan SPIR-V
229     LastOSType = Vulkan
230   };
231   enum EnvironmentType {
232     UnknownEnvironment,
233 
234     GNU,
235     GNUABIN32,
236     GNUABI64,
237     GNUEABI,
238     GNUEABIHF,
239     GNUF32,
240     GNUF64,
241     GNUSF,
242     GNUX32,
243     GNUILP32,
244     CODE16,
245     EABI,
246     EABIHF,
247     Android,
248     Musl,
249     MuslEABI,
250     MuslEABIHF,
251     MuslX32,
252 
253     MSVC,
254     Itanium,
255     Cygnus,
256     CoreCLR,
257     Simulator, // Simulator variants of other systems, e.g., Apple's iOS
258     MacABI, // Mac Catalyst variant of Apple's iOS deployment target.
259 
260     // Shader Stages
261     // The order of these values matters, and must be kept in sync with the
262     // language options enum in Clang. The ordering is enforced in
263     // static_asserts in Triple.cpp and in Clang.
264     Pixel,
265     Vertex,
266     Geometry,
267     Hull,
268     Domain,
269     Compute,
270     Library,
271     RayGeneration,
272     Intersection,
273     AnyHit,
274     ClosestHit,
275     Miss,
276     Callable,
277     Mesh,
278     Amplification,
279 
280     OpenHOS,
281 
282     LastEnvironmentType = OpenHOS
283   };
284   enum ObjectFormatType {
285     UnknownObjectFormat,
286 
287     COFF,
288     DXContainer,
289     ELF,
290     GOFF,
291     MachO,
292     SPIRV,
293     Wasm,
294     XCOFF,
295   };
296 
297 private:
298   std::string Data;
299 
300   /// The parsed arch type.
301   ArchType Arch{};
302 
303   /// The parsed subarchitecture type.
304   SubArchType SubArch{};
305 
306   /// The parsed vendor type.
307   VendorType Vendor{};
308 
309   /// The parsed OS type.
310   OSType OS{};
311 
312   /// The parsed Environment type.
313   EnvironmentType Environment{};
314 
315   /// The object format type.
316   ObjectFormatType ObjectFormat{};
317 
318 public:
319   /// @name Constructors
320   /// @{
321 
322   /// Default constructor is the same as an empty string and leaves all
323   /// triple fields unknown.
324   Triple() = default;
325 
326   explicit Triple(const Twine &Str);
327   Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
328   Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
329          const Twine &EnvironmentStr);
330 
331   bool operator==(const Triple &Other) const {
332     return Arch == Other.Arch && SubArch == Other.SubArch &&
333            Vendor == Other.Vendor && OS == Other.OS &&
334            Environment == Other.Environment &&
335            ObjectFormat == Other.ObjectFormat;
336   }
337 
338   bool operator!=(const Triple &Other) const {
339     return !(*this == Other);
340   }
341 
342   /// @}
343   /// @name Normalization
344   /// @{
345 
346   /// Turn an arbitrary machine specification into the canonical triple form (or
347   /// something sensible that the Triple class understands if nothing better can
348   /// reasonably be done).  In particular, it handles the common case in which
349   /// otherwise valid components are in the wrong order.
350   static std::string normalize(StringRef Str);
351 
352   /// Return the normalized form of this triple's string.
normalize()353   std::string normalize() const { return normalize(Data); }
354 
355   /// @}
356   /// @name Typed Component Access
357   /// @{
358 
359   /// Get the parsed architecture type of this triple.
getArch()360   ArchType getArch() const { return Arch; }
361 
362   /// get the parsed subarchitecture type for this triple.
getSubArch()363   SubArchType getSubArch() const { return SubArch; }
364 
365   /// Get the parsed vendor type of this triple.
getVendor()366   VendorType getVendor() const { return Vendor; }
367 
368   /// Get the parsed operating system type of this triple.
getOS()369   OSType getOS() const { return OS; }
370 
371   /// Does this triple have the optional environment (fourth) component?
hasEnvironment()372   bool hasEnvironment() const {
373     return getEnvironmentName() != "";
374   }
375 
376   /// Get the parsed environment type of this triple.
getEnvironment()377   EnvironmentType getEnvironment() const { return Environment; }
378 
379   /// Parse the version number from the OS name component of the
380   /// triple, if present.
381   ///
382   /// For example, "fooos1.2.3" would return (1, 2, 3).
383   VersionTuple getEnvironmentVersion() const;
384 
385   /// Get the object format for this triple.
getObjectFormat()386   ObjectFormatType getObjectFormat() const { return ObjectFormat; }
387 
388   /// Parse the version number from the OS name component of the triple, if
389   /// present.
390   ///
391   /// For example, "fooos1.2.3" would return (1, 2, 3).
392   VersionTuple getOSVersion() const;
393 
394   /// Return just the major version number, this is specialized because it is a
395   /// common query.
getOSMajorVersion()396   unsigned getOSMajorVersion() const { return getOSVersion().getMajor(); }
397 
398   /// Parse the version number as with getOSVersion and then translate generic
399   /// "darwin" versions to the corresponding OS X versions.  This may also be
400   /// called with IOS triples but the OS X version number is just set to a
401   /// constant 10.4.0 in that case.  Returns true if successful.
402   bool getMacOSXVersion(VersionTuple &Version) const;
403 
404   /// Parse the version number as with getOSVersion.  This should only be called
405   /// with IOS or generic triples.
406   VersionTuple getiOSVersion() const;
407 
408   /// Parse the version number as with getOSVersion.  This should only be called
409   /// with WatchOS or generic triples.
410   VersionTuple getWatchOSVersion() const;
411 
412   /// Parse the version number as with getOSVersion.
413   VersionTuple getDriverKitVersion() const;
414 
415   /// Parse the Vulkan version number from the OSVersion and SPIR-V version
416   /// (SubArch).  This should only be called with Vulkan SPIR-V triples.
417   VersionTuple getVulkanVersion() const;
418 
419   /// @}
420   /// @name Direct Component Access
421   /// @{
422 
str()423   const std::string &str() const { return Data; }
424 
getTriple()425   const std::string &getTriple() const { return Data; }
426 
427   /// Get the architecture (first) component of the triple.
428   StringRef getArchName() const;
429 
430   /// Get the vendor (second) component of the triple.
431   StringRef getVendorName() const;
432 
433   /// Get the operating system (third) component of the triple.
434   StringRef getOSName() const;
435 
436   /// Get the optional environment (fourth) component of the triple, or "" if
437   /// empty.
438   StringRef getEnvironmentName() const;
439 
440   /// Get the operating system and optional environment components as a single
441   /// string (separated by a '-' if the environment component is present).
442   StringRef getOSAndEnvironmentName() const;
443 
444   /// Get the version component of the environment component as a single
445   /// string (the version after the environment).
446   ///
447   /// For example, "fooos1.2.3" would return "1.2.3".
448   StringRef getEnvironmentVersionString() const;
449 
450   /// @}
451   /// @name Convenience Predicates
452   /// @{
453 
454   /// Test whether the architecture is 64-bit
455   ///
456   /// Note that this tests for 64-bit pointer width, and nothing else. Note
457   /// that we intentionally expose only three predicates, 64-bit, 32-bit, and
458   /// 16-bit. The inner details of pointer width for particular architectures
459   /// is not summed up in the triple, and so only a coarse grained predicate
460   /// system is provided.
461   bool isArch64Bit() const;
462 
463   /// Test whether the architecture is 32-bit
464   ///
465   /// Note that this tests for 32-bit pointer width, and nothing else.
466   bool isArch32Bit() const;
467 
468   /// Test whether the architecture is 16-bit
469   ///
470   /// Note that this tests for 16-bit pointer width, and nothing else.
471   bool isArch16Bit() const;
472 
473   /// Helper function for doing comparisons against version numbers included in
474   /// the target triple.
475   bool isOSVersionLT(unsigned Major, unsigned Minor = 0,
476                      unsigned Micro = 0) const {
477     if (Minor == 0) {
478       return getOSVersion() < VersionTuple(Major);
479     }
480     if (Micro == 0) {
481       return getOSVersion() < VersionTuple(Major, Minor);
482     }
483     return getOSVersion() < VersionTuple(Major, Minor, Micro);
484   }
485 
isOSVersionLT(const Triple & Other)486   bool isOSVersionLT(const Triple &Other) const {
487     return getOSVersion() < Other.getOSVersion();
488   }
489 
490   /// Comparison function for checking OS X version compatibility, which handles
491   /// supporting skewed version numbering schemes used by the "darwin" triples.
492   bool isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
493                          unsigned Micro = 0) const;
494 
495   /// Is this a Mac OS X triple. For legacy reasons, we support both "darwin"
496   /// and "osx" as OS X triples.
isMacOSX()497   bool isMacOSX() const {
498     return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
499   }
500 
501   /// Is this an iOS triple.
502   /// Note: This identifies tvOS as a variant of iOS. If that ever
503   /// changes, i.e., if the two operating systems diverge or their version
504   /// numbers get out of sync, that will need to be changed.
505   /// watchOS has completely different version numbers so it is not included.
isiOS()506   bool isiOS() const {
507     return getOS() == Triple::IOS || isTvOS();
508   }
509 
510   /// Is this an Apple tvOS triple.
isTvOS()511   bool isTvOS() const {
512     return getOS() == Triple::TvOS;
513   }
514 
515   /// Is this an Apple watchOS triple.
isWatchOS()516   bool isWatchOS() const {
517     return getOS() == Triple::WatchOS;
518   }
519 
isWatchABI()520   bool isWatchABI() const {
521     return getSubArch() == Triple::ARMSubArch_v7k;
522   }
523 
524   /// Is this an Apple XROS triple.
isXROS()525   bool isXROS() const { return getOS() == Triple::XROS; }
526 
527   /// Is this an Apple DriverKit triple.
isDriverKit()528   bool isDriverKit() const { return getOS() == Triple::DriverKit; }
529 
isOSzOS()530   bool isOSzOS() const { return getOS() == Triple::ZOS; }
531 
532   /// Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).
isOSDarwin()533   bool isOSDarwin() const {
534     return isMacOSX() || isiOS() || isWatchOS() || isDriverKit() || isXROS();
535   }
536 
isSimulatorEnvironment()537   bool isSimulatorEnvironment() const {
538     return getEnvironment() == Triple::Simulator;
539   }
540 
isMacCatalystEnvironment()541   bool isMacCatalystEnvironment() const {
542     return getEnvironment() == Triple::MacABI;
543   }
544 
545   /// Returns true for targets that run on a macOS machine.
isTargetMachineMac()546   bool isTargetMachineMac() const {
547     return isMacOSX() || (isOSDarwin() && (isSimulatorEnvironment() ||
548                                            isMacCatalystEnvironment()));
549   }
550 
isOSNetBSD()551   bool isOSNetBSD() const {
552     return getOS() == Triple::NetBSD;
553   }
554 
isOSOpenBSD()555   bool isOSOpenBSD() const {
556     return getOS() == Triple::OpenBSD;
557   }
558 
isOSFreeBSD()559   bool isOSFreeBSD() const {
560     return getOS() == Triple::FreeBSD;
561   }
562 
isOSFuchsia()563   bool isOSFuchsia() const {
564     return getOS() == Triple::Fuchsia;
565   }
566 
isOSDragonFly()567   bool isOSDragonFly() const { return getOS() == Triple::DragonFly; }
568 
isOSSolaris()569   bool isOSSolaris() const {
570     return getOS() == Triple::Solaris;
571   }
572 
isOSIAMCU()573   bool isOSIAMCU() const {
574     return getOS() == Triple::ELFIAMCU;
575   }
576 
isOSUnknown()577   bool isOSUnknown() const { return getOS() == Triple::UnknownOS; }
578 
isGNUEnvironment()579   bool isGNUEnvironment() const {
580     EnvironmentType Env = getEnvironment();
581     return Env == Triple::GNU || Env == Triple::GNUABIN32 ||
582            Env == Triple::GNUABI64 || Env == Triple::GNUEABI ||
583            Env == Triple::GNUEABIHF || Env == Triple::GNUF32 ||
584            Env == Triple::GNUF64 || Env == Triple::GNUSF ||
585            Env == Triple::GNUX32;
586   }
587 
588   /// Tests whether the OS is Haiku.
isOSHaiku()589   bool isOSHaiku() const {
590     return getOS() == Triple::Haiku;
591   }
592 
593   /// Tests whether the OS is UEFI.
isUEFI()594   bool isUEFI() const {
595     return getOS() == Triple::UEFI;
596   }
597 
598   /// Tests whether the OS is Windows.
isOSWindows()599   bool isOSWindows() const {
600     return getOS() == Triple::Win32;
601   }
602 
603   /// Checks if the environment is MSVC.
isKnownWindowsMSVCEnvironment()604   bool isKnownWindowsMSVCEnvironment() const {
605     return isOSWindows() && getEnvironment() == Triple::MSVC;
606   }
607 
608   /// Checks if the environment could be MSVC.
isWindowsMSVCEnvironment()609   bool isWindowsMSVCEnvironment() const {
610     return isKnownWindowsMSVCEnvironment() ||
611            (isOSWindows() && getEnvironment() == Triple::UnknownEnvironment);
612   }
613 
614   // Checks if we're using the Windows Arm64EC ABI.
isWindowsArm64EC()615   bool isWindowsArm64EC() const {
616     return getArch() == Triple::aarch64 &&
617            getSubArch() == Triple::AArch64SubArch_arm64ec;
618   }
619 
isWindowsCoreCLREnvironment()620   bool isWindowsCoreCLREnvironment() const {
621     return isOSWindows() && getEnvironment() == Triple::CoreCLR;
622   }
623 
isWindowsItaniumEnvironment()624   bool isWindowsItaniumEnvironment() const {
625     return isOSWindows() && getEnvironment() == Triple::Itanium;
626   }
627 
isWindowsCygwinEnvironment()628   bool isWindowsCygwinEnvironment() const {
629     return isOSWindows() && getEnvironment() == Triple::Cygnus;
630   }
631 
isWindowsGNUEnvironment()632   bool isWindowsGNUEnvironment() const {
633     return isOSWindows() && getEnvironment() == Triple::GNU;
634   }
635 
636   /// Tests for either Cygwin or MinGW OS
isOSCygMing()637   bool isOSCygMing() const {
638     return isWindowsCygwinEnvironment() || isWindowsGNUEnvironment();
639   }
640 
641   /// Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
isOSMSVCRT()642   bool isOSMSVCRT() const {
643     return isWindowsMSVCEnvironment() || isWindowsGNUEnvironment() ||
644            isWindowsItaniumEnvironment();
645   }
646 
647   /// Tests whether the OS is NaCl (Native Client)
isOSNaCl()648   bool isOSNaCl() const {
649     return getOS() == Triple::NaCl;
650   }
651 
652   /// Tests whether the OS is Linux.
isOSLinux()653   bool isOSLinux() const {
654     return getOS() == Triple::Linux;
655   }
656 
657   /// Tests whether the OS is kFreeBSD.
isOSKFreeBSD()658   bool isOSKFreeBSD() const {
659     return getOS() == Triple::KFreeBSD;
660   }
661 
662   /// Tests whether the OS is Hurd.
isOSHurd()663   bool isOSHurd() const {
664     return getOS() == Triple::Hurd;
665   }
666 
667   /// Tests whether the OS is WASI.
isOSWASI()668   bool isOSWASI() const {
669     return getOS() == Triple::WASI;
670   }
671 
672   /// Tests whether the OS is Emscripten.
isOSEmscripten()673   bool isOSEmscripten() const {
674     return getOS() == Triple::Emscripten;
675   }
676 
677   /// Tests whether the OS uses glibc.
isOSGlibc()678   bool isOSGlibc() const {
679     return (getOS() == Triple::Linux || getOS() == Triple::KFreeBSD ||
680             getOS() == Triple::Hurd) &&
681            !isAndroid();
682   }
683 
684   /// Tests whether the OS is AIX.
isOSAIX()685   bool isOSAIX() const {
686     return getOS() == Triple::AIX;
687   }
688 
isOSSerenity()689   bool isOSSerenity() const {
690     return getOS() == Triple::Serenity;
691   }
692 
693   /// Tests whether the OS uses the ELF binary format.
isOSBinFormatELF()694   bool isOSBinFormatELF() const {
695     return getObjectFormat() == Triple::ELF;
696   }
697 
698   /// Tests whether the OS uses the COFF binary format.
isOSBinFormatCOFF()699   bool isOSBinFormatCOFF() const {
700     return getObjectFormat() == Triple::COFF;
701   }
702 
703   /// Tests whether the OS uses the GOFF binary format.
isOSBinFormatGOFF()704   bool isOSBinFormatGOFF() const { return getObjectFormat() == Triple::GOFF; }
705 
706   /// Tests whether the environment is MachO.
isOSBinFormatMachO()707   bool isOSBinFormatMachO() const {
708     return getObjectFormat() == Triple::MachO;
709   }
710 
711   /// Tests whether the OS uses the Wasm binary format.
isOSBinFormatWasm()712   bool isOSBinFormatWasm() const {
713     return getObjectFormat() == Triple::Wasm;
714   }
715 
716   /// Tests whether the OS uses the XCOFF binary format.
isOSBinFormatXCOFF()717   bool isOSBinFormatXCOFF() const {
718     return getObjectFormat() == Triple::XCOFF;
719   }
720 
721   /// Tests whether the OS uses the DXContainer binary format.
isOSBinFormatDXContainer()722   bool isOSBinFormatDXContainer() const {
723     return getObjectFormat() == Triple::DXContainer;
724   }
725 
726   /// Tests whether the target is the PS4 platform.
isPS4()727   bool isPS4() const {
728     return getArch() == Triple::x86_64 &&
729            getVendor() == Triple::SCEI &&
730            getOS() == Triple::PS4;
731   }
732 
733   /// Tests whether the target is the PS5 platform.
isPS5()734   bool isPS5() const {
735     return getArch() == Triple::x86_64 &&
736       getVendor() == Triple::SCEI &&
737       getOS() == Triple::PS5;
738   }
739 
740   /// Tests whether the target is the PS4 or PS5 platform.
isPS()741   bool isPS() const { return isPS4() || isPS5(); }
742 
743   /// Tests whether the target is Android
isAndroid()744   bool isAndroid() const { return getEnvironment() == Triple::Android; }
745 
isAndroidVersionLT(unsigned Major)746   bool isAndroidVersionLT(unsigned Major) const {
747     assert(isAndroid() && "Not an Android triple!");
748 
749     VersionTuple Version = getEnvironmentVersion();
750 
751     // 64-bit targets did not exist before API level 21 (Lollipop).
752     if (isArch64Bit() && Version.getMajor() < 21)
753       return VersionTuple(21) < VersionTuple(Major);
754 
755     return Version < VersionTuple(Major);
756   }
757 
758   /// Tests whether the environment is musl-libc
isMusl()759   bool isMusl() const {
760     return getEnvironment() == Triple::Musl ||
761            getEnvironment() == Triple::MuslEABI ||
762            getEnvironment() == Triple::MuslEABIHF ||
763            getEnvironment() == Triple::MuslX32 ||
764            getEnvironment() == Triple::OpenHOS || isOSLiteOS();
765   }
766 
767   /// Tests whether the target is OHOS
768   /// LiteOS default enviroment is also OHOS, but omited on triple.
isOHOSFamily()769   bool isOHOSFamily() const { return isOpenHOS() || isOSLiteOS(); }
770 
isOpenHOS()771   bool isOpenHOS() const { return getEnvironment() == Triple::OpenHOS; }
772 
isOSLiteOS()773   bool isOSLiteOS() const { return getOS() == Triple::LiteOS; }
774 
775   /// Tests whether the target is DXIL.
isDXIL()776   bool isDXIL() const {
777     return getArch() == Triple::dxil;
778   }
779 
isShaderModelOS()780   bool isShaderModelOS() const {
781     return getOS() == Triple::ShaderModel;
782   }
783 
isVulkanOS()784   bool isVulkanOS() const { return getOS() == Triple::Vulkan; }
785 
isShaderStageEnvironment()786   bool isShaderStageEnvironment() const {
787     EnvironmentType Env = getEnvironment();
788     return Env == Triple::Pixel || Env == Triple::Vertex ||
789            Env == Triple::Geometry || Env == Triple::Hull ||
790            Env == Triple::Domain || Env == Triple::Compute ||
791            Env == Triple::Library || Env == Triple::RayGeneration ||
792            Env == Triple::Intersection || Env == Triple::AnyHit ||
793            Env == Triple::ClosestHit || Env == Triple::Miss ||
794            Env == Triple::Callable || Env == Triple::Mesh ||
795            Env == Triple::Amplification;
796   }
797 
798   /// Tests whether the target is SPIR (32- or 64-bit).
isSPIR()799   bool isSPIR() const {
800     return getArch() == Triple::spir || getArch() == Triple::spir64;
801   }
802 
803   /// Tests whether the target is SPIR-V (32/64-bit/Logical).
isSPIRV()804   bool isSPIRV() const {
805     return getArch() == Triple::spirv32 || getArch() == Triple::spirv64 ||
806            getArch() == Triple::spirv;
807   }
808 
809   /// Tests whether the target is SPIR-V Logical
isSPIRVLogical()810   bool isSPIRVLogical() const {
811     return getArch() == Triple::spirv;
812   }
813 
814   /// Tests whether the target is NVPTX (32- or 64-bit).
isNVPTX()815   bool isNVPTX() const {
816     return getArch() == Triple::nvptx || getArch() == Triple::nvptx64;
817   }
818 
819   /// Tests whether the target is AMDGCN
isAMDGCN()820   bool isAMDGCN() const { return getArch() == Triple::amdgcn; }
821 
isAMDGPU()822   bool isAMDGPU() const {
823     return getArch() == Triple::r600 || getArch() == Triple::amdgcn;
824   }
825 
826   /// Tests whether the target is Thumb (little and big endian).
isThumb()827   bool isThumb() const {
828     return getArch() == Triple::thumb || getArch() == Triple::thumbeb;
829   }
830 
831   /// Tests whether the target is ARM (little and big endian).
isARM()832   bool isARM() const {
833     return getArch() == Triple::arm || getArch() == Triple::armeb;
834   }
835 
836   /// Tests whether the target supports the EHABI exception
837   /// handling standard.
isTargetEHABICompatible()838   bool isTargetEHABICompatible() const {
839     return (isARM() || isThumb()) &&
840            (getEnvironment() == Triple::EABI ||
841             getEnvironment() == Triple::GNUEABI ||
842             getEnvironment() == Triple::MuslEABI ||
843             getEnvironment() == Triple::EABIHF ||
844             getEnvironment() == Triple::GNUEABIHF ||
845             getEnvironment() == Triple::OpenHOS ||
846             getEnvironment() == Triple::MuslEABIHF || isAndroid()) &&
847            isOSBinFormatELF();
848   }
849 
850   /// Tests whether the target is T32.
isArmT32()851   bool isArmT32() const {
852     switch (getSubArch()) {
853     case Triple::ARMSubArch_v8m_baseline:
854     case Triple::ARMSubArch_v7s:
855     case Triple::ARMSubArch_v7k:
856     case Triple::ARMSubArch_v7ve:
857     case Triple::ARMSubArch_v6:
858     case Triple::ARMSubArch_v6m:
859     case Triple::ARMSubArch_v6k:
860     case Triple::ARMSubArch_v6t2:
861     case Triple::ARMSubArch_v5:
862     case Triple::ARMSubArch_v5te:
863     case Triple::ARMSubArch_v4t:
864       return false;
865     default:
866       return true;
867     }
868   }
869 
870   /// Tests whether the target is an M-class.
isArmMClass()871   bool isArmMClass() const {
872     switch (getSubArch()) {
873     case Triple::ARMSubArch_v6m:
874     case Triple::ARMSubArch_v7m:
875     case Triple::ARMSubArch_v7em:
876     case Triple::ARMSubArch_v8m_mainline:
877     case Triple::ARMSubArch_v8m_baseline:
878     case Triple::ARMSubArch_v8_1m_mainline:
879       return true;
880     default:
881       return false;
882     }
883   }
884 
885   /// Tests whether the target is AArch64 (little and big endian).
isAArch64()886   bool isAArch64() const {
887     return getArch() == Triple::aarch64 || getArch() == Triple::aarch64_be ||
888            getArch() == Triple::aarch64_32;
889   }
890 
891   /// Tests whether the target is AArch64 and pointers are the size specified by
892   /// \p PointerWidth.
isAArch64(int PointerWidth)893   bool isAArch64(int PointerWidth) const {
894     assert(PointerWidth == 64 || PointerWidth == 32);
895     if (!isAArch64())
896       return false;
897     return getArch() == Triple::aarch64_32 ||
898                    getEnvironment() == Triple::GNUILP32
899                ? PointerWidth == 32
900                : PointerWidth == 64;
901   }
902 
903   /// Tests whether the target is 32-bit LoongArch.
isLoongArch32()904   bool isLoongArch32() const { return getArch() == Triple::loongarch32; }
905 
906   /// Tests whether the target is 64-bit LoongArch.
isLoongArch64()907   bool isLoongArch64() const { return getArch() == Triple::loongarch64; }
908 
909   /// Tests whether the target is LoongArch (32- and 64-bit).
isLoongArch()910   bool isLoongArch() const { return isLoongArch32() || isLoongArch64(); }
911 
912   /// Tests whether the target is MIPS 32-bit (little and big endian).
isMIPS32()913   bool isMIPS32() const {
914     return getArch() == Triple::mips || getArch() == Triple::mipsel;
915   }
916 
917   /// Tests whether the target is MIPS 64-bit (little and big endian).
isMIPS64()918   bool isMIPS64() const {
919     return getArch() == Triple::mips64 || getArch() == Triple::mips64el;
920   }
921 
922   /// Tests whether the target is MIPS (little and big endian, 32- or 64-bit).
isMIPS()923   bool isMIPS() const {
924     return isMIPS32() || isMIPS64();
925   }
926 
927   /// Tests whether the target is PowerPC (32- or 64-bit LE or BE).
isPPC()928   bool isPPC() const {
929     return getArch() == Triple::ppc || getArch() == Triple::ppc64 ||
930            getArch() == Triple::ppcle || getArch() == Triple::ppc64le;
931   }
932 
933   /// Tests whether the target is 32-bit PowerPC (little and big endian).
isPPC32()934   bool isPPC32() const {
935     return getArch() == Triple::ppc || getArch() == Triple::ppcle;
936   }
937 
938   /// Tests whether the target is 64-bit PowerPC (little and big endian).
isPPC64()939   bool isPPC64() const {
940     return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le;
941   }
942 
943   /// Tests whether the target 64-bit PowerPC big endian ABI is ELFv2.
isPPC64ELFv2ABI()944   bool isPPC64ELFv2ABI() const {
945     return (getArch() == Triple::ppc64 &&
946             ((getOS() == Triple::FreeBSD &&
947               (getOSMajorVersion() >= 13 || getOSVersion().empty())) ||
948              getOS() == Triple::OpenBSD || isMusl()));
949   }
950 
951   /// Tests whether the target 32-bit PowerPC uses Secure PLT.
isPPC32SecurePlt()952   bool isPPC32SecurePlt() const {
953     return ((getArch() == Triple::ppc || getArch() == Triple::ppcle) &&
954             ((getOS() == Triple::FreeBSD &&
955               (getOSMajorVersion() >= 13 || getOSVersion().empty())) ||
956              getOS() == Triple::NetBSD || getOS() == Triple::OpenBSD ||
957              isMusl()));
958   }
959 
960   /// Tests whether the target is 32-bit RISC-V.
isRISCV32()961   bool isRISCV32() const { return getArch() == Triple::riscv32; }
962 
963   /// Tests whether the target is 64-bit RISC-V.
isRISCV64()964   bool isRISCV64() const { return getArch() == Triple::riscv64; }
965 
966   /// Tests whether the target is RISC-V (32- and 64-bit).
isRISCV()967   bool isRISCV() const { return isRISCV32() || isRISCV64(); }
968 
969   /// Tests whether the target is 32-bit SPARC (little and big endian).
isSPARC32()970   bool isSPARC32() const {
971     return getArch() == Triple::sparc || getArch() == Triple::sparcel;
972   }
973 
974   /// Tests whether the target is 64-bit SPARC (big endian).
isSPARC64()975   bool isSPARC64() const { return getArch() == Triple::sparcv9; }
976 
977   /// Tests whether the target is SPARC.
isSPARC()978   bool isSPARC() const { return isSPARC32() || isSPARC64(); }
979 
980   /// Tests whether the target is SystemZ.
isSystemZ()981   bool isSystemZ() const {
982     return getArch() == Triple::systemz;
983   }
984 
985   /// Tests whether the target is x86 (32- or 64-bit).
isX86()986   bool isX86() const {
987     return getArch() == Triple::x86 || getArch() == Triple::x86_64;
988   }
989 
990   /// Tests whether the target is VE
isVE()991   bool isVE() const {
992     return getArch() == Triple::ve;
993   }
994 
995   /// Tests whether the target is wasm (32- and 64-bit).
isWasm()996   bool isWasm() const {
997     return getArch() == Triple::wasm32 || getArch() == Triple::wasm64;
998   }
999 
1000   // Tests whether the target is CSKY
isCSKY()1001   bool isCSKY() const {
1002     return getArch() == Triple::csky;
1003   }
1004 
1005   /// Tests whether the target is the Apple "arm64e" AArch64 subarch.
isArm64e()1006   bool isArm64e() const {
1007     return getArch() == Triple::aarch64 &&
1008            getSubArch() == Triple::AArch64SubArch_arm64e;
1009   }
1010 
1011   /// Tests whether the target is X32.
isX32()1012   bool isX32() const {
1013     EnvironmentType Env = getEnvironment();
1014     return Env == Triple::GNUX32 || Env == Triple::MuslX32;
1015   }
1016 
1017   /// Tests whether the target is eBPF.
isBPF()1018   bool isBPF() const {
1019     return getArch() == Triple::bpfel || getArch() == Triple::bpfeb;
1020   }
1021 
1022   /// Tests whether the target supports comdat
supportsCOMDAT()1023   bool supportsCOMDAT() const {
1024     return !(isOSBinFormatMachO() || isOSBinFormatXCOFF() ||
1025              isOSBinFormatDXContainer());
1026   }
1027 
1028   /// Tests whether the target uses emulated TLS as default.
1029   ///
1030   /// Note: Android API level 29 (10) introduced ELF TLS.
hasDefaultEmulatedTLS()1031   bool hasDefaultEmulatedTLS() const {
1032     return (isAndroid() && isAndroidVersionLT(29)) || isOSOpenBSD() ||
1033            isWindowsCygwinEnvironment() || isOHOSFamily();
1034   }
1035 
1036   /// True if the target supports both general-dynamic and TLSDESC, and TLSDESC
1037   /// is enabled by default.
hasDefaultTLSDESC()1038   bool hasDefaultTLSDESC() const {
1039     // TODO: Improve check for other platforms, like Android, and RISC-V
1040     return false;
1041   }
1042 
1043   /// Tests whether the target uses -data-sections as default.
hasDefaultDataSections()1044   bool hasDefaultDataSections() const {
1045     return isOSBinFormatXCOFF() || isWasm();
1046   }
1047 
1048   /// Tests if the environment supports dllimport/export annotations.
hasDLLImportExport()1049   bool hasDLLImportExport() const { return isOSWindows() || isPS(); }
1050 
1051   /// @}
1052   /// @name Mutators
1053   /// @{
1054 
1055   /// Set the architecture (first) component of the triple to a known type.
1056   void setArch(ArchType Kind, SubArchType SubArch = NoSubArch);
1057 
1058   /// Set the vendor (second) component of the triple to a known type.
1059   void setVendor(VendorType Kind);
1060 
1061   /// Set the operating system (third) component of the triple to a known type.
1062   void setOS(OSType Kind);
1063 
1064   /// Set the environment (fourth) component of the triple to a known type.
1065   void setEnvironment(EnvironmentType Kind);
1066 
1067   /// Set the object file format.
1068   void setObjectFormat(ObjectFormatType Kind);
1069 
1070   /// Set all components to the new triple \p Str.
1071   void setTriple(const Twine &Str);
1072 
1073   /// Set the architecture (first) component of the triple by name.
1074   void setArchName(StringRef Str);
1075 
1076   /// Set the vendor (second) component of the triple by name.
1077   void setVendorName(StringRef Str);
1078 
1079   /// Set the operating system (third) component of the triple by name.
1080   void setOSName(StringRef Str);
1081 
1082   /// Set the optional environment (fourth) component of the triple by name.
1083   void setEnvironmentName(StringRef Str);
1084 
1085   /// Set the operating system and optional environment components with a single
1086   /// string.
1087   void setOSAndEnvironmentName(StringRef Str);
1088 
1089   /// @}
1090   /// @name Helpers to build variants of a particular triple.
1091   /// @{
1092 
1093   /// Form a triple with a 32-bit variant of the current architecture.
1094   ///
1095   /// This can be used to move across "families" of architectures where useful.
1096   ///
1097   /// \returns A new triple with a 32-bit architecture or an unknown
1098   ///          architecture if no such variant can be found.
1099   llvm::Triple get32BitArchVariant() const;
1100 
1101   /// Form a triple with a 64-bit variant of the current architecture.
1102   ///
1103   /// This can be used to move across "families" of architectures where useful.
1104   ///
1105   /// \returns A new triple with a 64-bit architecture or an unknown
1106   ///          architecture if no such variant can be found.
1107   llvm::Triple get64BitArchVariant() const;
1108 
1109   /// Form a triple with a big endian variant of the current architecture.
1110   ///
1111   /// This can be used to move across "families" of architectures where useful.
1112   ///
1113   /// \returns A new triple with a big endian architecture or an unknown
1114   ///          architecture if no such variant can be found.
1115   llvm::Triple getBigEndianArchVariant() const;
1116 
1117   /// Form a triple with a little endian variant of the current architecture.
1118   ///
1119   /// This can be used to move across "families" of architectures where useful.
1120   ///
1121   /// \returns A new triple with a little endian architecture or an unknown
1122   ///          architecture if no such variant can be found.
1123   llvm::Triple getLittleEndianArchVariant() const;
1124 
1125   /// Tests whether the target triple is little endian.
1126   ///
1127   /// \returns true if the triple is little endian, false otherwise.
1128   bool isLittleEndian() const;
1129 
1130   /// Test whether target triples are compatible.
1131   bool isCompatibleWith(const Triple &Other) const;
1132 
1133   /// Merge target triples.
1134   std::string merge(const Triple &Other) const;
1135 
1136   /// Some platforms have different minimum supported OS versions that
1137   /// varies by the architecture specified in the triple. This function
1138   /// returns the minimum supported OS version for this triple if one an exists,
1139   /// or an invalid version tuple if this triple doesn't have one.
1140   VersionTuple getMinimumSupportedOSVersion() const;
1141 
1142   /// @}
1143   /// @name Static helpers for IDs.
1144   /// @{
1145 
1146   /// Get the canonical name for the \p Kind architecture.
1147   static StringRef getArchTypeName(ArchType Kind);
1148 
1149   /// Get the architecture name based on \p Kind and \p SubArch.
1150   static StringRef getArchName(ArchType Kind, SubArchType SubArch = NoSubArch);
1151 
1152   /// Get the "prefix" canonical name for the \p Kind architecture. This is the
1153   /// prefix used by the architecture specific builtins, and is suitable for
1154   /// passing to \see Intrinsic::getIntrinsicForClangBuiltin().
1155   ///
1156   /// \return - The architecture prefix, or 0 if none is defined.
1157   static StringRef getArchTypePrefix(ArchType Kind);
1158 
1159   /// Get the canonical name for the \p Kind vendor.
1160   static StringRef getVendorTypeName(VendorType Kind);
1161 
1162   /// Get the canonical name for the \p Kind operating system.
1163   static StringRef getOSTypeName(OSType Kind);
1164 
1165   /// Get the canonical name for the \p Kind environment.
1166   static StringRef getEnvironmentTypeName(EnvironmentType Kind);
1167 
1168   /// Get the name for the \p Object format.
1169   static StringRef getObjectFormatTypeName(ObjectFormatType ObjectFormat);
1170 
1171   /// @}
1172   /// @name Static helpers for converting alternate architecture names.
1173   /// @{
1174 
1175   /// The canonical type for the given LLVM architecture name (e.g., "x86").
1176   static ArchType getArchTypeForLLVMName(StringRef Str);
1177 
1178   /// @}
1179 
1180   /// Returns a canonicalized OS version number for the specified OS.
1181   static VersionTuple getCanonicalVersionForOS(OSType OSKind,
1182                                                const VersionTuple &Version);
1183 };
1184 
1185 } // End llvm namespace
1186 
1187 
1188 #endif
1189