1193323Sed//===-- llvm/ADT/Triple.h - Target triple helper class ----------*- C++ -*-===//
2193323Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193323Sed//
7193323Sed//===----------------------------------------------------------------------===//
8193323Sed
9193323Sed#ifndef LLVM_ADT_TRIPLE_H
10193323Sed#define LLVM_ADT_TRIPLE_H
11193323Sed
12226633Sdim#include "llvm/ADT/Twine.h"
13193323Sed
14198090Srdivacky// Some system headers or GCC predefined macros conflict with identifiers in
15198090Srdivacky// this file.  Undefine them here.
16261991Sdim#undef NetBSD
17198090Srdivacky#undef mips
18198090Srdivacky#undef sparc
19198090Srdivacky
20193323Sednamespace llvm {
21193323Sed
22261991Sdim/// Triple - Helper class for working with autoconf configuration names. For
23261991Sdim/// historical reasons, we also call these 'triples' (they used to contain
24261991Sdim/// exactly three fields).
25193323Sed///
26261991Sdim/// Configuration names are strings in the canonical form:
27193323Sed///   ARCHITECTURE-VENDOR-OPERATING_SYSTEM
28193323Sed/// or
29193323Sed///   ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT
30193323Sed///
31193323Sed/// This class is used for clients which want to support arbitrary
32261991Sdim/// configuration names, but also want to implement certain special
33261991Sdim/// behavior for particular configurations. This class isolates the mapping
34261991Sdim/// from the components of the configuration name to well known IDs.
35193323Sed///
36198090Srdivacky/// At its core the Triple class is designed to be a wrapper for a triple
37212904Sdim/// string; the constructor does not change or normalize the triple string.
38212904Sdim/// Clients that need to handle the non-canonical triples that users often
39212904Sdim/// specify should use the normalize method.
40198090Srdivacky///
41261991Sdim/// See autoconf/config.guess for a glimpse into what configuration names
42261991Sdim/// look like in practice.
43193323Sedclass Triple {
44193323Sedpublic:
45193323Sed  enum ArchType {
46193323Sed    UnknownArch,
47218893Sdim
48309124Sdim    arm,            // ARM (little endian): arm, armv.*, xscale
49309124Sdim    armeb,          // ARM (big endian): armeb
50309124Sdim    aarch64,        // AArch64 (little endian): aarch64
51309124Sdim    aarch64_be,     // AArch64 (big endian): aarch64_be
52353358Sdim    aarch64_32,     // AArch64 (little endian) ILP32: aarch64_32
53327952Sdim    arc,            // ARC: Synopsys ARC
54309124Sdim    avr,            // AVR: Atmel AVR microcontroller
55309124Sdim    bpfel,          // eBPF or extended BPF or 64-bit BPF (little endian)
56309124Sdim    bpfeb,          // eBPF or extended BPF or 64-bit BPF (big endian)
57309124Sdim    hexagon,        // Hexagon: hexagon
58344779Sdim    mips,           // MIPS: mips, mipsallegrex, mipsr6
59344779Sdim    mipsel,         // MIPSEL: mipsel, mipsallegrexe, mipsr6el
60344779Sdim    mips64,         // MIPS64: mips64, mips64r6, mipsn32, mipsn32r6
61344779Sdim    mips64el,       // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el
62309124Sdim    msp430,         // MSP430: msp430
63309124Sdim    ppc,            // PPC: powerpc
64309124Sdim    ppc64,          // PPC64: powerpc64, ppu
65309124Sdim    ppc64le,        // PPC64LE: powerpc64le
66309124Sdim    r600,           // R600: AMD GPUs HD2XXX - HD6XXX
67309124Sdim    amdgcn,         // AMDGCN: AMD GCN GPUs
68314564Sdim    riscv32,        // RISC-V (32-bit): riscv32
69314564Sdim    riscv64,        // RISC-V (64-bit): riscv64
70309124Sdim    sparc,          // Sparc: sparc
71309124Sdim    sparcv9,        // Sparcv9: Sparcv9
72309124Sdim    sparcel,        // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant
73309124Sdim    systemz,        // SystemZ: s390x
74309124Sdim    tce,            // TCE (http://tce.cs.tut.fi/): tce
75314564Sdim    tcele,          // TCE little endian (http://tce.cs.tut.fi/): tcele
76309124Sdim    thumb,          // Thumb (little endian): thumb, thumbv.*
77309124Sdim    thumbeb,        // Thumb (big endian): thumbeb
78309124Sdim    x86,            // X86: i[3-9]86
79309124Sdim    x86_64,         // X86-64: amd64, x86_64
80309124Sdim    xcore,          // XCore: xcore
81309124Sdim    nvptx,          // NVPTX: 32-bit
82309124Sdim    nvptx64,        // NVPTX: 64-bit
83309124Sdim    le32,           // le32: generic little-endian 32-bit CPU (PNaCl)
84309124Sdim    le64,           // le64: generic little-endian 64-bit CPU (PNaCl)
85309124Sdim    amdil,          // AMDIL
86309124Sdim    amdil64,        // AMDIL with 64-bit pointers
87309124Sdim    hsail,          // AMD HSAIL
88309124Sdim    hsail64,        // AMD HSAIL with 64-bit pointers
89309124Sdim    spir,           // SPIR: standard portable IR for OpenCL 32-bit version
90309124Sdim    spir64,         // SPIR: standard portable IR for OpenCL 64-bit version
91309124Sdim    kalimba,        // Kalimba: generic kalimba
92309124Sdim    shave,          // SHAVE: Movidius vector VLIW processors
93309124Sdim    lanai,          // Lanai: Lanai 32-bit
94309124Sdim    wasm32,         // WebAssembly with 32-bit pointers
95309124Sdim    wasm64,         // WebAssembly with 64-bit pointers
96309124Sdim    renderscript32, // 32-bit RenderScript
97309124Sdim    renderscript64, // 64-bit RenderScript
98360784Sdim    ve,             // NEC SX-Aurora Vector Engine
99360784Sdim    LastArchType = ve
100193323Sed  };
101276479Sdim  enum SubArchType {
102276479Sdim    NoSubArch,
103276479Sdim
104344779Sdim    ARMSubArch_v8_5a,
105341825Sdim    ARMSubArch_v8_4a,
106327952Sdim    ARMSubArch_v8_3a,
107296417Sdim    ARMSubArch_v8_2a,
108288943Sdim    ARMSubArch_v8_1a,
109276479Sdim    ARMSubArch_v8,
110314564Sdim    ARMSubArch_v8r,
111309124Sdim    ARMSubArch_v8m_baseline,
112309124Sdim    ARMSubArch_v8m_mainline,
113353358Sdim    ARMSubArch_v8_1m_mainline,
114276479Sdim    ARMSubArch_v7,
115276479Sdim    ARMSubArch_v7em,
116276479Sdim    ARMSubArch_v7m,
117276479Sdim    ARMSubArch_v7s,
118296417Sdim    ARMSubArch_v7k,
119321369Sdim    ARMSubArch_v7ve,
120276479Sdim    ARMSubArch_v6,
121276479Sdim    ARMSubArch_v6m,
122288943Sdim    ARMSubArch_v6k,
123276479Sdim    ARMSubArch_v6t2,
124276479Sdim    ARMSubArch_v5,
125276479Sdim    ARMSubArch_v5te,
126280031Sdim    ARMSubArch_v4t,
127280031Sdim
128280031Sdim    KalimbaSubArch_v3,
129280031Sdim    KalimbaSubArch_v4,
130344779Sdim    KalimbaSubArch_v5,
131344779Sdim
132360661Sdim    MipsSubArch_r6,
133360661Sdim
134360661Sdim    PPCSubArch_spe
135276479Sdim  };
136193323Sed  enum VendorType {
137193323Sed    UnknownVendor,
138193323Sed
139218893Sdim    Apple,
140221345Sdim    PC,
141234353Sdim    SCEI,
142234353Sdim    BGP,
143243830Sdim    BGQ,
144243830Sdim    Freescale,
145261991Sdim    IBM,
146276479Sdim    ImaginationTechnologies,
147276479Sdim    MipsTechnologies,
148276479Sdim    NVIDIA,
149288943Sdim    CSR,
150296417Sdim    Myriad,
151309124Sdim    AMD,
152309124Sdim    Mesa,
153321369Sdim    SUSE,
154341825Sdim    OpenEmbedded,
155341825Sdim    LastVendorType = OpenEmbedded
156193323Sed  };
157193323Sed  enum OSType {
158193323Sed    UnknownOS,
159193323Sed
160321369Sdim    Ananas,
161288943Sdim    CloudABI,
162193323Sed    Darwin,
163193323Sed    DragonFly,
164193323Sed    FreeBSD,
165314564Sdim    Fuchsia,
166221345Sdim    IOS,
167226633Sdim    KFreeBSD,
168195340Sed    Linux,
169199989Srdivacky    Lv2,        // PS3
170221345Sdim    MacOSX,
171198090Srdivacky    NetBSD,
172198090Srdivacky    OpenBSD,
173198090Srdivacky    Solaris,
174198396Srdivacky    Win32,
175210299Sed    Haiku,
176224145Sdim    Minix,
177226633Sdim    RTEMS,
178249423Sdim    NaCl,       // Native Client
179249423Sdim    CNK,        // BG/P Compute-Node Kernel
180261991Sdim    AIX,
181261991Sdim    CUDA,       // NVIDIA CUDA
182280031Sdim    NVCL,       // NVIDIA OpenCL
183288943Sdim    AMDHSA,     // AMD HSA Runtime
184288943Sdim    PS4,
185296417Sdim    ELFIAMCU,
186296417Sdim    TvOS,       // Apple tvOS
187296417Sdim    WatchOS,    // Apple watchOS
188309124Sdim    Mesa3D,
189314564Sdim    Contiki,
190327952Sdim    AMDPAL,     // AMD PAL Runtime
191344779Sdim    HermitCore, // HermitCore Unikernel/Multikernel
192344779Sdim    Hurd,       // GNU/Hurd
193344779Sdim    WASI,       // Experimental WebAssembly OS
194353358Sdim    Emscripten,
195353358Sdim    LastOSType = Emscripten
196193323Sed  };
197218893Sdim  enum EnvironmentType {
198218893Sdim    UnknownEnvironment,
199218893Sdim
200218893Sdim    GNU,
201327952Sdim    GNUABIN32,
202309124Sdim    GNUABI64,
203218893Sdim    GNUEABI,
204234353Sdim    GNUEABIHF,
205249423Sdim    GNUX32,
206276479Sdim    CODE16,
207218893Sdim    EABI,
208276479Sdim    EABIHF,
209243830Sdim    Android,
210309124Sdim    Musl,
211309124Sdim    MuslEABI,
212309124Sdim    MuslEABIHF,
213276479Sdim
214276479Sdim    MSVC,
215276479Sdim    Itanium,
216276479Sdim    Cygnus,
217296417Sdim    CoreCLR,
218353358Sdim    Simulator, // Simulator variants of other systems, e.g., Apple's iOS
219353358Sdim    MacABI, // Mac Catalyst variant of Apple's iOS deployment target.
220353358Sdim    LastEnvironmentType = MacABI
221218893Sdim  };
222276479Sdim  enum ObjectFormatType {
223276479Sdim    UnknownObjectFormat,
224218893Sdim
225276479Sdim    COFF,
226276479Sdim    ELF,
227276479Sdim    MachO,
228321369Sdim    Wasm,
229353358Sdim    XCOFF,
230276479Sdim  };
231276479Sdim
232193323Sedprivate:
233193323Sed  std::string Data;
234193323Sed
235234353Sdim  /// The parsed arch type.
236234353Sdim  ArchType Arch;
237193323Sed
238276479Sdim  /// The parsed subarchitecture type.
239276479Sdim  SubArchType SubArch;
240276479Sdim
241193323Sed  /// The parsed vendor type.
242234353Sdim  VendorType Vendor;
243193323Sed
244193323Sed  /// The parsed OS type.
245234353Sdim  OSType OS;
246193323Sed
247218893Sdim  /// The parsed Environment type.
248234353Sdim  EnvironmentType Environment;
249218893Sdim
250276479Sdim  /// The object format type.
251276479Sdim  ObjectFormatType ObjectFormat;
252276479Sdim
253193323Sedpublic:
254193323Sed  /// @name Constructors
255193323Sed  /// @{
256218893Sdim
257296417Sdim  /// Default constructor is the same as an empty string and leaves all
258234353Sdim  /// triple fields unknown.
259321369Sdim  Triple()
260321369Sdim      : Data(), Arch(), SubArch(), Vendor(), OS(), Environment(),
261321369Sdim        ObjectFormat() {}
262193323Sed
263234353Sdim  explicit Triple(const Twine &Str);
264234353Sdim  Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
265226633Sdim  Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
266234353Sdim         const Twine &EnvironmentStr);
267218893Sdim
268288943Sdim  bool operator==(const Triple &Other) const {
269288943Sdim    return Arch == Other.Arch && SubArch == Other.SubArch &&
270288943Sdim           Vendor == Other.Vendor && OS == Other.OS &&
271288943Sdim           Environment == Other.Environment &&
272288943Sdim           ObjectFormat == Other.ObjectFormat;
273288943Sdim  }
274288943Sdim
275321369Sdim  bool operator!=(const Triple &Other) const {
276321369Sdim    return !(*this == Other);
277321369Sdim  }
278321369Sdim
279193323Sed  /// @}
280212904Sdim  /// @name Normalization
281212904Sdim  /// @{
282212904Sdim
283212904Sdim  /// normalize - Turn an arbitrary machine specification into the canonical
284212904Sdim  /// triple form (or something sensible that the Triple class understands if
285212904Sdim  /// nothing better can reasonably be done).  In particular, it handles the
286212904Sdim  /// common case in which otherwise valid components are in the wrong order.
287212904Sdim  static std::string normalize(StringRef Str);
288212904Sdim
289296417Sdim  /// Return the normalized form of this triple's string.
290288943Sdim  std::string normalize() const { return normalize(Data); }
291288943Sdim
292212904Sdim  /// @}
293193323Sed  /// @name Typed Component Access
294193323Sed  /// @{
295218893Sdim
296193323Sed  /// getArch - Get the parsed architecture type of this triple.
297234353Sdim  ArchType getArch() const { return Arch; }
298218893Sdim
299276479Sdim  /// getSubArch - get the parsed subarchitecture type for this triple.
300276479Sdim  SubArchType getSubArch() const { return SubArch; }
301276479Sdim
302193323Sed  /// getVendor - Get the parsed vendor type of this triple.
303234353Sdim  VendorType getVendor() const { return Vendor; }
304218893Sdim
305193323Sed  /// getOS - Get the parsed operating system type of this triple.
306234353Sdim  OSType getOS() const { return OS; }
307193323Sed
308193323Sed  /// hasEnvironment - Does this triple have the optional environment
309193323Sed  /// (fourth) component?
310193323Sed  bool hasEnvironment() const {
311193323Sed    return getEnvironmentName() != "";
312193323Sed  }
313193323Sed
314218893Sdim  /// getEnvironment - Get the parsed environment type of this triple.
315234353Sdim  EnvironmentType getEnvironment() const { return Environment; }
316234353Sdim
317296417Sdim  /// Parse the version number from the OS name component of the
318288943Sdim  /// triple, if present.
319288943Sdim  ///
320288943Sdim  /// For example, "fooos1.2.3" would return (1, 2, 3).
321288943Sdim  ///
322288943Sdim  /// If an entry is not defined, it will be returned as 0.
323288943Sdim  void getEnvironmentVersion(unsigned &Major, unsigned &Minor,
324288943Sdim                             unsigned &Micro) const;
325288943Sdim
326276479Sdim  /// getFormat - Get the object format for this triple.
327276479Sdim  ObjectFormatType getObjectFormat() const { return ObjectFormat; }
328276479Sdim
329234353Sdim  /// getOSVersion - Parse the version number from the OS name component of the
330234353Sdim  /// triple, if present.
331234353Sdim  ///
332234353Sdim  /// For example, "fooos1.2.3" would return (1, 2, 3).
333234353Sdim  ///
334234353Sdim  /// If an entry is not defined, it will be returned as 0.
335234353Sdim  void getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const;
336234353Sdim
337234353Sdim  /// getOSMajorVersion - Return just the major version number, this is
338234353Sdim  /// specialized because it is a common query.
339234353Sdim  unsigned getOSMajorVersion() const {
340234353Sdim    unsigned Maj, Min, Micro;
341234353Sdim    getOSVersion(Maj, Min, Micro);
342234353Sdim    return Maj;
343218893Sdim  }
344218893Sdim
345234353Sdim  /// getMacOSXVersion - Parse the version number as with getOSVersion and then
346234353Sdim  /// translate generic "darwin" versions to the corresponding OS X versions.
347234353Sdim  /// This may also be called with IOS triples but the OS X version number is
348234353Sdim  /// just set to a constant 10.4.0 in that case.  Returns true if successful.
349234353Sdim  bool getMacOSXVersion(unsigned &Major, unsigned &Minor,
350234353Sdim                        unsigned &Micro) const;
351234353Sdim
352239462Sdim  /// getiOSVersion - Parse the version number as with getOSVersion.  This should
353296417Sdim  /// only be called with IOS or generic triples.
354239462Sdim  void getiOSVersion(unsigned &Major, unsigned &Minor,
355239462Sdim                     unsigned &Micro) const;
356239462Sdim
357296417Sdim  /// getWatchOSVersion - Parse the version number as with getOSVersion.  This
358296417Sdim  /// should only be called with WatchOS or generic triples.
359296417Sdim  void getWatchOSVersion(unsigned &Major, unsigned &Minor,
360296417Sdim                         unsigned &Micro) const;
361296417Sdim
362193323Sed  /// @}
363193323Sed  /// @name Direct Component Access
364193323Sed  /// @{
365193323Sed
366199481Srdivacky  const std::string &str() const { return Data; }
367199481Srdivacky
368193323Sed  const std::string &getTriple() const { return Data; }
369193323Sed
370193323Sed  /// getArchName - Get the architecture (first) component of the
371193323Sed  /// triple.
372198090Srdivacky  StringRef getArchName() const;
373193323Sed
374193323Sed  /// getVendorName - Get the vendor (second) component of the triple.
375198090Srdivacky  StringRef getVendorName() const;
376193323Sed
377193323Sed  /// getOSName - Get the operating system (third) component of the
378193323Sed  /// triple.
379198090Srdivacky  StringRef getOSName() const;
380193323Sed
381193323Sed  /// getEnvironmentName - Get the optional environment (fourth)
382193323Sed  /// component of the triple, or "" if empty.
383198090Srdivacky  StringRef getEnvironmentName() const;
384193323Sed
385193323Sed  /// getOSAndEnvironmentName - Get the operating system and optional
386193323Sed  /// environment components as a single string (separated by a '-'
387193323Sed  /// if the environment component is present).
388198090Srdivacky  StringRef getOSAndEnvironmentName() const;
389193323Sed
390234353Sdim  /// @}
391234353Sdim  /// @name Convenience Predicates
392234353Sdim  /// @{
393234353Sdim
394296417Sdim  /// Test whether the architecture is 64-bit
395221345Sdim  ///
396234353Sdim  /// Note that this tests for 64-bit pointer width, and nothing else. Note
397234353Sdim  /// that we intentionally expose only three predicates, 64-bit, 32-bit, and
398234353Sdim  /// 16-bit. The inner details of pointer width for particular architectures
399234353Sdim  /// is not summed up in the triple, and so only a coarse grained predicate
400234353Sdim  /// system is provided.
401234353Sdim  bool isArch64Bit() const;
402234353Sdim
403296417Sdim  /// Test whether the architecture is 32-bit
404221345Sdim  ///
405234353Sdim  /// Note that this tests for 32-bit pointer width, and nothing else.
406234353Sdim  bool isArch32Bit() const;
407218893Sdim
408296417Sdim  /// Test whether the architecture is 16-bit
409234353Sdim  ///
410234353Sdim  /// Note that this tests for 16-bit pointer width, and nothing else.
411234353Sdim  bool isArch16Bit() const;
412218893Sdim
413221345Sdim  /// isOSVersionLT - Helper function for doing comparisons against version
414221345Sdim  /// numbers included in the target triple.
415221345Sdim  bool isOSVersionLT(unsigned Major, unsigned Minor = 0,
416221345Sdim                     unsigned Micro = 0) const {
417221345Sdim    unsigned LHS[3];
418221345Sdim    getOSVersion(LHS[0], LHS[1], LHS[2]);
419221345Sdim
420221345Sdim    if (LHS[0] != Major)
421221345Sdim      return LHS[0] < Major;
422221345Sdim    if (LHS[1] != Minor)
423221345Sdim      return LHS[1] < Minor;
424221345Sdim    if (LHS[2] != Micro)
425353358Sdim      return LHS[2] < Micro;
426221345Sdim
427221345Sdim    return false;
428221345Sdim  }
429221345Sdim
430288943Sdim  bool isOSVersionLT(const Triple &Other) const {
431288943Sdim    unsigned RHS[3];
432288943Sdim    Other.getOSVersion(RHS[0], RHS[1], RHS[2]);
433288943Sdim    return isOSVersionLT(RHS[0], RHS[1], RHS[2]);
434288943Sdim  }
435288943Sdim
436234353Sdim  /// isMacOSXVersionLT - Comparison function for checking OS X version
437234353Sdim  /// compatibility, which handles supporting skewed version numbering schemes
438234353Sdim  /// used by the "darwin" triples.
439309124Sdim  bool isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
440309124Sdim                         unsigned Micro = 0) const {
441234353Sdim    assert(isMacOSX() && "Not an OS X triple!");
442234353Sdim
443234353Sdim    // If this is OS X, expect a sane version number.
444234353Sdim    if (getOS() == Triple::MacOSX)
445234353Sdim      return isOSVersionLT(Major, Minor, Micro);
446234353Sdim
447234353Sdim    // Otherwise, compare to the "Darwin" number.
448234353Sdim    assert(Major == 10 && "Unexpected major version");
449234353Sdim    return isOSVersionLT(Minor + 4, Micro, 0);
450234353Sdim  }
451234353Sdim
452221345Sdim  /// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both
453221345Sdim  /// "darwin" and "osx" as OS X triples.
454221345Sdim  bool isMacOSX() const {
455221345Sdim    return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
456221345Sdim  }
457221345Sdim
458249423Sdim  /// Is this an iOS triple.
459296417Sdim  /// Note: This identifies tvOS as a variant of iOS. If that ever
460296417Sdim  /// changes, i.e., if the two operating systems diverge or their version
461296417Sdim  /// numbers get out of sync, that will need to be changed.
462296417Sdim  /// watchOS has completely different version numbers so it is not included.
463249423Sdim  bool isiOS() const {
464296417Sdim    return getOS() == Triple::IOS || isTvOS();
465249423Sdim  }
466249423Sdim
467296417Sdim  /// Is this an Apple tvOS triple.
468296417Sdim  bool isTvOS() const {
469296417Sdim    return getOS() == Triple::TvOS;
470296417Sdim  }
471296417Sdim
472296417Sdim  /// Is this an Apple watchOS triple.
473296417Sdim  bool isWatchOS() const {
474296417Sdim    return getOS() == Triple::WatchOS;
475296417Sdim  }
476296417Sdim
477309124Sdim  bool isWatchABI() const {
478309124Sdim    return getSubArch() == Triple::ARMSubArch_v7k;
479309124Sdim  }
480309124Sdim
481360784Sdim  /// isOSDarwin - Is this a "Darwin" OS (macOS, iOS, tvOS or watchOS).
482221345Sdim  bool isOSDarwin() const {
483296417Sdim    return isMacOSX() || isiOS() || isWatchOS();
484221345Sdim  }
485221345Sdim
486327952Sdim  bool isSimulatorEnvironment() const {
487327952Sdim    return getEnvironment() == Triple::Simulator;
488327952Sdim  }
489327952Sdim
490353358Sdim  bool isMacCatalystEnvironment() const {
491353358Sdim    return getEnvironment() == Triple::MacABI;
492353358Sdim  }
493353358Sdim
494280031Sdim  bool isOSNetBSD() const {
495280031Sdim    return getOS() == Triple::NetBSD;
496280031Sdim  }
497280031Sdim
498280031Sdim  bool isOSOpenBSD() const {
499280031Sdim    return getOS() == Triple::OpenBSD;
500280031Sdim  }
501280031Sdim
502276479Sdim  bool isOSFreeBSD() const {
503276479Sdim    return getOS() == Triple::FreeBSD;
504276479Sdim  }
505276479Sdim
506314564Sdim  bool isOSFuchsia() const {
507314564Sdim    return getOS() == Triple::Fuchsia;
508314564Sdim  }
509314564Sdim
510280031Sdim  bool isOSDragonFly() const { return getOS() == Triple::DragonFly; }
511280031Sdim
512280031Sdim  bool isOSSolaris() const {
513280031Sdim    return getOS() == Triple::Solaris;
514280031Sdim  }
515280031Sdim
516296417Sdim  bool isOSIAMCU() const {
517296417Sdim    return getOS() == Triple::ELFIAMCU;
518296417Sdim  }
519296417Sdim
520327952Sdim  bool isOSUnknown() const { return getOS() == Triple::UnknownOS; }
521327952Sdim
522309124Sdim  bool isGNUEnvironment() const {
523309124Sdim    EnvironmentType Env = getEnvironment();
524327952Sdim    return Env == Triple::GNU || Env == Triple::GNUABIN32 ||
525327952Sdim           Env == Triple::GNUABI64 || Env == Triple::GNUEABI ||
526327952Sdim           Env == Triple::GNUEABIHF || Env == Triple::GNUX32;
527309124Sdim  }
528309124Sdim
529314564Sdim  bool isOSContiki() const {
530314564Sdim    return getOS() == Triple::Contiki;
531314564Sdim  }
532314564Sdim
533327952Sdim  /// Tests whether the OS is Haiku.
534327952Sdim  bool isOSHaiku() const {
535327952Sdim    return getOS() == Triple::Haiku;
536327952Sdim  }
537327952Sdim
538353358Sdim  /// Tests whether the OS is Windows.
539353358Sdim  bool isOSWindows() const {
540353358Sdim    return getOS() == Triple::Win32;
541276479Sdim  }
542276479Sdim
543296417Sdim  /// Checks if the environment is MSVC.
544276479Sdim  bool isKnownWindowsMSVCEnvironment() const {
545353358Sdim    return isOSWindows() && getEnvironment() == Triple::MSVC;
546276479Sdim  }
547276479Sdim
548353358Sdim  /// Checks if the environment could be MSVC.
549353358Sdim  bool isWindowsMSVCEnvironment() const {
550353358Sdim    return isKnownWindowsMSVCEnvironment() ||
551353358Sdim           (isOSWindows() && getEnvironment() == Triple::UnknownEnvironment);
552353358Sdim  }
553353358Sdim
554296417Sdim  bool isWindowsCoreCLREnvironment() const {
555353358Sdim    return isOSWindows() && getEnvironment() == Triple::CoreCLR;
556296417Sdim  }
557296417Sdim
558276479Sdim  bool isWindowsItaniumEnvironment() const {
559353358Sdim    return isOSWindows() && getEnvironment() == Triple::Itanium;
560276479Sdim  }
561276479Sdim
562276479Sdim  bool isWindowsCygwinEnvironment() const {
563353358Sdim    return isOSWindows() && getEnvironment() == Triple::Cygnus;
564276479Sdim  }
565276479Sdim
566276479Sdim  bool isWindowsGNUEnvironment() const {
567353358Sdim    return isOSWindows() && getEnvironment() == Triple::GNU;
568276479Sdim  }
569276479Sdim
570296417Sdim  /// Tests for either Cygwin or MinGW OS
571234353Sdim  bool isOSCygMing() const {
572276479Sdim    return isWindowsCygwinEnvironment() || isWindowsGNUEnvironment();
573234353Sdim  }
574234353Sdim
575296417Sdim  /// Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
576261991Sdim  bool isOSMSVCRT() const {
577280031Sdim    return isWindowsMSVCEnvironment() || isWindowsGNUEnvironment() ||
578280031Sdim           isWindowsItaniumEnvironment();
579261991Sdim  }
580261991Sdim
581296417Sdim  /// Tests whether the OS is NaCl (Native Client)
582249423Sdim  bool isOSNaCl() const {
583249423Sdim    return getOS() == Triple::NaCl;
584249423Sdim  }
585249423Sdim
586296417Sdim  /// Tests whether the OS is Linux.
587261991Sdim  bool isOSLinux() const {
588261991Sdim    return getOS() == Triple::Linux;
589261991Sdim  }
590261991Sdim
591309124Sdim  /// Tests whether the OS is kFreeBSD.
592309124Sdim  bool isOSKFreeBSD() const {
593309124Sdim    return getOS() == Triple::KFreeBSD;
594309124Sdim  }
595309124Sdim
596344779Sdim  /// Tests whether the OS is Hurd.
597344779Sdim  bool isOSHurd() const {
598344779Sdim    return getOS() == Triple::Hurd;
599344779Sdim  }
600344779Sdim
601344779Sdim  /// Tests whether the OS is WASI.
602344779Sdim  bool isOSWASI() const {
603344779Sdim    return getOS() == Triple::WASI;
604344779Sdim  }
605344779Sdim
606353358Sdim  /// Tests whether the OS is Emscripten.
607353358Sdim  bool isOSEmscripten() const {
608353358Sdim    return getOS() == Triple::Emscripten;
609353358Sdim  }
610353358Sdim
611309124Sdim  /// Tests whether the OS uses glibc.
612309124Sdim  bool isOSGlibc() const {
613344779Sdim    return (getOS() == Triple::Linux || getOS() == Triple::KFreeBSD ||
614344779Sdim            getOS() == Triple::Hurd) &&
615321369Sdim           !isAndroid();
616309124Sdim  }
617309124Sdim
618353358Sdim  /// Tests whether the OS is AIX.
619353358Sdim  bool isOSAIX() const {
620353358Sdim    return getOS() == Triple::AIX;
621353358Sdim  }
622353358Sdim
623296417Sdim  /// Tests whether the OS uses the ELF binary format.
624234353Sdim  bool isOSBinFormatELF() const {
625276479Sdim    return getObjectFormat() == Triple::ELF;
626234353Sdim  }
627221345Sdim
628296417Sdim  /// Tests whether the OS uses the COFF binary format.
629234353Sdim  bool isOSBinFormatCOFF() const {
630276479Sdim    return getObjectFormat() == Triple::COFF;
631234353Sdim  }
632221345Sdim
633296417Sdim  /// Tests whether the environment is MachO.
634276479Sdim  bool isOSBinFormatMachO() const {
635276479Sdim    return getObjectFormat() == Triple::MachO;
636221345Sdim  }
637224145Sdim
638321369Sdim  /// Tests whether the OS uses the Wasm binary format.
639321369Sdim  bool isOSBinFormatWasm() const {
640321369Sdim    return getObjectFormat() == Triple::Wasm;
641321369Sdim  }
642321369Sdim
643353358Sdim  /// Tests whether the OS uses the XCOFF binary format.
644353358Sdim  bool isOSBinFormatXCOFF() const {
645353358Sdim    return getObjectFormat() == Triple::XCOFF;
646353358Sdim  }
647353358Sdim
648296417Sdim  /// Tests whether the target is the PS4 CPU
649288943Sdim  bool isPS4CPU() const {
650288943Sdim    return getArch() == Triple::x86_64 &&
651288943Sdim           getVendor() == Triple::SCEI &&
652288943Sdim           getOS() == Triple::PS4;
653288943Sdim  }
654288943Sdim
655296417Sdim  /// Tests whether the target is the PS4 platform
656288943Sdim  bool isPS4() const {
657288943Sdim    return getVendor() == Triple::SCEI &&
658288943Sdim           getOS() == Triple::PS4;
659288943Sdim  }
660288943Sdim
661296417Sdim  /// Tests whether the target is Android
662296417Sdim  bool isAndroid() const { return getEnvironment() == Triple::Android; }
663296417Sdim
664321369Sdim  bool isAndroidVersionLT(unsigned Major) const {
665321369Sdim    assert(isAndroid() && "Not an Android triple!");
666321369Sdim
667321369Sdim    unsigned Env[3];
668321369Sdim    getEnvironmentVersion(Env[0], Env[1], Env[2]);
669321369Sdim
670321369Sdim    // 64-bit targets did not exist before API level 21 (Lollipop).
671321369Sdim    if (isArch64Bit() && Env[0] < 21)
672321369Sdim      Env[0] = 21;
673321369Sdim
674321369Sdim    return Env[0] < Major;
675321369Sdim  }
676321369Sdim
677309124Sdim  /// Tests whether the environment is musl-libc
678309124Sdim  bool isMusl() const {
679309124Sdim    return getEnvironment() == Triple::Musl ||
680309124Sdim           getEnvironment() == Triple::MuslEABI ||
681309124Sdim           getEnvironment() == Triple::MuslEABIHF;
682309124Sdim  }
683309124Sdim
684353358Sdim  /// Tests whether the target is SPIR (32- or 64-bit).
685353358Sdim  bool isSPIR() const {
686353358Sdim    return getArch() == Triple::spir || getArch() == Triple::spir64;
687353358Sdim  }
688353358Sdim
689309124Sdim  /// Tests whether the target is NVPTX (32- or 64-bit).
690309124Sdim  bool isNVPTX() const {
691309124Sdim    return getArch() == Triple::nvptx || getArch() == Triple::nvptx64;
692309124Sdim  }
693309124Sdim
694327952Sdim  /// Tests whether the target is Thumb (little and big endian).
695327952Sdim  bool isThumb() const {
696327952Sdim    return getArch() == Triple::thumb || getArch() == Triple::thumbeb;
697327952Sdim  }
698327952Sdim
699327952Sdim  /// Tests whether the target is ARM (little and big endian).
700327952Sdim  bool isARM() const {
701327952Sdim    return getArch() == Triple::arm || getArch() == Triple::armeb;
702327952Sdim  }
703327952Sdim
704327952Sdim  /// Tests whether the target is AArch64 (little and big endian).
705327952Sdim  bool isAArch64() const {
706327952Sdim    return getArch() == Triple::aarch64 || getArch() == Triple::aarch64_be;
707327952Sdim  }
708327952Sdim
709341825Sdim  /// Tests whether the target is MIPS 32-bit (little and big endian).
710341825Sdim  bool isMIPS32() const {
711341825Sdim    return getArch() == Triple::mips || getArch() == Triple::mipsel;
712341825Sdim  }
713341825Sdim
714341825Sdim  /// Tests whether the target is MIPS 64-bit (little and big endian).
715341825Sdim  bool isMIPS64() const {
716341825Sdim    return getArch() == Triple::mips64 || getArch() == Triple::mips64el;
717341825Sdim  }
718341825Sdim
719341825Sdim  /// Tests whether the target is MIPS (little and big endian, 32- or 64-bit).
720341825Sdim  bool isMIPS() const {
721341825Sdim    return isMIPS32() || isMIPS64();
722341825Sdim  }
723341825Sdim
724353358Sdim  /// Tests whether the target is 64-bit PowerPC (little and big endian).
725353358Sdim  bool isPPC64() const {
726353358Sdim    return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le;
727353358Sdim  }
728353358Sdim
729353358Sdim  /// Tests whether the target is RISC-V (32- and 64-bit).
730353358Sdim  bool isRISCV() const {
731353358Sdim    return getArch() == Triple::riscv32 || getArch() == Triple::riscv64;
732353358Sdim  }
733353358Sdim
734360784Sdim  /// Tests whether the target is x86 (32- or 64-bit).
735360784Sdim  bool isX86() const {
736360784Sdim    return getArch() == Triple::x86 || getArch() == Triple::x86_64;
737360784Sdim  }
738360784Sdim
739360784Sdim  /// Tests whether the target is VE
740360784Sdim  bool isVE() const {
741360784Sdim    return getArch() == Triple::ve;
742360784Sdim  }
743360784Sdim
744341825Sdim  /// Tests whether the target supports comdat
745327952Sdim  bool supportsCOMDAT() const {
746341825Sdim    return !isOSBinFormatMachO();
747327952Sdim  }
748309124Sdim
749341825Sdim  /// Tests whether the target uses emulated TLS as default.
750341825Sdim  bool hasDefaultEmulatedTLS() const {
751341825Sdim    return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment();
752341825Sdim  }
753341825Sdim
754193323Sed  /// @}
755193323Sed  /// @name Mutators
756193323Sed  /// @{
757193323Sed
758193323Sed  /// setArch - Set the architecture (first) component of the triple
759193323Sed  /// to a known type.
760193323Sed  void setArch(ArchType Kind);
761193323Sed
762193323Sed  /// setVendor - Set the vendor (second) component of the triple to a
763193323Sed  /// known type.
764193323Sed  void setVendor(VendorType Kind);
765193323Sed
766193323Sed  /// setOS - Set the operating system (third) component of the triple
767193323Sed  /// to a known type.
768193323Sed  void setOS(OSType Kind);
769193323Sed
770218893Sdim  /// setEnvironment - Set the environment (fourth) component of the triple
771218893Sdim  /// to a known type.
772218893Sdim  void setEnvironment(EnvironmentType Kind);
773218893Sdim
774276479Sdim  /// setObjectFormat - Set the object file format
775276479Sdim  void setObjectFormat(ObjectFormatType Kind);
776276479Sdim
777243830Sdim  /// setTriple - Set all components to the new triple \p Str.
778198090Srdivacky  void setTriple(const Twine &Str);
779193323Sed
780193323Sed  /// setArchName - Set the architecture (first) component of the
781193323Sed  /// triple by name.
782199481Srdivacky  void setArchName(StringRef Str);
783193323Sed
784193323Sed  /// setVendorName - Set the vendor (second) component of the triple
785193323Sed  /// by name.
786199481Srdivacky  void setVendorName(StringRef Str);
787193323Sed
788193323Sed  /// setOSName - Set the operating system (third) component of the
789193323Sed  /// triple by name.
790199481Srdivacky  void setOSName(StringRef Str);
791193323Sed
792193323Sed  /// setEnvironmentName - Set the optional environment (fourth)
793193323Sed  /// component of the triple by name.
794199481Srdivacky  void setEnvironmentName(StringRef Str);
795193323Sed
796193323Sed  /// setOSAndEnvironmentName - Set the operating system and optional
797193323Sed  /// environment components with a single string.
798199481Srdivacky  void setOSAndEnvironmentName(StringRef Str);
799193323Sed
800193323Sed  /// @}
801234353Sdim  /// @name Helpers to build variants of a particular triple.
802234353Sdim  /// @{
803234353Sdim
804296417Sdim  /// Form a triple with a 32-bit variant of the current architecture.
805234353Sdim  ///
806234353Sdim  /// This can be used to move across "families" of architectures where useful.
807234353Sdim  ///
808234353Sdim  /// \returns A new triple with a 32-bit architecture or an unknown
809234353Sdim  ///          architecture if no such variant can be found.
810234353Sdim  llvm::Triple get32BitArchVariant() const;
811234353Sdim
812296417Sdim  /// Form a triple with a 64-bit variant of the current architecture.
813234353Sdim  ///
814234353Sdim  /// This can be used to move across "families" of architectures where useful.
815234353Sdim  ///
816234353Sdim  /// \returns A new triple with a 64-bit architecture or an unknown
817234353Sdim  ///          architecture if no such variant can be found.
818234353Sdim  llvm::Triple get64BitArchVariant() const;
819234353Sdim
820288943Sdim  /// Form a triple with a big endian variant of the current architecture.
821288943Sdim  ///
822288943Sdim  /// This can be used to move across "families" of architectures where useful.
823288943Sdim  ///
824288943Sdim  /// \returns A new triple with a big endian architecture or an unknown
825288943Sdim  ///          architecture if no such variant can be found.
826288943Sdim  llvm::Triple getBigEndianArchVariant() const;
827288943Sdim
828288943Sdim  /// Form a triple with a little endian variant of the current architecture.
829288943Sdim  ///
830288943Sdim  /// This can be used to move across "families" of architectures where useful.
831288943Sdim  ///
832288943Sdim  /// \returns A new triple with a little endian architecture or an unknown
833288943Sdim  ///          architecture if no such variant can be found.
834288943Sdim  llvm::Triple getLittleEndianArchVariant() const;
835288943Sdim
836276479Sdim  /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
837276479Sdim  ///
838276479Sdim  /// \param Arch the architecture name (e.g., "armv7s"). If it is an empty
839276479Sdim  /// string then the triple's arch name is used.
840296417Sdim  StringRef getARMCPUForArch(StringRef Arch = StringRef()) const;
841276479Sdim
842309124Sdim  /// Tests whether the target triple is little endian.
843309124Sdim  ///
844309124Sdim  /// \returns true if the triple is little endian, false otherwise.
845309124Sdim  bool isLittleEndian() const;
846309124Sdim
847321369Sdim  /// Test whether target triples are compatible.
848321369Sdim  bool isCompatibleWith(const Triple &Other) const;
849321369Sdim
850321369Sdim  /// Merge target triples.
851321369Sdim  std::string merge(const Triple &Other) const;
852321369Sdim
853234353Sdim  /// @}
854193323Sed  /// @name Static helpers for IDs.
855193323Sed  /// @{
856193323Sed
857243830Sdim  /// getArchTypeName - Get the canonical name for the \p Kind architecture.
858314564Sdim  static StringRef getArchTypeName(ArchType Kind);
859193323Sed
860243830Sdim  /// getArchTypePrefix - Get the "prefix" canonical name for the \p Kind
861198090Srdivacky  /// architecture. This is the prefix used by the architecture specific
862198090Srdivacky  /// builtins, and is suitable for passing to \see
863198090Srdivacky  /// Intrinsic::getIntrinsicForGCCBuiltin().
864198090Srdivacky  ///
865198090Srdivacky  /// \return - The architecture prefix, or 0 if none is defined.
866314564Sdim  static StringRef getArchTypePrefix(ArchType Kind);
867198090Srdivacky
868243830Sdim  /// getVendorTypeName - Get the canonical name for the \p Kind vendor.
869314564Sdim  static StringRef getVendorTypeName(VendorType Kind);
870193323Sed
871243830Sdim  /// getOSTypeName - Get the canonical name for the \p Kind operating system.
872314564Sdim  static StringRef getOSTypeName(OSType Kind);
873193323Sed
874243830Sdim  /// getEnvironmentTypeName - Get the canonical name for the \p Kind
875218893Sdim  /// environment.
876314564Sdim  static StringRef getEnvironmentTypeName(EnvironmentType Kind);
877218893Sdim
878193323Sed  /// @}
879198090Srdivacky  /// @name Static helpers for converting alternate architecture names.
880198090Srdivacky  /// @{
881198090Srdivacky
882198090Srdivacky  /// getArchTypeForLLVMName - The canonical type for the given LLVM
883198090Srdivacky  /// architecture name (e.g., "x86").
884199481Srdivacky  static ArchType getArchTypeForLLVMName(StringRef Str);
885198090Srdivacky
886198090Srdivacky  /// @}
887193323Sed};
888193323Sed
889193323Sed} // End llvm namespace
890193323Sed
891193323Sed
892193323Sed#endif
893