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
13226890Sdim#include "llvm/ADT/Twine.h"
14193323Sed
15198090Srdivacky// Some system headers or GCC predefined macros conflict with identifiers in
16198090Srdivacky// this file.  Undefine them here.
17263509Sdim#undef NetBSD
18198090Srdivacky#undef mips
19198090Srdivacky#undef sparc
20198090Srdivacky
21193323Sednamespace llvm {
22193323Sed
23263509Sdim/// Triple - Helper class for working with autoconf configuration names. For
24263509Sdim/// historical reasons, we also call these 'triples' (they used to contain
25263509Sdim/// exactly three fields).
26193323Sed///
27263509Sdim/// 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
33263509Sdim/// configuration names, but also want to implement certain special
34263509Sdim/// behavior for particular configurations. This class isolates the mapping
35263509Sdim/// 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///
42263509Sdim/// See autoconf/config.guess for a glimpse into what configuration names
43263509Sdim/// look like in practice.
44193323Sedclass Triple {
45193323Sedpublic:
46193323Sed  enum ArchType {
47193323Sed    UnknownArch,
48218893Sdim
49252723Sdim    arm,     // ARM: arm, armv.*, xscale
50252723Sdim    aarch64, // AArch64: aarch64
51235633Sdim    hexagon, // Hexagon: hexagon
52198090Srdivacky    mips,    // MIPS: mips, mipsallegrex
53235633Sdim    mipsel,  // MIPSEL: mipsel, mipsallegrexel
54226890Sdim    mips64,  // MIPS64: mips64
55226890Sdim    mips64el,// MIPS64EL: mips64el
56198090Srdivacky    msp430,  // MSP430: msp430
57198090Srdivacky    ppc,     // PPC: powerpc
58199989Srdivacky    ppc64,   // PPC64: powerpc64, ppu
59263509Sdim    ppc64le, // PPC64LE: powerpc64le
60235633Sdim    r600,    // R600: AMD GPUs HD2XXX - HD6XXX
61198090Srdivacky    sparc,   // Sparc: sparc
62203954Srdivacky    sparcv9, // Sparcv9: Sparcv9
63252723Sdim    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
69245431Sdim    nvptx,   // NVPTX: 32-bit
70245431Sdim    nvptx64, // NVPTX: 64-bit
71226890Sdim    le32,    // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
72245431Sdim    amdil,   // amdil: amd IL
73245431Sdim    spir,    // SPIR: standard portable IR for OpenCL 32-bit version
74245431Sdim    spir64   // SPIR: standard portable IR for OpenCL 64-bit version
75193323Sed  };
76193323Sed  enum VendorType {
77193323Sed    UnknownVendor,
78193323Sed
79218893Sdim    Apple,
80221345Sdim    PC,
81235633Sdim    SCEI,
82235633Sdim    BGP,
83245431Sdim    BGQ,
84245431Sdim    Freescale,
85263509Sdim    IBM,
86263509Sdim    NVIDIA
87193323Sed  };
88193323Sed  enum OSType {
89193323Sed    UnknownOS,
90193323Sed
91194612Sed    AuroraUX,
92198090Srdivacky    Cygwin,
93193323Sed    Darwin,
94193323Sed    DragonFly,
95193323Sed    FreeBSD,
96221345Sdim    IOS,
97226890Sdim    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,
108226890Sdim    RTEMS,
109252723Sdim    NaCl,       // Native Client
110252723Sdim    CNK,        // BG/P Compute-Node Kernel
111245431Sdim    Bitrig,
112263509Sdim    AIX,
113263509Sdim    CUDA,       // NVIDIA CUDA
114263509Sdim    NVCL        // NVIDIA OpenCL
115193323Sed  };
116218893Sdim  enum EnvironmentType {
117218893Sdim    UnknownEnvironment,
118218893Sdim
119218893Sdim    GNU,
120218893Sdim    GNUEABI,
121235633Sdim    GNUEABIHF,
122252723Sdim    GNUX32,
123218893Sdim    EABI,
124235633Sdim    MachO,
125245431Sdim    Android,
126245431Sdim    ELF
127218893Sdim  };
128218893Sdim
129193323Sedprivate:
130193323Sed  std::string Data;
131193323Sed
132235633Sdim  /// The parsed arch type.
133235633Sdim  ArchType Arch;
134193323Sed
135193323Sed  /// The parsed vendor type.
136235633Sdim  VendorType Vendor;
137193323Sed
138193323Sed  /// The parsed OS type.
139235633Sdim  OSType OS;
140193323Sed
141218893Sdim  /// The parsed Environment type.
142235633Sdim  EnvironmentType Environment;
143218893Sdim
144193323Sedpublic:
145193323Sed  /// @name Constructors
146193323Sed  /// @{
147218893Sdim
148235633Sdim  /// \brief Default constructor is the same as an empty string and leaves all
149235633Sdim  /// triple fields unknown.
150235633Sdim  Triple() : Data(), Arch(), Vendor(), OS(), Environment() {}
151193323Sed
152235633Sdim  explicit Triple(const Twine &Str);
153235633Sdim  Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
154226890Sdim  Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
155235633Sdim         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.
172235633Sdim  ArchType getArch() const { return Arch; }
173218893Sdim
174193323Sed  /// getVendor - Get the parsed vendor type of this triple.
175235633Sdim  VendorType getVendor() const { return Vendor; }
176218893Sdim
177193323Sed  /// getOS - Get the parsed operating system type of this triple.
178235633Sdim  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.
187235633Sdim  EnvironmentType getEnvironment() const { return Environment; }
188235633Sdim
189235633Sdim  /// getOSVersion - Parse the version number from the OS name component of the
190235633Sdim  /// triple, if present.
191235633Sdim  ///
192235633Sdim  /// For example, "fooos1.2.3" would return (1, 2, 3).
193235633Sdim  ///
194235633Sdim  /// If an entry is not defined, it will be returned as 0.
195235633Sdim  void getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const;
196235633Sdim
197235633Sdim  /// getOSMajorVersion - Return just the major version number, this is
198235633Sdim  /// specialized because it is a common query.
199235633Sdim  unsigned getOSMajorVersion() const {
200235633Sdim    unsigned Maj, Min, Micro;
201235633Sdim    getOSVersion(Maj, Min, Micro);
202235633Sdim    return Maj;
203218893Sdim  }
204218893Sdim
205235633Sdim  /// getMacOSXVersion - Parse the version number as with getOSVersion and then
206235633Sdim  /// translate generic "darwin" versions to the corresponding OS X versions.
207235633Sdim  /// This may also be called with IOS triples but the OS X version number is
208235633Sdim  /// just set to a constant 10.4.0 in that case.  Returns true if successful.
209235633Sdim  bool getMacOSXVersion(unsigned &Major, unsigned &Minor,
210235633Sdim                        unsigned &Micro) const;
211235633Sdim
212245431Sdim  /// getiOSVersion - Parse the version number as with getOSVersion.  This should
213245431Sdim  /// only be called with IOS triples.
214245431Sdim  void getiOSVersion(unsigned &Major, unsigned &Minor,
215245431Sdim                     unsigned &Micro) const;
216245431Sdim
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
245235633Sdim  /// @}
246235633Sdim  /// @name Convenience Predicates
247235633Sdim  /// @{
248235633Sdim
249235633Sdim  /// \brief Test whether the architecture is 64-bit
250221345Sdim  ///
251235633Sdim  /// Note that this tests for 64-bit pointer width, and nothing else. Note
252235633Sdim  /// that we intentionally expose only three predicates, 64-bit, 32-bit, and
253235633Sdim  /// 16-bit. The inner details of pointer width for particular architectures
254235633Sdim  /// is not summed up in the triple, and so only a coarse grained predicate
255235633Sdim  /// system is provided.
256235633Sdim  bool isArch64Bit() const;
257235633Sdim
258235633Sdim  /// \brief Test whether the architecture is 32-bit
259221345Sdim  ///
260235633Sdim  /// Note that this tests for 32-bit pointer width, and nothing else.
261235633Sdim  bool isArch32Bit() const;
262218893Sdim
263235633Sdim  /// \brief Test whether the architecture is 16-bit
264235633Sdim  ///
265235633Sdim  /// Note that this tests for 16-bit pointer width, and nothing else.
266235633Sdim  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
285235633Sdim  /// isMacOSXVersionLT - Comparison function for checking OS X version
286235633Sdim  /// compatibility, which handles supporting skewed version numbering schemes
287235633Sdim  /// used by the "darwin" triples.
288235633Sdim  unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
289245431Sdim                             unsigned Micro = 0) const {
290235633Sdim    assert(isMacOSX() && "Not an OS X triple!");
291235633Sdim
292235633Sdim    // If this is OS X, expect a sane version number.
293235633Sdim    if (getOS() == Triple::MacOSX)
294235633Sdim      return isOSVersionLT(Major, Minor, Micro);
295235633Sdim
296235633Sdim    // Otherwise, compare to the "Darwin" number.
297235633Sdim    assert(Major == 10 && "Unexpected major version");
298235633Sdim    return isOSVersionLT(Minor + 4, Micro, 0);
299235633Sdim  }
300235633Sdim
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
307252723Sdim  /// Is this an iOS triple.
308252723Sdim  bool isiOS() const {
309252723Sdim    return getOS() == Triple::IOS;
310252723Sdim  }
311252723Sdim
312221345Sdim  /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
313221345Sdim  bool isOSDarwin() const {
314252723Sdim    return isMacOSX() || isiOS();
315221345Sdim  }
316221345Sdim
317235633Sdim  /// \brief Tests for either Cygwin or MinGW OS
318235633Sdim  bool isOSCygMing() const {
319235633Sdim    return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32;
320235633Sdim  }
321235633Sdim
322263509Sdim  /// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
323263509Sdim  bool isOSMSVCRT() const {
324263509Sdim    return getOS() == Triple::Win32 || getOS() == Triple::MinGW32;
325263509Sdim  }
326263509Sdim
327263509Sdim  /// \brief Tests whether the OS is Windows.
328221345Sdim  bool isOSWindows() const {
329235633Sdim    return getOS() == Triple::Win32 || isOSCygMing();
330221345Sdim  }
331221345Sdim
332252723Sdim  /// \brief Tests whether the OS is NaCl (Native Client)
333252723Sdim  bool isOSNaCl() const {
334252723Sdim    return getOS() == Triple::NaCl;
335252723Sdim  }
336252723Sdim
337263509Sdim  /// \brief Tests whether the OS is Linux.
338263509Sdim  bool isOSLinux() const {
339263509Sdim    return getOS() == Triple::Linux;
340263509Sdim  }
341263509Sdim
342235633Sdim  /// \brief Tests whether the OS uses the ELF binary format.
343235633Sdim  bool isOSBinFormatELF() const {
344235633Sdim    return !isOSDarwin() && !isOSWindows();
345235633Sdim  }
346221345Sdim
347235633Sdim  /// \brief Tests whether the OS uses the COFF binary format.
348235633Sdim  bool isOSBinFormatCOFF() const {
349235633Sdim    return isOSWindows();
350235633Sdim  }
351221345Sdim
352235633Sdim  /// \brief Tests whether the environment is MachO.
353235633Sdim  // FIXME: Should this be an OSBinFormat predicate?
354235633Sdim  bool isEnvironmentMachO() const {
355235633Sdim    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
378245431Sdim  /// 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  /// @}
406235633Sdim  /// @name Helpers to build variants of a particular triple.
407235633Sdim  /// @{
408235633Sdim
409235633Sdim  /// \brief Form a triple with a 32-bit variant of the current architecture.
410235633Sdim  ///
411235633Sdim  /// This can be used to move across "families" of architectures where useful.
412235633Sdim  ///
413235633Sdim  /// \returns A new triple with a 32-bit architecture or an unknown
414235633Sdim  ///          architecture if no such variant can be found.
415235633Sdim  llvm::Triple get32BitArchVariant() const;
416235633Sdim
417235633Sdim  /// \brief Form a triple with a 64-bit variant of the current architecture.
418235633Sdim  ///
419235633Sdim  /// This can be used to move across "families" of architectures where useful.
420235633Sdim  ///
421235633Sdim  /// \returns A new triple with a 64-bit architecture or an unknown
422235633Sdim  ///          architecture if no such variant can be found.
423235633Sdim  llvm::Triple get64BitArchVariant() const;
424235633Sdim
425235633Sdim  /// @}
426193323Sed  /// @name Static helpers for IDs.
427193323Sed  /// @{
428193323Sed
429245431Sdim  /// getArchTypeName - Get the canonical name for the \p Kind architecture.
430193323Sed  static const char *getArchTypeName(ArchType Kind);
431193323Sed
432245431Sdim  /// 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
440245431Sdim  /// getVendorTypeName - Get the canonical name for the \p Kind vendor.
441193323Sed  static const char *getVendorTypeName(VendorType Kind);
442193323Sed
443245431Sdim  /// getOSTypeName - Get the canonical name for the \p Kind operating system.
444193323Sed  static const char *getOSTypeName(OSType Kind);
445193323Sed
446245431Sdim  /// 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