1193323Sed//===-- llvm/ADT/Triple.h - Target triple helper class ----------*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed
10193323Sed#ifndef LLVM_ADT_TRIPLE_H
11193323Sed#define LLVM_ADT_TRIPLE_H
12193323Sed
13226633Sdim#include "llvm/ADT/Twine.h"
14193323Sed
15198090Srdivacky// Some system headers or GCC predefined macros conflict with identifiers in
16198090Srdivacky// this file.  Undefine them here.
17263508Sdim#undef NetBSD
18198090Srdivacky#undef mips
19198090Srdivacky#undef sparc
20198090Srdivacky
21193323Sednamespace llvm {
22193323Sed
23263508Sdim/// Triple - Helper class for working with autoconf configuration names. For
24263508Sdim/// historical reasons, we also call these 'triples' (they used to contain
25263508Sdim/// exactly three fields).
26193323Sed///
27263508Sdim/// Configuration names are strings in the canonical form:
28193323Sed///   ARCHITECTURE-VENDOR-OPERATING_SYSTEM
29193323Sed/// or
30193323Sed///   ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT
31193323Sed///
32193323Sed/// This class is used for clients which want to support arbitrary
33263508Sdim/// configuration names, but also want to implement certain special
34263508Sdim/// behavior for particular configurations. This class isolates the mapping
35263508Sdim/// from the components of the configuration name to well known IDs.
36193323Sed///
37198090Srdivacky/// At its core the Triple class is designed to be a wrapper for a triple
38212904Sdim/// string; the constructor does not change or normalize the triple string.
39212904Sdim/// Clients that need to handle the non-canonical triples that users often
40212904Sdim/// specify should use the normalize method.
41198090Srdivacky///
42263508Sdim/// See autoconf/config.guess for a glimpse into what configuration names
43263508Sdim/// look like in practice.
44193323Sedclass Triple {
45193323Sedpublic:
46193323Sed  enum ArchType {
47193323Sed    UnknownArch,
48218893Sdim
49251662Sdim    arm,     // ARM: arm, armv.*, xscale
50249423Sdim    aarch64, // AArch64: aarch64
51234353Sdim    hexagon, // Hexagon: hexagon
52198090Srdivacky    mips,    // MIPS: mips, mipsallegrex
53234353Sdim    mipsel,  // MIPSEL: mipsel, mipsallegrexel
54226633Sdim    mips64,  // MIPS64: mips64
55226633Sdim    mips64el,// MIPS64EL: mips64el
56198090Srdivacky    msp430,  // MSP430: msp430
57198090Srdivacky    ppc,     // PPC: powerpc
58199989Srdivacky    ppc64,   // PPC64: powerpc64, ppu
59263508Sdim    ppc64le, // PPC64LE: powerpc64le
60234353Sdim    r600,    // R600: AMD GPUs HD2XXX - HD6XXX
61198090Srdivacky    sparc,   // Sparc: sparc
62203954Srdivacky    sparcv9, // Sparcv9: Sparcv9
63251662Sdim    systemz, // SystemZ: s390x
64198090Srdivacky    tce,     // TCE (http://tce.cs.tut.fi/): tce
65198090Srdivacky    thumb,   // Thumb: thumb, thumbv.*
66198090Srdivacky    x86,     // X86: i[3-9]86
67198090Srdivacky    x86_64,  // X86-64: amd64, x86_64
68198090Srdivacky    xcore,   // XCore: xcore
69239462Sdim    nvptx,   // NVPTX: 32-bit
70239462Sdim    nvptx64, // NVPTX: 64-bit
71226633Sdim    le32,    // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
72243830Sdim    amdil,   // amdil: amd IL
73243830Sdim    spir,    // SPIR: standard portable IR for OpenCL 32-bit version
74243830Sdim    spir64   // SPIR: standard portable IR for OpenCL 64-bit version
75193323Sed  };
76193323Sed  enum VendorType {
77193323Sed    UnknownVendor,
78193323Sed
79218893Sdim    Apple,
80221345Sdim    PC,
81234353Sdim    SCEI,
82234353Sdim    BGP,
83243830Sdim    BGQ,
84243830Sdim    Freescale,
85263508Sdim    IBM,
86263508Sdim    NVIDIA
87193323Sed  };
88193323Sed  enum OSType {
89193323Sed    UnknownOS,
90193323Sed
91194612Sed    AuroraUX,
92198090Srdivacky    Cygwin,
93193323Sed    Darwin,
94193323Sed    DragonFly,
95193323Sed    FreeBSD,
96221345Sdim    IOS,
97226633Sdim    KFreeBSD,
98195340Sed    Linux,
99199989Srdivacky    Lv2,        // PS3
100221345Sdim    MacOSX,
101218893Sdim    MinGW32,    // i*86-pc-mingw32, *-w64-mingw32
102198090Srdivacky    NetBSD,
103198090Srdivacky    OpenBSD,
104198090Srdivacky    Solaris,
105198396Srdivacky    Win32,
106210299Sed    Haiku,
107224145Sdim    Minix,
108226633Sdim    RTEMS,
109249423Sdim    NaCl,       // Native Client
110249423Sdim    CNK,        // BG/P Compute-Node Kernel
111243830Sdim    Bitrig,
112263508Sdim    AIX,
113263508Sdim    CUDA,       // NVIDIA CUDA
114263508Sdim    NVCL        // NVIDIA OpenCL
115193323Sed  };
116218893Sdim  enum EnvironmentType {
117218893Sdim    UnknownEnvironment,
118218893Sdim
119218893Sdim    GNU,
120218893Sdim    GNUEABI,
121234353Sdim    GNUEABIHF,
122249423Sdim    GNUX32,
123218893Sdim    EABI,
124234353Sdim    MachO,
125243830Sdim    Android,
126243830Sdim    ELF
127218893Sdim  };
128218893Sdim
129193323Sedprivate:
130193323Sed  std::string Data;
131193323Sed
132234353Sdim  /// The parsed arch type.
133234353Sdim  ArchType Arch;
134193323Sed
135193323Sed  /// The parsed vendor type.
136234353Sdim  VendorType Vendor;
137193323Sed
138193323Sed  /// The parsed OS type.
139234353Sdim  OSType OS;
140193323Sed
141218893Sdim  /// The parsed Environment type.
142234353Sdim  EnvironmentType Environment;
143218893Sdim
144193323Sedpublic:
145193323Sed  /// @name Constructors
146193323Sed  /// @{
147218893Sdim
148234353Sdim  /// \brief Default constructor is the same as an empty string and leaves all
149234353Sdim  /// triple fields unknown.
150234353Sdim  Triple() : Data(), Arch(), Vendor(), OS(), Environment() {}
151193323Sed
152234353Sdim  explicit Triple(const Twine &Str);
153234353Sdim  Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
154226633Sdim  Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
155234353Sdim         const Twine &EnvironmentStr);
156218893Sdim
157193323Sed  /// @}
158212904Sdim  /// @name Normalization
159212904Sdim  /// @{
160212904Sdim
161212904Sdim  /// normalize - Turn an arbitrary machine specification into the canonical
162212904Sdim  /// triple form (or something sensible that the Triple class understands if
163212904Sdim  /// nothing better can reasonably be done).  In particular, it handles the
164212904Sdim  /// common case in which otherwise valid components are in the wrong order.
165212904Sdim  static std::string normalize(StringRef Str);
166212904Sdim
167212904Sdim  /// @}
168193323Sed  /// @name Typed Component Access
169193323Sed  /// @{
170218893Sdim
171193323Sed  /// getArch - Get the parsed architecture type of this triple.
172234353Sdim  ArchType getArch() const { return Arch; }
173218893Sdim
174193323Sed  /// getVendor - Get the parsed vendor type of this triple.
175234353Sdim  VendorType getVendor() const { return Vendor; }
176218893Sdim
177193323Sed  /// getOS - Get the parsed operating system type of this triple.
178234353Sdim  OSType getOS() const { return OS; }
179193323Sed
180193323Sed  /// hasEnvironment - Does this triple have the optional environment
181193323Sed  /// (fourth) component?
182193323Sed  bool hasEnvironment() const {
183193323Sed    return getEnvironmentName() != "";
184193323Sed  }
185193323Sed
186218893Sdim  /// getEnvironment - Get the parsed environment type of this triple.
187234353Sdim  EnvironmentType getEnvironment() const { return Environment; }
188234353Sdim
189234353Sdim  /// getOSVersion - Parse the version number from the OS name component of the
190234353Sdim  /// triple, if present.
191234353Sdim  ///
192234353Sdim  /// For example, "fooos1.2.3" would return (1, 2, 3).
193234353Sdim  ///
194234353Sdim  /// If an entry is not defined, it will be returned as 0.
195234353Sdim  void getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const;
196234353Sdim
197234353Sdim  /// getOSMajorVersion - Return just the major version number, this is
198234353Sdim  /// specialized because it is a common query.
199234353Sdim  unsigned getOSMajorVersion() const {
200234353Sdim    unsigned Maj, Min, Micro;
201234353Sdim    getOSVersion(Maj, Min, Micro);
202234353Sdim    return Maj;
203218893Sdim  }
204218893Sdim
205234353Sdim  /// getMacOSXVersion - Parse the version number as with getOSVersion and then
206234353Sdim  /// translate generic "darwin" versions to the corresponding OS X versions.
207234353Sdim  /// This may also be called with IOS triples but the OS X version number is
208234353Sdim  /// just set to a constant 10.4.0 in that case.  Returns true if successful.
209234353Sdim  bool getMacOSXVersion(unsigned &Major, unsigned &Minor,
210234353Sdim                        unsigned &Micro) const;
211234353Sdim
212239462Sdim  /// getiOSVersion - Parse the version number as with getOSVersion.  This should
213239462Sdim  /// only be called with IOS triples.
214239462Sdim  void getiOSVersion(unsigned &Major, unsigned &Minor,
215239462Sdim                     unsigned &Micro) const;
216239462Sdim
217193323Sed  /// @}
218193323Sed  /// @name Direct Component Access
219193323Sed  /// @{
220193323Sed
221199481Srdivacky  const std::string &str() const { return Data; }
222199481Srdivacky
223193323Sed  const std::string &getTriple() const { return Data; }
224193323Sed
225193323Sed  /// getArchName - Get the architecture (first) component of the
226193323Sed  /// triple.
227198090Srdivacky  StringRef getArchName() const;
228193323Sed
229193323Sed  /// getVendorName - Get the vendor (second) component of the triple.
230198090Srdivacky  StringRef getVendorName() const;
231193323Sed
232193323Sed  /// getOSName - Get the operating system (third) component of the
233193323Sed  /// triple.
234198090Srdivacky  StringRef getOSName() const;
235193323Sed
236193323Sed  /// getEnvironmentName - Get the optional environment (fourth)
237193323Sed  /// component of the triple, or "" if empty.
238198090Srdivacky  StringRef getEnvironmentName() const;
239193323Sed
240193323Sed  /// getOSAndEnvironmentName - Get the operating system and optional
241193323Sed  /// environment components as a single string (separated by a '-'
242193323Sed  /// if the environment component is present).
243198090Srdivacky  StringRef getOSAndEnvironmentName() const;
244193323Sed
245234353Sdim  /// @}
246234353Sdim  /// @name Convenience Predicates
247234353Sdim  /// @{
248234353Sdim
249234353Sdim  /// \brief Test whether the architecture is 64-bit
250221345Sdim  ///
251234353Sdim  /// Note that this tests for 64-bit pointer width, and nothing else. Note
252234353Sdim  /// that we intentionally expose only three predicates, 64-bit, 32-bit, and
253234353Sdim  /// 16-bit. The inner details of pointer width for particular architectures
254234353Sdim  /// is not summed up in the triple, and so only a coarse grained predicate
255234353Sdim  /// system is provided.
256234353Sdim  bool isArch64Bit() const;
257234353Sdim
258234353Sdim  /// \brief Test whether the architecture is 32-bit
259221345Sdim  ///
260234353Sdim  /// Note that this tests for 32-bit pointer width, and nothing else.
261234353Sdim  bool isArch32Bit() const;
262218893Sdim
263234353Sdim  /// \brief Test whether the architecture is 16-bit
264234353Sdim  ///
265234353Sdim  /// Note that this tests for 16-bit pointer width, and nothing else.
266234353Sdim  bool isArch16Bit() const;
267218893Sdim
268221345Sdim  /// isOSVersionLT - Helper function for doing comparisons against version
269221345Sdim  /// numbers included in the target triple.
270221345Sdim  bool isOSVersionLT(unsigned Major, unsigned Minor = 0,
271221345Sdim                     unsigned Micro = 0) const {
272221345Sdim    unsigned LHS[3];
273221345Sdim    getOSVersion(LHS[0], LHS[1], LHS[2]);
274221345Sdim
275221345Sdim    if (LHS[0] != Major)
276221345Sdim      return LHS[0] < Major;
277221345Sdim    if (LHS[1] != Minor)
278221345Sdim      return LHS[1] < Minor;
279221345Sdim    if (LHS[2] != Micro)
280221345Sdim      return LHS[1] < Micro;
281221345Sdim
282221345Sdim    return false;
283221345Sdim  }
284221345Sdim
285234353Sdim  /// isMacOSXVersionLT - Comparison function for checking OS X version
286234353Sdim  /// compatibility, which handles supporting skewed version numbering schemes
287234353Sdim  /// used by the "darwin" triples.
288234353Sdim  unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
289239462Sdim                             unsigned Micro = 0) const {
290234353Sdim    assert(isMacOSX() && "Not an OS X triple!");
291234353Sdim
292234353Sdim    // If this is OS X, expect a sane version number.
293234353Sdim    if (getOS() == Triple::MacOSX)
294234353Sdim      return isOSVersionLT(Major, Minor, Micro);
295234353Sdim
296234353Sdim    // Otherwise, compare to the "Darwin" number.
297234353Sdim    assert(Major == 10 && "Unexpected major version");
298234353Sdim    return isOSVersionLT(Minor + 4, Micro, 0);
299234353Sdim  }
300234353Sdim
301221345Sdim  /// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both
302221345Sdim  /// "darwin" and "osx" as OS X triples.
303221345Sdim  bool isMacOSX() const {
304221345Sdim    return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
305221345Sdim  }
306221345Sdim
307249423Sdim  /// Is this an iOS triple.
308249423Sdim  bool isiOS() const {
309249423Sdim    return getOS() == Triple::IOS;
310249423Sdim  }
311249423Sdim
312221345Sdim  /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
313221345Sdim  bool isOSDarwin() const {
314249423Sdim    return isMacOSX() || isiOS();
315221345Sdim  }
316221345Sdim
317234353Sdim  /// \brief Tests for either Cygwin or MinGW OS
318234353Sdim  bool isOSCygMing() const {
319234353Sdim    return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32;
320234353Sdim  }
321234353Sdim
322263508Sdim  /// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
323263508Sdim  bool isOSMSVCRT() const {
324263508Sdim    return getOS() == Triple::Win32 || getOS() == Triple::MinGW32;
325263508Sdim  }
326263508Sdim
327263508Sdim  /// \brief Tests whether the OS is Windows.
328221345Sdim  bool isOSWindows() const {
329234353Sdim    return getOS() == Triple::Win32 || isOSCygMing();
330221345Sdim  }
331221345Sdim
332249423Sdim  /// \brief Tests whether the OS is NaCl (Native Client)
333249423Sdim  bool isOSNaCl() const {
334249423Sdim    return getOS() == Triple::NaCl;
335249423Sdim  }
336249423Sdim
337263508Sdim  /// \brief Tests whether the OS is Linux.
338263508Sdim  bool isOSLinux() const {
339263508Sdim    return getOS() == Triple::Linux;
340263508Sdim  }
341263508Sdim
342234353Sdim  /// \brief Tests whether the OS uses the ELF binary format.
343234353Sdim  bool isOSBinFormatELF() const {
344234353Sdim    return !isOSDarwin() && !isOSWindows();
345234353Sdim  }
346221345Sdim
347234353Sdim  /// \brief Tests whether the OS uses the COFF binary format.
348234353Sdim  bool isOSBinFormatCOFF() const {
349234353Sdim    return isOSWindows();
350234353Sdim  }
351221345Sdim
352234353Sdim  /// \brief Tests whether the environment is MachO.
353234353Sdim  // FIXME: Should this be an OSBinFormat predicate?
354234353Sdim  bool isEnvironmentMachO() const {
355234353Sdim    return getEnvironment() == Triple::MachO || isOSDarwin();
356221345Sdim  }
357224145Sdim
358193323Sed  /// @}
359193323Sed  /// @name Mutators
360193323Sed  /// @{
361193323Sed
362193323Sed  /// setArch - Set the architecture (first) component of the triple
363193323Sed  /// to a known type.
364193323Sed  void setArch(ArchType Kind);
365193323Sed
366193323Sed  /// setVendor - Set the vendor (second) component of the triple to a
367193323Sed  /// known type.
368193323Sed  void setVendor(VendorType Kind);
369193323Sed
370193323Sed  /// setOS - Set the operating system (third) component of the triple
371193323Sed  /// to a known type.
372193323Sed  void setOS(OSType Kind);
373193323Sed
374218893Sdim  /// setEnvironment - Set the environment (fourth) component of the triple
375218893Sdim  /// to a known type.
376218893Sdim  void setEnvironment(EnvironmentType Kind);
377218893Sdim
378243830Sdim  /// setTriple - Set all components to the new triple \p Str.
379198090Srdivacky  void setTriple(const Twine &Str);
380193323Sed
381193323Sed  /// setArchName - Set the architecture (first) component of the
382193323Sed  /// triple by name.
383199481Srdivacky  void setArchName(StringRef Str);
384193323Sed
385193323Sed  /// setVendorName - Set the vendor (second) component of the triple
386193323Sed  /// by name.
387199481Srdivacky  void setVendorName(StringRef Str);
388193323Sed
389193323Sed  /// setOSName - Set the operating system (third) component of the
390193323Sed  /// triple by name.
391199481Srdivacky  void setOSName(StringRef Str);
392193323Sed
393193323Sed  /// setEnvironmentName - Set the optional environment (fourth)
394193323Sed  /// component of the triple by name.
395199481Srdivacky  void setEnvironmentName(StringRef Str);
396193323Sed
397193323Sed  /// setOSAndEnvironmentName - Set the operating system and optional
398193323Sed  /// environment components with a single string.
399199481Srdivacky  void setOSAndEnvironmentName(StringRef Str);
400193323Sed
401210299Sed  /// getArchNameForAssembler - Get an architecture name that is understood by
402210299Sed  /// the target assembler.
403199481Srdivacky  const char *getArchNameForAssembler();
404199481Srdivacky
405193323Sed  /// @}
406234353Sdim  /// @name Helpers to build variants of a particular triple.
407234353Sdim  /// @{
408234353Sdim
409234353Sdim  /// \brief Form a triple with a 32-bit variant of the current architecture.
410234353Sdim  ///
411234353Sdim  /// This can be used to move across "families" of architectures where useful.
412234353Sdim  ///
413234353Sdim  /// \returns A new triple with a 32-bit architecture or an unknown
414234353Sdim  ///          architecture if no such variant can be found.
415234353Sdim  llvm::Triple get32BitArchVariant() const;
416234353Sdim
417234353Sdim  /// \brief Form a triple with a 64-bit variant of the current architecture.
418234353Sdim  ///
419234353Sdim  /// This can be used to move across "families" of architectures where useful.
420234353Sdim  ///
421234353Sdim  /// \returns A new triple with a 64-bit architecture or an unknown
422234353Sdim  ///          architecture if no such variant can be found.
423234353Sdim  llvm::Triple get64BitArchVariant() const;
424234353Sdim
425234353Sdim  /// @}
426193323Sed  /// @name Static helpers for IDs.
427193323Sed  /// @{
428193323Sed
429243830Sdim  /// getArchTypeName - Get the canonical name for the \p Kind architecture.
430193323Sed  static const char *getArchTypeName(ArchType Kind);
431193323Sed
432243830Sdim  /// getArchTypePrefix - Get the "prefix" canonical name for the \p Kind
433198090Srdivacky  /// architecture. This is the prefix used by the architecture specific
434198090Srdivacky  /// builtins, and is suitable for passing to \see
435198090Srdivacky  /// Intrinsic::getIntrinsicForGCCBuiltin().
436198090Srdivacky  ///
437198090Srdivacky  /// \return - The architecture prefix, or 0 if none is defined.
438198090Srdivacky  static const char *getArchTypePrefix(ArchType Kind);
439198090Srdivacky
440243830Sdim  /// getVendorTypeName - Get the canonical name for the \p Kind vendor.
441193323Sed  static const char *getVendorTypeName(VendorType Kind);
442193323Sed
443243830Sdim  /// getOSTypeName - Get the canonical name for the \p Kind operating system.
444193323Sed  static const char *getOSTypeName(OSType Kind);
445193323Sed
446243830Sdim  /// getEnvironmentTypeName - Get the canonical name for the \p Kind
447218893Sdim  /// environment.
448218893Sdim  static const char *getEnvironmentTypeName(EnvironmentType Kind);
449218893Sdim
450193323Sed  /// @}
451198090Srdivacky  /// @name Static helpers for converting alternate architecture names.
452198090Srdivacky  /// @{
453198090Srdivacky
454198090Srdivacky  /// getArchTypeForLLVMName - The canonical type for the given LLVM
455198090Srdivacky  /// architecture name (e.g., "x86").
456199481Srdivacky  static ArchType getArchTypeForLLVMName(StringRef Str);
457198090Srdivacky
458198090Srdivacky  /// @}
459193323Sed};
460193323Sed
461193323Sed} // End llvm namespace
462193323Sed
463193323Sed
464193323Sed#endif
465