xref: /minix3/external/bsd/llvm/dist/clang/lib/Basic/Targets.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- Targets.cpp - Implement -arch option and targets -----------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements construction of a TargetInfo object from a
11f4a2713aSLionel Sambuc // target triple.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc 
15f4a2713aSLionel Sambuc #include "clang/Basic/TargetInfo.h"
16f4a2713aSLionel Sambuc #include "clang/Basic/Builtins.h"
17f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h"
18f4a2713aSLionel Sambuc #include "clang/Basic/LangOptions.h"
19f4a2713aSLionel Sambuc #include "clang/Basic/MacroBuilder.h"
20f4a2713aSLionel Sambuc #include "clang/Basic/TargetBuiltins.h"
21f4a2713aSLionel Sambuc #include "clang/Basic/TargetOptions.h"
22f4a2713aSLionel Sambuc #include "llvm/ADT/APFloat.h"
23f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
24*0a6a1f1dSLionel Sambuc #include "llvm/ADT/StringExtras.h"
25f4a2713aSLionel Sambuc #include "llvm/ADT/StringRef.h"
26f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
27f4a2713aSLionel Sambuc #include "llvm/ADT/Triple.h"
28f4a2713aSLionel Sambuc #include "llvm/IR/Type.h"
29f4a2713aSLionel Sambuc #include "llvm/MC/MCSectionMachO.h"
30f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
31f4a2713aSLionel Sambuc #include <algorithm>
32*0a6a1f1dSLionel Sambuc #include <memory>
33f4a2713aSLionel Sambuc using namespace clang;
34f4a2713aSLionel Sambuc 
35f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
36f4a2713aSLionel Sambuc //  Common code shared among targets.
37f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
38f4a2713aSLionel Sambuc 
39f4a2713aSLionel Sambuc /// DefineStd - Define a macro name and standard variants.  For example if
40f4a2713aSLionel Sambuc /// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
41f4a2713aSLionel Sambuc /// when in GNU mode.
DefineStd(MacroBuilder & Builder,StringRef MacroName,const LangOptions & Opts)42f4a2713aSLionel Sambuc static void DefineStd(MacroBuilder &Builder, StringRef MacroName,
43f4a2713aSLionel Sambuc                       const LangOptions &Opts) {
44f4a2713aSLionel Sambuc   assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
45f4a2713aSLionel Sambuc 
46f4a2713aSLionel Sambuc   // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
47f4a2713aSLionel Sambuc   // in the user's namespace.
48f4a2713aSLionel Sambuc   if (Opts.GNUMode)
49f4a2713aSLionel Sambuc     Builder.defineMacro(MacroName);
50f4a2713aSLionel Sambuc 
51f4a2713aSLionel Sambuc   // Define __unix.
52f4a2713aSLionel Sambuc   Builder.defineMacro("__" + MacroName);
53f4a2713aSLionel Sambuc 
54f4a2713aSLionel Sambuc   // Define __unix__.
55f4a2713aSLionel Sambuc   Builder.defineMacro("__" + MacroName + "__");
56f4a2713aSLionel Sambuc }
57f4a2713aSLionel Sambuc 
defineCPUMacros(MacroBuilder & Builder,StringRef CPUName,bool Tuning=true)58f4a2713aSLionel Sambuc static void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName,
59f4a2713aSLionel Sambuc                             bool Tuning = true) {
60f4a2713aSLionel Sambuc   Builder.defineMacro("__" + CPUName);
61f4a2713aSLionel Sambuc   Builder.defineMacro("__" + CPUName + "__");
62f4a2713aSLionel Sambuc   if (Tuning)
63f4a2713aSLionel Sambuc     Builder.defineMacro("__tune_" + CPUName + "__");
64f4a2713aSLionel Sambuc }
65f4a2713aSLionel Sambuc 
66f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
67f4a2713aSLionel Sambuc // Defines specific to certain operating systems.
68f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
69f4a2713aSLionel Sambuc 
70f4a2713aSLionel Sambuc namespace {
71f4a2713aSLionel Sambuc template<typename TgtInfo>
72f4a2713aSLionel Sambuc class OSTargetInfo : public TgtInfo {
73f4a2713aSLionel Sambuc protected:
74f4a2713aSLionel Sambuc   virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
75f4a2713aSLionel Sambuc                             MacroBuilder &Builder) const=0;
76f4a2713aSLionel Sambuc public:
OSTargetInfo(const llvm::Triple & Triple)77f4a2713aSLionel Sambuc   OSTargetInfo(const llvm::Triple &Triple) : TgtInfo(Triple) {}
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const78*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
79*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
80f4a2713aSLionel Sambuc     TgtInfo::getTargetDefines(Opts, Builder);
81f4a2713aSLionel Sambuc     getOSDefines(Opts, TgtInfo::getTriple(), Builder);
82f4a2713aSLionel Sambuc   }
83f4a2713aSLionel Sambuc 
84f4a2713aSLionel Sambuc };
85f4a2713aSLionel Sambuc } // end anonymous namespace
86f4a2713aSLionel Sambuc 
87f4a2713aSLionel Sambuc 
getDarwinDefines(MacroBuilder & Builder,const LangOptions & Opts,const llvm::Triple & Triple,StringRef & PlatformName,VersionTuple & PlatformMinVersion)88f4a2713aSLionel Sambuc static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
89f4a2713aSLionel Sambuc                              const llvm::Triple &Triple,
90f4a2713aSLionel Sambuc                              StringRef &PlatformName,
91f4a2713aSLionel Sambuc                              VersionTuple &PlatformMinVersion) {
92f4a2713aSLionel Sambuc   Builder.defineMacro("__APPLE_CC__", "6000");
93f4a2713aSLionel Sambuc   Builder.defineMacro("__APPLE__");
94f4a2713aSLionel Sambuc   Builder.defineMacro("OBJC_NEW_PROPERTIES");
95f4a2713aSLionel Sambuc   // AddressSanitizer doesn't play well with source fortification, which is on
96f4a2713aSLionel Sambuc   // by default on Darwin.
97*0a6a1f1dSLionel Sambuc   if (Opts.Sanitize.has(SanitizerKind::Address))
98*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_FORTIFY_SOURCE", "0");
99f4a2713aSLionel Sambuc 
100f4a2713aSLionel Sambuc   if (!Opts.ObjCAutoRefCount) {
101f4a2713aSLionel Sambuc     // __weak is always defined, for use in blocks and with objc pointers.
102f4a2713aSLionel Sambuc     Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
103f4a2713aSLionel Sambuc 
104f4a2713aSLionel Sambuc     // Darwin defines __strong even in C mode (just to nothing).
105f4a2713aSLionel Sambuc     if (Opts.getGC() != LangOptions::NonGC)
106f4a2713aSLionel Sambuc       Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
107f4a2713aSLionel Sambuc     else
108f4a2713aSLionel Sambuc       Builder.defineMacro("__strong", "");
109f4a2713aSLionel Sambuc 
110f4a2713aSLionel Sambuc     // __unsafe_unretained is defined to nothing in non-ARC mode. We even
111f4a2713aSLionel Sambuc     // allow this in C, since one might have block pointers in structs that
112f4a2713aSLionel Sambuc     // are used in pure C code and in Objective-C ARC.
113f4a2713aSLionel Sambuc     Builder.defineMacro("__unsafe_unretained", "");
114f4a2713aSLionel Sambuc   }
115f4a2713aSLionel Sambuc 
116f4a2713aSLionel Sambuc   if (Opts.Static)
117f4a2713aSLionel Sambuc     Builder.defineMacro("__STATIC__");
118f4a2713aSLionel Sambuc   else
119f4a2713aSLionel Sambuc     Builder.defineMacro("__DYNAMIC__");
120f4a2713aSLionel Sambuc 
121f4a2713aSLionel Sambuc   if (Opts.POSIXThreads)
122f4a2713aSLionel Sambuc     Builder.defineMacro("_REENTRANT");
123f4a2713aSLionel Sambuc 
124f4a2713aSLionel Sambuc   // Get the platform type and version number from the triple.
125f4a2713aSLionel Sambuc   unsigned Maj, Min, Rev;
126f4a2713aSLionel Sambuc   if (Triple.isMacOSX()) {
127f4a2713aSLionel Sambuc     Triple.getMacOSXVersion(Maj, Min, Rev);
128f4a2713aSLionel Sambuc     PlatformName = "macosx";
129f4a2713aSLionel Sambuc   } else {
130f4a2713aSLionel Sambuc     Triple.getOSVersion(Maj, Min, Rev);
131f4a2713aSLionel Sambuc     PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
132f4a2713aSLionel Sambuc   }
133f4a2713aSLionel Sambuc 
134f4a2713aSLionel Sambuc   // If -target arch-pc-win32-macho option specified, we're
135f4a2713aSLionel Sambuc   // generating code for Win32 ABI. No need to emit
136f4a2713aSLionel Sambuc   // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.
137f4a2713aSLionel Sambuc   if (PlatformName == "win32") {
138f4a2713aSLionel Sambuc     PlatformMinVersion = VersionTuple(Maj, Min, Rev);
139f4a2713aSLionel Sambuc     return;
140f4a2713aSLionel Sambuc   }
141f4a2713aSLionel Sambuc 
142f4a2713aSLionel Sambuc   // Set the appropriate OS version define.
143f4a2713aSLionel Sambuc   if (Triple.isiOS()) {
144f4a2713aSLionel Sambuc     assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
145f4a2713aSLionel Sambuc     char Str[6];
146f4a2713aSLionel Sambuc     Str[0] = '0' + Maj;
147f4a2713aSLionel Sambuc     Str[1] = '0' + (Min / 10);
148f4a2713aSLionel Sambuc     Str[2] = '0' + (Min % 10);
149f4a2713aSLionel Sambuc     Str[3] = '0' + (Rev / 10);
150f4a2713aSLionel Sambuc     Str[4] = '0' + (Rev % 10);
151f4a2713aSLionel Sambuc     Str[5] = '\0';
152f4a2713aSLionel Sambuc     Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
153f4a2713aSLionel Sambuc                         Str);
154*0a6a1f1dSLionel Sambuc   } else if (Triple.isMacOSX()) {
155f4a2713aSLionel Sambuc     // Note that the Driver allows versions which aren't representable in the
156f4a2713aSLionel Sambuc     // define (because we only get a single digit for the minor and micro
157f4a2713aSLionel Sambuc     // revision numbers). So, we limit them to the maximum representable
158f4a2713aSLionel Sambuc     // version.
159f4a2713aSLionel Sambuc     assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
160*0a6a1f1dSLionel Sambuc     char Str[7];
161*0a6a1f1dSLionel Sambuc     if (Maj < 10 || (Maj == 10 && Min < 10)) {
162f4a2713aSLionel Sambuc       Str[0] = '0' + (Maj / 10);
163f4a2713aSLionel Sambuc       Str[1] = '0' + (Maj % 10);
164f4a2713aSLionel Sambuc       Str[2] = '0' + std::min(Min, 9U);
165f4a2713aSLionel Sambuc       Str[3] = '0' + std::min(Rev, 9U);
166f4a2713aSLionel Sambuc       Str[4] = '\0';
167*0a6a1f1dSLionel Sambuc     } else {
168*0a6a1f1dSLionel Sambuc       // Handle versions > 10.9.
169*0a6a1f1dSLionel Sambuc       Str[0] = '0' + (Maj / 10);
170*0a6a1f1dSLionel Sambuc       Str[1] = '0' + (Maj % 10);
171*0a6a1f1dSLionel Sambuc       Str[2] = '0' + (Min / 10);
172*0a6a1f1dSLionel Sambuc       Str[3] = '0' + (Min % 10);
173*0a6a1f1dSLionel Sambuc       Str[4] = '0' + (Rev / 10);
174*0a6a1f1dSLionel Sambuc       Str[5] = '0' + (Rev % 10);
175*0a6a1f1dSLionel Sambuc       Str[6] = '\0';
176*0a6a1f1dSLionel Sambuc     }
177f4a2713aSLionel Sambuc     Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
178f4a2713aSLionel Sambuc   }
179*0a6a1f1dSLionel Sambuc 
180*0a6a1f1dSLionel Sambuc   // Tell users about the kernel if there is one.
181*0a6a1f1dSLionel Sambuc   if (Triple.isOSDarwin())
182*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__MACH__");
183f4a2713aSLionel Sambuc 
184f4a2713aSLionel Sambuc   PlatformMinVersion = VersionTuple(Maj, Min, Rev);
185f4a2713aSLionel Sambuc }
186f4a2713aSLionel Sambuc 
187f4a2713aSLionel Sambuc namespace {
188f4a2713aSLionel Sambuc template<typename Target>
189f4a2713aSLionel Sambuc class DarwinTargetInfo : public OSTargetInfo<Target> {
190f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const191*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
192*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
193f4a2713aSLionel Sambuc     getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
194f4a2713aSLionel Sambuc                      this->PlatformMinVersion);
195f4a2713aSLionel Sambuc   }
196f4a2713aSLionel Sambuc 
197f4a2713aSLionel Sambuc public:
DarwinTargetInfo(const llvm::Triple & Triple)198f4a2713aSLionel Sambuc   DarwinTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
199f4a2713aSLionel Sambuc     this->TLSSupported = Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 7);
200f4a2713aSLionel Sambuc     this->MCountName = "\01mcount";
201f4a2713aSLionel Sambuc   }
202f4a2713aSLionel Sambuc 
isValidSectionSpecifier(StringRef SR) const203*0a6a1f1dSLionel Sambuc   std::string isValidSectionSpecifier(StringRef SR) const override {
204f4a2713aSLionel Sambuc     // Let MCSectionMachO validate this.
205f4a2713aSLionel Sambuc     StringRef Segment, Section;
206f4a2713aSLionel Sambuc     unsigned TAA, StubSize;
207f4a2713aSLionel Sambuc     bool HasTAA;
208f4a2713aSLionel Sambuc     return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
209f4a2713aSLionel Sambuc                                                        TAA, HasTAA, StubSize);
210f4a2713aSLionel Sambuc   }
211f4a2713aSLionel Sambuc 
getStaticInitSectionSpecifier() const212*0a6a1f1dSLionel Sambuc   const char *getStaticInitSectionSpecifier() const override {
213f4a2713aSLionel Sambuc     // FIXME: We should return 0 when building kexts.
214f4a2713aSLionel Sambuc     return "__TEXT,__StaticInit,regular,pure_instructions";
215f4a2713aSLionel Sambuc   }
216f4a2713aSLionel Sambuc 
217f4a2713aSLionel Sambuc   /// Darwin does not support protected visibility.  Darwin's "default"
218f4a2713aSLionel Sambuc   /// is very similar to ELF's "protected";  Darwin requires a "weak"
219f4a2713aSLionel Sambuc   /// attribute on declarations that can be dynamically replaced.
hasProtectedVisibility() const220*0a6a1f1dSLionel Sambuc   bool hasProtectedVisibility() const override {
221f4a2713aSLionel Sambuc     return false;
222f4a2713aSLionel Sambuc   }
223f4a2713aSLionel Sambuc };
224f4a2713aSLionel Sambuc 
225f4a2713aSLionel Sambuc 
226f4a2713aSLionel Sambuc // DragonFlyBSD Target
227f4a2713aSLionel Sambuc template<typename Target>
228f4a2713aSLionel Sambuc class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
229f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const230*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
231*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
232f4a2713aSLionel Sambuc     // DragonFly defines; list based off of gcc output
233f4a2713aSLionel Sambuc     Builder.defineMacro("__DragonFly__");
234f4a2713aSLionel Sambuc     Builder.defineMacro("__DragonFly_cc_version", "100001");
235f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
236f4a2713aSLionel Sambuc     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
237f4a2713aSLionel Sambuc     Builder.defineMacro("__tune_i386__");
238f4a2713aSLionel Sambuc     DefineStd(Builder, "unix", Opts);
239f4a2713aSLionel Sambuc   }
240f4a2713aSLionel Sambuc public:
DragonFlyBSDTargetInfo(const llvm::Triple & Triple)241f4a2713aSLionel Sambuc   DragonFlyBSDTargetInfo(const llvm::Triple &Triple)
242f4a2713aSLionel Sambuc       : OSTargetInfo<Target>(Triple) {
243f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
244f4a2713aSLionel Sambuc 
245f4a2713aSLionel Sambuc     switch (Triple.getArch()) {
246f4a2713aSLionel Sambuc     default:
247f4a2713aSLionel Sambuc     case llvm::Triple::x86:
248f4a2713aSLionel Sambuc     case llvm::Triple::x86_64:
249f4a2713aSLionel Sambuc       this->MCountName = ".mcount";
250f4a2713aSLionel Sambuc       break;
251f4a2713aSLionel Sambuc     }
252f4a2713aSLionel Sambuc   }
253f4a2713aSLionel Sambuc };
254f4a2713aSLionel Sambuc 
255f4a2713aSLionel Sambuc // FreeBSD Target
256f4a2713aSLionel Sambuc template<typename Target>
257f4a2713aSLionel Sambuc class FreeBSDTargetInfo : public OSTargetInfo<Target> {
258f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const259*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
260*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
261f4a2713aSLionel Sambuc     // FreeBSD defines; list based off of gcc output
262f4a2713aSLionel Sambuc 
263f4a2713aSLionel Sambuc     unsigned Release = Triple.getOSMajorVersion();
264f4a2713aSLionel Sambuc     if (Release == 0U)
265f4a2713aSLionel Sambuc       Release = 8;
266f4a2713aSLionel Sambuc 
267f4a2713aSLionel Sambuc     Builder.defineMacro("__FreeBSD__", Twine(Release));
268f4a2713aSLionel Sambuc     Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U));
269f4a2713aSLionel Sambuc     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
270f4a2713aSLionel Sambuc     DefineStd(Builder, "unix", Opts);
271f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
272f4a2713aSLionel Sambuc 
273f4a2713aSLionel Sambuc     // On FreeBSD, wchar_t contains the number of the code point as
274f4a2713aSLionel Sambuc     // used by the character set of the locale. These character sets are
275f4a2713aSLionel Sambuc     // not necessarily a superset of ASCII.
276*0a6a1f1dSLionel Sambuc     //
277*0a6a1f1dSLionel Sambuc     // FIXME: This is wrong; the macro refers to the numerical values
278*0a6a1f1dSLionel Sambuc     // of wchar_t *literals*, which are not locale-dependent. However,
279*0a6a1f1dSLionel Sambuc     // FreeBSD systems apparently depend on us getting this wrong, and
280*0a6a1f1dSLionel Sambuc     // setting this to 1 is conforming even if all the basic source
281*0a6a1f1dSLionel Sambuc     // character literals have the same encoding as char and wchar_t.
282f4a2713aSLionel Sambuc     Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
283f4a2713aSLionel Sambuc   }
284f4a2713aSLionel Sambuc public:
FreeBSDTargetInfo(const llvm::Triple & Triple)285f4a2713aSLionel Sambuc   FreeBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
286f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
287f4a2713aSLionel Sambuc 
288f4a2713aSLionel Sambuc     switch (Triple.getArch()) {
289f4a2713aSLionel Sambuc     default:
290f4a2713aSLionel Sambuc     case llvm::Triple::x86:
291f4a2713aSLionel Sambuc     case llvm::Triple::x86_64:
292f4a2713aSLionel Sambuc       this->MCountName = ".mcount";
293f4a2713aSLionel Sambuc       break;
294f4a2713aSLionel Sambuc     case llvm::Triple::mips:
295f4a2713aSLionel Sambuc     case llvm::Triple::mipsel:
296f4a2713aSLionel Sambuc     case llvm::Triple::ppc:
297f4a2713aSLionel Sambuc     case llvm::Triple::ppc64:
298f4a2713aSLionel Sambuc     case llvm::Triple::ppc64le:
299f4a2713aSLionel Sambuc       this->MCountName = "_mcount";
300f4a2713aSLionel Sambuc       break;
301f4a2713aSLionel Sambuc     case llvm::Triple::arm:
302f4a2713aSLionel Sambuc       this->MCountName = "__mcount";
303f4a2713aSLionel Sambuc       break;
304f4a2713aSLionel Sambuc     }
305f4a2713aSLionel Sambuc   }
306f4a2713aSLionel Sambuc };
307f4a2713aSLionel Sambuc 
308f4a2713aSLionel Sambuc // GNU/kFreeBSD Target
309f4a2713aSLionel Sambuc template<typename Target>
310f4a2713aSLionel Sambuc class KFreeBSDTargetInfo : public OSTargetInfo<Target> {
311f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const312*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
313*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
314f4a2713aSLionel Sambuc     // GNU/kFreeBSD defines; list based off of gcc output
315f4a2713aSLionel Sambuc 
316f4a2713aSLionel Sambuc     DefineStd(Builder, "unix", Opts);
317f4a2713aSLionel Sambuc     Builder.defineMacro("__FreeBSD_kernel__");
318f4a2713aSLionel Sambuc     Builder.defineMacro("__GLIBC__");
319f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
320f4a2713aSLionel Sambuc     if (Opts.POSIXThreads)
321f4a2713aSLionel Sambuc       Builder.defineMacro("_REENTRANT");
322f4a2713aSLionel Sambuc     if (Opts.CPlusPlus)
323f4a2713aSLionel Sambuc       Builder.defineMacro("_GNU_SOURCE");
324f4a2713aSLionel Sambuc   }
325f4a2713aSLionel Sambuc public:
KFreeBSDTargetInfo(const llvm::Triple & Triple)326*0a6a1f1dSLionel Sambuc   KFreeBSDTargetInfo(const llvm::Triple &Triple)
327*0a6a1f1dSLionel Sambuc       : OSTargetInfo<Target>(Triple) {
328f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
329f4a2713aSLionel Sambuc   }
330f4a2713aSLionel Sambuc };
331f4a2713aSLionel Sambuc 
332f4a2713aSLionel Sambuc // Minix Target
333f4a2713aSLionel Sambuc template<typename Target>
334f4a2713aSLionel Sambuc class MinixTargetInfo : public OSTargetInfo<Target> {
335f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const336*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
337*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
338*0a6a1f1dSLionel Sambuc     // Minix defines; list based off of gcc output
339f4a2713aSLionel Sambuc     Builder.defineMacro("__minix", "3");
3404684ddb6SLionel Sambuc     Builder.defineMacro("__minix__", "3");
341*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__Minix__", "3");
3424684ddb6SLionel Sambuc     Builder.defineMacro("__unix__");
343f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
3444684ddb6SLionel Sambuc     if (Opts.POSIXThreads)
3454684ddb6SLionel Sambuc       Builder.defineMacro("_POSIX_THREADS");
346*0a6a1f1dSLionel Sambuc 
347*0a6a1f1dSLionel Sambuc     switch (Triple.getArch()) {
348*0a6a1f1dSLionel Sambuc     default:
349*0a6a1f1dSLionel Sambuc       break;
350*0a6a1f1dSLionel Sambuc     case llvm::Triple::arm:
351*0a6a1f1dSLionel Sambuc     case llvm::Triple::armeb:
352*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumb:
353*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumbeb:
354*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_DWARF_EH__");
355*0a6a1f1dSLionel Sambuc       break;
356*0a6a1f1dSLionel Sambuc     }
357f4a2713aSLionel Sambuc   }
358f4a2713aSLionel Sambuc public:
MinixTargetInfo(const llvm::Triple & Triple)359f4a2713aSLionel Sambuc   MinixTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
360f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
361*0a6a1f1dSLionel Sambuc     this->MCountName = "_mcount";
362f4a2713aSLionel Sambuc   }
363f4a2713aSLionel Sambuc };
364f4a2713aSLionel Sambuc 
365f4a2713aSLionel Sambuc // Linux target
366f4a2713aSLionel Sambuc template<typename Target>
367f4a2713aSLionel Sambuc class LinuxTargetInfo : public OSTargetInfo<Target> {
368f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const369*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
370*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
371f4a2713aSLionel Sambuc     // Linux defines; list based off of gcc output
372f4a2713aSLionel Sambuc     DefineStd(Builder, "unix", Opts);
373f4a2713aSLionel Sambuc     DefineStd(Builder, "linux", Opts);
374f4a2713aSLionel Sambuc     Builder.defineMacro("__gnu_linux__");
375f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
376f4a2713aSLionel Sambuc     if (Triple.getEnvironment() == llvm::Triple::Android)
377f4a2713aSLionel Sambuc       Builder.defineMacro("__ANDROID__", "1");
378f4a2713aSLionel Sambuc     if (Opts.POSIXThreads)
379f4a2713aSLionel Sambuc       Builder.defineMacro("_REENTRANT");
380f4a2713aSLionel Sambuc     if (Opts.CPlusPlus)
381f4a2713aSLionel Sambuc       Builder.defineMacro("_GNU_SOURCE");
382f4a2713aSLionel Sambuc   }
383f4a2713aSLionel Sambuc public:
LinuxTargetInfo(const llvm::Triple & Triple)384f4a2713aSLionel Sambuc   LinuxTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
385f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
386f4a2713aSLionel Sambuc     this->WIntType = TargetInfo::UnsignedInt;
387*0a6a1f1dSLionel Sambuc 
388*0a6a1f1dSLionel Sambuc     switch (Triple.getArch()) {
389*0a6a1f1dSLionel Sambuc     default:
390*0a6a1f1dSLionel Sambuc       break;
391*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc:
392*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc64:
393*0a6a1f1dSLionel Sambuc     case llvm::Triple::ppc64le:
394*0a6a1f1dSLionel Sambuc       this->MCountName = "_mcount";
395*0a6a1f1dSLionel Sambuc       break;
396*0a6a1f1dSLionel Sambuc     }
397f4a2713aSLionel Sambuc   }
398f4a2713aSLionel Sambuc 
getStaticInitSectionSpecifier() const399*0a6a1f1dSLionel Sambuc   const char *getStaticInitSectionSpecifier() const override {
400f4a2713aSLionel Sambuc     return ".text.startup";
401f4a2713aSLionel Sambuc   }
402f4a2713aSLionel Sambuc };
403f4a2713aSLionel Sambuc 
404f4a2713aSLionel Sambuc // NetBSD Target
405f4a2713aSLionel Sambuc template<typename Target>
406f4a2713aSLionel Sambuc class NetBSDTargetInfo : public OSTargetInfo<Target> {
407f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const408*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
409*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
410f4a2713aSLionel Sambuc     // NetBSD defines; list based off of gcc output
411f4a2713aSLionel Sambuc     Builder.defineMacro("__NetBSD__");
412f4a2713aSLionel Sambuc     Builder.defineMacro("__unix__");
413f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
414f4a2713aSLionel Sambuc     if (Opts.POSIXThreads)
415f4a2713aSLionel Sambuc       Builder.defineMacro("_POSIX_THREADS");
416*0a6a1f1dSLionel Sambuc 
417*0a6a1f1dSLionel Sambuc     switch (Triple.getArch()) {
418*0a6a1f1dSLionel Sambuc     default:
419*0a6a1f1dSLionel Sambuc       break;
420*0a6a1f1dSLionel Sambuc     case llvm::Triple::arm:
421*0a6a1f1dSLionel Sambuc     case llvm::Triple::armeb:
422*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumb:
423*0a6a1f1dSLionel Sambuc     case llvm::Triple::thumbeb:
424*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_DWARF_EH__");
425*0a6a1f1dSLionel Sambuc       break;
426*0a6a1f1dSLionel Sambuc     }
427f4a2713aSLionel Sambuc   }
428f4a2713aSLionel Sambuc public:
NetBSDTargetInfo(const llvm::Triple & Triple)429f4a2713aSLionel Sambuc   NetBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
430f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
431*0a6a1f1dSLionel Sambuc     this->MCountName = "_mcount";
432f4a2713aSLionel Sambuc   }
433f4a2713aSLionel Sambuc };
434f4a2713aSLionel Sambuc 
435f4a2713aSLionel Sambuc // OpenBSD Target
436f4a2713aSLionel Sambuc template<typename Target>
437f4a2713aSLionel Sambuc class OpenBSDTargetInfo : public OSTargetInfo<Target> {
438f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const439*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
440*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
441f4a2713aSLionel Sambuc     // OpenBSD defines; list based off of gcc output
442f4a2713aSLionel Sambuc 
443f4a2713aSLionel Sambuc     Builder.defineMacro("__OpenBSD__");
444f4a2713aSLionel Sambuc     DefineStd(Builder, "unix", Opts);
445f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
446f4a2713aSLionel Sambuc     if (Opts.POSIXThreads)
447f4a2713aSLionel Sambuc       Builder.defineMacro("_REENTRANT");
448f4a2713aSLionel Sambuc   }
449f4a2713aSLionel Sambuc public:
OpenBSDTargetInfo(const llvm::Triple & Triple)450f4a2713aSLionel Sambuc   OpenBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
451f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
452f4a2713aSLionel Sambuc     this->TLSSupported = false;
453f4a2713aSLionel Sambuc 
454f4a2713aSLionel Sambuc       switch (Triple.getArch()) {
455f4a2713aSLionel Sambuc         default:
456f4a2713aSLionel Sambuc         case llvm::Triple::x86:
457f4a2713aSLionel Sambuc         case llvm::Triple::x86_64:
458f4a2713aSLionel Sambuc         case llvm::Triple::arm:
459f4a2713aSLionel Sambuc         case llvm::Triple::sparc:
460f4a2713aSLionel Sambuc           this->MCountName = "__mcount";
461f4a2713aSLionel Sambuc           break;
462f4a2713aSLionel Sambuc         case llvm::Triple::mips64:
463f4a2713aSLionel Sambuc         case llvm::Triple::mips64el:
464f4a2713aSLionel Sambuc         case llvm::Triple::ppc:
465f4a2713aSLionel Sambuc         case llvm::Triple::sparcv9:
466f4a2713aSLionel Sambuc           this->MCountName = "_mcount";
467f4a2713aSLionel Sambuc           break;
468f4a2713aSLionel Sambuc       }
469f4a2713aSLionel Sambuc   }
470f4a2713aSLionel Sambuc };
471f4a2713aSLionel Sambuc 
472f4a2713aSLionel Sambuc // Bitrig Target
473f4a2713aSLionel Sambuc template<typename Target>
474f4a2713aSLionel Sambuc class BitrigTargetInfo : public OSTargetInfo<Target> {
475f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const476*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
477*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
478f4a2713aSLionel Sambuc     // Bitrig defines; list based off of gcc output
479f4a2713aSLionel Sambuc 
480f4a2713aSLionel Sambuc     Builder.defineMacro("__Bitrig__");
481f4a2713aSLionel Sambuc     DefineStd(Builder, "unix", Opts);
482f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
483f4a2713aSLionel Sambuc     if (Opts.POSIXThreads)
484f4a2713aSLionel Sambuc       Builder.defineMacro("_REENTRANT");
485f4a2713aSLionel Sambuc   }
486f4a2713aSLionel Sambuc public:
BitrigTargetInfo(const llvm::Triple & Triple)487f4a2713aSLionel Sambuc   BitrigTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
488f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
489f4a2713aSLionel Sambuc     this->MCountName = "__mcount";
490f4a2713aSLionel Sambuc   }
491f4a2713aSLionel Sambuc };
492f4a2713aSLionel Sambuc 
493f4a2713aSLionel Sambuc // PSP Target
494f4a2713aSLionel Sambuc template<typename Target>
495f4a2713aSLionel Sambuc class PSPTargetInfo : public OSTargetInfo<Target> {
496f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const497*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
498*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
499f4a2713aSLionel Sambuc     // PSP defines; list based on the output of the pspdev gcc toolchain.
500f4a2713aSLionel Sambuc     Builder.defineMacro("PSP");
501f4a2713aSLionel Sambuc     Builder.defineMacro("_PSP");
502f4a2713aSLionel Sambuc     Builder.defineMacro("__psp__");
503f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
504f4a2713aSLionel Sambuc   }
505f4a2713aSLionel Sambuc public:
PSPTargetInfo(const llvm::Triple & Triple)506f4a2713aSLionel Sambuc   PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
507f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
508f4a2713aSLionel Sambuc   }
509f4a2713aSLionel Sambuc };
510f4a2713aSLionel Sambuc 
511f4a2713aSLionel Sambuc // PS3 PPU Target
512f4a2713aSLionel Sambuc template<typename Target>
513f4a2713aSLionel Sambuc class PS3PPUTargetInfo : public OSTargetInfo<Target> {
514f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const515*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
516*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
517f4a2713aSLionel Sambuc     // PS3 PPU defines.
518f4a2713aSLionel Sambuc     Builder.defineMacro("__PPC__");
519f4a2713aSLionel Sambuc     Builder.defineMacro("__PPU__");
520f4a2713aSLionel Sambuc     Builder.defineMacro("__CELLOS_LV2__");
521f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
522f4a2713aSLionel Sambuc     Builder.defineMacro("__LP32__");
523f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_PPC64");
524f4a2713aSLionel Sambuc     Builder.defineMacro("__powerpc64__");
525f4a2713aSLionel Sambuc   }
526f4a2713aSLionel Sambuc public:
PS3PPUTargetInfo(const llvm::Triple & Triple)527f4a2713aSLionel Sambuc   PS3PPUTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
528f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
529f4a2713aSLionel Sambuc     this->LongWidth = this->LongAlign = 32;
530f4a2713aSLionel Sambuc     this->PointerWidth = this->PointerAlign = 32;
531f4a2713aSLionel Sambuc     this->IntMaxType = TargetInfo::SignedLongLong;
532f4a2713aSLionel Sambuc     this->Int64Type = TargetInfo::SignedLongLong;
533f4a2713aSLionel Sambuc     this->SizeType = TargetInfo::UnsignedInt;
534*0a6a1f1dSLionel Sambuc     this->DescriptionString = "E-m:e-p:32:32-i64:64-n32:64";
535f4a2713aSLionel Sambuc   }
536f4a2713aSLionel Sambuc };
537f4a2713aSLionel Sambuc 
538f4a2713aSLionel Sambuc // Solaris target
539f4a2713aSLionel Sambuc template<typename Target>
540f4a2713aSLionel Sambuc class SolarisTargetInfo : public OSTargetInfo<Target> {
541f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const542*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
543*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
544f4a2713aSLionel Sambuc     DefineStd(Builder, "sun", Opts);
545f4a2713aSLionel Sambuc     DefineStd(Builder, "unix", Opts);
546f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
547f4a2713aSLionel Sambuc     Builder.defineMacro("__svr4__");
548f4a2713aSLionel Sambuc     Builder.defineMacro("__SVR4");
549f4a2713aSLionel Sambuc     // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
550f4a2713aSLionel Sambuc     // newer, but to 500 for everything else.  feature_test.h has a check to
551f4a2713aSLionel Sambuc     // ensure that you are not using C99 with an old version of X/Open or C89
552f4a2713aSLionel Sambuc     // with a new version.
553*0a6a1f1dSLionel Sambuc     if (Opts.C99)
554f4a2713aSLionel Sambuc       Builder.defineMacro("_XOPEN_SOURCE", "600");
555f4a2713aSLionel Sambuc     else
556f4a2713aSLionel Sambuc       Builder.defineMacro("_XOPEN_SOURCE", "500");
557f4a2713aSLionel Sambuc     if (Opts.CPlusPlus)
558f4a2713aSLionel Sambuc       Builder.defineMacro("__C99FEATURES__");
559f4a2713aSLionel Sambuc     Builder.defineMacro("_LARGEFILE_SOURCE");
560f4a2713aSLionel Sambuc     Builder.defineMacro("_LARGEFILE64_SOURCE");
561f4a2713aSLionel Sambuc     Builder.defineMacro("__EXTENSIONS__");
562f4a2713aSLionel Sambuc     Builder.defineMacro("_REENTRANT");
563f4a2713aSLionel Sambuc   }
564f4a2713aSLionel Sambuc public:
SolarisTargetInfo(const llvm::Triple & Triple)565f4a2713aSLionel Sambuc   SolarisTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
566f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
567f4a2713aSLionel Sambuc     this->WCharType = this->SignedInt;
568f4a2713aSLionel Sambuc     // FIXME: WIntType should be SignedLong
569f4a2713aSLionel Sambuc   }
570f4a2713aSLionel Sambuc };
571f4a2713aSLionel Sambuc 
572f4a2713aSLionel Sambuc // Windows target
573f4a2713aSLionel Sambuc template<typename Target>
574f4a2713aSLionel Sambuc class WindowsTargetInfo : public OSTargetInfo<Target> {
575f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const576*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
577*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
578f4a2713aSLionel Sambuc     Builder.defineMacro("_WIN32");
579f4a2713aSLionel Sambuc   }
getVisualStudioDefines(const LangOptions & Opts,MacroBuilder & Builder) const580f4a2713aSLionel Sambuc   void getVisualStudioDefines(const LangOptions &Opts,
581f4a2713aSLionel Sambuc                               MacroBuilder &Builder) const {
582f4a2713aSLionel Sambuc     if (Opts.CPlusPlus) {
583*0a6a1f1dSLionel Sambuc       if (Opts.RTTIData)
584f4a2713aSLionel Sambuc         Builder.defineMacro("_CPPRTTI");
585f4a2713aSLionel Sambuc 
586f4a2713aSLionel Sambuc       if (Opts.Exceptions)
587f4a2713aSLionel Sambuc         Builder.defineMacro("_CPPUNWIND");
588f4a2713aSLionel Sambuc     }
589f4a2713aSLionel Sambuc 
590f4a2713aSLionel Sambuc     if (!Opts.CharIsSigned)
591f4a2713aSLionel Sambuc       Builder.defineMacro("_CHAR_UNSIGNED");
592f4a2713aSLionel Sambuc 
593f4a2713aSLionel Sambuc     // FIXME: POSIXThreads isn't exactly the option this should be defined for,
594f4a2713aSLionel Sambuc     //        but it works for now.
595f4a2713aSLionel Sambuc     if (Opts.POSIXThreads)
596f4a2713aSLionel Sambuc       Builder.defineMacro("_MT");
597f4a2713aSLionel Sambuc 
598*0a6a1f1dSLionel Sambuc     if (Opts.MSCompatibilityVersion) {
599*0a6a1f1dSLionel Sambuc       Builder.defineMacro("_MSC_VER",
600*0a6a1f1dSLionel Sambuc                           Twine(Opts.MSCompatibilityVersion / 100000));
601*0a6a1f1dSLionel Sambuc       Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion));
602*0a6a1f1dSLionel Sambuc       // FIXME We cannot encode the revision information into 32-bits
603*0a6a1f1dSLionel Sambuc       Builder.defineMacro("_MSC_BUILD", Twine(1));
604*0a6a1f1dSLionel Sambuc     }
605f4a2713aSLionel Sambuc 
606f4a2713aSLionel Sambuc     if (Opts.MicrosoftExt) {
607f4a2713aSLionel Sambuc       Builder.defineMacro("_MSC_EXTENSIONS");
608f4a2713aSLionel Sambuc 
609f4a2713aSLionel Sambuc       if (Opts.CPlusPlus11) {
610f4a2713aSLionel Sambuc         Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
611f4a2713aSLionel Sambuc         Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
612f4a2713aSLionel Sambuc         Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
613f4a2713aSLionel Sambuc       }
614f4a2713aSLionel Sambuc     }
615f4a2713aSLionel Sambuc 
616f4a2713aSLionel Sambuc     Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
617f4a2713aSLionel Sambuc   }
618f4a2713aSLionel Sambuc 
619f4a2713aSLionel Sambuc public:
WindowsTargetInfo(const llvm::Triple & Triple)620f4a2713aSLionel Sambuc   WindowsTargetInfo(const llvm::Triple &Triple)
621f4a2713aSLionel Sambuc       : OSTargetInfo<Target>(Triple) {}
622f4a2713aSLionel Sambuc };
623f4a2713aSLionel Sambuc 
624f4a2713aSLionel Sambuc template <typename Target>
625f4a2713aSLionel Sambuc class NaClTargetInfo : public OSTargetInfo<Target> {
626f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const627*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
628*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
629f4a2713aSLionel Sambuc     if (Opts.POSIXThreads)
630f4a2713aSLionel Sambuc       Builder.defineMacro("_REENTRANT");
631f4a2713aSLionel Sambuc     if (Opts.CPlusPlus)
632f4a2713aSLionel Sambuc       Builder.defineMacro("_GNU_SOURCE");
633f4a2713aSLionel Sambuc 
634f4a2713aSLionel Sambuc     DefineStd(Builder, "unix", Opts);
635f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
636f4a2713aSLionel Sambuc     Builder.defineMacro("__native_client__");
637f4a2713aSLionel Sambuc   }
638f4a2713aSLionel Sambuc 
639f4a2713aSLionel Sambuc public:
NaClTargetInfo(const llvm::Triple & Triple)640f4a2713aSLionel Sambuc   NaClTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
641f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
642f4a2713aSLionel Sambuc     this->LongAlign = 32;
643f4a2713aSLionel Sambuc     this->LongWidth = 32;
644f4a2713aSLionel Sambuc     this->PointerAlign = 32;
645f4a2713aSLionel Sambuc     this->PointerWidth = 32;
646f4a2713aSLionel Sambuc     this->IntMaxType = TargetInfo::SignedLongLong;
647f4a2713aSLionel Sambuc     this->Int64Type = TargetInfo::SignedLongLong;
648f4a2713aSLionel Sambuc     this->DoubleAlign = 64;
649f4a2713aSLionel Sambuc     this->LongDoubleWidth = 64;
650f4a2713aSLionel Sambuc     this->LongDoubleAlign = 64;
651*0a6a1f1dSLionel Sambuc     this->LongLongWidth = 64;
652*0a6a1f1dSLionel Sambuc     this->LongLongAlign = 64;
653f4a2713aSLionel Sambuc     this->SizeType = TargetInfo::UnsignedInt;
654f4a2713aSLionel Sambuc     this->PtrDiffType = TargetInfo::SignedInt;
655f4a2713aSLionel Sambuc     this->IntPtrType = TargetInfo::SignedInt;
656f4a2713aSLionel Sambuc     // RegParmMax is inherited from the underlying architecture
657f4a2713aSLionel Sambuc     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
658*0a6a1f1dSLionel Sambuc     if (Triple.getArch() == llvm::Triple::arm) {
659*0a6a1f1dSLionel Sambuc       this->DescriptionString =
660*0a6a1f1dSLionel Sambuc           "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128";
661*0a6a1f1dSLionel Sambuc     } else if (Triple.getArch() == llvm::Triple::x86) {
662*0a6a1f1dSLionel Sambuc       this->DescriptionString = "e-m:e-p:32:32-i64:64-n8:16:32-S128";
663*0a6a1f1dSLionel Sambuc     } else if (Triple.getArch() == llvm::Triple::x86_64) {
664*0a6a1f1dSLionel Sambuc       this->DescriptionString = "e-m:e-p:32:32-i64:64-n8:16:32:64-S128";
665*0a6a1f1dSLionel Sambuc     } else if (Triple.getArch() == llvm::Triple::mipsel) {
666*0a6a1f1dSLionel Sambuc       // Handled on mips' setDescriptionString.
667*0a6a1f1dSLionel Sambuc     } else {
668*0a6a1f1dSLionel Sambuc       assert(Triple.getArch() == llvm::Triple::le32);
669*0a6a1f1dSLionel Sambuc       this->DescriptionString = "e-p:32:32-i64:64";
670f4a2713aSLionel Sambuc     }
671*0a6a1f1dSLionel Sambuc   }
checkCallingConvention(CallingConv CC) const672*0a6a1f1dSLionel Sambuc   typename Target::CallingConvCheckResult checkCallingConvention(
673*0a6a1f1dSLionel Sambuc       CallingConv CC) const override {
674f4a2713aSLionel Sambuc     return CC == CC_PnaclCall ? Target::CCCR_OK :
675f4a2713aSLionel Sambuc         Target::checkCallingConvention(CC);
676f4a2713aSLionel Sambuc   }
677f4a2713aSLionel Sambuc };
678f4a2713aSLionel Sambuc } // end anonymous namespace.
679f4a2713aSLionel Sambuc 
680f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
681f4a2713aSLionel Sambuc // Specific target implementations.
682f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
683f4a2713aSLionel Sambuc 
684f4a2713aSLionel Sambuc namespace {
685f4a2713aSLionel Sambuc // PPC abstract base class
686f4a2713aSLionel Sambuc class PPCTargetInfo : public TargetInfo {
687f4a2713aSLionel Sambuc   static const Builtin::Info BuiltinInfo[];
688f4a2713aSLionel Sambuc   static const char * const GCCRegNames[];
689f4a2713aSLionel Sambuc   static const TargetInfo::GCCRegAlias GCCRegAliases[];
690f4a2713aSLionel Sambuc   std::string CPU;
691f4a2713aSLionel Sambuc 
692f4a2713aSLionel Sambuc   // Target cpu features.
693f4a2713aSLionel Sambuc   bool HasVSX;
694*0a6a1f1dSLionel Sambuc   bool HasP8Vector;
695*0a6a1f1dSLionel Sambuc 
696*0a6a1f1dSLionel Sambuc protected:
697*0a6a1f1dSLionel Sambuc   std::string ABI;
698f4a2713aSLionel Sambuc 
699f4a2713aSLionel Sambuc public:
PPCTargetInfo(const llvm::Triple & Triple)700f4a2713aSLionel Sambuc   PPCTargetInfo(const llvm::Triple &Triple)
701*0a6a1f1dSLionel Sambuc     : TargetInfo(Triple), HasVSX(false), HasP8Vector(false) {
702f4a2713aSLionel Sambuc     BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
703f4a2713aSLionel Sambuc     LongDoubleWidth = LongDoubleAlign = 128;
704f4a2713aSLionel Sambuc     LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
705f4a2713aSLionel Sambuc   }
706f4a2713aSLionel Sambuc 
707f4a2713aSLionel Sambuc   /// \brief Flags for architecture specific defines.
708f4a2713aSLionel Sambuc   typedef enum {
709f4a2713aSLionel Sambuc     ArchDefineNone  = 0,
710f4a2713aSLionel Sambuc     ArchDefineName  = 1 << 0, // <name> is substituted for arch name.
711f4a2713aSLionel Sambuc     ArchDefinePpcgr = 1 << 1,
712f4a2713aSLionel Sambuc     ArchDefinePpcsq = 1 << 2,
713f4a2713aSLionel Sambuc     ArchDefine440   = 1 << 3,
714f4a2713aSLionel Sambuc     ArchDefine603   = 1 << 4,
715f4a2713aSLionel Sambuc     ArchDefine604   = 1 << 5,
716f4a2713aSLionel Sambuc     ArchDefinePwr4  = 1 << 6,
717f4a2713aSLionel Sambuc     ArchDefinePwr5  = 1 << 7,
718f4a2713aSLionel Sambuc     ArchDefinePwr5x = 1 << 8,
719f4a2713aSLionel Sambuc     ArchDefinePwr6  = 1 << 9,
720f4a2713aSLionel Sambuc     ArchDefinePwr6x = 1 << 10,
721f4a2713aSLionel Sambuc     ArchDefinePwr7  = 1 << 11,
722*0a6a1f1dSLionel Sambuc     ArchDefinePwr8  = 1 << 12,
723*0a6a1f1dSLionel Sambuc     ArchDefineA2    = 1 << 13,
724*0a6a1f1dSLionel Sambuc     ArchDefineA2q   = 1 << 14
725f4a2713aSLionel Sambuc   } ArchDefineTypes;
726f4a2713aSLionel Sambuc 
727f4a2713aSLionel Sambuc   // Note: GCC recognizes the following additional cpus:
728f4a2713aSLionel Sambuc   //  401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801,
729f4a2713aSLionel Sambuc   //  821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell,
730f4a2713aSLionel Sambuc   //  titan, rs64.
setCPU(const std::string & Name)731*0a6a1f1dSLionel Sambuc   bool setCPU(const std::string &Name) override {
732f4a2713aSLionel Sambuc     bool CPUKnown = llvm::StringSwitch<bool>(Name)
733f4a2713aSLionel Sambuc       .Case("generic", true)
734f4a2713aSLionel Sambuc       .Case("440", true)
735f4a2713aSLionel Sambuc       .Case("450", true)
736f4a2713aSLionel Sambuc       .Case("601", true)
737f4a2713aSLionel Sambuc       .Case("602", true)
738f4a2713aSLionel Sambuc       .Case("603", true)
739f4a2713aSLionel Sambuc       .Case("603e", true)
740f4a2713aSLionel Sambuc       .Case("603ev", true)
741f4a2713aSLionel Sambuc       .Case("604", true)
742f4a2713aSLionel Sambuc       .Case("604e", true)
743f4a2713aSLionel Sambuc       .Case("620", true)
744f4a2713aSLionel Sambuc       .Case("630", true)
745f4a2713aSLionel Sambuc       .Case("g3", true)
746f4a2713aSLionel Sambuc       .Case("7400", true)
747f4a2713aSLionel Sambuc       .Case("g4", true)
748f4a2713aSLionel Sambuc       .Case("7450", true)
749f4a2713aSLionel Sambuc       .Case("g4+", true)
750f4a2713aSLionel Sambuc       .Case("750", true)
751f4a2713aSLionel Sambuc       .Case("970", true)
752f4a2713aSLionel Sambuc       .Case("g5", true)
753f4a2713aSLionel Sambuc       .Case("a2", true)
754f4a2713aSLionel Sambuc       .Case("a2q", true)
755f4a2713aSLionel Sambuc       .Case("e500mc", true)
756f4a2713aSLionel Sambuc       .Case("e5500", true)
757f4a2713aSLionel Sambuc       .Case("power3", true)
758f4a2713aSLionel Sambuc       .Case("pwr3", true)
759f4a2713aSLionel Sambuc       .Case("power4", true)
760f4a2713aSLionel Sambuc       .Case("pwr4", true)
761f4a2713aSLionel Sambuc       .Case("power5", true)
762f4a2713aSLionel Sambuc       .Case("pwr5", true)
763f4a2713aSLionel Sambuc       .Case("power5x", true)
764f4a2713aSLionel Sambuc       .Case("pwr5x", true)
765f4a2713aSLionel Sambuc       .Case("power6", true)
766f4a2713aSLionel Sambuc       .Case("pwr6", true)
767f4a2713aSLionel Sambuc       .Case("power6x", true)
768f4a2713aSLionel Sambuc       .Case("pwr6x", true)
769f4a2713aSLionel Sambuc       .Case("power7", true)
770f4a2713aSLionel Sambuc       .Case("pwr7", true)
771*0a6a1f1dSLionel Sambuc       .Case("power8", true)
772*0a6a1f1dSLionel Sambuc       .Case("pwr8", true)
773f4a2713aSLionel Sambuc       .Case("powerpc", true)
774f4a2713aSLionel Sambuc       .Case("ppc", true)
775f4a2713aSLionel Sambuc       .Case("powerpc64", true)
776f4a2713aSLionel Sambuc       .Case("ppc64", true)
777f4a2713aSLionel Sambuc       .Case("powerpc64le", true)
778f4a2713aSLionel Sambuc       .Case("ppc64le", true)
779f4a2713aSLionel Sambuc       .Default(false);
780f4a2713aSLionel Sambuc 
781f4a2713aSLionel Sambuc     if (CPUKnown)
782f4a2713aSLionel Sambuc       CPU = Name;
783f4a2713aSLionel Sambuc 
784f4a2713aSLionel Sambuc     return CPUKnown;
785f4a2713aSLionel Sambuc   }
786f4a2713aSLionel Sambuc 
787*0a6a1f1dSLionel Sambuc 
getABI() const788*0a6a1f1dSLionel Sambuc   StringRef getABI() const override { return ABI; }
789*0a6a1f1dSLionel Sambuc 
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const790*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
791*0a6a1f1dSLionel Sambuc                          unsigned &NumRecords) const override {
792f4a2713aSLionel Sambuc     Records = BuiltinInfo;
793f4a2713aSLionel Sambuc     NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
794f4a2713aSLionel Sambuc   }
795f4a2713aSLionel Sambuc 
isCLZForZeroUndef() const796*0a6a1f1dSLionel Sambuc   bool isCLZForZeroUndef() const override { return false; }
797f4a2713aSLionel Sambuc 
798*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
799*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override;
800f4a2713aSLionel Sambuc 
801*0a6a1f1dSLionel Sambuc   void getDefaultFeatures(llvm::StringMap<bool> &Features) const override;
802f4a2713aSLionel Sambuc 
803*0a6a1f1dSLionel Sambuc   bool handleTargetFeatures(std::vector<std::string> &Features,
804*0a6a1f1dSLionel Sambuc                             DiagnosticsEngine &Diags) override;
805*0a6a1f1dSLionel Sambuc   bool hasFeature(StringRef Feature) const override;
806f4a2713aSLionel Sambuc 
807*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char * const *&Names,
808*0a6a1f1dSLionel Sambuc                       unsigned &NumNames) const override;
809*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
810*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const811*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
812*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &Info) const override {
813f4a2713aSLionel Sambuc     switch (*Name) {
814f4a2713aSLionel Sambuc     default: return false;
815f4a2713aSLionel Sambuc     case 'O': // Zero
816f4a2713aSLionel Sambuc       break;
817f4a2713aSLionel Sambuc     case 'b': // Base register
818f4a2713aSLionel Sambuc     case 'f': // Floating point register
819f4a2713aSLionel Sambuc       Info.setAllowsRegister();
820f4a2713aSLionel Sambuc       break;
821f4a2713aSLionel Sambuc     // FIXME: The following are added to allow parsing.
822f4a2713aSLionel Sambuc     // I just took a guess at what the actions should be.
823f4a2713aSLionel Sambuc     // Also, is more specific checking needed?  I.e. specific registers?
824f4a2713aSLionel Sambuc     case 'd': // Floating point register (containing 64-bit value)
825f4a2713aSLionel Sambuc     case 'v': // Altivec vector register
826f4a2713aSLionel Sambuc       Info.setAllowsRegister();
827f4a2713aSLionel Sambuc       break;
828f4a2713aSLionel Sambuc     case 'w':
829f4a2713aSLionel Sambuc       switch (Name[1]) {
830f4a2713aSLionel Sambuc         case 'd':// VSX vector register to hold vector double data
831f4a2713aSLionel Sambuc         case 'f':// VSX vector register to hold vector float data
832f4a2713aSLionel Sambuc         case 's':// VSX vector register to hold scalar float data
833f4a2713aSLionel Sambuc         case 'a':// Any VSX register
834*0a6a1f1dSLionel Sambuc         case 'c':// An individual CR bit
835f4a2713aSLionel Sambuc           break;
836f4a2713aSLionel Sambuc         default:
837f4a2713aSLionel Sambuc           return false;
838f4a2713aSLionel Sambuc       }
839f4a2713aSLionel Sambuc       Info.setAllowsRegister();
840f4a2713aSLionel Sambuc       Name++; // Skip over 'w'.
841f4a2713aSLionel Sambuc       break;
842f4a2713aSLionel Sambuc     case 'h': // `MQ', `CTR', or `LINK' register
843f4a2713aSLionel Sambuc     case 'q': // `MQ' register
844f4a2713aSLionel Sambuc     case 'c': // `CTR' register
845f4a2713aSLionel Sambuc     case 'l': // `LINK' register
846f4a2713aSLionel Sambuc     case 'x': // `CR' register (condition register) number 0
847f4a2713aSLionel Sambuc     case 'y': // `CR' register (condition register)
848f4a2713aSLionel Sambuc     case 'z': // `XER[CA]' carry bit (part of the XER register)
849f4a2713aSLionel Sambuc       Info.setAllowsRegister();
850f4a2713aSLionel Sambuc       break;
851f4a2713aSLionel Sambuc     case 'I': // Signed 16-bit constant
852f4a2713aSLionel Sambuc     case 'J': // Unsigned 16-bit constant shifted left 16 bits
853f4a2713aSLionel Sambuc               //  (use `L' instead for SImode constants)
854f4a2713aSLionel Sambuc     case 'K': // Unsigned 16-bit constant
855f4a2713aSLionel Sambuc     case 'L': // Signed 16-bit constant shifted left 16 bits
856f4a2713aSLionel Sambuc     case 'M': // Constant larger than 31
857f4a2713aSLionel Sambuc     case 'N': // Exact power of 2
858f4a2713aSLionel Sambuc     case 'P': // Constant whose negation is a signed 16-bit constant
859f4a2713aSLionel Sambuc     case 'G': // Floating point constant that can be loaded into a
860f4a2713aSLionel Sambuc               // register with one instruction per word
861f4a2713aSLionel Sambuc     case 'H': // Integer/Floating point constant that can be loaded
862f4a2713aSLionel Sambuc               // into a register using three instructions
863f4a2713aSLionel Sambuc       break;
864f4a2713aSLionel Sambuc     case 'm': // Memory operand. Note that on PowerPC targets, m can
865f4a2713aSLionel Sambuc               // include addresses that update the base register. It
866f4a2713aSLionel Sambuc               // is therefore only safe to use `m' in an asm statement
867f4a2713aSLionel Sambuc               // if that asm statement accesses the operand exactly once.
868f4a2713aSLionel Sambuc               // The asm statement must also use `%U<opno>' as a
869f4a2713aSLionel Sambuc               // placeholder for the "update" flag in the corresponding
870f4a2713aSLionel Sambuc               // load or store instruction. For example:
871f4a2713aSLionel Sambuc               // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
872f4a2713aSLionel Sambuc               // is correct but:
873f4a2713aSLionel Sambuc               // asm ("st %1,%0" : "=m" (mem) : "r" (val));
874f4a2713aSLionel Sambuc               // is not. Use es rather than m if you don't want the base
875f4a2713aSLionel Sambuc               // register to be updated.
876f4a2713aSLionel Sambuc     case 'e':
877f4a2713aSLionel Sambuc       if (Name[1] != 's')
878f4a2713aSLionel Sambuc           return false;
879f4a2713aSLionel Sambuc               // es: A "stable" memory operand; that is, one which does not
880f4a2713aSLionel Sambuc               // include any automodification of the base register. Unlike
881f4a2713aSLionel Sambuc               // `m', this constraint can be used in asm statements that
882f4a2713aSLionel Sambuc               // might access the operand several times, or that might not
883f4a2713aSLionel Sambuc               // access it at all.
884f4a2713aSLionel Sambuc       Info.setAllowsMemory();
885f4a2713aSLionel Sambuc       Name++; // Skip over 'e'.
886f4a2713aSLionel Sambuc       break;
887f4a2713aSLionel Sambuc     case 'Q': // Memory operand that is an offset from a register (it is
888f4a2713aSLionel Sambuc               // usually better to use `m' or `es' in asm statements)
889f4a2713aSLionel Sambuc     case 'Z': // Memory operand that is an indexed or indirect from a
890f4a2713aSLionel Sambuc               // register (it is usually better to use `m' or `es' in
891f4a2713aSLionel Sambuc               // asm statements)
892f4a2713aSLionel Sambuc       Info.setAllowsMemory();
893f4a2713aSLionel Sambuc       Info.setAllowsRegister();
894f4a2713aSLionel Sambuc       break;
895f4a2713aSLionel Sambuc     case 'R': // AIX TOC entry
896f4a2713aSLionel Sambuc     case 'a': // Address operand that is an indexed or indirect from a
897f4a2713aSLionel Sambuc               // register (`p' is preferable for asm statements)
898f4a2713aSLionel Sambuc     case 'S': // Constant suitable as a 64-bit mask operand
899f4a2713aSLionel Sambuc     case 'T': // Constant suitable as a 32-bit mask operand
900f4a2713aSLionel Sambuc     case 'U': // System V Release 4 small data area reference
901f4a2713aSLionel Sambuc     case 't': // AND masks that can be performed by two rldic{l, r}
902f4a2713aSLionel Sambuc               // instructions
903f4a2713aSLionel Sambuc     case 'W': // Vector constant that does not require memory
904f4a2713aSLionel Sambuc     case 'j': // Vector constant that is all zeros.
905f4a2713aSLionel Sambuc       break;
906f4a2713aSLionel Sambuc     // End FIXME.
907f4a2713aSLionel Sambuc     }
908f4a2713aSLionel Sambuc     return true;
909f4a2713aSLionel Sambuc   }
convertConstraint(const char * & Constraint) const910*0a6a1f1dSLionel Sambuc   std::string convertConstraint(const char *&Constraint) const override {
911*0a6a1f1dSLionel Sambuc     std::string R;
912*0a6a1f1dSLionel Sambuc     switch (*Constraint) {
913*0a6a1f1dSLionel Sambuc     case 'e':
914*0a6a1f1dSLionel Sambuc     case 'w':
915*0a6a1f1dSLionel Sambuc       // Two-character constraint; add "^" hint for later parsing.
916*0a6a1f1dSLionel Sambuc       R = std::string("^") + std::string(Constraint, 2);
917*0a6a1f1dSLionel Sambuc       Constraint++;
918*0a6a1f1dSLionel Sambuc       break;
919*0a6a1f1dSLionel Sambuc     default:
920*0a6a1f1dSLionel Sambuc       return TargetInfo::convertConstraint(Constraint);
921*0a6a1f1dSLionel Sambuc     }
922*0a6a1f1dSLionel Sambuc     return R;
923*0a6a1f1dSLionel Sambuc   }
getClobbers() const924*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override {
925f4a2713aSLionel Sambuc     return "";
926f4a2713aSLionel Sambuc   }
getEHDataRegisterNumber(unsigned RegNo) const927*0a6a1f1dSLionel Sambuc   int getEHDataRegisterNumber(unsigned RegNo) const override {
928f4a2713aSLionel Sambuc     if (RegNo == 0) return 3;
929f4a2713aSLionel Sambuc     if (RegNo == 1) return 4;
930f4a2713aSLionel Sambuc     return -1;
931f4a2713aSLionel Sambuc   }
932*0a6a1f1dSLionel Sambuc 
hasSjLjLowering() const933*0a6a1f1dSLionel Sambuc   bool hasSjLjLowering() const override {
934*0a6a1f1dSLionel Sambuc     return true;
935*0a6a1f1dSLionel Sambuc   }
936f4a2713aSLionel Sambuc };
937f4a2713aSLionel Sambuc 
938f4a2713aSLionel Sambuc const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
939f4a2713aSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
940f4a2713aSLionel Sambuc #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
941f4a2713aSLionel Sambuc                                               ALL_LANGUAGES },
942f4a2713aSLionel Sambuc #include "clang/Basic/BuiltinsPPC.def"
943f4a2713aSLionel Sambuc };
944f4a2713aSLionel Sambuc 
945f4a2713aSLionel Sambuc /// handleTargetFeatures - Perform initialization based on the user
946f4a2713aSLionel Sambuc /// configured set of features.
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)947f4a2713aSLionel Sambuc bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
948f4a2713aSLionel Sambuc                                          DiagnosticsEngine &Diags) {
949f4a2713aSLionel Sambuc   for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
950f4a2713aSLionel Sambuc     // Ignore disabled features.
951f4a2713aSLionel Sambuc     if (Features[i][0] == '-')
952f4a2713aSLionel Sambuc       continue;
953f4a2713aSLionel Sambuc 
954f4a2713aSLionel Sambuc     StringRef Feature = StringRef(Features[i]).substr(1);
955f4a2713aSLionel Sambuc 
956f4a2713aSLionel Sambuc     if (Feature == "vsx") {
957f4a2713aSLionel Sambuc       HasVSX = true;
958f4a2713aSLionel Sambuc       continue;
959f4a2713aSLionel Sambuc     }
960f4a2713aSLionel Sambuc 
961*0a6a1f1dSLionel Sambuc     if (Feature == "power8-vector") {
962*0a6a1f1dSLionel Sambuc       HasP8Vector = true;
963*0a6a1f1dSLionel Sambuc       continue;
964*0a6a1f1dSLionel Sambuc     }
965*0a6a1f1dSLionel Sambuc 
966f4a2713aSLionel Sambuc     // TODO: Finish this list and add an assert that we've handled them
967f4a2713aSLionel Sambuc     // all.
968f4a2713aSLionel Sambuc   }
969f4a2713aSLionel Sambuc 
970f4a2713aSLionel Sambuc   return true;
971f4a2713aSLionel Sambuc }
972f4a2713aSLionel Sambuc 
973f4a2713aSLionel Sambuc /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
974f4a2713aSLionel Sambuc /// #defines that are not tied to a specific subtarget.
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const975f4a2713aSLionel Sambuc void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
976f4a2713aSLionel Sambuc                                      MacroBuilder &Builder) const {
977f4a2713aSLionel Sambuc   // Target identification.
978f4a2713aSLionel Sambuc   Builder.defineMacro("__ppc__");
979f4a2713aSLionel Sambuc   Builder.defineMacro("__PPC__");
980f4a2713aSLionel Sambuc   Builder.defineMacro("_ARCH_PPC");
981f4a2713aSLionel Sambuc   Builder.defineMacro("__powerpc__");
982f4a2713aSLionel Sambuc   Builder.defineMacro("__POWERPC__");
983f4a2713aSLionel Sambuc   if (PointerWidth == 64) {
984f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_PPC64");
985f4a2713aSLionel Sambuc     Builder.defineMacro("__powerpc64__");
986f4a2713aSLionel Sambuc     Builder.defineMacro("__ppc64__");
987f4a2713aSLionel Sambuc     Builder.defineMacro("__PPC64__");
988f4a2713aSLionel Sambuc   }
989f4a2713aSLionel Sambuc 
990f4a2713aSLionel Sambuc   // Target properties.
991f4a2713aSLionel Sambuc   if (getTriple().getArch() == llvm::Triple::ppc64le) {
992f4a2713aSLionel Sambuc     Builder.defineMacro("_LITTLE_ENDIAN");
993f4a2713aSLionel Sambuc   } else {
994f4a2713aSLionel Sambuc     if (getTriple().getOS() != llvm::Triple::NetBSD &&
995f4a2713aSLionel Sambuc         getTriple().getOS() != llvm::Triple::OpenBSD)
996f4a2713aSLionel Sambuc       Builder.defineMacro("_BIG_ENDIAN");
997f4a2713aSLionel Sambuc   }
998f4a2713aSLionel Sambuc 
999*0a6a1f1dSLionel Sambuc   // ABI options.
1000*0a6a1f1dSLionel Sambuc   if (ABI == "elfv1")
1001*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_CALL_ELF", "1");
1002*0a6a1f1dSLionel Sambuc   if (ABI == "elfv2")
1003*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_CALL_ELF", "2");
1004*0a6a1f1dSLionel Sambuc 
1005f4a2713aSLionel Sambuc   // Subtarget options.
1006f4a2713aSLionel Sambuc   Builder.defineMacro("__NATURAL_ALIGNMENT__");
1007f4a2713aSLionel Sambuc   Builder.defineMacro("__REGISTER_PREFIX__", "");
1008f4a2713aSLionel Sambuc 
1009f4a2713aSLionel Sambuc   // FIXME: Should be controlled by command line option.
1010f4a2713aSLionel Sambuc   if (LongDoubleWidth == 128)
1011f4a2713aSLionel Sambuc     Builder.defineMacro("__LONG_DOUBLE_128__");
1012f4a2713aSLionel Sambuc 
1013f4a2713aSLionel Sambuc   if (Opts.AltiVec) {
1014f4a2713aSLionel Sambuc     Builder.defineMacro("__VEC__", "10206");
1015f4a2713aSLionel Sambuc     Builder.defineMacro("__ALTIVEC__");
1016f4a2713aSLionel Sambuc   }
1017f4a2713aSLionel Sambuc 
1018f4a2713aSLionel Sambuc   // CPU identification.
1019f4a2713aSLionel Sambuc   ArchDefineTypes defs = (ArchDefineTypes)llvm::StringSwitch<int>(CPU)
1020f4a2713aSLionel Sambuc     .Case("440",   ArchDefineName)
1021f4a2713aSLionel Sambuc     .Case("450",   ArchDefineName | ArchDefine440)
1022f4a2713aSLionel Sambuc     .Case("601",   ArchDefineName)
1023f4a2713aSLionel Sambuc     .Case("602",   ArchDefineName | ArchDefinePpcgr)
1024f4a2713aSLionel Sambuc     .Case("603",   ArchDefineName | ArchDefinePpcgr)
1025f4a2713aSLionel Sambuc     .Case("603e",  ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
1026f4a2713aSLionel Sambuc     .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
1027f4a2713aSLionel Sambuc     .Case("604",   ArchDefineName | ArchDefinePpcgr)
1028f4a2713aSLionel Sambuc     .Case("604e",  ArchDefineName | ArchDefine604 | ArchDefinePpcgr)
1029f4a2713aSLionel Sambuc     .Case("620",   ArchDefineName | ArchDefinePpcgr)
1030f4a2713aSLionel Sambuc     .Case("630",   ArchDefineName | ArchDefinePpcgr)
1031f4a2713aSLionel Sambuc     .Case("7400",  ArchDefineName | ArchDefinePpcgr)
1032f4a2713aSLionel Sambuc     .Case("7450",  ArchDefineName | ArchDefinePpcgr)
1033f4a2713aSLionel Sambuc     .Case("750",   ArchDefineName | ArchDefinePpcgr)
1034f4a2713aSLionel Sambuc     .Case("970",   ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
1035f4a2713aSLionel Sambuc                      | ArchDefinePpcsq)
1036f4a2713aSLionel Sambuc     .Case("a2",    ArchDefineA2)
1037f4a2713aSLionel Sambuc     .Case("a2q",   ArchDefineName | ArchDefineA2 | ArchDefineA2q)
1038f4a2713aSLionel Sambuc     .Case("pwr3",  ArchDefinePpcgr)
1039f4a2713aSLionel Sambuc     .Case("pwr4",  ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq)
1040f4a2713aSLionel Sambuc     .Case("pwr5",  ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
1041f4a2713aSLionel Sambuc                      | ArchDefinePpcsq)
1042f4a2713aSLionel Sambuc     .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4
1043f4a2713aSLionel Sambuc                      | ArchDefinePpcgr | ArchDefinePpcsq)
1044f4a2713aSLionel Sambuc     .Case("pwr6",  ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5
1045f4a2713aSLionel Sambuc                      | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
1046f4a2713aSLionel Sambuc     .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x
1047f4a2713aSLionel Sambuc                      | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
1048f4a2713aSLionel Sambuc                      | ArchDefinePpcsq)
1049f4a2713aSLionel Sambuc     .Case("pwr7",  ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6
1050f4a2713aSLionel Sambuc                      | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
1051*0a6a1f1dSLionel Sambuc                      | ArchDefinePpcgr | ArchDefinePpcsq)
1052*0a6a1f1dSLionel Sambuc     .Case("pwr8",  ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x
1053*0a6a1f1dSLionel Sambuc                      | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
1054*0a6a1f1dSLionel Sambuc                      | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
1055f4a2713aSLionel Sambuc     .Case("power3",  ArchDefinePpcgr)
1056f4a2713aSLionel Sambuc     .Case("power4",  ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
1057f4a2713aSLionel Sambuc     .Case("power5",  ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
1058f4a2713aSLionel Sambuc                        | ArchDefinePpcsq)
1059f4a2713aSLionel Sambuc     .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
1060f4a2713aSLionel Sambuc                        | ArchDefinePpcgr | ArchDefinePpcsq)
1061f4a2713aSLionel Sambuc     .Case("power6",  ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
1062f4a2713aSLionel Sambuc                        | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
1063f4a2713aSLionel Sambuc     .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x
1064f4a2713aSLionel Sambuc                        | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
1065f4a2713aSLionel Sambuc                        | ArchDefinePpcsq)
1066f4a2713aSLionel Sambuc     .Case("power7",  ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6
1067f4a2713aSLionel Sambuc                        | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
1068*0a6a1f1dSLionel Sambuc                        | ArchDefinePpcgr | ArchDefinePpcsq)
1069*0a6a1f1dSLionel Sambuc     .Case("power8",  ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x
1070*0a6a1f1dSLionel Sambuc                        | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
1071*0a6a1f1dSLionel Sambuc                        | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
1072f4a2713aSLionel Sambuc     .Default(ArchDefineNone);
1073f4a2713aSLionel Sambuc 
1074f4a2713aSLionel Sambuc   if (defs & ArchDefineName)
1075f4a2713aSLionel Sambuc     Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
1076f4a2713aSLionel Sambuc   if (defs & ArchDefinePpcgr)
1077f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_PPCGR");
1078f4a2713aSLionel Sambuc   if (defs & ArchDefinePpcsq)
1079f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_PPCSQ");
1080f4a2713aSLionel Sambuc   if (defs & ArchDefine440)
1081f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_440");
1082f4a2713aSLionel Sambuc   if (defs & ArchDefine603)
1083f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_603");
1084f4a2713aSLionel Sambuc   if (defs & ArchDefine604)
1085f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_604");
1086f4a2713aSLionel Sambuc   if (defs & ArchDefinePwr4)
1087f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_PWR4");
1088f4a2713aSLionel Sambuc   if (defs & ArchDefinePwr5)
1089f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_PWR5");
1090f4a2713aSLionel Sambuc   if (defs & ArchDefinePwr5x)
1091f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_PWR5X");
1092f4a2713aSLionel Sambuc   if (defs & ArchDefinePwr6)
1093f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_PWR6");
1094f4a2713aSLionel Sambuc   if (defs & ArchDefinePwr6x)
1095f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_PWR6X");
1096f4a2713aSLionel Sambuc   if (defs & ArchDefinePwr7)
1097f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_PWR7");
1098*0a6a1f1dSLionel Sambuc   if (defs & ArchDefinePwr8)
1099*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_ARCH_PWR8");
1100f4a2713aSLionel Sambuc   if (defs & ArchDefineA2)
1101f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_A2");
1102f4a2713aSLionel Sambuc   if (defs & ArchDefineA2q) {
1103f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_A2Q");
1104f4a2713aSLionel Sambuc     Builder.defineMacro("_ARCH_QP");
1105f4a2713aSLionel Sambuc   }
1106f4a2713aSLionel Sambuc 
1107f4a2713aSLionel Sambuc   if (getTriple().getVendor() == llvm::Triple::BGQ) {
1108f4a2713aSLionel Sambuc     Builder.defineMacro("__bg__");
1109f4a2713aSLionel Sambuc     Builder.defineMacro("__THW_BLUEGENE__");
1110f4a2713aSLionel Sambuc     Builder.defineMacro("__bgq__");
1111f4a2713aSLionel Sambuc     Builder.defineMacro("__TOS_BGQ__");
1112f4a2713aSLionel Sambuc   }
1113f4a2713aSLionel Sambuc 
1114f4a2713aSLionel Sambuc   if (HasVSX)
1115f4a2713aSLionel Sambuc     Builder.defineMacro("__VSX__");
1116*0a6a1f1dSLionel Sambuc   if (HasP8Vector)
1117*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__POWER8_VECTOR__");
1118f4a2713aSLionel Sambuc 
1119f4a2713aSLionel Sambuc   // FIXME: The following are not yet generated here by Clang, but are
1120f4a2713aSLionel Sambuc   //        generated by GCC:
1121f4a2713aSLionel Sambuc   //
1122f4a2713aSLionel Sambuc   //   _SOFT_FLOAT_
1123f4a2713aSLionel Sambuc   //   __RECIP_PRECISION__
1124f4a2713aSLionel Sambuc   //   __APPLE_ALTIVEC__
1125f4a2713aSLionel Sambuc   //   __RECIP__
1126f4a2713aSLionel Sambuc   //   __RECIPF__
1127f4a2713aSLionel Sambuc   //   __RSQRTE__
1128f4a2713aSLionel Sambuc   //   __RSQRTEF__
1129f4a2713aSLionel Sambuc   //   _SOFT_DOUBLE_
1130f4a2713aSLionel Sambuc   //   __NO_LWSYNC__
1131f4a2713aSLionel Sambuc   //   __HAVE_BSWAP__
1132f4a2713aSLionel Sambuc   //   __LONGDOUBLE128
1133f4a2713aSLionel Sambuc   //   __CMODEL_MEDIUM__
1134f4a2713aSLionel Sambuc   //   __CMODEL_LARGE__
1135f4a2713aSLionel Sambuc   //   _CALL_SYSV
1136f4a2713aSLionel Sambuc   //   _CALL_DARWIN
1137f4a2713aSLionel Sambuc   //   __NO_FPRS__
1138f4a2713aSLionel Sambuc }
1139f4a2713aSLionel Sambuc 
getDefaultFeatures(llvm::StringMap<bool> & Features) const1140f4a2713aSLionel Sambuc void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
1141f4a2713aSLionel Sambuc   Features["altivec"] = llvm::StringSwitch<bool>(CPU)
1142f4a2713aSLionel Sambuc     .Case("7400", true)
1143f4a2713aSLionel Sambuc     .Case("g4", true)
1144f4a2713aSLionel Sambuc     .Case("7450", true)
1145f4a2713aSLionel Sambuc     .Case("g4+", true)
1146f4a2713aSLionel Sambuc     .Case("970", true)
1147f4a2713aSLionel Sambuc     .Case("g5", true)
1148f4a2713aSLionel Sambuc     .Case("pwr6", true)
1149f4a2713aSLionel Sambuc     .Case("pwr7", true)
1150*0a6a1f1dSLionel Sambuc     .Case("pwr8", true)
1151f4a2713aSLionel Sambuc     .Case("ppc64", true)
1152f4a2713aSLionel Sambuc     .Case("ppc64le", true)
1153f4a2713aSLionel Sambuc     .Default(false);
1154f4a2713aSLionel Sambuc 
1155f4a2713aSLionel Sambuc   Features["qpx"] = (CPU == "a2q");
1156*0a6a1f1dSLionel Sambuc 
1157*0a6a1f1dSLionel Sambuc   if (!ABI.empty())
1158*0a6a1f1dSLionel Sambuc     Features[ABI] = true;
1159f4a2713aSLionel Sambuc }
1160f4a2713aSLionel Sambuc 
hasFeature(StringRef Feature) const1161f4a2713aSLionel Sambuc bool PPCTargetInfo::hasFeature(StringRef Feature) const {
1162*0a6a1f1dSLionel Sambuc   return llvm::StringSwitch<bool>(Feature)
1163*0a6a1f1dSLionel Sambuc     .Case("powerpc", true)
1164*0a6a1f1dSLionel Sambuc     .Case("vsx", HasVSX)
1165*0a6a1f1dSLionel Sambuc     .Case("power8-vector", HasP8Vector)
1166*0a6a1f1dSLionel Sambuc     .Default(false);
1167f4a2713aSLionel Sambuc }
1168f4a2713aSLionel Sambuc 
1169f4a2713aSLionel Sambuc const char * const PPCTargetInfo::GCCRegNames[] = {
1170f4a2713aSLionel Sambuc   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1171f4a2713aSLionel Sambuc   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1172f4a2713aSLionel Sambuc   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1173f4a2713aSLionel Sambuc   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
1174f4a2713aSLionel Sambuc   "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1175f4a2713aSLionel Sambuc   "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1176f4a2713aSLionel Sambuc   "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1177f4a2713aSLionel Sambuc   "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1178f4a2713aSLionel Sambuc   "mq", "lr", "ctr", "ap",
1179f4a2713aSLionel Sambuc   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
1180f4a2713aSLionel Sambuc   "xer",
1181f4a2713aSLionel Sambuc   "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
1182f4a2713aSLionel Sambuc   "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
1183f4a2713aSLionel Sambuc   "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
1184f4a2713aSLionel Sambuc   "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
1185f4a2713aSLionel Sambuc   "vrsave", "vscr",
1186f4a2713aSLionel Sambuc   "spe_acc", "spefscr",
1187f4a2713aSLionel Sambuc   "sfp"
1188f4a2713aSLionel Sambuc };
1189f4a2713aSLionel Sambuc 
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const1190f4a2713aSLionel Sambuc void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
1191f4a2713aSLionel Sambuc                                    unsigned &NumNames) const {
1192f4a2713aSLionel Sambuc   Names = GCCRegNames;
1193f4a2713aSLionel Sambuc   NumNames = llvm::array_lengthof(GCCRegNames);
1194f4a2713aSLionel Sambuc }
1195f4a2713aSLionel Sambuc 
1196f4a2713aSLionel Sambuc const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
1197f4a2713aSLionel Sambuc   // While some of these aliases do map to different registers
1198f4a2713aSLionel Sambuc   // they still share the same register name.
1199f4a2713aSLionel Sambuc   { { "0" }, "r0" },
1200f4a2713aSLionel Sambuc   { { "1"}, "r1" },
1201f4a2713aSLionel Sambuc   { { "2" }, "r2" },
1202f4a2713aSLionel Sambuc   { { "3" }, "r3" },
1203f4a2713aSLionel Sambuc   { { "4" }, "r4" },
1204f4a2713aSLionel Sambuc   { { "5" }, "r5" },
1205f4a2713aSLionel Sambuc   { { "6" }, "r6" },
1206f4a2713aSLionel Sambuc   { { "7" }, "r7" },
1207f4a2713aSLionel Sambuc   { { "8" }, "r8" },
1208f4a2713aSLionel Sambuc   { { "9" }, "r9" },
1209f4a2713aSLionel Sambuc   { { "10" }, "r10" },
1210f4a2713aSLionel Sambuc   { { "11" }, "r11" },
1211f4a2713aSLionel Sambuc   { { "12" }, "r12" },
1212f4a2713aSLionel Sambuc   { { "13" }, "r13" },
1213f4a2713aSLionel Sambuc   { { "14" }, "r14" },
1214f4a2713aSLionel Sambuc   { { "15" }, "r15" },
1215f4a2713aSLionel Sambuc   { { "16" }, "r16" },
1216f4a2713aSLionel Sambuc   { { "17" }, "r17" },
1217f4a2713aSLionel Sambuc   { { "18" }, "r18" },
1218f4a2713aSLionel Sambuc   { { "19" }, "r19" },
1219f4a2713aSLionel Sambuc   { { "20" }, "r20" },
1220f4a2713aSLionel Sambuc   { { "21" }, "r21" },
1221f4a2713aSLionel Sambuc   { { "22" }, "r22" },
1222f4a2713aSLionel Sambuc   { { "23" }, "r23" },
1223f4a2713aSLionel Sambuc   { { "24" }, "r24" },
1224f4a2713aSLionel Sambuc   { { "25" }, "r25" },
1225f4a2713aSLionel Sambuc   { { "26" }, "r26" },
1226f4a2713aSLionel Sambuc   { { "27" }, "r27" },
1227f4a2713aSLionel Sambuc   { { "28" }, "r28" },
1228f4a2713aSLionel Sambuc   { { "29" }, "r29" },
1229f4a2713aSLionel Sambuc   { { "30" }, "r30" },
1230f4a2713aSLionel Sambuc   { { "31" }, "r31" },
1231f4a2713aSLionel Sambuc   { { "fr0" }, "f0" },
1232f4a2713aSLionel Sambuc   { { "fr1" }, "f1" },
1233f4a2713aSLionel Sambuc   { { "fr2" }, "f2" },
1234f4a2713aSLionel Sambuc   { { "fr3" }, "f3" },
1235f4a2713aSLionel Sambuc   { { "fr4" }, "f4" },
1236f4a2713aSLionel Sambuc   { { "fr5" }, "f5" },
1237f4a2713aSLionel Sambuc   { { "fr6" }, "f6" },
1238f4a2713aSLionel Sambuc   { { "fr7" }, "f7" },
1239f4a2713aSLionel Sambuc   { { "fr8" }, "f8" },
1240f4a2713aSLionel Sambuc   { { "fr9" }, "f9" },
1241f4a2713aSLionel Sambuc   { { "fr10" }, "f10" },
1242f4a2713aSLionel Sambuc   { { "fr11" }, "f11" },
1243f4a2713aSLionel Sambuc   { { "fr12" }, "f12" },
1244f4a2713aSLionel Sambuc   { { "fr13" }, "f13" },
1245f4a2713aSLionel Sambuc   { { "fr14" }, "f14" },
1246f4a2713aSLionel Sambuc   { { "fr15" }, "f15" },
1247f4a2713aSLionel Sambuc   { { "fr16" }, "f16" },
1248f4a2713aSLionel Sambuc   { { "fr17" }, "f17" },
1249f4a2713aSLionel Sambuc   { { "fr18" }, "f18" },
1250f4a2713aSLionel Sambuc   { { "fr19" }, "f19" },
1251f4a2713aSLionel Sambuc   { { "fr20" }, "f20" },
1252f4a2713aSLionel Sambuc   { { "fr21" }, "f21" },
1253f4a2713aSLionel Sambuc   { { "fr22" }, "f22" },
1254f4a2713aSLionel Sambuc   { { "fr23" }, "f23" },
1255f4a2713aSLionel Sambuc   { { "fr24" }, "f24" },
1256f4a2713aSLionel Sambuc   { { "fr25" }, "f25" },
1257f4a2713aSLionel Sambuc   { { "fr26" }, "f26" },
1258f4a2713aSLionel Sambuc   { { "fr27" }, "f27" },
1259f4a2713aSLionel Sambuc   { { "fr28" }, "f28" },
1260f4a2713aSLionel Sambuc   { { "fr29" }, "f29" },
1261f4a2713aSLionel Sambuc   { { "fr30" }, "f30" },
1262f4a2713aSLionel Sambuc   { { "fr31" }, "f31" },
1263f4a2713aSLionel Sambuc   { { "cc" }, "cr0" },
1264f4a2713aSLionel Sambuc };
1265f4a2713aSLionel Sambuc 
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const1266f4a2713aSLionel Sambuc void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1267f4a2713aSLionel Sambuc                                      unsigned &NumAliases) const {
1268f4a2713aSLionel Sambuc   Aliases = GCCRegAliases;
1269f4a2713aSLionel Sambuc   NumAliases = llvm::array_lengthof(GCCRegAliases);
1270f4a2713aSLionel Sambuc }
1271f4a2713aSLionel Sambuc } // end anonymous namespace.
1272f4a2713aSLionel Sambuc 
1273f4a2713aSLionel Sambuc namespace {
1274f4a2713aSLionel Sambuc class PPC32TargetInfo : public PPCTargetInfo {
1275f4a2713aSLionel Sambuc public:
PPC32TargetInfo(const llvm::Triple & Triple)1276f4a2713aSLionel Sambuc   PPC32TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) {
1277*0a6a1f1dSLionel Sambuc     DescriptionString = "E-m:e-p:32:32-i64:64-n32";
1278f4a2713aSLionel Sambuc 
1279f4a2713aSLionel Sambuc     switch (getTriple().getOS()) {
1280f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
1281f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
1282f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
1283f4a2713aSLionel Sambuc       SizeType = UnsignedInt;
1284f4a2713aSLionel Sambuc       PtrDiffType = SignedInt;
1285f4a2713aSLionel Sambuc       IntPtrType = SignedInt;
1286f4a2713aSLionel Sambuc       break;
1287f4a2713aSLionel Sambuc     default:
1288f4a2713aSLionel Sambuc       break;
1289f4a2713aSLionel Sambuc     }
1290f4a2713aSLionel Sambuc 
1291f4a2713aSLionel Sambuc     if (getTriple().getOS() == llvm::Triple::FreeBSD) {
1292f4a2713aSLionel Sambuc       LongDoubleWidth = LongDoubleAlign = 64;
1293f4a2713aSLionel Sambuc       LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1294f4a2713aSLionel Sambuc     }
1295f4a2713aSLionel Sambuc 
1296f4a2713aSLionel Sambuc     // PPC32 supports atomics up to 4 bytes.
1297f4a2713aSLionel Sambuc     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
1298f4a2713aSLionel Sambuc   }
1299f4a2713aSLionel Sambuc 
getBuiltinVaListKind() const1300*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
1301f4a2713aSLionel Sambuc     // This is the ELF definition, and is overridden by the Darwin sub-target
1302f4a2713aSLionel Sambuc     return TargetInfo::PowerABIBuiltinVaList;
1303f4a2713aSLionel Sambuc   }
1304f4a2713aSLionel Sambuc };
1305f4a2713aSLionel Sambuc } // end anonymous namespace.
1306f4a2713aSLionel Sambuc 
1307f4a2713aSLionel Sambuc // Note: ABI differences may eventually require us to have a separate
1308f4a2713aSLionel Sambuc // TargetInfo for little endian.
1309f4a2713aSLionel Sambuc namespace {
1310f4a2713aSLionel Sambuc class PPC64TargetInfo : public PPCTargetInfo {
1311f4a2713aSLionel Sambuc public:
PPC64TargetInfo(const llvm::Triple & Triple)1312f4a2713aSLionel Sambuc   PPC64TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) {
1313f4a2713aSLionel Sambuc     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
1314f4a2713aSLionel Sambuc     IntMaxType = SignedLong;
1315f4a2713aSLionel Sambuc     Int64Type = SignedLong;
1316f4a2713aSLionel Sambuc 
1317*0a6a1f1dSLionel Sambuc     if ((Triple.getArch() == llvm::Triple::ppc64le)) {
1318*0a6a1f1dSLionel Sambuc       DescriptionString = "e-m:e-i64:64-n32:64";
1319*0a6a1f1dSLionel Sambuc       ABI = "elfv2";
1320*0a6a1f1dSLionel Sambuc     } else {
1321*0a6a1f1dSLionel Sambuc       DescriptionString = "E-m:e-i64:64-n32:64";
1322*0a6a1f1dSLionel Sambuc       ABI = "elfv1";
1323*0a6a1f1dSLionel Sambuc     }
1324*0a6a1f1dSLionel Sambuc 
1325*0a6a1f1dSLionel Sambuc     switch (getTriple().getOS()) {
1326*0a6a1f1dSLionel Sambuc     case llvm::Triple::FreeBSD:
1327f4a2713aSLionel Sambuc       LongDoubleWidth = LongDoubleAlign = 64;
1328f4a2713aSLionel Sambuc       LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1329*0a6a1f1dSLionel Sambuc       break;
1330*0a6a1f1dSLionel Sambuc     case llvm::Triple::NetBSD:
1331*0a6a1f1dSLionel Sambuc       IntMaxType = SignedLongLong;
1332*0a6a1f1dSLionel Sambuc       Int64Type = SignedLongLong;
1333*0a6a1f1dSLionel Sambuc       break;
1334*0a6a1f1dSLionel Sambuc     default:
1335*0a6a1f1dSLionel Sambuc       break;
1336*0a6a1f1dSLionel Sambuc     }
1337f4a2713aSLionel Sambuc 
1338f4a2713aSLionel Sambuc     // PPC64 supports atomics up to 8 bytes.
1339f4a2713aSLionel Sambuc     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
1340f4a2713aSLionel Sambuc   }
getBuiltinVaListKind() const1341*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
1342f4a2713aSLionel Sambuc     return TargetInfo::CharPtrBuiltinVaList;
1343f4a2713aSLionel Sambuc   }
1344*0a6a1f1dSLionel Sambuc   // PPC64 Linux-specifc ABI options.
setABI(const std::string & Name)1345*0a6a1f1dSLionel Sambuc   bool setABI(const std::string &Name) override {
1346*0a6a1f1dSLionel Sambuc     if (Name == "elfv1" || Name == "elfv2") {
1347*0a6a1f1dSLionel Sambuc       ABI = Name;
1348*0a6a1f1dSLionel Sambuc       return true;
1349*0a6a1f1dSLionel Sambuc     }
1350*0a6a1f1dSLionel Sambuc     return false;
1351*0a6a1f1dSLionel Sambuc   }
1352f4a2713aSLionel Sambuc };
1353f4a2713aSLionel Sambuc } // end anonymous namespace.
1354f4a2713aSLionel Sambuc 
1355f4a2713aSLionel Sambuc 
1356f4a2713aSLionel Sambuc namespace {
1357f4a2713aSLionel Sambuc class DarwinPPC32TargetInfo :
1358f4a2713aSLionel Sambuc   public DarwinTargetInfo<PPC32TargetInfo> {
1359f4a2713aSLionel Sambuc public:
DarwinPPC32TargetInfo(const llvm::Triple & Triple)1360f4a2713aSLionel Sambuc   DarwinPPC32TargetInfo(const llvm::Triple &Triple)
1361f4a2713aSLionel Sambuc       : DarwinTargetInfo<PPC32TargetInfo>(Triple) {
1362f4a2713aSLionel Sambuc     HasAlignMac68kSupport = true;
1363f4a2713aSLionel Sambuc     BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
1364f4a2713aSLionel Sambuc     PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726
1365f4a2713aSLionel Sambuc     LongLongAlign = 32;
1366f4a2713aSLionel Sambuc     SuitableAlign = 128;
1367*0a6a1f1dSLionel Sambuc     DescriptionString = "E-m:o-p:32:32-f64:32:64-n32";
1368f4a2713aSLionel Sambuc   }
getBuiltinVaListKind() const1369*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
1370f4a2713aSLionel Sambuc     return TargetInfo::CharPtrBuiltinVaList;
1371f4a2713aSLionel Sambuc   }
1372f4a2713aSLionel Sambuc };
1373f4a2713aSLionel Sambuc 
1374f4a2713aSLionel Sambuc class DarwinPPC64TargetInfo :
1375f4a2713aSLionel Sambuc   public DarwinTargetInfo<PPC64TargetInfo> {
1376f4a2713aSLionel Sambuc public:
DarwinPPC64TargetInfo(const llvm::Triple & Triple)1377f4a2713aSLionel Sambuc   DarwinPPC64TargetInfo(const llvm::Triple &Triple)
1378f4a2713aSLionel Sambuc       : DarwinTargetInfo<PPC64TargetInfo>(Triple) {
1379f4a2713aSLionel Sambuc     HasAlignMac68kSupport = true;
1380f4a2713aSLionel Sambuc     SuitableAlign = 128;
1381*0a6a1f1dSLionel Sambuc     DescriptionString = "E-m:o-i64:64-n32:64";
1382f4a2713aSLionel Sambuc   }
1383f4a2713aSLionel Sambuc };
1384f4a2713aSLionel Sambuc } // end anonymous namespace.
1385f4a2713aSLionel Sambuc 
1386f4a2713aSLionel Sambuc namespace {
1387f4a2713aSLionel Sambuc   static const unsigned NVPTXAddrSpaceMap[] = {
1388f4a2713aSLionel Sambuc     1,    // opencl_global
1389f4a2713aSLionel Sambuc     3,    // opencl_local
1390f4a2713aSLionel Sambuc     4,    // opencl_constant
1391*0a6a1f1dSLionel Sambuc     // FIXME: generic has to be added to the target
1392*0a6a1f1dSLionel Sambuc     0,    // opencl_generic
1393f4a2713aSLionel Sambuc     1,    // cuda_device
1394f4a2713aSLionel Sambuc     4,    // cuda_constant
1395f4a2713aSLionel Sambuc     3,    // cuda_shared
1396f4a2713aSLionel Sambuc   };
1397f4a2713aSLionel Sambuc   class NVPTXTargetInfo : public TargetInfo {
1398f4a2713aSLionel Sambuc     static const char * const GCCRegNames[];
1399f4a2713aSLionel Sambuc     static const Builtin::Info BuiltinInfo[];
1400*0a6a1f1dSLionel Sambuc 
1401*0a6a1f1dSLionel Sambuc   // The GPU profiles supported by the NVPTX backend
1402*0a6a1f1dSLionel Sambuc   enum GPUKind {
1403*0a6a1f1dSLionel Sambuc     GK_NONE,
1404*0a6a1f1dSLionel Sambuc     GK_SM20,
1405*0a6a1f1dSLionel Sambuc     GK_SM21,
1406*0a6a1f1dSLionel Sambuc     GK_SM30,
1407*0a6a1f1dSLionel Sambuc     GK_SM35,
1408*0a6a1f1dSLionel Sambuc   } GPU;
1409*0a6a1f1dSLionel Sambuc 
1410f4a2713aSLionel Sambuc   public:
NVPTXTargetInfo(const llvm::Triple & Triple)1411f4a2713aSLionel Sambuc     NVPTXTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
1412f4a2713aSLionel Sambuc       BigEndian = false;
1413f4a2713aSLionel Sambuc       TLSSupported = false;
1414f4a2713aSLionel Sambuc       LongWidth = LongAlign = 64;
1415f4a2713aSLionel Sambuc       AddrSpaceMap = &NVPTXAddrSpaceMap;
1416f4a2713aSLionel Sambuc       UseAddrSpaceMapMangling = true;
1417f4a2713aSLionel Sambuc       // Define available target features
1418f4a2713aSLionel Sambuc       // These must be defined in sorted order!
1419f4a2713aSLionel Sambuc       NoAsmVariants = true;
1420*0a6a1f1dSLionel Sambuc       // Set the default GPU to sm20
1421*0a6a1f1dSLionel Sambuc       GPU = GK_SM20;
1422f4a2713aSLionel Sambuc     }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1423*0a6a1f1dSLionel Sambuc     void getTargetDefines(const LangOptions &Opts,
1424*0a6a1f1dSLionel Sambuc                           MacroBuilder &Builder) const override {
1425f4a2713aSLionel Sambuc       Builder.defineMacro("__PTX__");
1426f4a2713aSLionel Sambuc       Builder.defineMacro("__NVPTX__");
1427*0a6a1f1dSLionel Sambuc       if (Opts.CUDAIsDevice) {
1428*0a6a1f1dSLionel Sambuc         // Set __CUDA_ARCH__ for the GPU specified.
1429*0a6a1f1dSLionel Sambuc         std::string CUDAArchCode;
1430*0a6a1f1dSLionel Sambuc         switch (GPU) {
1431*0a6a1f1dSLionel Sambuc         case GK_SM20:
1432*0a6a1f1dSLionel Sambuc           CUDAArchCode = "200";
1433*0a6a1f1dSLionel Sambuc           break;
1434*0a6a1f1dSLionel Sambuc         case GK_SM21:
1435*0a6a1f1dSLionel Sambuc           CUDAArchCode = "210";
1436*0a6a1f1dSLionel Sambuc           break;
1437*0a6a1f1dSLionel Sambuc         case GK_SM30:
1438*0a6a1f1dSLionel Sambuc           CUDAArchCode = "300";
1439*0a6a1f1dSLionel Sambuc           break;
1440*0a6a1f1dSLionel Sambuc         case GK_SM35:
1441*0a6a1f1dSLionel Sambuc           CUDAArchCode = "350";
1442*0a6a1f1dSLionel Sambuc           break;
1443*0a6a1f1dSLionel Sambuc         default:
1444*0a6a1f1dSLionel Sambuc           llvm_unreachable("Unhandled target CPU");
1445f4a2713aSLionel Sambuc         }
1446*0a6a1f1dSLionel Sambuc         Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
1447*0a6a1f1dSLionel Sambuc       }
1448*0a6a1f1dSLionel Sambuc     }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const1449*0a6a1f1dSLionel Sambuc     void getTargetBuiltins(const Builtin::Info *&Records,
1450*0a6a1f1dSLionel Sambuc                            unsigned &NumRecords) const override {
1451f4a2713aSLionel Sambuc       Records = BuiltinInfo;
1452f4a2713aSLionel Sambuc       NumRecords = clang::NVPTX::LastTSBuiltin-Builtin::FirstTSBuiltin;
1453f4a2713aSLionel Sambuc     }
hasFeature(StringRef Feature) const1454*0a6a1f1dSLionel Sambuc     bool hasFeature(StringRef Feature) const override {
1455f4a2713aSLionel Sambuc       return Feature == "ptx" || Feature == "nvptx";
1456f4a2713aSLionel Sambuc     }
1457f4a2713aSLionel Sambuc 
1458*0a6a1f1dSLionel Sambuc     void getGCCRegNames(const char * const *&Names,
1459*0a6a1f1dSLionel Sambuc                         unsigned &NumNames) const override;
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const1460*0a6a1f1dSLionel Sambuc     void getGCCRegAliases(const GCCRegAlias *&Aliases,
1461*0a6a1f1dSLionel Sambuc                                   unsigned &NumAliases) const override {
1462f4a2713aSLionel Sambuc       // No aliases.
1463*0a6a1f1dSLionel Sambuc       Aliases = nullptr;
1464f4a2713aSLionel Sambuc       NumAliases = 0;
1465f4a2713aSLionel Sambuc     }
1466*0a6a1f1dSLionel Sambuc     bool
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const1467*0a6a1f1dSLionel Sambuc     validateAsmConstraint(const char *&Name,
1468*0a6a1f1dSLionel Sambuc                           TargetInfo::ConstraintInfo &Info) const override {
1469f4a2713aSLionel Sambuc       switch (*Name) {
1470f4a2713aSLionel Sambuc       default: return false;
1471f4a2713aSLionel Sambuc       case 'c':
1472f4a2713aSLionel Sambuc       case 'h':
1473f4a2713aSLionel Sambuc       case 'r':
1474f4a2713aSLionel Sambuc       case 'l':
1475f4a2713aSLionel Sambuc       case 'f':
1476f4a2713aSLionel Sambuc       case 'd':
1477f4a2713aSLionel Sambuc         Info.setAllowsRegister();
1478f4a2713aSLionel Sambuc         return true;
1479f4a2713aSLionel Sambuc       }
1480f4a2713aSLionel Sambuc     }
getClobbers() const1481*0a6a1f1dSLionel Sambuc     const char *getClobbers() const override {
1482f4a2713aSLionel Sambuc       // FIXME: Is this really right?
1483f4a2713aSLionel Sambuc       return "";
1484f4a2713aSLionel Sambuc     }
getBuiltinVaListKind() const1485*0a6a1f1dSLionel Sambuc     BuiltinVaListKind getBuiltinVaListKind() const override {
1486f4a2713aSLionel Sambuc       // FIXME: implement
1487f4a2713aSLionel Sambuc       return TargetInfo::CharPtrBuiltinVaList;
1488f4a2713aSLionel Sambuc     }
setCPU(const std::string & Name)1489*0a6a1f1dSLionel Sambuc     bool setCPU(const std::string &Name) override {
1490*0a6a1f1dSLionel Sambuc       GPU = llvm::StringSwitch<GPUKind>(Name)
1491*0a6a1f1dSLionel Sambuc                 .Case("sm_20", GK_SM20)
1492*0a6a1f1dSLionel Sambuc                 .Case("sm_21", GK_SM21)
1493*0a6a1f1dSLionel Sambuc                 .Case("sm_30", GK_SM30)
1494*0a6a1f1dSLionel Sambuc                 .Case("sm_35", GK_SM35)
1495*0a6a1f1dSLionel Sambuc                 .Default(GK_NONE);
1496f4a2713aSLionel Sambuc 
1497*0a6a1f1dSLionel Sambuc       return GPU != GK_NONE;
1498f4a2713aSLionel Sambuc     }
1499f4a2713aSLionel Sambuc   };
1500f4a2713aSLionel Sambuc 
1501f4a2713aSLionel Sambuc   const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
1502f4a2713aSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
1503f4a2713aSLionel Sambuc #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1504f4a2713aSLionel Sambuc                                               ALL_LANGUAGES },
1505f4a2713aSLionel Sambuc #include "clang/Basic/BuiltinsNVPTX.def"
1506f4a2713aSLionel Sambuc   };
1507f4a2713aSLionel Sambuc 
1508f4a2713aSLionel Sambuc   const char * const NVPTXTargetInfo::GCCRegNames[] = {
1509f4a2713aSLionel Sambuc     "r0"
1510f4a2713aSLionel Sambuc   };
1511f4a2713aSLionel Sambuc 
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const1512f4a2713aSLionel Sambuc   void NVPTXTargetInfo::getGCCRegNames(const char * const *&Names,
1513f4a2713aSLionel Sambuc                                      unsigned &NumNames) const {
1514f4a2713aSLionel Sambuc     Names = GCCRegNames;
1515f4a2713aSLionel Sambuc     NumNames = llvm::array_lengthof(GCCRegNames);
1516f4a2713aSLionel Sambuc   }
1517f4a2713aSLionel Sambuc 
1518f4a2713aSLionel Sambuc   class NVPTX32TargetInfo : public NVPTXTargetInfo {
1519f4a2713aSLionel Sambuc   public:
NVPTX32TargetInfo(const llvm::Triple & Triple)1520f4a2713aSLionel Sambuc     NVPTX32TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) {
1521f4a2713aSLionel Sambuc       PointerWidth = PointerAlign = 32;
1522*0a6a1f1dSLionel Sambuc       SizeType     = PtrDiffType = TargetInfo::UnsignedInt;
1523*0a6a1f1dSLionel Sambuc       IntPtrType = TargetInfo::SignedInt;
1524*0a6a1f1dSLionel Sambuc       DescriptionString = "e-p:32:32-i64:64-v16:16-v32:32-n16:32:64";
1525f4a2713aSLionel Sambuc   }
1526f4a2713aSLionel Sambuc   };
1527f4a2713aSLionel Sambuc 
1528f4a2713aSLionel Sambuc   class NVPTX64TargetInfo : public NVPTXTargetInfo {
1529f4a2713aSLionel Sambuc   public:
NVPTX64TargetInfo(const llvm::Triple & Triple)1530f4a2713aSLionel Sambuc     NVPTX64TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) {
1531f4a2713aSLionel Sambuc       PointerWidth = PointerAlign = 64;
1532*0a6a1f1dSLionel Sambuc       SizeType     = PtrDiffType = TargetInfo::UnsignedLongLong;
1533*0a6a1f1dSLionel Sambuc       IntPtrType = TargetInfo::SignedLongLong;
1534*0a6a1f1dSLionel Sambuc       DescriptionString = "e-i64:64-v16:16-v32:32-n16:32:64";
1535f4a2713aSLionel Sambuc   }
1536f4a2713aSLionel Sambuc   };
1537f4a2713aSLionel Sambuc }
1538f4a2713aSLionel Sambuc 
1539f4a2713aSLionel Sambuc namespace {
1540f4a2713aSLionel Sambuc 
1541f4a2713aSLionel Sambuc static const unsigned R600AddrSpaceMap[] = {
1542f4a2713aSLionel Sambuc   1,    // opencl_global
1543f4a2713aSLionel Sambuc   3,    // opencl_local
1544f4a2713aSLionel Sambuc   2,    // opencl_constant
1545*0a6a1f1dSLionel Sambuc   4,    // opencl_generic
1546f4a2713aSLionel Sambuc   1,    // cuda_device
1547f4a2713aSLionel Sambuc   2,    // cuda_constant
1548f4a2713aSLionel Sambuc   3     // cuda_shared
1549f4a2713aSLionel Sambuc };
1550f4a2713aSLionel Sambuc 
1551*0a6a1f1dSLionel Sambuc // If you edit the description strings, make sure you update
1552*0a6a1f1dSLionel Sambuc // getPointerWidthV().
1553*0a6a1f1dSLionel Sambuc 
1554f4a2713aSLionel Sambuc static const char *DescriptionStringR600 =
1555*0a6a1f1dSLionel Sambuc   "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
1556*0a6a1f1dSLionel Sambuc   "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
1557f4a2713aSLionel Sambuc 
1558f4a2713aSLionel Sambuc static const char *DescriptionStringR600DoubleOps =
1559*0a6a1f1dSLionel Sambuc   "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
1560*0a6a1f1dSLionel Sambuc   "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
1561f4a2713aSLionel Sambuc 
1562f4a2713aSLionel Sambuc static const char *DescriptionStringSI =
1563*0a6a1f1dSLionel Sambuc   "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-p24:64:64"
1564*0a6a1f1dSLionel Sambuc   "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
1565*0a6a1f1dSLionel Sambuc   "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
1566f4a2713aSLionel Sambuc 
1567f4a2713aSLionel Sambuc class R600TargetInfo : public TargetInfo {
1568*0a6a1f1dSLionel Sambuc   static const Builtin::Info BuiltinInfo[];
1569*0a6a1f1dSLionel Sambuc 
1570f4a2713aSLionel Sambuc   /// \brief The GPU profiles supported by the R600 target.
1571f4a2713aSLionel Sambuc   enum GPUKind {
1572f4a2713aSLionel Sambuc     GK_NONE,
1573f4a2713aSLionel Sambuc     GK_R600,
1574f4a2713aSLionel Sambuc     GK_R600_DOUBLE_OPS,
1575f4a2713aSLionel Sambuc     GK_R700,
1576f4a2713aSLionel Sambuc     GK_R700_DOUBLE_OPS,
1577f4a2713aSLionel Sambuc     GK_EVERGREEN,
1578f4a2713aSLionel Sambuc     GK_EVERGREEN_DOUBLE_OPS,
1579f4a2713aSLionel Sambuc     GK_NORTHERN_ISLANDS,
1580f4a2713aSLionel Sambuc     GK_CAYMAN,
1581f4a2713aSLionel Sambuc     GK_SOUTHERN_ISLANDS,
1582f4a2713aSLionel Sambuc     GK_SEA_ISLANDS
1583f4a2713aSLionel Sambuc   } GPU;
1584f4a2713aSLionel Sambuc 
1585f4a2713aSLionel Sambuc public:
R600TargetInfo(const llvm::Triple & Triple)1586f4a2713aSLionel Sambuc   R600TargetInfo(const llvm::Triple &Triple)
1587f4a2713aSLionel Sambuc       : TargetInfo(Triple), GPU(GK_R600) {
1588f4a2713aSLionel Sambuc     DescriptionString = DescriptionStringR600;
1589f4a2713aSLionel Sambuc     AddrSpaceMap = &R600AddrSpaceMap;
1590f4a2713aSLionel Sambuc     UseAddrSpaceMapMangling = true;
1591f4a2713aSLionel Sambuc   }
1592f4a2713aSLionel Sambuc 
getPointerWidthV(unsigned AddrSpace) const1593*0a6a1f1dSLionel Sambuc   uint64_t getPointerWidthV(unsigned AddrSpace) const override {
1594*0a6a1f1dSLionel Sambuc     if (GPU <= GK_CAYMAN)
1595*0a6a1f1dSLionel Sambuc       return 32;
1596*0a6a1f1dSLionel Sambuc 
1597*0a6a1f1dSLionel Sambuc     switch(AddrSpace) {
1598*0a6a1f1dSLionel Sambuc       default:
1599*0a6a1f1dSLionel Sambuc         return 64;
1600*0a6a1f1dSLionel Sambuc       case 0:
1601*0a6a1f1dSLionel Sambuc       case 3:
1602*0a6a1f1dSLionel Sambuc       case 5:
1603*0a6a1f1dSLionel Sambuc         return 32;
1604*0a6a1f1dSLionel Sambuc     }
1605*0a6a1f1dSLionel Sambuc   }
1606*0a6a1f1dSLionel Sambuc 
getClobbers() const1607*0a6a1f1dSLionel Sambuc   const char * getClobbers() const override {
1608f4a2713aSLionel Sambuc     return "";
1609f4a2713aSLionel Sambuc   }
1610f4a2713aSLionel Sambuc 
getGCCRegNames(const char * const * & Names,unsigned & numNames) const1611*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char * const *&Names,
1612*0a6a1f1dSLionel Sambuc                       unsigned &numNames) const override {
1613*0a6a1f1dSLionel Sambuc     Names = nullptr;
1614f4a2713aSLionel Sambuc     numNames = 0;
1615f4a2713aSLionel Sambuc   }
1616f4a2713aSLionel Sambuc 
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const1617*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
1618*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override {
1619*0a6a1f1dSLionel Sambuc     Aliases = nullptr;
1620f4a2713aSLionel Sambuc     NumAliases = 0;
1621f4a2713aSLionel Sambuc   }
1622f4a2713aSLionel Sambuc 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const1623*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
1624*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &info) const override {
1625f4a2713aSLionel Sambuc     return true;
1626f4a2713aSLionel Sambuc   }
1627f4a2713aSLionel Sambuc 
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const1628*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
1629*0a6a1f1dSLionel Sambuc                          unsigned &NumRecords) const override {
1630*0a6a1f1dSLionel Sambuc     Records = BuiltinInfo;
1631*0a6a1f1dSLionel Sambuc     NumRecords = clang::R600::LastTSBuiltin - Builtin::FirstTSBuiltin;
1632f4a2713aSLionel Sambuc   }
1633f4a2713aSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1634*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
1635*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
1636f4a2713aSLionel Sambuc     Builder.defineMacro("__R600__");
1637f4a2713aSLionel Sambuc   }
1638f4a2713aSLionel Sambuc 
getBuiltinVaListKind() const1639*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
1640f4a2713aSLionel Sambuc     return TargetInfo::CharPtrBuiltinVaList;
1641f4a2713aSLionel Sambuc   }
1642f4a2713aSLionel Sambuc 
setCPU(const std::string & Name)1643*0a6a1f1dSLionel Sambuc   bool setCPU(const std::string &Name) override {
1644f4a2713aSLionel Sambuc     GPU = llvm::StringSwitch<GPUKind>(Name)
1645f4a2713aSLionel Sambuc       .Case("r600" ,    GK_R600)
1646f4a2713aSLionel Sambuc       .Case("rv610",    GK_R600)
1647f4a2713aSLionel Sambuc       .Case("rv620",    GK_R600)
1648f4a2713aSLionel Sambuc       .Case("rv630",    GK_R600)
1649f4a2713aSLionel Sambuc       .Case("rv635",    GK_R600)
1650f4a2713aSLionel Sambuc       .Case("rs780",    GK_R600)
1651f4a2713aSLionel Sambuc       .Case("rs880",    GK_R600)
1652f4a2713aSLionel Sambuc       .Case("rv670",    GK_R600_DOUBLE_OPS)
1653f4a2713aSLionel Sambuc       .Case("rv710",    GK_R700)
1654f4a2713aSLionel Sambuc       .Case("rv730",    GK_R700)
1655f4a2713aSLionel Sambuc       .Case("rv740",    GK_R700_DOUBLE_OPS)
1656f4a2713aSLionel Sambuc       .Case("rv770",    GK_R700_DOUBLE_OPS)
1657f4a2713aSLionel Sambuc       .Case("palm",     GK_EVERGREEN)
1658f4a2713aSLionel Sambuc       .Case("cedar",    GK_EVERGREEN)
1659f4a2713aSLionel Sambuc       .Case("sumo",     GK_EVERGREEN)
1660f4a2713aSLionel Sambuc       .Case("sumo2",    GK_EVERGREEN)
1661f4a2713aSLionel Sambuc       .Case("redwood",  GK_EVERGREEN)
1662f4a2713aSLionel Sambuc       .Case("juniper",  GK_EVERGREEN)
1663f4a2713aSLionel Sambuc       .Case("hemlock",  GK_EVERGREEN_DOUBLE_OPS)
1664f4a2713aSLionel Sambuc       .Case("cypress",  GK_EVERGREEN_DOUBLE_OPS)
1665f4a2713aSLionel Sambuc       .Case("barts",    GK_NORTHERN_ISLANDS)
1666f4a2713aSLionel Sambuc       .Case("turks",    GK_NORTHERN_ISLANDS)
1667f4a2713aSLionel Sambuc       .Case("caicos",   GK_NORTHERN_ISLANDS)
1668f4a2713aSLionel Sambuc       .Case("cayman",   GK_CAYMAN)
1669f4a2713aSLionel Sambuc       .Case("aruba",    GK_CAYMAN)
1670f4a2713aSLionel Sambuc       .Case("tahiti",   GK_SOUTHERN_ISLANDS)
1671f4a2713aSLionel Sambuc       .Case("pitcairn", GK_SOUTHERN_ISLANDS)
1672f4a2713aSLionel Sambuc       .Case("verde",    GK_SOUTHERN_ISLANDS)
1673f4a2713aSLionel Sambuc       .Case("oland",    GK_SOUTHERN_ISLANDS)
1674*0a6a1f1dSLionel Sambuc       .Case("hainan",   GK_SOUTHERN_ISLANDS)
1675f4a2713aSLionel Sambuc       .Case("bonaire",  GK_SEA_ISLANDS)
1676f4a2713aSLionel Sambuc       .Case("kabini",   GK_SEA_ISLANDS)
1677f4a2713aSLionel Sambuc       .Case("kaveri",   GK_SEA_ISLANDS)
1678f4a2713aSLionel Sambuc       .Case("hawaii",   GK_SEA_ISLANDS)
1679*0a6a1f1dSLionel Sambuc       .Case("mullins",  GK_SEA_ISLANDS)
1680f4a2713aSLionel Sambuc       .Default(GK_NONE);
1681f4a2713aSLionel Sambuc 
1682f4a2713aSLionel Sambuc     if (GPU == GK_NONE) {
1683f4a2713aSLionel Sambuc       return false;
1684f4a2713aSLionel Sambuc     }
1685f4a2713aSLionel Sambuc 
1686f4a2713aSLionel Sambuc     // Set the correct data layout
1687f4a2713aSLionel Sambuc     switch (GPU) {
1688f4a2713aSLionel Sambuc     case GK_NONE:
1689f4a2713aSLionel Sambuc     case GK_R600:
1690f4a2713aSLionel Sambuc     case GK_R700:
1691f4a2713aSLionel Sambuc     case GK_EVERGREEN:
1692f4a2713aSLionel Sambuc     case GK_NORTHERN_ISLANDS:
1693f4a2713aSLionel Sambuc       DescriptionString = DescriptionStringR600;
1694f4a2713aSLionel Sambuc       break;
1695f4a2713aSLionel Sambuc     case GK_R600_DOUBLE_OPS:
1696f4a2713aSLionel Sambuc     case GK_R700_DOUBLE_OPS:
1697f4a2713aSLionel Sambuc     case GK_EVERGREEN_DOUBLE_OPS:
1698f4a2713aSLionel Sambuc     case GK_CAYMAN:
1699f4a2713aSLionel Sambuc       DescriptionString = DescriptionStringR600DoubleOps;
1700f4a2713aSLionel Sambuc       break;
1701f4a2713aSLionel Sambuc     case GK_SOUTHERN_ISLANDS:
1702f4a2713aSLionel Sambuc     case GK_SEA_ISLANDS:
1703f4a2713aSLionel Sambuc       DescriptionString = DescriptionStringSI;
1704f4a2713aSLionel Sambuc       break;
1705f4a2713aSLionel Sambuc     }
1706f4a2713aSLionel Sambuc 
1707f4a2713aSLionel Sambuc     return true;
1708f4a2713aSLionel Sambuc   }
1709f4a2713aSLionel Sambuc };
1710f4a2713aSLionel Sambuc 
1711*0a6a1f1dSLionel Sambuc const Builtin::Info R600TargetInfo::BuiltinInfo[] = {
1712*0a6a1f1dSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS)                \
1713*0a6a1f1dSLionel Sambuc   { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
1714*0a6a1f1dSLionel Sambuc #include "clang/Basic/BuiltinsR600.def"
1715*0a6a1f1dSLionel Sambuc };
1716*0a6a1f1dSLionel Sambuc 
1717f4a2713aSLionel Sambuc } // end anonymous namespace
1718f4a2713aSLionel Sambuc 
1719f4a2713aSLionel Sambuc namespace {
1720f4a2713aSLionel Sambuc // Namespace for x86 abstract base class
1721f4a2713aSLionel Sambuc const Builtin::Info BuiltinInfo[] = {
1722f4a2713aSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
1723f4a2713aSLionel Sambuc #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1724f4a2713aSLionel Sambuc                                               ALL_LANGUAGES },
1725f4a2713aSLionel Sambuc #include "clang/Basic/BuiltinsX86.def"
1726f4a2713aSLionel Sambuc };
1727f4a2713aSLionel Sambuc 
1728f4a2713aSLionel Sambuc static const char* const GCCRegNames[] = {
1729f4a2713aSLionel Sambuc   "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
1730f4a2713aSLionel Sambuc   "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
1731f4a2713aSLionel Sambuc   "argp", "flags", "fpcr", "fpsr", "dirflag", "frame",
1732f4a2713aSLionel Sambuc   "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
1733f4a2713aSLionel Sambuc   "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
1734f4a2713aSLionel Sambuc   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1735f4a2713aSLionel Sambuc   "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
1736f4a2713aSLionel Sambuc   "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
1737f4a2713aSLionel Sambuc   "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15",
1738f4a2713aSLionel Sambuc };
1739f4a2713aSLionel Sambuc 
1740f4a2713aSLionel Sambuc const TargetInfo::AddlRegName AddlRegNames[] = {
1741f4a2713aSLionel Sambuc   { { "al", "ah", "eax", "rax" }, 0 },
1742f4a2713aSLionel Sambuc   { { "bl", "bh", "ebx", "rbx" }, 3 },
1743f4a2713aSLionel Sambuc   { { "cl", "ch", "ecx", "rcx" }, 2 },
1744f4a2713aSLionel Sambuc   { { "dl", "dh", "edx", "rdx" }, 1 },
1745f4a2713aSLionel Sambuc   { { "esi", "rsi" }, 4 },
1746f4a2713aSLionel Sambuc   { { "edi", "rdi" }, 5 },
1747f4a2713aSLionel Sambuc   { { "esp", "rsp" }, 7 },
1748f4a2713aSLionel Sambuc   { { "ebp", "rbp" }, 6 },
1749f4a2713aSLionel Sambuc };
1750f4a2713aSLionel Sambuc 
1751f4a2713aSLionel Sambuc // X86 target abstract base class; x86-32 and x86-64 are very close, so
1752f4a2713aSLionel Sambuc // most of the implementation can be shared.
1753f4a2713aSLionel Sambuc class X86TargetInfo : public TargetInfo {
1754f4a2713aSLionel Sambuc   enum X86SSEEnum {
1755f4a2713aSLionel Sambuc     NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F
1756f4a2713aSLionel Sambuc   } SSELevel;
1757f4a2713aSLionel Sambuc   enum MMX3DNowEnum {
1758f4a2713aSLionel Sambuc     NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon
1759f4a2713aSLionel Sambuc   } MMX3DNowLevel;
1760f4a2713aSLionel Sambuc   enum XOPEnum {
1761f4a2713aSLionel Sambuc     NoXOP,
1762f4a2713aSLionel Sambuc     SSE4A,
1763f4a2713aSLionel Sambuc     FMA4,
1764f4a2713aSLionel Sambuc     XOP
1765f4a2713aSLionel Sambuc   } XOPLevel;
1766f4a2713aSLionel Sambuc 
1767f4a2713aSLionel Sambuc   bool HasAES;
1768f4a2713aSLionel Sambuc   bool HasPCLMUL;
1769f4a2713aSLionel Sambuc   bool HasLZCNT;
1770f4a2713aSLionel Sambuc   bool HasRDRND;
1771*0a6a1f1dSLionel Sambuc   bool HasFSGSBASE;
1772f4a2713aSLionel Sambuc   bool HasBMI;
1773f4a2713aSLionel Sambuc   bool HasBMI2;
1774f4a2713aSLionel Sambuc   bool HasPOPCNT;
1775f4a2713aSLionel Sambuc   bool HasRTM;
1776f4a2713aSLionel Sambuc   bool HasPRFCHW;
1777f4a2713aSLionel Sambuc   bool HasRDSEED;
1778*0a6a1f1dSLionel Sambuc   bool HasADX;
1779f4a2713aSLionel Sambuc   bool HasTBM;
1780f4a2713aSLionel Sambuc   bool HasFMA;
1781f4a2713aSLionel Sambuc   bool HasF16C;
1782*0a6a1f1dSLionel Sambuc   bool HasAVX512CD, HasAVX512ER, HasAVX512PF, HasAVX512DQ, HasAVX512BW,
1783*0a6a1f1dSLionel Sambuc       HasAVX512VL;
1784f4a2713aSLionel Sambuc   bool HasSHA;
1785f4a2713aSLionel Sambuc   bool HasCX16;
1786f4a2713aSLionel Sambuc 
1787f4a2713aSLionel Sambuc   /// \brief Enumeration of all of the X86 CPUs supported by Clang.
1788f4a2713aSLionel Sambuc   ///
1789f4a2713aSLionel Sambuc   /// Each enumeration represents a particular CPU supported by Clang. These
1790f4a2713aSLionel Sambuc   /// loosely correspond to the options passed to '-march' or '-mtune' flags.
1791f4a2713aSLionel Sambuc   enum CPUKind {
1792f4a2713aSLionel Sambuc     CK_Generic,
1793f4a2713aSLionel Sambuc 
1794f4a2713aSLionel Sambuc     /// \name i386
1795f4a2713aSLionel Sambuc     /// i386-generation processors.
1796f4a2713aSLionel Sambuc     //@{
1797f4a2713aSLionel Sambuc     CK_i386,
1798f4a2713aSLionel Sambuc     //@}
1799f4a2713aSLionel Sambuc 
1800f4a2713aSLionel Sambuc     /// \name i486
1801f4a2713aSLionel Sambuc     /// i486-generation processors.
1802f4a2713aSLionel Sambuc     //@{
1803f4a2713aSLionel Sambuc     CK_i486,
1804f4a2713aSLionel Sambuc     CK_WinChipC6,
1805f4a2713aSLionel Sambuc     CK_WinChip2,
1806f4a2713aSLionel Sambuc     CK_C3,
1807f4a2713aSLionel Sambuc     //@}
1808f4a2713aSLionel Sambuc 
1809f4a2713aSLionel Sambuc     /// \name i586
1810f4a2713aSLionel Sambuc     /// i586-generation processors, P5 microarchitecture based.
1811f4a2713aSLionel Sambuc     //@{
1812f4a2713aSLionel Sambuc     CK_i586,
1813f4a2713aSLionel Sambuc     CK_Pentium,
1814f4a2713aSLionel Sambuc     CK_PentiumMMX,
1815f4a2713aSLionel Sambuc     //@}
1816f4a2713aSLionel Sambuc 
1817f4a2713aSLionel Sambuc     /// \name i686
1818f4a2713aSLionel Sambuc     /// i686-generation processors, P6 / Pentium M microarchitecture based.
1819f4a2713aSLionel Sambuc     //@{
1820f4a2713aSLionel Sambuc     CK_i686,
1821f4a2713aSLionel Sambuc     CK_PentiumPro,
1822f4a2713aSLionel Sambuc     CK_Pentium2,
1823f4a2713aSLionel Sambuc     CK_Pentium3,
1824f4a2713aSLionel Sambuc     CK_Pentium3M,
1825f4a2713aSLionel Sambuc     CK_PentiumM,
1826f4a2713aSLionel Sambuc     CK_C3_2,
1827f4a2713aSLionel Sambuc 
1828f4a2713aSLionel Sambuc     /// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
1829f4a2713aSLionel Sambuc     /// Clang however has some logic to suport this.
1830f4a2713aSLionel Sambuc     // FIXME: Warn, deprecate, and potentially remove this.
1831f4a2713aSLionel Sambuc     CK_Yonah,
1832f4a2713aSLionel Sambuc     //@}
1833f4a2713aSLionel Sambuc 
1834f4a2713aSLionel Sambuc     /// \name Netburst
1835f4a2713aSLionel Sambuc     /// Netburst microarchitecture based processors.
1836f4a2713aSLionel Sambuc     //@{
1837f4a2713aSLionel Sambuc     CK_Pentium4,
1838f4a2713aSLionel Sambuc     CK_Pentium4M,
1839f4a2713aSLionel Sambuc     CK_Prescott,
1840f4a2713aSLionel Sambuc     CK_Nocona,
1841f4a2713aSLionel Sambuc     //@}
1842f4a2713aSLionel Sambuc 
1843f4a2713aSLionel Sambuc     /// \name Core
1844f4a2713aSLionel Sambuc     /// Core microarchitecture based processors.
1845f4a2713aSLionel Sambuc     //@{
1846f4a2713aSLionel Sambuc     CK_Core2,
1847f4a2713aSLionel Sambuc 
1848f4a2713aSLionel Sambuc     /// This enumerator, like \see CK_Yonah, is a bit odd. It is another
1849f4a2713aSLionel Sambuc     /// codename which GCC no longer accepts as an option to -march, but Clang
1850f4a2713aSLionel Sambuc     /// has some logic for recognizing it.
1851f4a2713aSLionel Sambuc     // FIXME: Warn, deprecate, and potentially remove this.
1852f4a2713aSLionel Sambuc     CK_Penryn,
1853f4a2713aSLionel Sambuc     //@}
1854f4a2713aSLionel Sambuc 
1855f4a2713aSLionel Sambuc     /// \name Atom
1856f4a2713aSLionel Sambuc     /// Atom processors
1857f4a2713aSLionel Sambuc     //@{
1858*0a6a1f1dSLionel Sambuc     CK_Bonnell,
1859f4a2713aSLionel Sambuc     CK_Silvermont,
1860f4a2713aSLionel Sambuc     //@}
1861f4a2713aSLionel Sambuc 
1862f4a2713aSLionel Sambuc     /// \name Nehalem
1863f4a2713aSLionel Sambuc     /// Nehalem microarchitecture based processors.
1864*0a6a1f1dSLionel Sambuc     CK_Nehalem,
1865*0a6a1f1dSLionel Sambuc 
1866*0a6a1f1dSLionel Sambuc     /// \name Westmere
1867*0a6a1f1dSLionel Sambuc     /// Westmere microarchitecture based processors.
1868*0a6a1f1dSLionel Sambuc     CK_Westmere,
1869*0a6a1f1dSLionel Sambuc 
1870*0a6a1f1dSLionel Sambuc     /// \name Sandy Bridge
1871*0a6a1f1dSLionel Sambuc     /// Sandy Bridge microarchitecture based processors.
1872*0a6a1f1dSLionel Sambuc     CK_SandyBridge,
1873*0a6a1f1dSLionel Sambuc 
1874*0a6a1f1dSLionel Sambuc     /// \name Ivy Bridge
1875*0a6a1f1dSLionel Sambuc     /// Ivy Bridge microarchitecture based processors.
1876*0a6a1f1dSLionel Sambuc     CK_IvyBridge,
1877*0a6a1f1dSLionel Sambuc 
1878*0a6a1f1dSLionel Sambuc     /// \name Haswell
1879*0a6a1f1dSLionel Sambuc     /// Haswell microarchitecture based processors.
1880*0a6a1f1dSLionel Sambuc     CK_Haswell,
1881*0a6a1f1dSLionel Sambuc 
1882*0a6a1f1dSLionel Sambuc     /// \name Broadwell
1883*0a6a1f1dSLionel Sambuc     /// Broadwell microarchitecture based processors.
1884*0a6a1f1dSLionel Sambuc     CK_Broadwell,
1885*0a6a1f1dSLionel Sambuc 
1886*0a6a1f1dSLionel Sambuc     /// \name Skylake
1887*0a6a1f1dSLionel Sambuc     /// Skylake microarchitecture based processors.
1888*0a6a1f1dSLionel Sambuc     CK_Skylake,
1889f4a2713aSLionel Sambuc 
1890f4a2713aSLionel Sambuc     /// \name Knights Landing
1891f4a2713aSLionel Sambuc     /// Knights Landing processor.
1892f4a2713aSLionel Sambuc     CK_KNL,
1893f4a2713aSLionel Sambuc 
1894f4a2713aSLionel Sambuc     /// \name K6
1895f4a2713aSLionel Sambuc     /// K6 architecture processors.
1896f4a2713aSLionel Sambuc     //@{
1897f4a2713aSLionel Sambuc     CK_K6,
1898f4a2713aSLionel Sambuc     CK_K6_2,
1899f4a2713aSLionel Sambuc     CK_K6_3,
1900f4a2713aSLionel Sambuc     //@}
1901f4a2713aSLionel Sambuc 
1902f4a2713aSLionel Sambuc     /// \name K7
1903f4a2713aSLionel Sambuc     /// K7 architecture processors.
1904f4a2713aSLionel Sambuc     //@{
1905f4a2713aSLionel Sambuc     CK_Athlon,
1906f4a2713aSLionel Sambuc     CK_AthlonThunderbird,
1907f4a2713aSLionel Sambuc     CK_Athlon4,
1908f4a2713aSLionel Sambuc     CK_AthlonXP,
1909f4a2713aSLionel Sambuc     CK_AthlonMP,
1910f4a2713aSLionel Sambuc     //@}
1911f4a2713aSLionel Sambuc 
1912f4a2713aSLionel Sambuc     /// \name K8
1913f4a2713aSLionel Sambuc     /// K8 architecture processors.
1914f4a2713aSLionel Sambuc     //@{
1915f4a2713aSLionel Sambuc     CK_Athlon64,
1916f4a2713aSLionel Sambuc     CK_Athlon64SSE3,
1917f4a2713aSLionel Sambuc     CK_AthlonFX,
1918f4a2713aSLionel Sambuc     CK_K8,
1919f4a2713aSLionel Sambuc     CK_K8SSE3,
1920f4a2713aSLionel Sambuc     CK_Opteron,
1921f4a2713aSLionel Sambuc     CK_OpteronSSE3,
1922f4a2713aSLionel Sambuc     CK_AMDFAM10,
1923f4a2713aSLionel Sambuc     //@}
1924f4a2713aSLionel Sambuc 
1925f4a2713aSLionel Sambuc     /// \name Bobcat
1926f4a2713aSLionel Sambuc     /// Bobcat architecture processors.
1927f4a2713aSLionel Sambuc     //@{
1928f4a2713aSLionel Sambuc     CK_BTVER1,
1929f4a2713aSLionel Sambuc     CK_BTVER2,
1930f4a2713aSLionel Sambuc     //@}
1931f4a2713aSLionel Sambuc 
1932f4a2713aSLionel Sambuc     /// \name Bulldozer
1933f4a2713aSLionel Sambuc     /// Bulldozer architecture processors.
1934f4a2713aSLionel Sambuc     //@{
1935f4a2713aSLionel Sambuc     CK_BDVER1,
1936f4a2713aSLionel Sambuc     CK_BDVER2,
1937f4a2713aSLionel Sambuc     CK_BDVER3,
1938*0a6a1f1dSLionel Sambuc     CK_BDVER4,
1939f4a2713aSLionel Sambuc     //@}
1940f4a2713aSLionel Sambuc 
1941f4a2713aSLionel Sambuc     /// This specification is deprecated and will be removed in the future.
1942f4a2713aSLionel Sambuc     /// Users should prefer \see CK_K8.
1943f4a2713aSLionel Sambuc     // FIXME: Warn on this when the CPU is set to it.
1944*0a6a1f1dSLionel Sambuc     //@{
1945f4a2713aSLionel Sambuc     CK_x86_64,
1946f4a2713aSLionel Sambuc     //@}
1947f4a2713aSLionel Sambuc 
1948f4a2713aSLionel Sambuc     /// \name Geode
1949f4a2713aSLionel Sambuc     /// Geode processors.
1950f4a2713aSLionel Sambuc     //@{
1951f4a2713aSLionel Sambuc     CK_Geode
1952f4a2713aSLionel Sambuc     //@}
1953f4a2713aSLionel Sambuc   } CPU;
1954f4a2713aSLionel Sambuc 
1955f4a2713aSLionel Sambuc   enum FPMathKind {
1956f4a2713aSLionel Sambuc     FP_Default,
1957f4a2713aSLionel Sambuc     FP_SSE,
1958f4a2713aSLionel Sambuc     FP_387
1959f4a2713aSLionel Sambuc   } FPMath;
1960f4a2713aSLionel Sambuc 
1961f4a2713aSLionel Sambuc public:
X86TargetInfo(const llvm::Triple & Triple)1962f4a2713aSLionel Sambuc   X86TargetInfo(const llvm::Triple &Triple)
1963f4a2713aSLionel Sambuc       : TargetInfo(Triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
1964f4a2713aSLionel Sambuc         XOPLevel(NoXOP), HasAES(false), HasPCLMUL(false), HasLZCNT(false),
1965*0a6a1f1dSLionel Sambuc         HasRDRND(false), HasFSGSBASE(false), HasBMI(false), HasBMI2(false),
1966*0a6a1f1dSLionel Sambuc         HasPOPCNT(false), HasRTM(false), HasPRFCHW(false), HasRDSEED(false),
1967*0a6a1f1dSLionel Sambuc         HasADX(false), HasTBM(false), HasFMA(false), HasF16C(false),
1968*0a6a1f1dSLionel Sambuc         HasAVX512CD(false), HasAVX512ER(false), HasAVX512PF(false),
1969*0a6a1f1dSLionel Sambuc         HasAVX512DQ(false), HasAVX512BW(false), HasAVX512VL(false),
1970*0a6a1f1dSLionel Sambuc         HasSHA(false), HasCX16(false), CPU(CK_Generic), FPMath(FP_Default) {
1971f4a2713aSLionel Sambuc     BigEndian = false;
1972f4a2713aSLionel Sambuc     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
1973f4a2713aSLionel Sambuc   }
getFloatEvalMethod() const1974*0a6a1f1dSLionel Sambuc   unsigned getFloatEvalMethod() const override {
1975f4a2713aSLionel Sambuc     // X87 evaluates with 80 bits "long double" precision.
1976f4a2713aSLionel Sambuc     return SSELevel == NoSSE ? 2 : 0;
1977f4a2713aSLionel Sambuc   }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const1978*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
1979*0a6a1f1dSLionel Sambuc                                  unsigned &NumRecords) const override {
1980f4a2713aSLionel Sambuc     Records = BuiltinInfo;
1981f4a2713aSLionel Sambuc     NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
1982f4a2713aSLionel Sambuc   }
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const1983*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char * const *&Names,
1984*0a6a1f1dSLionel Sambuc                       unsigned &NumNames) const override {
1985f4a2713aSLionel Sambuc     Names = GCCRegNames;
1986f4a2713aSLionel Sambuc     NumNames = llvm::array_lengthof(GCCRegNames);
1987f4a2713aSLionel Sambuc   }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const1988*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
1989*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override {
1990*0a6a1f1dSLionel Sambuc     Aliases = nullptr;
1991f4a2713aSLionel Sambuc     NumAliases = 0;
1992f4a2713aSLionel Sambuc   }
getGCCAddlRegNames(const AddlRegName * & Names,unsigned & NumNames) const1993*0a6a1f1dSLionel Sambuc   void getGCCAddlRegNames(const AddlRegName *&Names,
1994*0a6a1f1dSLionel Sambuc                           unsigned &NumNames) const override {
1995f4a2713aSLionel Sambuc     Names = AddlRegNames;
1996f4a2713aSLionel Sambuc     NumNames = llvm::array_lengthof(AddlRegNames);
1997f4a2713aSLionel Sambuc   }
1998*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
1999*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &info) const override;
2000*0a6a1f1dSLionel Sambuc 
2001*0a6a1f1dSLionel Sambuc   bool validateOutputSize(StringRef Constraint, unsigned Size) const override;
2002*0a6a1f1dSLionel Sambuc 
2003*0a6a1f1dSLionel Sambuc   bool validateInputSize(StringRef Constraint, unsigned Size) const override;
2004*0a6a1f1dSLionel Sambuc 
2005*0a6a1f1dSLionel Sambuc   virtual bool validateOperandSize(StringRef Constraint, unsigned Size) const;
2006*0a6a1f1dSLionel Sambuc 
2007*0a6a1f1dSLionel Sambuc   std::string convertConstraint(const char *&Constraint) const override;
getClobbers() const2008*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override {
2009f4a2713aSLionel Sambuc     return "~{dirflag},~{fpsr},~{flags}";
2010f4a2713aSLionel Sambuc   }
2011*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
2012*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override;
2013f4a2713aSLionel Sambuc   static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level,
2014f4a2713aSLionel Sambuc                           bool Enabled);
2015f4a2713aSLionel Sambuc   static void setMMXLevel(llvm::StringMap<bool> &Features, MMX3DNowEnum Level,
2016f4a2713aSLionel Sambuc                           bool Enabled);
2017f4a2713aSLionel Sambuc   static void setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
2018f4a2713aSLionel Sambuc                           bool Enabled);
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const2019*0a6a1f1dSLionel Sambuc   void setFeatureEnabled(llvm::StringMap<bool> &Features,
2020*0a6a1f1dSLionel Sambuc                          StringRef Name, bool Enabled) const override {
2021f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, Name, Enabled);
2022f4a2713aSLionel Sambuc   }
2023f4a2713aSLionel Sambuc   // This exists purely to cut down on the number of virtual calls in
2024f4a2713aSLionel Sambuc   // getDefaultFeatures which calls this repeatedly.
2025f4a2713aSLionel Sambuc   static void setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
2026f4a2713aSLionel Sambuc                                     StringRef Name, bool Enabled);
2027*0a6a1f1dSLionel Sambuc   void getDefaultFeatures(llvm::StringMap<bool> &Features) const override;
2028*0a6a1f1dSLionel Sambuc   bool hasFeature(StringRef Feature) const override;
2029*0a6a1f1dSLionel Sambuc   bool handleTargetFeatures(std::vector<std::string> &Features,
2030*0a6a1f1dSLionel Sambuc                             DiagnosticsEngine &Diags) override;
getABI() const2031*0a6a1f1dSLionel Sambuc   StringRef getABI() const override {
2032f4a2713aSLionel Sambuc     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
2033f4a2713aSLionel Sambuc       return "avx";
2034f4a2713aSLionel Sambuc     else if (getTriple().getArch() == llvm::Triple::x86 &&
2035f4a2713aSLionel Sambuc              MMX3DNowLevel == NoMMX3DNow)
2036f4a2713aSLionel Sambuc       return "no-mmx";
2037f4a2713aSLionel Sambuc     return "";
2038f4a2713aSLionel Sambuc   }
setCPU(const std::string & Name)2039*0a6a1f1dSLionel Sambuc   bool setCPU(const std::string &Name) override {
2040f4a2713aSLionel Sambuc     CPU = llvm::StringSwitch<CPUKind>(Name)
2041f4a2713aSLionel Sambuc       .Case("i386", CK_i386)
2042f4a2713aSLionel Sambuc       .Case("i486", CK_i486)
2043f4a2713aSLionel Sambuc       .Case("winchip-c6", CK_WinChipC6)
2044f4a2713aSLionel Sambuc       .Case("winchip2", CK_WinChip2)
2045f4a2713aSLionel Sambuc       .Case("c3", CK_C3)
2046f4a2713aSLionel Sambuc       .Case("i586", CK_i586)
2047f4a2713aSLionel Sambuc       .Case("pentium", CK_Pentium)
2048f4a2713aSLionel Sambuc       .Case("pentium-mmx", CK_PentiumMMX)
2049f4a2713aSLionel Sambuc       .Case("i686", CK_i686)
2050f4a2713aSLionel Sambuc       .Case("pentiumpro", CK_PentiumPro)
2051f4a2713aSLionel Sambuc       .Case("pentium2", CK_Pentium2)
2052f4a2713aSLionel Sambuc       .Case("pentium3", CK_Pentium3)
2053f4a2713aSLionel Sambuc       .Case("pentium3m", CK_Pentium3M)
2054f4a2713aSLionel Sambuc       .Case("pentium-m", CK_PentiumM)
2055f4a2713aSLionel Sambuc       .Case("c3-2", CK_C3_2)
2056f4a2713aSLionel Sambuc       .Case("yonah", CK_Yonah)
2057f4a2713aSLionel Sambuc       .Case("pentium4", CK_Pentium4)
2058f4a2713aSLionel Sambuc       .Case("pentium4m", CK_Pentium4M)
2059f4a2713aSLionel Sambuc       .Case("prescott", CK_Prescott)
2060f4a2713aSLionel Sambuc       .Case("nocona", CK_Nocona)
2061f4a2713aSLionel Sambuc       .Case("core2", CK_Core2)
2062f4a2713aSLionel Sambuc       .Case("penryn", CK_Penryn)
2063*0a6a1f1dSLionel Sambuc       .Case("bonnell", CK_Bonnell)
2064*0a6a1f1dSLionel Sambuc       .Case("atom", CK_Bonnell) // Legacy name.
2065*0a6a1f1dSLionel Sambuc       .Case("silvermont", CK_Silvermont)
2066*0a6a1f1dSLionel Sambuc       .Case("slm", CK_Silvermont) // Legacy name.
2067*0a6a1f1dSLionel Sambuc       .Case("nehalem", CK_Nehalem)
2068*0a6a1f1dSLionel Sambuc       .Case("corei7", CK_Nehalem) // Legacy name.
2069*0a6a1f1dSLionel Sambuc       .Case("westmere", CK_Westmere)
2070*0a6a1f1dSLionel Sambuc       .Case("sandybridge", CK_SandyBridge)
2071*0a6a1f1dSLionel Sambuc       .Case("corei7-avx", CK_SandyBridge) // Legacy name.
2072*0a6a1f1dSLionel Sambuc       .Case("ivybridge", CK_IvyBridge)
2073*0a6a1f1dSLionel Sambuc       .Case("core-avx-i", CK_IvyBridge) // Legacy name.
2074*0a6a1f1dSLionel Sambuc       .Case("haswell", CK_Haswell)
2075*0a6a1f1dSLionel Sambuc       .Case("core-avx2", CK_Haswell) // Legacy name.
2076*0a6a1f1dSLionel Sambuc       .Case("broadwell", CK_Broadwell)
2077*0a6a1f1dSLionel Sambuc       .Case("skylake", CK_Skylake)
2078*0a6a1f1dSLionel Sambuc       .Case("skx", CK_Skylake) // Legacy name.
2079f4a2713aSLionel Sambuc       .Case("knl", CK_KNL)
2080f4a2713aSLionel Sambuc       .Case("k6", CK_K6)
2081f4a2713aSLionel Sambuc       .Case("k6-2", CK_K6_2)
2082f4a2713aSLionel Sambuc       .Case("k6-3", CK_K6_3)
2083f4a2713aSLionel Sambuc       .Case("athlon", CK_Athlon)
2084f4a2713aSLionel Sambuc       .Case("athlon-tbird", CK_AthlonThunderbird)
2085f4a2713aSLionel Sambuc       .Case("athlon-4", CK_Athlon4)
2086f4a2713aSLionel Sambuc       .Case("athlon-xp", CK_AthlonXP)
2087f4a2713aSLionel Sambuc       .Case("athlon-mp", CK_AthlonMP)
2088f4a2713aSLionel Sambuc       .Case("athlon64", CK_Athlon64)
2089f4a2713aSLionel Sambuc       .Case("athlon64-sse3", CK_Athlon64SSE3)
2090f4a2713aSLionel Sambuc       .Case("athlon-fx", CK_AthlonFX)
2091f4a2713aSLionel Sambuc       .Case("k8", CK_K8)
2092f4a2713aSLionel Sambuc       .Case("k8-sse3", CK_K8SSE3)
2093f4a2713aSLionel Sambuc       .Case("opteron", CK_Opteron)
2094f4a2713aSLionel Sambuc       .Case("opteron-sse3", CK_OpteronSSE3)
2095*0a6a1f1dSLionel Sambuc       .Case("barcelona", CK_AMDFAM10)
2096f4a2713aSLionel Sambuc       .Case("amdfam10", CK_AMDFAM10)
2097f4a2713aSLionel Sambuc       .Case("btver1", CK_BTVER1)
2098f4a2713aSLionel Sambuc       .Case("btver2", CK_BTVER2)
2099f4a2713aSLionel Sambuc       .Case("bdver1", CK_BDVER1)
2100f4a2713aSLionel Sambuc       .Case("bdver2", CK_BDVER2)
2101f4a2713aSLionel Sambuc       .Case("bdver3", CK_BDVER3)
2102*0a6a1f1dSLionel Sambuc       .Case("bdver4", CK_BDVER4)
2103f4a2713aSLionel Sambuc       .Case("x86-64", CK_x86_64)
2104f4a2713aSLionel Sambuc       .Case("geode", CK_Geode)
2105f4a2713aSLionel Sambuc       .Default(CK_Generic);
2106f4a2713aSLionel Sambuc 
2107f4a2713aSLionel Sambuc     // Perform any per-CPU checks necessary to determine if this CPU is
2108f4a2713aSLionel Sambuc     // acceptable.
2109f4a2713aSLionel Sambuc     // FIXME: This results in terrible diagnostics. Clang just says the CPU is
2110f4a2713aSLionel Sambuc     // invalid without explaining *why*.
2111f4a2713aSLionel Sambuc     switch (CPU) {
2112f4a2713aSLionel Sambuc     case CK_Generic:
2113f4a2713aSLionel Sambuc       // No processor selected!
2114f4a2713aSLionel Sambuc       return false;
2115f4a2713aSLionel Sambuc 
2116f4a2713aSLionel Sambuc     case CK_i386:
2117f4a2713aSLionel Sambuc     case CK_i486:
2118f4a2713aSLionel Sambuc     case CK_WinChipC6:
2119f4a2713aSLionel Sambuc     case CK_WinChip2:
2120f4a2713aSLionel Sambuc     case CK_C3:
2121f4a2713aSLionel Sambuc     case CK_i586:
2122f4a2713aSLionel Sambuc     case CK_Pentium:
2123f4a2713aSLionel Sambuc     case CK_PentiumMMX:
2124f4a2713aSLionel Sambuc     case CK_i686:
2125f4a2713aSLionel Sambuc     case CK_PentiumPro:
2126f4a2713aSLionel Sambuc     case CK_Pentium2:
2127f4a2713aSLionel Sambuc     case CK_Pentium3:
2128f4a2713aSLionel Sambuc     case CK_Pentium3M:
2129f4a2713aSLionel Sambuc     case CK_PentiumM:
2130f4a2713aSLionel Sambuc     case CK_Yonah:
2131f4a2713aSLionel Sambuc     case CK_C3_2:
2132f4a2713aSLionel Sambuc     case CK_Pentium4:
2133f4a2713aSLionel Sambuc     case CK_Pentium4M:
2134f4a2713aSLionel Sambuc     case CK_Prescott:
2135f4a2713aSLionel Sambuc     case CK_K6:
2136f4a2713aSLionel Sambuc     case CK_K6_2:
2137f4a2713aSLionel Sambuc     case CK_K6_3:
2138f4a2713aSLionel Sambuc     case CK_Athlon:
2139f4a2713aSLionel Sambuc     case CK_AthlonThunderbird:
2140f4a2713aSLionel Sambuc     case CK_Athlon4:
2141f4a2713aSLionel Sambuc     case CK_AthlonXP:
2142f4a2713aSLionel Sambuc     case CK_AthlonMP:
2143f4a2713aSLionel Sambuc     case CK_Geode:
2144f4a2713aSLionel Sambuc       // Only accept certain architectures when compiling in 32-bit mode.
2145f4a2713aSLionel Sambuc       if (getTriple().getArch() != llvm::Triple::x86)
2146f4a2713aSLionel Sambuc         return false;
2147f4a2713aSLionel Sambuc 
2148f4a2713aSLionel Sambuc       // Fallthrough
2149f4a2713aSLionel Sambuc     case CK_Nocona:
2150f4a2713aSLionel Sambuc     case CK_Core2:
2151f4a2713aSLionel Sambuc     case CK_Penryn:
2152*0a6a1f1dSLionel Sambuc     case CK_Bonnell:
2153f4a2713aSLionel Sambuc     case CK_Silvermont:
2154*0a6a1f1dSLionel Sambuc     case CK_Nehalem:
2155*0a6a1f1dSLionel Sambuc     case CK_Westmere:
2156*0a6a1f1dSLionel Sambuc     case CK_SandyBridge:
2157*0a6a1f1dSLionel Sambuc     case CK_IvyBridge:
2158*0a6a1f1dSLionel Sambuc     case CK_Haswell:
2159*0a6a1f1dSLionel Sambuc     case CK_Broadwell:
2160*0a6a1f1dSLionel Sambuc     case CK_Skylake:
2161f4a2713aSLionel Sambuc     case CK_KNL:
2162f4a2713aSLionel Sambuc     case CK_Athlon64:
2163f4a2713aSLionel Sambuc     case CK_Athlon64SSE3:
2164f4a2713aSLionel Sambuc     case CK_AthlonFX:
2165f4a2713aSLionel Sambuc     case CK_K8:
2166f4a2713aSLionel Sambuc     case CK_K8SSE3:
2167f4a2713aSLionel Sambuc     case CK_Opteron:
2168f4a2713aSLionel Sambuc     case CK_OpteronSSE3:
2169f4a2713aSLionel Sambuc     case CK_AMDFAM10:
2170f4a2713aSLionel Sambuc     case CK_BTVER1:
2171f4a2713aSLionel Sambuc     case CK_BTVER2:
2172f4a2713aSLionel Sambuc     case CK_BDVER1:
2173f4a2713aSLionel Sambuc     case CK_BDVER2:
2174f4a2713aSLionel Sambuc     case CK_BDVER3:
2175*0a6a1f1dSLionel Sambuc     case CK_BDVER4:
2176f4a2713aSLionel Sambuc     case CK_x86_64:
2177f4a2713aSLionel Sambuc       return true;
2178f4a2713aSLionel Sambuc     }
2179f4a2713aSLionel Sambuc     llvm_unreachable("Unhandled CPU kind");
2180f4a2713aSLionel Sambuc   }
2181f4a2713aSLionel Sambuc 
2182*0a6a1f1dSLionel Sambuc   bool setFPMath(StringRef Name) override;
2183f4a2713aSLionel Sambuc 
checkCallingConvention(CallingConv CC) const2184*0a6a1f1dSLionel Sambuc   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
2185f4a2713aSLionel Sambuc     // We accept all non-ARM calling conventions
2186f4a2713aSLionel Sambuc     return (CC == CC_X86ThisCall ||
2187f4a2713aSLionel Sambuc             CC == CC_X86FastCall ||
2188f4a2713aSLionel Sambuc             CC == CC_X86StdCall ||
2189*0a6a1f1dSLionel Sambuc             CC == CC_X86VectorCall ||
2190f4a2713aSLionel Sambuc             CC == CC_C ||
2191f4a2713aSLionel Sambuc             CC == CC_X86Pascal ||
2192f4a2713aSLionel Sambuc             CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
2193f4a2713aSLionel Sambuc   }
2194f4a2713aSLionel Sambuc 
getDefaultCallingConv(CallingConvMethodType MT) const2195*0a6a1f1dSLionel Sambuc   CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
2196f4a2713aSLionel Sambuc     return MT == CCMT_Member ? CC_X86ThisCall : CC_C;
2197f4a2713aSLionel Sambuc   }
2198*0a6a1f1dSLionel Sambuc 
hasSjLjLowering() const2199*0a6a1f1dSLionel Sambuc   bool hasSjLjLowering() const override {
2200*0a6a1f1dSLionel Sambuc     return true;
2201*0a6a1f1dSLionel Sambuc   }
2202f4a2713aSLionel Sambuc };
2203f4a2713aSLionel Sambuc 
setFPMath(StringRef Name)2204f4a2713aSLionel Sambuc bool X86TargetInfo::setFPMath(StringRef Name) {
2205f4a2713aSLionel Sambuc   if (Name == "387") {
2206f4a2713aSLionel Sambuc     FPMath = FP_387;
2207f4a2713aSLionel Sambuc     return true;
2208f4a2713aSLionel Sambuc   }
2209f4a2713aSLionel Sambuc   if (Name == "sse") {
2210f4a2713aSLionel Sambuc     FPMath = FP_SSE;
2211f4a2713aSLionel Sambuc     return true;
2212f4a2713aSLionel Sambuc   }
2213f4a2713aSLionel Sambuc   return false;
2214f4a2713aSLionel Sambuc }
2215f4a2713aSLionel Sambuc 
getDefaultFeatures(llvm::StringMap<bool> & Features) const2216f4a2713aSLionel Sambuc void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
2217f4a2713aSLionel Sambuc   // FIXME: This *really* should not be here.
2218f4a2713aSLionel Sambuc 
2219f4a2713aSLionel Sambuc   // X86_64 always has SSE2.
2220f4a2713aSLionel Sambuc   if (getTriple().getArch() == llvm::Triple::x86_64)
2221f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "sse2", true);
2222f4a2713aSLionel Sambuc 
2223f4a2713aSLionel Sambuc   switch (CPU) {
2224f4a2713aSLionel Sambuc   case CK_Generic:
2225f4a2713aSLionel Sambuc   case CK_i386:
2226f4a2713aSLionel Sambuc   case CK_i486:
2227f4a2713aSLionel Sambuc   case CK_i586:
2228f4a2713aSLionel Sambuc   case CK_Pentium:
2229f4a2713aSLionel Sambuc   case CK_i686:
2230f4a2713aSLionel Sambuc   case CK_PentiumPro:
2231f4a2713aSLionel Sambuc     break;
2232f4a2713aSLionel Sambuc   case CK_PentiumMMX:
2233f4a2713aSLionel Sambuc   case CK_Pentium2:
2234*0a6a1f1dSLionel Sambuc   case CK_K6:
2235*0a6a1f1dSLionel Sambuc   case CK_WinChipC6:
2236f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "mmx", true);
2237f4a2713aSLionel Sambuc     break;
2238f4a2713aSLionel Sambuc   case CK_Pentium3:
2239f4a2713aSLionel Sambuc   case CK_Pentium3M:
2240*0a6a1f1dSLionel Sambuc   case CK_C3_2:
2241f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "sse", true);
2242f4a2713aSLionel Sambuc     break;
2243f4a2713aSLionel Sambuc   case CK_PentiumM:
2244f4a2713aSLionel Sambuc   case CK_Pentium4:
2245f4a2713aSLionel Sambuc   case CK_Pentium4M:
2246f4a2713aSLionel Sambuc   case CK_x86_64:
2247f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "sse2", true);
2248f4a2713aSLionel Sambuc     break;
2249f4a2713aSLionel Sambuc   case CK_Yonah:
2250f4a2713aSLionel Sambuc   case CK_Prescott:
2251f4a2713aSLionel Sambuc   case CK_Nocona:
2252f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "sse3", true);
2253f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "cx16", true);
2254f4a2713aSLionel Sambuc     break;
2255f4a2713aSLionel Sambuc   case CK_Core2:
2256*0a6a1f1dSLionel Sambuc   case CK_Bonnell:
2257f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "ssse3", true);
2258f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "cx16", true);
2259f4a2713aSLionel Sambuc     break;
2260f4a2713aSLionel Sambuc   case CK_Penryn:
2261f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "sse4.1", true);
2262f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "cx16", true);
2263f4a2713aSLionel Sambuc     break;
2264*0a6a1f1dSLionel Sambuc   case CK_Skylake:
2265*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "avx512f", true);
2266*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "avx512cd", true);
2267*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "avx512dq", true);
2268*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "avx512bw", true);
2269*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "avx512vl", true);
2270*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2271*0a6a1f1dSLionel Sambuc   case CK_Broadwell:
2272*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "rdseed", true);
2273*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "adx", true);
2274*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2275*0a6a1f1dSLionel Sambuc   case CK_Haswell:
2276f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "avx2", true);
2277f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "lzcnt", true);
2278f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "bmi", true);
2279f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "bmi2", true);
2280f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "rtm", true);
2281f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "fma", true);
2282*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2283*0a6a1f1dSLionel Sambuc   case CK_IvyBridge:
2284*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "rdrnd", true);
2285*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "f16c", true);
2286*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "fsgsbase", true);
2287*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2288*0a6a1f1dSLionel Sambuc   case CK_SandyBridge:
2289*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "avx", true);
2290*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2291*0a6a1f1dSLionel Sambuc   case CK_Westmere:
2292*0a6a1f1dSLionel Sambuc   case CK_Silvermont:
2293*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "aes", true);
2294*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "pclmul", true);
2295*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2296*0a6a1f1dSLionel Sambuc   case CK_Nehalem:
2297*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "sse4.2", true);
2298f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "cx16", true);
2299f4a2713aSLionel Sambuc     break;
2300f4a2713aSLionel Sambuc   case CK_KNL:
2301f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "avx512f", true);
2302f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "avx512cd", true);
2303f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "avx512er", true);
2304f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "avx512pf", true);
2305*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "rdseed", true);
2306*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "adx", true);
2307f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "lzcnt", true);
2308f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "bmi", true);
2309f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "bmi2", true);
2310f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "rtm", true);
2311f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "fma", true);
2312*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "rdrnd", true);
2313*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "f16c", true);
2314*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "fsgsbase", true);
2315*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "aes", true);
2316*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "pclmul", true);
2317*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "cx16", true);
2318f4a2713aSLionel Sambuc     break;
2319f4a2713aSLionel Sambuc   case CK_K6_2:
2320f4a2713aSLionel Sambuc   case CK_K6_3:
2321f4a2713aSLionel Sambuc   case CK_WinChip2:
2322f4a2713aSLionel Sambuc   case CK_C3:
2323f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "3dnow", true);
2324f4a2713aSLionel Sambuc     break;
2325f4a2713aSLionel Sambuc   case CK_Athlon:
2326f4a2713aSLionel Sambuc   case CK_AthlonThunderbird:
2327f4a2713aSLionel Sambuc   case CK_Geode:
2328f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "3dnowa", true);
2329f4a2713aSLionel Sambuc     break;
2330f4a2713aSLionel Sambuc   case CK_Athlon4:
2331f4a2713aSLionel Sambuc   case CK_AthlonXP:
2332f4a2713aSLionel Sambuc   case CK_AthlonMP:
2333f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "sse", true);
2334f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "3dnowa", true);
2335f4a2713aSLionel Sambuc     break;
2336f4a2713aSLionel Sambuc   case CK_K8:
2337f4a2713aSLionel Sambuc   case CK_Opteron:
2338f4a2713aSLionel Sambuc   case CK_Athlon64:
2339f4a2713aSLionel Sambuc   case CK_AthlonFX:
2340f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "sse2", true);
2341f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "3dnowa", true);
2342f4a2713aSLionel Sambuc     break;
2343*0a6a1f1dSLionel Sambuc   case CK_AMDFAM10:
2344*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "sse4a", true);
2345*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "lzcnt", true);
2346*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "popcnt", true);
2347*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2348f4a2713aSLionel Sambuc   case CK_K8SSE3:
2349f4a2713aSLionel Sambuc   case CK_OpteronSSE3:
2350f4a2713aSLionel Sambuc   case CK_Athlon64SSE3:
2351f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "sse3", true);
2352f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "3dnowa", true);
2353f4a2713aSLionel Sambuc     break;
2354*0a6a1f1dSLionel Sambuc   case CK_BTVER2:
2355*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "avx", true);
2356*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "aes", true);
2357*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "pclmul", true);
2358*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "bmi", true);
2359*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "f16c", true);
2360*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2361f4a2713aSLionel Sambuc   case CK_BTVER1:
2362f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "ssse3", true);
2363f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "sse4a", true);
2364f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "lzcnt", true);
2365f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "popcnt", true);
2366f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "prfchw", true);
2367f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "cx16", true);
2368f4a2713aSLionel Sambuc     break;
2369*0a6a1f1dSLionel Sambuc   case CK_BDVER4:
2370*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "avx2", true);
2371*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "bmi2", true);
2372*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2373f4a2713aSLionel Sambuc   case CK_BDVER3:
2374*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "fsgsbase", true);
2375*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2376*0a6a1f1dSLionel Sambuc   case CK_BDVER2:
2377f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "bmi", true);
2378f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "fma", true);
2379f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "f16c", true);
2380f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "tbm", true);
2381*0a6a1f1dSLionel Sambuc     // FALLTHROUGH
2382*0a6a1f1dSLionel Sambuc   case CK_BDVER1:
2383*0a6a1f1dSLionel Sambuc     // xop implies avx, sse4a and fma4.
2384*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "xop", true);
2385*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "lzcnt", true);
2386*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "aes", true);
2387*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "pclmul", true);
2388*0a6a1f1dSLionel Sambuc     setFeatureEnabledImpl(Features, "prfchw", true);
2389f4a2713aSLionel Sambuc     setFeatureEnabledImpl(Features, "cx16", true);
2390f4a2713aSLionel Sambuc     break;
2391f4a2713aSLionel Sambuc   }
2392f4a2713aSLionel Sambuc }
2393f4a2713aSLionel Sambuc 
setSSELevel(llvm::StringMap<bool> & Features,X86SSEEnum Level,bool Enabled)2394f4a2713aSLionel Sambuc void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
2395f4a2713aSLionel Sambuc                                 X86SSEEnum Level, bool Enabled) {
2396f4a2713aSLionel Sambuc   if (Enabled) {
2397f4a2713aSLionel Sambuc     switch (Level) {
2398f4a2713aSLionel Sambuc     case AVX512F:
2399f4a2713aSLionel Sambuc       Features["avx512f"] = true;
2400f4a2713aSLionel Sambuc     case AVX2:
2401f4a2713aSLionel Sambuc       Features["avx2"] = true;
2402f4a2713aSLionel Sambuc     case AVX:
2403f4a2713aSLionel Sambuc       Features["avx"] = true;
2404f4a2713aSLionel Sambuc     case SSE42:
2405f4a2713aSLionel Sambuc       Features["sse4.2"] = true;
2406f4a2713aSLionel Sambuc     case SSE41:
2407f4a2713aSLionel Sambuc       Features["sse4.1"] = true;
2408f4a2713aSLionel Sambuc     case SSSE3:
2409f4a2713aSLionel Sambuc       Features["ssse3"] = true;
2410f4a2713aSLionel Sambuc     case SSE3:
2411f4a2713aSLionel Sambuc       Features["sse3"] = true;
2412f4a2713aSLionel Sambuc     case SSE2:
2413f4a2713aSLionel Sambuc       Features["sse2"] = true;
2414f4a2713aSLionel Sambuc     case SSE1:
2415f4a2713aSLionel Sambuc       Features["sse"] = true;
2416f4a2713aSLionel Sambuc     case NoSSE:
2417f4a2713aSLionel Sambuc       break;
2418f4a2713aSLionel Sambuc     }
2419f4a2713aSLionel Sambuc     return;
2420f4a2713aSLionel Sambuc   }
2421f4a2713aSLionel Sambuc 
2422f4a2713aSLionel Sambuc   switch (Level) {
2423f4a2713aSLionel Sambuc   case NoSSE:
2424f4a2713aSLionel Sambuc   case SSE1:
2425f4a2713aSLionel Sambuc     Features["sse"] = false;
2426f4a2713aSLionel Sambuc   case SSE2:
2427f4a2713aSLionel Sambuc     Features["sse2"] = Features["pclmul"] = Features["aes"] =
2428f4a2713aSLionel Sambuc       Features["sha"] = false;
2429f4a2713aSLionel Sambuc   case SSE3:
2430f4a2713aSLionel Sambuc     Features["sse3"] = false;
2431f4a2713aSLionel Sambuc     setXOPLevel(Features, NoXOP, false);
2432f4a2713aSLionel Sambuc   case SSSE3:
2433f4a2713aSLionel Sambuc     Features["ssse3"] = false;
2434f4a2713aSLionel Sambuc   case SSE41:
2435f4a2713aSLionel Sambuc     Features["sse4.1"] = false;
2436f4a2713aSLionel Sambuc   case SSE42:
2437f4a2713aSLionel Sambuc     Features["sse4.2"] = false;
2438f4a2713aSLionel Sambuc   case AVX:
2439f4a2713aSLionel Sambuc     Features["fma"] = Features["avx"] = Features["f16c"] = false;
2440f4a2713aSLionel Sambuc     setXOPLevel(Features, FMA4, false);
2441f4a2713aSLionel Sambuc   case AVX2:
2442f4a2713aSLionel Sambuc     Features["avx2"] = false;
2443f4a2713aSLionel Sambuc   case AVX512F:
2444f4a2713aSLionel Sambuc     Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] =
2445*0a6a1f1dSLionel Sambuc       Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] =
2446*0a6a1f1dSLionel Sambuc       Features["avx512vl"] = false;
2447f4a2713aSLionel Sambuc   }
2448f4a2713aSLionel Sambuc }
2449f4a2713aSLionel Sambuc 
setMMXLevel(llvm::StringMap<bool> & Features,MMX3DNowEnum Level,bool Enabled)2450f4a2713aSLionel Sambuc void X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features,
2451f4a2713aSLionel Sambuc                                 MMX3DNowEnum Level, bool Enabled) {
2452f4a2713aSLionel Sambuc   if (Enabled) {
2453f4a2713aSLionel Sambuc     switch (Level) {
2454f4a2713aSLionel Sambuc     case AMD3DNowAthlon:
2455f4a2713aSLionel Sambuc       Features["3dnowa"] = true;
2456f4a2713aSLionel Sambuc     case AMD3DNow:
2457f4a2713aSLionel Sambuc       Features["3dnow"] = true;
2458f4a2713aSLionel Sambuc     case MMX:
2459f4a2713aSLionel Sambuc       Features["mmx"] = true;
2460f4a2713aSLionel Sambuc     case NoMMX3DNow:
2461f4a2713aSLionel Sambuc       break;
2462f4a2713aSLionel Sambuc     }
2463f4a2713aSLionel Sambuc     return;
2464f4a2713aSLionel Sambuc   }
2465f4a2713aSLionel Sambuc 
2466f4a2713aSLionel Sambuc   switch (Level) {
2467f4a2713aSLionel Sambuc   case NoMMX3DNow:
2468f4a2713aSLionel Sambuc   case MMX:
2469f4a2713aSLionel Sambuc     Features["mmx"] = false;
2470f4a2713aSLionel Sambuc   case AMD3DNow:
2471f4a2713aSLionel Sambuc     Features["3dnow"] = false;
2472f4a2713aSLionel Sambuc   case AMD3DNowAthlon:
2473f4a2713aSLionel Sambuc     Features["3dnowa"] = false;
2474f4a2713aSLionel Sambuc   }
2475f4a2713aSLionel Sambuc }
2476f4a2713aSLionel Sambuc 
setXOPLevel(llvm::StringMap<bool> & Features,XOPEnum Level,bool Enabled)2477f4a2713aSLionel Sambuc void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
2478f4a2713aSLionel Sambuc                                 bool Enabled) {
2479f4a2713aSLionel Sambuc   if (Enabled) {
2480f4a2713aSLionel Sambuc     switch (Level) {
2481f4a2713aSLionel Sambuc     case XOP:
2482f4a2713aSLionel Sambuc       Features["xop"] = true;
2483f4a2713aSLionel Sambuc     case FMA4:
2484f4a2713aSLionel Sambuc       Features["fma4"] = true;
2485f4a2713aSLionel Sambuc       setSSELevel(Features, AVX, true);
2486f4a2713aSLionel Sambuc     case SSE4A:
2487f4a2713aSLionel Sambuc       Features["sse4a"] = true;
2488f4a2713aSLionel Sambuc       setSSELevel(Features, SSE3, true);
2489f4a2713aSLionel Sambuc     case NoXOP:
2490f4a2713aSLionel Sambuc       break;
2491f4a2713aSLionel Sambuc     }
2492f4a2713aSLionel Sambuc     return;
2493f4a2713aSLionel Sambuc   }
2494f4a2713aSLionel Sambuc 
2495f4a2713aSLionel Sambuc   switch (Level) {
2496f4a2713aSLionel Sambuc   case NoXOP:
2497f4a2713aSLionel Sambuc   case SSE4A:
2498f4a2713aSLionel Sambuc     Features["sse4a"] = false;
2499f4a2713aSLionel Sambuc   case FMA4:
2500f4a2713aSLionel Sambuc     Features["fma4"] = false;
2501f4a2713aSLionel Sambuc   case XOP:
2502f4a2713aSLionel Sambuc     Features["xop"] = false;
2503f4a2713aSLionel Sambuc   }
2504f4a2713aSLionel Sambuc }
2505f4a2713aSLionel Sambuc 
setFeatureEnabledImpl(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled)2506f4a2713aSLionel Sambuc void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
2507f4a2713aSLionel Sambuc                                           StringRef Name, bool Enabled) {
2508f4a2713aSLionel Sambuc   // FIXME: This *really* should not be here.  We need some way of translating
2509f4a2713aSLionel Sambuc   // options into llvm subtarget features.
2510f4a2713aSLionel Sambuc   if (Name == "sse4")
2511f4a2713aSLionel Sambuc     Name = "sse4.2";
2512f4a2713aSLionel Sambuc 
2513f4a2713aSLionel Sambuc   Features[Name] = Enabled;
2514f4a2713aSLionel Sambuc 
2515f4a2713aSLionel Sambuc   if (Name == "mmx") {
2516f4a2713aSLionel Sambuc     setMMXLevel(Features, MMX, Enabled);
2517f4a2713aSLionel Sambuc   } else if (Name == "sse") {
2518f4a2713aSLionel Sambuc     setSSELevel(Features, SSE1, Enabled);
2519f4a2713aSLionel Sambuc   } else if (Name == "sse2") {
2520f4a2713aSLionel Sambuc     setSSELevel(Features, SSE2, Enabled);
2521f4a2713aSLionel Sambuc   } else if (Name == "sse3") {
2522f4a2713aSLionel Sambuc     setSSELevel(Features, SSE3, Enabled);
2523f4a2713aSLionel Sambuc   } else if (Name == "ssse3") {
2524f4a2713aSLionel Sambuc     setSSELevel(Features, SSSE3, Enabled);
2525f4a2713aSLionel Sambuc   } else if (Name == "sse4.2") {
2526f4a2713aSLionel Sambuc     setSSELevel(Features, SSE42, Enabled);
2527f4a2713aSLionel Sambuc   } else if (Name == "sse4.1") {
2528f4a2713aSLionel Sambuc     setSSELevel(Features, SSE41, Enabled);
2529f4a2713aSLionel Sambuc   } else if (Name == "3dnow") {
2530f4a2713aSLionel Sambuc     setMMXLevel(Features, AMD3DNow, Enabled);
2531f4a2713aSLionel Sambuc   } else if (Name == "3dnowa") {
2532f4a2713aSLionel Sambuc     setMMXLevel(Features, AMD3DNowAthlon, Enabled);
2533f4a2713aSLionel Sambuc   } else if (Name == "aes") {
2534f4a2713aSLionel Sambuc     if (Enabled)
2535f4a2713aSLionel Sambuc       setSSELevel(Features, SSE2, Enabled);
2536f4a2713aSLionel Sambuc   } else if (Name == "pclmul") {
2537f4a2713aSLionel Sambuc     if (Enabled)
2538f4a2713aSLionel Sambuc       setSSELevel(Features, SSE2, Enabled);
2539f4a2713aSLionel Sambuc   } else if (Name == "avx") {
2540f4a2713aSLionel Sambuc     setSSELevel(Features, AVX, Enabled);
2541f4a2713aSLionel Sambuc   } else if (Name == "avx2") {
2542f4a2713aSLionel Sambuc     setSSELevel(Features, AVX2, Enabled);
2543f4a2713aSLionel Sambuc   } else if (Name == "avx512f") {
2544f4a2713aSLionel Sambuc     setSSELevel(Features, AVX512F, Enabled);
2545*0a6a1f1dSLionel Sambuc   } else if (Name == "avx512cd" || Name == "avx512er" || Name == "avx512pf"
2546*0a6a1f1dSLionel Sambuc           || Name == "avx512dq" || Name == "avx512bw" || Name == "avx512vl") {
2547f4a2713aSLionel Sambuc     if (Enabled)
2548f4a2713aSLionel Sambuc       setSSELevel(Features, AVX512F, Enabled);
2549f4a2713aSLionel Sambuc   } else if (Name == "fma") {
2550f4a2713aSLionel Sambuc     if (Enabled)
2551f4a2713aSLionel Sambuc       setSSELevel(Features, AVX, Enabled);
2552f4a2713aSLionel Sambuc   } else if (Name == "fma4") {
2553f4a2713aSLionel Sambuc     setXOPLevel(Features, FMA4, Enabled);
2554f4a2713aSLionel Sambuc   } else if (Name == "xop") {
2555f4a2713aSLionel Sambuc     setXOPLevel(Features, XOP, Enabled);
2556f4a2713aSLionel Sambuc   } else if (Name == "sse4a") {
2557f4a2713aSLionel Sambuc     setXOPLevel(Features, SSE4A, Enabled);
2558f4a2713aSLionel Sambuc   } else if (Name == "f16c") {
2559f4a2713aSLionel Sambuc     if (Enabled)
2560f4a2713aSLionel Sambuc       setSSELevel(Features, AVX, Enabled);
2561f4a2713aSLionel Sambuc   } else if (Name == "sha") {
2562f4a2713aSLionel Sambuc     if (Enabled)
2563f4a2713aSLionel Sambuc       setSSELevel(Features, SSE2, Enabled);
2564f4a2713aSLionel Sambuc   }
2565f4a2713aSLionel Sambuc }
2566f4a2713aSLionel Sambuc 
2567f4a2713aSLionel Sambuc /// handleTargetFeatures - Perform initialization based on the user
2568f4a2713aSLionel Sambuc /// configured set of features.
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)2569f4a2713aSLionel Sambuc bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
2570f4a2713aSLionel Sambuc                                          DiagnosticsEngine &Diags) {
2571f4a2713aSLionel Sambuc   // Remember the maximum enabled sselevel.
2572f4a2713aSLionel Sambuc   for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
2573f4a2713aSLionel Sambuc     // Ignore disabled features.
2574f4a2713aSLionel Sambuc     if (Features[i][0] == '-')
2575f4a2713aSLionel Sambuc       continue;
2576f4a2713aSLionel Sambuc 
2577f4a2713aSLionel Sambuc     StringRef Feature = StringRef(Features[i]).substr(1);
2578f4a2713aSLionel Sambuc 
2579f4a2713aSLionel Sambuc     if (Feature == "aes") {
2580f4a2713aSLionel Sambuc       HasAES = true;
2581f4a2713aSLionel Sambuc       continue;
2582f4a2713aSLionel Sambuc     }
2583f4a2713aSLionel Sambuc 
2584f4a2713aSLionel Sambuc     if (Feature == "pclmul") {
2585f4a2713aSLionel Sambuc       HasPCLMUL = true;
2586f4a2713aSLionel Sambuc       continue;
2587f4a2713aSLionel Sambuc     }
2588f4a2713aSLionel Sambuc 
2589f4a2713aSLionel Sambuc     if (Feature == "lzcnt") {
2590f4a2713aSLionel Sambuc       HasLZCNT = true;
2591f4a2713aSLionel Sambuc       continue;
2592f4a2713aSLionel Sambuc     }
2593f4a2713aSLionel Sambuc 
2594f4a2713aSLionel Sambuc     if (Feature == "rdrnd") {
2595f4a2713aSLionel Sambuc       HasRDRND = true;
2596f4a2713aSLionel Sambuc       continue;
2597f4a2713aSLionel Sambuc     }
2598f4a2713aSLionel Sambuc 
2599*0a6a1f1dSLionel Sambuc     if (Feature == "fsgsbase") {
2600*0a6a1f1dSLionel Sambuc       HasFSGSBASE = true;
2601*0a6a1f1dSLionel Sambuc       continue;
2602*0a6a1f1dSLionel Sambuc     }
2603*0a6a1f1dSLionel Sambuc 
2604f4a2713aSLionel Sambuc     if (Feature == "bmi") {
2605f4a2713aSLionel Sambuc       HasBMI = true;
2606f4a2713aSLionel Sambuc       continue;
2607f4a2713aSLionel Sambuc     }
2608f4a2713aSLionel Sambuc 
2609f4a2713aSLionel Sambuc     if (Feature == "bmi2") {
2610f4a2713aSLionel Sambuc       HasBMI2 = true;
2611f4a2713aSLionel Sambuc       continue;
2612f4a2713aSLionel Sambuc     }
2613f4a2713aSLionel Sambuc 
2614f4a2713aSLionel Sambuc     if (Feature == "popcnt") {
2615f4a2713aSLionel Sambuc       HasPOPCNT = true;
2616f4a2713aSLionel Sambuc       continue;
2617f4a2713aSLionel Sambuc     }
2618f4a2713aSLionel Sambuc 
2619f4a2713aSLionel Sambuc     if (Feature == "rtm") {
2620f4a2713aSLionel Sambuc       HasRTM = true;
2621f4a2713aSLionel Sambuc       continue;
2622f4a2713aSLionel Sambuc     }
2623f4a2713aSLionel Sambuc 
2624f4a2713aSLionel Sambuc     if (Feature == "prfchw") {
2625f4a2713aSLionel Sambuc       HasPRFCHW = true;
2626f4a2713aSLionel Sambuc       continue;
2627f4a2713aSLionel Sambuc     }
2628f4a2713aSLionel Sambuc 
2629f4a2713aSLionel Sambuc     if (Feature == "rdseed") {
2630f4a2713aSLionel Sambuc       HasRDSEED = true;
2631f4a2713aSLionel Sambuc       continue;
2632f4a2713aSLionel Sambuc     }
2633f4a2713aSLionel Sambuc 
2634*0a6a1f1dSLionel Sambuc     if (Feature == "adx") {
2635*0a6a1f1dSLionel Sambuc       HasADX = true;
2636*0a6a1f1dSLionel Sambuc       continue;
2637*0a6a1f1dSLionel Sambuc     }
2638*0a6a1f1dSLionel Sambuc 
2639f4a2713aSLionel Sambuc     if (Feature == "tbm") {
2640f4a2713aSLionel Sambuc       HasTBM = true;
2641f4a2713aSLionel Sambuc       continue;
2642f4a2713aSLionel Sambuc     }
2643f4a2713aSLionel Sambuc 
2644f4a2713aSLionel Sambuc     if (Feature == "fma") {
2645f4a2713aSLionel Sambuc       HasFMA = true;
2646f4a2713aSLionel Sambuc       continue;
2647f4a2713aSLionel Sambuc     }
2648f4a2713aSLionel Sambuc 
2649f4a2713aSLionel Sambuc     if (Feature == "f16c") {
2650f4a2713aSLionel Sambuc       HasF16C = true;
2651f4a2713aSLionel Sambuc       continue;
2652f4a2713aSLionel Sambuc     }
2653f4a2713aSLionel Sambuc 
2654f4a2713aSLionel Sambuc     if (Feature == "avx512cd") {
2655f4a2713aSLionel Sambuc       HasAVX512CD = true;
2656f4a2713aSLionel Sambuc       continue;
2657f4a2713aSLionel Sambuc     }
2658f4a2713aSLionel Sambuc 
2659f4a2713aSLionel Sambuc     if (Feature == "avx512er") {
2660f4a2713aSLionel Sambuc       HasAVX512ER = true;
2661f4a2713aSLionel Sambuc       continue;
2662f4a2713aSLionel Sambuc     }
2663f4a2713aSLionel Sambuc 
2664f4a2713aSLionel Sambuc     if (Feature == "avx512pf") {
2665f4a2713aSLionel Sambuc       HasAVX512PF = true;
2666f4a2713aSLionel Sambuc       continue;
2667f4a2713aSLionel Sambuc     }
2668f4a2713aSLionel Sambuc 
2669*0a6a1f1dSLionel Sambuc     if (Feature == "avx512dq") {
2670*0a6a1f1dSLionel Sambuc       HasAVX512DQ = true;
2671*0a6a1f1dSLionel Sambuc       continue;
2672*0a6a1f1dSLionel Sambuc     }
2673*0a6a1f1dSLionel Sambuc 
2674*0a6a1f1dSLionel Sambuc     if (Feature == "avx512bw") {
2675*0a6a1f1dSLionel Sambuc       HasAVX512BW = true;
2676*0a6a1f1dSLionel Sambuc       continue;
2677*0a6a1f1dSLionel Sambuc     }
2678*0a6a1f1dSLionel Sambuc 
2679*0a6a1f1dSLionel Sambuc     if (Feature == "avx512vl") {
2680*0a6a1f1dSLionel Sambuc       HasAVX512VL = true;
2681*0a6a1f1dSLionel Sambuc       continue;
2682*0a6a1f1dSLionel Sambuc     }
2683*0a6a1f1dSLionel Sambuc 
2684f4a2713aSLionel Sambuc     if (Feature == "sha") {
2685f4a2713aSLionel Sambuc       HasSHA = true;
2686f4a2713aSLionel Sambuc       continue;
2687f4a2713aSLionel Sambuc     }
2688f4a2713aSLionel Sambuc 
2689f4a2713aSLionel Sambuc     if (Feature == "cx16") {
2690f4a2713aSLionel Sambuc       HasCX16 = true;
2691f4a2713aSLionel Sambuc       continue;
2692f4a2713aSLionel Sambuc     }
2693f4a2713aSLionel Sambuc 
2694f4a2713aSLionel Sambuc     assert(Features[i][0] == '+' && "Invalid target feature!");
2695f4a2713aSLionel Sambuc     X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
2696f4a2713aSLionel Sambuc       .Case("avx512f", AVX512F)
2697f4a2713aSLionel Sambuc       .Case("avx2", AVX2)
2698f4a2713aSLionel Sambuc       .Case("avx", AVX)
2699f4a2713aSLionel Sambuc       .Case("sse4.2", SSE42)
2700f4a2713aSLionel Sambuc       .Case("sse4.1", SSE41)
2701f4a2713aSLionel Sambuc       .Case("ssse3", SSSE3)
2702f4a2713aSLionel Sambuc       .Case("sse3", SSE3)
2703f4a2713aSLionel Sambuc       .Case("sse2", SSE2)
2704f4a2713aSLionel Sambuc       .Case("sse", SSE1)
2705f4a2713aSLionel Sambuc       .Default(NoSSE);
2706f4a2713aSLionel Sambuc     SSELevel = std::max(SSELevel, Level);
2707f4a2713aSLionel Sambuc 
2708f4a2713aSLionel Sambuc     MMX3DNowEnum ThreeDNowLevel =
2709f4a2713aSLionel Sambuc       llvm::StringSwitch<MMX3DNowEnum>(Feature)
2710f4a2713aSLionel Sambuc         .Case("3dnowa", AMD3DNowAthlon)
2711f4a2713aSLionel Sambuc         .Case("3dnow", AMD3DNow)
2712f4a2713aSLionel Sambuc         .Case("mmx", MMX)
2713f4a2713aSLionel Sambuc         .Default(NoMMX3DNow);
2714f4a2713aSLionel Sambuc     MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
2715f4a2713aSLionel Sambuc 
2716f4a2713aSLionel Sambuc     XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
2717f4a2713aSLionel Sambuc         .Case("xop", XOP)
2718f4a2713aSLionel Sambuc         .Case("fma4", FMA4)
2719f4a2713aSLionel Sambuc         .Case("sse4a", SSE4A)
2720f4a2713aSLionel Sambuc         .Default(NoXOP);
2721f4a2713aSLionel Sambuc     XOPLevel = std::max(XOPLevel, XLevel);
2722f4a2713aSLionel Sambuc   }
2723f4a2713aSLionel Sambuc 
2724f4a2713aSLionel Sambuc   // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
2725f4a2713aSLionel Sambuc   // Can't do this earlier because we need to be able to explicitly enable
2726f4a2713aSLionel Sambuc   // popcnt and still disable sse4.2.
2727f4a2713aSLionel Sambuc   if (!HasPOPCNT && SSELevel >= SSE42 &&
2728f4a2713aSLionel Sambuc       std::find(Features.begin(), Features.end(), "-popcnt") == Features.end()){
2729f4a2713aSLionel Sambuc     HasPOPCNT = true;
2730f4a2713aSLionel Sambuc     Features.push_back("+popcnt");
2731f4a2713aSLionel Sambuc   }
2732f4a2713aSLionel Sambuc 
2733f4a2713aSLionel Sambuc   // Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled.
2734f4a2713aSLionel Sambuc   if (!HasPRFCHW && MMX3DNowLevel >= AMD3DNow &&
2735f4a2713aSLionel Sambuc       std::find(Features.begin(), Features.end(), "-prfchw") == Features.end()){
2736f4a2713aSLionel Sambuc     HasPRFCHW = true;
2737f4a2713aSLionel Sambuc     Features.push_back("+prfchw");
2738f4a2713aSLionel Sambuc   }
2739f4a2713aSLionel Sambuc 
2740f4a2713aSLionel Sambuc   // LLVM doesn't have a separate switch for fpmath, so only accept it if it
2741f4a2713aSLionel Sambuc   // matches the selected sse level.
2742f4a2713aSLionel Sambuc   if (FPMath == FP_SSE && SSELevel < SSE1) {
2743f4a2713aSLionel Sambuc     Diags.Report(diag::err_target_unsupported_fpmath) << "sse";
2744f4a2713aSLionel Sambuc     return false;
2745f4a2713aSLionel Sambuc   } else if (FPMath == FP_387 && SSELevel >= SSE1) {
2746f4a2713aSLionel Sambuc     Diags.Report(diag::err_target_unsupported_fpmath) << "387";
2747f4a2713aSLionel Sambuc     return false;
2748f4a2713aSLionel Sambuc   }
2749f4a2713aSLionel Sambuc 
2750f4a2713aSLionel Sambuc   // Don't tell the backend if we're turning off mmx; it will end up disabling
2751f4a2713aSLionel Sambuc   // SSE, which we don't want.
2752f4a2713aSLionel Sambuc   // Additionally, if SSE is enabled and mmx is not explicitly disabled,
2753f4a2713aSLionel Sambuc   // then enable MMX.
2754f4a2713aSLionel Sambuc   std::vector<std::string>::iterator it;
2755f4a2713aSLionel Sambuc   it = std::find(Features.begin(), Features.end(), "-mmx");
2756f4a2713aSLionel Sambuc   if (it != Features.end())
2757f4a2713aSLionel Sambuc     Features.erase(it);
2758f4a2713aSLionel Sambuc   else if (SSELevel > NoSSE)
2759f4a2713aSLionel Sambuc     MMX3DNowLevel = std::max(MMX3DNowLevel, MMX);
2760f4a2713aSLionel Sambuc   return true;
2761f4a2713aSLionel Sambuc }
2762f4a2713aSLionel Sambuc 
2763f4a2713aSLionel Sambuc /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
2764f4a2713aSLionel Sambuc /// definitions for this particular subtarget.
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const2765f4a2713aSLionel Sambuc void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
2766f4a2713aSLionel Sambuc                                      MacroBuilder &Builder) const {
2767f4a2713aSLionel Sambuc   // Target identification.
2768f4a2713aSLionel Sambuc   if (getTriple().getArch() == llvm::Triple::x86_64) {
2769f4a2713aSLionel Sambuc     Builder.defineMacro("__amd64__");
2770f4a2713aSLionel Sambuc     Builder.defineMacro("__amd64");
2771f4a2713aSLionel Sambuc     Builder.defineMacro("__x86_64");
2772f4a2713aSLionel Sambuc     Builder.defineMacro("__x86_64__");
2773*0a6a1f1dSLionel Sambuc     if (getTriple().getArchName() == "x86_64h") {
2774*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__x86_64h");
2775*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__x86_64h__");
2776*0a6a1f1dSLionel Sambuc     }
2777f4a2713aSLionel Sambuc   } else {
2778f4a2713aSLionel Sambuc     DefineStd(Builder, "i386", Opts);
2779f4a2713aSLionel Sambuc   }
2780f4a2713aSLionel Sambuc 
2781f4a2713aSLionel Sambuc   // Subtarget options.
2782f4a2713aSLionel Sambuc   // FIXME: We are hard-coding the tune parameters based on the CPU, but they
2783f4a2713aSLionel Sambuc   // truly should be based on -mtune options.
2784f4a2713aSLionel Sambuc   switch (CPU) {
2785f4a2713aSLionel Sambuc   case CK_Generic:
2786f4a2713aSLionel Sambuc     break;
2787f4a2713aSLionel Sambuc   case CK_i386:
2788f4a2713aSLionel Sambuc     // The rest are coming from the i386 define above.
2789f4a2713aSLionel Sambuc     Builder.defineMacro("__tune_i386__");
2790f4a2713aSLionel Sambuc     break;
2791f4a2713aSLionel Sambuc   case CK_i486:
2792f4a2713aSLionel Sambuc   case CK_WinChipC6:
2793f4a2713aSLionel Sambuc   case CK_WinChip2:
2794f4a2713aSLionel Sambuc   case CK_C3:
2795f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "i486");
2796f4a2713aSLionel Sambuc     break;
2797f4a2713aSLionel Sambuc   case CK_PentiumMMX:
2798f4a2713aSLionel Sambuc     Builder.defineMacro("__pentium_mmx__");
2799f4a2713aSLionel Sambuc     Builder.defineMacro("__tune_pentium_mmx__");
2800f4a2713aSLionel Sambuc     // Fallthrough
2801f4a2713aSLionel Sambuc   case CK_i586:
2802f4a2713aSLionel Sambuc   case CK_Pentium:
2803f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "i586");
2804f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "pentium");
2805f4a2713aSLionel Sambuc     break;
2806f4a2713aSLionel Sambuc   case CK_Pentium3:
2807f4a2713aSLionel Sambuc   case CK_Pentium3M:
2808f4a2713aSLionel Sambuc   case CK_PentiumM:
2809f4a2713aSLionel Sambuc     Builder.defineMacro("__tune_pentium3__");
2810f4a2713aSLionel Sambuc     // Fallthrough
2811f4a2713aSLionel Sambuc   case CK_Pentium2:
2812f4a2713aSLionel Sambuc   case CK_C3_2:
2813f4a2713aSLionel Sambuc     Builder.defineMacro("__tune_pentium2__");
2814f4a2713aSLionel Sambuc     // Fallthrough
2815f4a2713aSLionel Sambuc   case CK_PentiumPro:
2816f4a2713aSLionel Sambuc     Builder.defineMacro("__tune_i686__");
2817f4a2713aSLionel Sambuc     Builder.defineMacro("__tune_pentiumpro__");
2818f4a2713aSLionel Sambuc     // Fallthrough
2819f4a2713aSLionel Sambuc   case CK_i686:
2820f4a2713aSLionel Sambuc     Builder.defineMacro("__i686");
2821f4a2713aSLionel Sambuc     Builder.defineMacro("__i686__");
2822f4a2713aSLionel Sambuc     // Strangely, __tune_i686__ isn't defined by GCC when CPU == i686.
2823f4a2713aSLionel Sambuc     Builder.defineMacro("__pentiumpro");
2824f4a2713aSLionel Sambuc     Builder.defineMacro("__pentiumpro__");
2825f4a2713aSLionel Sambuc     break;
2826f4a2713aSLionel Sambuc   case CK_Pentium4:
2827f4a2713aSLionel Sambuc   case CK_Pentium4M:
2828f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "pentium4");
2829f4a2713aSLionel Sambuc     break;
2830f4a2713aSLionel Sambuc   case CK_Yonah:
2831f4a2713aSLionel Sambuc   case CK_Prescott:
2832f4a2713aSLionel Sambuc   case CK_Nocona:
2833f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "nocona");
2834f4a2713aSLionel Sambuc     break;
2835f4a2713aSLionel Sambuc   case CK_Core2:
2836f4a2713aSLionel Sambuc   case CK_Penryn:
2837f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "core2");
2838f4a2713aSLionel Sambuc     break;
2839*0a6a1f1dSLionel Sambuc   case CK_Bonnell:
2840f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "atom");
2841f4a2713aSLionel Sambuc     break;
2842f4a2713aSLionel Sambuc   case CK_Silvermont:
2843f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "slm");
2844f4a2713aSLionel Sambuc     break;
2845*0a6a1f1dSLionel Sambuc   case CK_Nehalem:
2846*0a6a1f1dSLionel Sambuc   case CK_Westmere:
2847*0a6a1f1dSLionel Sambuc   case CK_SandyBridge:
2848*0a6a1f1dSLionel Sambuc   case CK_IvyBridge:
2849*0a6a1f1dSLionel Sambuc   case CK_Haswell:
2850*0a6a1f1dSLionel Sambuc   case CK_Broadwell:
2851*0a6a1f1dSLionel Sambuc     // FIXME: Historically, we defined this legacy name, it would be nice to
2852*0a6a1f1dSLionel Sambuc     // remove it at some point. We've never exposed fine-grained names for
2853*0a6a1f1dSLionel Sambuc     // recent primary x86 CPUs, and we should keep it that way.
2854f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "corei7");
2855f4a2713aSLionel Sambuc     break;
2856*0a6a1f1dSLionel Sambuc   case CK_Skylake:
2857*0a6a1f1dSLionel Sambuc     // FIXME: Historically, we defined this legacy name, it would be nice to
2858*0a6a1f1dSLionel Sambuc     // remove it at some point. This is the only fine-grained CPU macro in the
2859*0a6a1f1dSLionel Sambuc     // main intel CPU line, and it would be better to not have these and force
2860*0a6a1f1dSLionel Sambuc     // people to use ISA macros.
2861*0a6a1f1dSLionel Sambuc     defineCPUMacros(Builder, "skx");
2862*0a6a1f1dSLionel Sambuc     break;
2863f4a2713aSLionel Sambuc   case CK_KNL:
2864f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "knl");
2865f4a2713aSLionel Sambuc     break;
2866f4a2713aSLionel Sambuc   case CK_K6_2:
2867f4a2713aSLionel Sambuc     Builder.defineMacro("__k6_2__");
2868f4a2713aSLionel Sambuc     Builder.defineMacro("__tune_k6_2__");
2869f4a2713aSLionel Sambuc     // Fallthrough
2870f4a2713aSLionel Sambuc   case CK_K6_3:
2871f4a2713aSLionel Sambuc     if (CPU != CK_K6_2) {  // In case of fallthrough
2872f4a2713aSLionel Sambuc       // FIXME: GCC may be enabling these in cases where some other k6
2873f4a2713aSLionel Sambuc       // architecture is specified but -m3dnow is explicitly provided. The
2874f4a2713aSLionel Sambuc       // exact semantics need to be determined and emulated here.
2875f4a2713aSLionel Sambuc       Builder.defineMacro("__k6_3__");
2876f4a2713aSLionel Sambuc       Builder.defineMacro("__tune_k6_3__");
2877f4a2713aSLionel Sambuc     }
2878f4a2713aSLionel Sambuc     // Fallthrough
2879f4a2713aSLionel Sambuc   case CK_K6:
2880f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "k6");
2881f4a2713aSLionel Sambuc     break;
2882f4a2713aSLionel Sambuc   case CK_Athlon:
2883f4a2713aSLionel Sambuc   case CK_AthlonThunderbird:
2884f4a2713aSLionel Sambuc   case CK_Athlon4:
2885f4a2713aSLionel Sambuc   case CK_AthlonXP:
2886f4a2713aSLionel Sambuc   case CK_AthlonMP:
2887f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "athlon");
2888f4a2713aSLionel Sambuc     if (SSELevel != NoSSE) {
2889f4a2713aSLionel Sambuc       Builder.defineMacro("__athlon_sse__");
2890f4a2713aSLionel Sambuc       Builder.defineMacro("__tune_athlon_sse__");
2891f4a2713aSLionel Sambuc     }
2892f4a2713aSLionel Sambuc     break;
2893f4a2713aSLionel Sambuc   case CK_K8:
2894f4a2713aSLionel Sambuc   case CK_K8SSE3:
2895f4a2713aSLionel Sambuc   case CK_x86_64:
2896f4a2713aSLionel Sambuc   case CK_Opteron:
2897f4a2713aSLionel Sambuc   case CK_OpteronSSE3:
2898f4a2713aSLionel Sambuc   case CK_Athlon64:
2899f4a2713aSLionel Sambuc   case CK_Athlon64SSE3:
2900f4a2713aSLionel Sambuc   case CK_AthlonFX:
2901f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "k8");
2902f4a2713aSLionel Sambuc     break;
2903f4a2713aSLionel Sambuc   case CK_AMDFAM10:
2904f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "amdfam10");
2905f4a2713aSLionel Sambuc     break;
2906f4a2713aSLionel Sambuc   case CK_BTVER1:
2907f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "btver1");
2908f4a2713aSLionel Sambuc     break;
2909f4a2713aSLionel Sambuc   case CK_BTVER2:
2910f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "btver2");
2911f4a2713aSLionel Sambuc     break;
2912f4a2713aSLionel Sambuc   case CK_BDVER1:
2913f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "bdver1");
2914f4a2713aSLionel Sambuc     break;
2915f4a2713aSLionel Sambuc   case CK_BDVER2:
2916f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "bdver2");
2917f4a2713aSLionel Sambuc     break;
2918f4a2713aSLionel Sambuc   case CK_BDVER3:
2919f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "bdver3");
2920f4a2713aSLionel Sambuc     break;
2921*0a6a1f1dSLionel Sambuc   case CK_BDVER4:
2922*0a6a1f1dSLionel Sambuc     defineCPUMacros(Builder, "bdver4");
2923*0a6a1f1dSLionel Sambuc     break;
2924f4a2713aSLionel Sambuc   case CK_Geode:
2925f4a2713aSLionel Sambuc     defineCPUMacros(Builder, "geode");
2926f4a2713aSLionel Sambuc     break;
2927f4a2713aSLionel Sambuc   }
2928f4a2713aSLionel Sambuc 
2929f4a2713aSLionel Sambuc   // Target properties.
2930f4a2713aSLionel Sambuc   Builder.defineMacro("__REGISTER_PREFIX__", "");
2931f4a2713aSLionel Sambuc 
2932f4a2713aSLionel Sambuc   // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
2933f4a2713aSLionel Sambuc   // functions in glibc header files that use FP Stack inline asm which the
2934f4a2713aSLionel Sambuc   // backend can't deal with (PR879).
2935f4a2713aSLionel Sambuc   Builder.defineMacro("__NO_MATH_INLINES");
2936f4a2713aSLionel Sambuc 
2937f4a2713aSLionel Sambuc   if (HasAES)
2938f4a2713aSLionel Sambuc     Builder.defineMacro("__AES__");
2939f4a2713aSLionel Sambuc 
2940f4a2713aSLionel Sambuc   if (HasPCLMUL)
2941f4a2713aSLionel Sambuc     Builder.defineMacro("__PCLMUL__");
2942f4a2713aSLionel Sambuc 
2943f4a2713aSLionel Sambuc   if (HasLZCNT)
2944f4a2713aSLionel Sambuc     Builder.defineMacro("__LZCNT__");
2945f4a2713aSLionel Sambuc 
2946f4a2713aSLionel Sambuc   if (HasRDRND)
2947f4a2713aSLionel Sambuc     Builder.defineMacro("__RDRND__");
2948f4a2713aSLionel Sambuc 
2949*0a6a1f1dSLionel Sambuc   if (HasFSGSBASE)
2950*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__FSGSBASE__");
2951*0a6a1f1dSLionel Sambuc 
2952f4a2713aSLionel Sambuc   if (HasBMI)
2953f4a2713aSLionel Sambuc     Builder.defineMacro("__BMI__");
2954f4a2713aSLionel Sambuc 
2955f4a2713aSLionel Sambuc   if (HasBMI2)
2956f4a2713aSLionel Sambuc     Builder.defineMacro("__BMI2__");
2957f4a2713aSLionel Sambuc 
2958f4a2713aSLionel Sambuc   if (HasPOPCNT)
2959f4a2713aSLionel Sambuc     Builder.defineMacro("__POPCNT__");
2960f4a2713aSLionel Sambuc 
2961f4a2713aSLionel Sambuc   if (HasRTM)
2962f4a2713aSLionel Sambuc     Builder.defineMacro("__RTM__");
2963f4a2713aSLionel Sambuc 
2964f4a2713aSLionel Sambuc   if (HasPRFCHW)
2965f4a2713aSLionel Sambuc     Builder.defineMacro("__PRFCHW__");
2966f4a2713aSLionel Sambuc 
2967f4a2713aSLionel Sambuc   if (HasRDSEED)
2968f4a2713aSLionel Sambuc     Builder.defineMacro("__RDSEED__");
2969f4a2713aSLionel Sambuc 
2970*0a6a1f1dSLionel Sambuc   if (HasADX)
2971*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ADX__");
2972*0a6a1f1dSLionel Sambuc 
2973f4a2713aSLionel Sambuc   if (HasTBM)
2974f4a2713aSLionel Sambuc     Builder.defineMacro("__TBM__");
2975f4a2713aSLionel Sambuc 
2976f4a2713aSLionel Sambuc   switch (XOPLevel) {
2977f4a2713aSLionel Sambuc   case XOP:
2978f4a2713aSLionel Sambuc     Builder.defineMacro("__XOP__");
2979f4a2713aSLionel Sambuc   case FMA4:
2980f4a2713aSLionel Sambuc     Builder.defineMacro("__FMA4__");
2981f4a2713aSLionel Sambuc   case SSE4A:
2982f4a2713aSLionel Sambuc     Builder.defineMacro("__SSE4A__");
2983f4a2713aSLionel Sambuc   case NoXOP:
2984f4a2713aSLionel Sambuc     break;
2985f4a2713aSLionel Sambuc   }
2986f4a2713aSLionel Sambuc 
2987f4a2713aSLionel Sambuc   if (HasFMA)
2988f4a2713aSLionel Sambuc     Builder.defineMacro("__FMA__");
2989f4a2713aSLionel Sambuc 
2990f4a2713aSLionel Sambuc   if (HasF16C)
2991f4a2713aSLionel Sambuc     Builder.defineMacro("__F16C__");
2992f4a2713aSLionel Sambuc 
2993f4a2713aSLionel Sambuc   if (HasAVX512CD)
2994f4a2713aSLionel Sambuc     Builder.defineMacro("__AVX512CD__");
2995f4a2713aSLionel Sambuc   if (HasAVX512ER)
2996f4a2713aSLionel Sambuc     Builder.defineMacro("__AVX512ER__");
2997f4a2713aSLionel Sambuc   if (HasAVX512PF)
2998f4a2713aSLionel Sambuc     Builder.defineMacro("__AVX512PF__");
2999*0a6a1f1dSLionel Sambuc   if (HasAVX512DQ)
3000*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__AVX512DQ__");
3001*0a6a1f1dSLionel Sambuc   if (HasAVX512BW)
3002*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__AVX512BW__");
3003*0a6a1f1dSLionel Sambuc   if (HasAVX512VL)
3004*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__AVX512VL__");
3005f4a2713aSLionel Sambuc 
3006f4a2713aSLionel Sambuc   if (HasSHA)
3007f4a2713aSLionel Sambuc     Builder.defineMacro("__SHA__");
3008f4a2713aSLionel Sambuc 
3009f4a2713aSLionel Sambuc   if (HasCX16)
3010f4a2713aSLionel Sambuc     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
3011f4a2713aSLionel Sambuc 
3012f4a2713aSLionel Sambuc   // Each case falls through to the previous one here.
3013f4a2713aSLionel Sambuc   switch (SSELevel) {
3014f4a2713aSLionel Sambuc   case AVX512F:
3015f4a2713aSLionel Sambuc     Builder.defineMacro("__AVX512F__");
3016f4a2713aSLionel Sambuc   case AVX2:
3017f4a2713aSLionel Sambuc     Builder.defineMacro("__AVX2__");
3018f4a2713aSLionel Sambuc   case AVX:
3019f4a2713aSLionel Sambuc     Builder.defineMacro("__AVX__");
3020f4a2713aSLionel Sambuc   case SSE42:
3021f4a2713aSLionel Sambuc     Builder.defineMacro("__SSE4_2__");
3022f4a2713aSLionel Sambuc   case SSE41:
3023f4a2713aSLionel Sambuc     Builder.defineMacro("__SSE4_1__");
3024f4a2713aSLionel Sambuc   case SSSE3:
3025f4a2713aSLionel Sambuc     Builder.defineMacro("__SSSE3__");
3026f4a2713aSLionel Sambuc   case SSE3:
3027f4a2713aSLionel Sambuc     Builder.defineMacro("__SSE3__");
3028f4a2713aSLionel Sambuc   case SSE2:
3029f4a2713aSLionel Sambuc     Builder.defineMacro("__SSE2__");
3030f4a2713aSLionel Sambuc     Builder.defineMacro("__SSE2_MATH__");  // -mfp-math=sse always implied.
3031f4a2713aSLionel Sambuc   case SSE1:
3032f4a2713aSLionel Sambuc     Builder.defineMacro("__SSE__");
3033f4a2713aSLionel Sambuc     Builder.defineMacro("__SSE_MATH__");   // -mfp-math=sse always implied.
3034f4a2713aSLionel Sambuc   case NoSSE:
3035f4a2713aSLionel Sambuc     break;
3036f4a2713aSLionel Sambuc   }
3037f4a2713aSLionel Sambuc 
3038f4a2713aSLionel Sambuc   if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
3039f4a2713aSLionel Sambuc     switch (SSELevel) {
3040f4a2713aSLionel Sambuc     case AVX512F:
3041f4a2713aSLionel Sambuc     case AVX2:
3042f4a2713aSLionel Sambuc     case AVX:
3043f4a2713aSLionel Sambuc     case SSE42:
3044f4a2713aSLionel Sambuc     case SSE41:
3045f4a2713aSLionel Sambuc     case SSSE3:
3046f4a2713aSLionel Sambuc     case SSE3:
3047f4a2713aSLionel Sambuc     case SSE2:
3048f4a2713aSLionel Sambuc       Builder.defineMacro("_M_IX86_FP", Twine(2));
3049f4a2713aSLionel Sambuc       break;
3050f4a2713aSLionel Sambuc     case SSE1:
3051f4a2713aSLionel Sambuc       Builder.defineMacro("_M_IX86_FP", Twine(1));
3052f4a2713aSLionel Sambuc       break;
3053f4a2713aSLionel Sambuc     default:
3054f4a2713aSLionel Sambuc       Builder.defineMacro("_M_IX86_FP", Twine(0));
3055f4a2713aSLionel Sambuc     }
3056f4a2713aSLionel Sambuc   }
3057f4a2713aSLionel Sambuc 
3058f4a2713aSLionel Sambuc   // Each case falls through to the previous one here.
3059f4a2713aSLionel Sambuc   switch (MMX3DNowLevel) {
3060f4a2713aSLionel Sambuc   case AMD3DNowAthlon:
3061f4a2713aSLionel Sambuc     Builder.defineMacro("__3dNOW_A__");
3062f4a2713aSLionel Sambuc   case AMD3DNow:
3063f4a2713aSLionel Sambuc     Builder.defineMacro("__3dNOW__");
3064f4a2713aSLionel Sambuc   case MMX:
3065f4a2713aSLionel Sambuc     Builder.defineMacro("__MMX__");
3066f4a2713aSLionel Sambuc   case NoMMX3DNow:
3067f4a2713aSLionel Sambuc     break;
3068f4a2713aSLionel Sambuc   }
3069f4a2713aSLionel Sambuc 
3070f4a2713aSLionel Sambuc   if (CPU >= CK_i486) {
3071f4a2713aSLionel Sambuc     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
3072f4a2713aSLionel Sambuc     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
3073f4a2713aSLionel Sambuc     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
3074f4a2713aSLionel Sambuc   }
3075f4a2713aSLionel Sambuc   if (CPU >= CK_i586)
3076f4a2713aSLionel Sambuc     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
3077f4a2713aSLionel Sambuc }
3078f4a2713aSLionel Sambuc 
hasFeature(StringRef Feature) const3079f4a2713aSLionel Sambuc bool X86TargetInfo::hasFeature(StringRef Feature) const {
3080f4a2713aSLionel Sambuc   return llvm::StringSwitch<bool>(Feature)
3081f4a2713aSLionel Sambuc       .Case("aes", HasAES)
3082f4a2713aSLionel Sambuc       .Case("avx", SSELevel >= AVX)
3083f4a2713aSLionel Sambuc       .Case("avx2", SSELevel >= AVX2)
3084f4a2713aSLionel Sambuc       .Case("avx512f", SSELevel >= AVX512F)
3085f4a2713aSLionel Sambuc       .Case("avx512cd", HasAVX512CD)
3086f4a2713aSLionel Sambuc       .Case("avx512er", HasAVX512ER)
3087f4a2713aSLionel Sambuc       .Case("avx512pf", HasAVX512PF)
3088*0a6a1f1dSLionel Sambuc       .Case("avx512dq", HasAVX512DQ)
3089*0a6a1f1dSLionel Sambuc       .Case("avx512bw", HasAVX512BW)
3090*0a6a1f1dSLionel Sambuc       .Case("avx512vl", HasAVX512VL)
3091f4a2713aSLionel Sambuc       .Case("bmi", HasBMI)
3092f4a2713aSLionel Sambuc       .Case("bmi2", HasBMI2)
3093f4a2713aSLionel Sambuc       .Case("cx16", HasCX16)
3094f4a2713aSLionel Sambuc       .Case("f16c", HasF16C)
3095f4a2713aSLionel Sambuc       .Case("fma", HasFMA)
3096f4a2713aSLionel Sambuc       .Case("fma4", XOPLevel >= FMA4)
3097*0a6a1f1dSLionel Sambuc       .Case("fsgsbase", HasFSGSBASE)
3098f4a2713aSLionel Sambuc       .Case("lzcnt", HasLZCNT)
3099f4a2713aSLionel Sambuc       .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
3100f4a2713aSLionel Sambuc       .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
3101f4a2713aSLionel Sambuc       .Case("mmx", MMX3DNowLevel >= MMX)
3102f4a2713aSLionel Sambuc       .Case("pclmul", HasPCLMUL)
3103f4a2713aSLionel Sambuc       .Case("popcnt", HasPOPCNT)
3104f4a2713aSLionel Sambuc       .Case("prfchw", HasPRFCHW)
3105*0a6a1f1dSLionel Sambuc       .Case("rdrnd", HasRDRND)
3106f4a2713aSLionel Sambuc       .Case("rdseed", HasRDSEED)
3107*0a6a1f1dSLionel Sambuc       .Case("rtm", HasRTM)
3108f4a2713aSLionel Sambuc       .Case("sha", HasSHA)
3109f4a2713aSLionel Sambuc       .Case("sse", SSELevel >= SSE1)
3110f4a2713aSLionel Sambuc       .Case("sse2", SSELevel >= SSE2)
3111f4a2713aSLionel Sambuc       .Case("sse3", SSELevel >= SSE3)
3112f4a2713aSLionel Sambuc       .Case("ssse3", SSELevel >= SSSE3)
3113f4a2713aSLionel Sambuc       .Case("sse4.1", SSELevel >= SSE41)
3114f4a2713aSLionel Sambuc       .Case("sse4.2", SSELevel >= SSE42)
3115f4a2713aSLionel Sambuc       .Case("sse4a", XOPLevel >= SSE4A)
3116*0a6a1f1dSLionel Sambuc       .Case("tbm", HasTBM)
3117f4a2713aSLionel Sambuc       .Case("x86", true)
3118f4a2713aSLionel Sambuc       .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
3119f4a2713aSLionel Sambuc       .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
3120f4a2713aSLionel Sambuc       .Case("xop", XOPLevel >= XOP)
3121f4a2713aSLionel Sambuc       .Default(false);
3122f4a2713aSLionel Sambuc }
3123f4a2713aSLionel Sambuc 
3124f4a2713aSLionel Sambuc bool
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const3125f4a2713aSLionel Sambuc X86TargetInfo::validateAsmConstraint(const char *&Name,
3126f4a2713aSLionel Sambuc                                      TargetInfo::ConstraintInfo &Info) const {
3127f4a2713aSLionel Sambuc   switch (*Name) {
3128f4a2713aSLionel Sambuc   default: return false;
3129*0a6a1f1dSLionel Sambuc   case 'I':
3130*0a6a1f1dSLionel Sambuc     Info.setRequiresImmediate(0, 31);
3131*0a6a1f1dSLionel Sambuc     return true;
3132*0a6a1f1dSLionel Sambuc   case 'J':
3133*0a6a1f1dSLionel Sambuc     Info.setRequiresImmediate(0, 63);
3134*0a6a1f1dSLionel Sambuc     return true;
3135*0a6a1f1dSLionel Sambuc   case 'K':
3136*0a6a1f1dSLionel Sambuc     Info.setRequiresImmediate(-128, 127);
3137*0a6a1f1dSLionel Sambuc     return true;
3138*0a6a1f1dSLionel Sambuc   case 'L':
3139*0a6a1f1dSLionel Sambuc     // FIXME: properly analyze this constraint:
3140*0a6a1f1dSLionel Sambuc     //  must be one of 0xff, 0xffff, or 0xffffffff
3141*0a6a1f1dSLionel Sambuc     return true;
3142*0a6a1f1dSLionel Sambuc   case 'M':
3143*0a6a1f1dSLionel Sambuc     Info.setRequiresImmediate(0, 3);
3144*0a6a1f1dSLionel Sambuc     return true;
3145*0a6a1f1dSLionel Sambuc   case 'N':
3146*0a6a1f1dSLionel Sambuc     Info.setRequiresImmediate(0, 255);
3147*0a6a1f1dSLionel Sambuc     return true;
3148*0a6a1f1dSLionel Sambuc   case 'O':
3149*0a6a1f1dSLionel Sambuc     Info.setRequiresImmediate(0, 127);
3150*0a6a1f1dSLionel Sambuc     return true;
3151f4a2713aSLionel Sambuc   case 'Y': // first letter of a pair:
3152f4a2713aSLionel Sambuc     switch (*(Name+1)) {
3153f4a2713aSLionel Sambuc     default: return false;
3154f4a2713aSLionel Sambuc     case '0':  // First SSE register.
3155f4a2713aSLionel Sambuc     case 't':  // Any SSE register, when SSE2 is enabled.
3156f4a2713aSLionel Sambuc     case 'i':  // Any SSE register, when SSE2 and inter-unit moves enabled.
3157f4a2713aSLionel Sambuc     case 'm':  // any MMX register, when inter-unit moves enabled.
3158f4a2713aSLionel Sambuc       break;   // falls through to setAllowsRegister.
3159f4a2713aSLionel Sambuc   }
3160*0a6a1f1dSLionel Sambuc   case 'f': // any x87 floating point stack register.
3161*0a6a1f1dSLionel Sambuc     // Constraint 'f' cannot be used for output operands.
3162*0a6a1f1dSLionel Sambuc     if (Info.ConstraintStr[0] == '=')
3163*0a6a1f1dSLionel Sambuc       return false;
3164*0a6a1f1dSLionel Sambuc 
3165*0a6a1f1dSLionel Sambuc     Info.setAllowsRegister();
3166*0a6a1f1dSLionel Sambuc     return true;
3167f4a2713aSLionel Sambuc   case 'a': // eax.
3168f4a2713aSLionel Sambuc   case 'b': // ebx.
3169f4a2713aSLionel Sambuc   case 'c': // ecx.
3170f4a2713aSLionel Sambuc   case 'd': // edx.
3171f4a2713aSLionel Sambuc   case 'S': // esi.
3172f4a2713aSLionel Sambuc   case 'D': // edi.
3173f4a2713aSLionel Sambuc   case 'A': // edx:eax.
3174f4a2713aSLionel Sambuc   case 't': // top of floating point stack.
3175f4a2713aSLionel Sambuc   case 'u': // second from top of floating point stack.
3176f4a2713aSLionel Sambuc   case 'q': // Any register accessible as [r]l: a, b, c, and d.
3177f4a2713aSLionel Sambuc   case 'y': // Any MMX register.
3178f4a2713aSLionel Sambuc   case 'x': // Any SSE register.
3179f4a2713aSLionel Sambuc   case 'Q': // Any register accessible as [r]h: a, b, c, and d.
3180f4a2713aSLionel Sambuc   case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
3181f4a2713aSLionel Sambuc   case 'l': // "Index" registers: any general register that can be used as an
3182f4a2713aSLionel Sambuc             // index in a base+index memory access.
3183f4a2713aSLionel Sambuc     Info.setAllowsRegister();
3184f4a2713aSLionel Sambuc     return true;
3185f4a2713aSLionel Sambuc   case 'C': // SSE floating point constant.
3186f4a2713aSLionel Sambuc   case 'G': // x87 floating point constant.
3187f4a2713aSLionel Sambuc   case 'e': // 32-bit signed integer constant for use with zero-extending
3188f4a2713aSLionel Sambuc             // x86_64 instructions.
3189f4a2713aSLionel Sambuc   case 'Z': // 32-bit unsigned integer constant for use with zero-extending
3190f4a2713aSLionel Sambuc             // x86_64 instructions.
3191f4a2713aSLionel Sambuc     return true;
3192f4a2713aSLionel Sambuc   }
3193f4a2713aSLionel Sambuc }
3194f4a2713aSLionel Sambuc 
validateOutputSize(StringRef Constraint,unsigned Size) const3195*0a6a1f1dSLionel Sambuc bool X86TargetInfo::validateOutputSize(StringRef Constraint,
3196*0a6a1f1dSLionel Sambuc                                        unsigned Size) const {
3197*0a6a1f1dSLionel Sambuc   // Strip off constraint modifiers.
3198*0a6a1f1dSLionel Sambuc   while (Constraint[0] == '=' ||
3199*0a6a1f1dSLionel Sambuc          Constraint[0] == '+' ||
3200*0a6a1f1dSLionel Sambuc          Constraint[0] == '&')
3201*0a6a1f1dSLionel Sambuc     Constraint = Constraint.substr(1);
3202*0a6a1f1dSLionel Sambuc 
3203*0a6a1f1dSLionel Sambuc   return validateOperandSize(Constraint, Size);
3204*0a6a1f1dSLionel Sambuc }
3205*0a6a1f1dSLionel Sambuc 
validateInputSize(StringRef Constraint,unsigned Size) const3206*0a6a1f1dSLionel Sambuc bool X86TargetInfo::validateInputSize(StringRef Constraint,
3207*0a6a1f1dSLionel Sambuc                                       unsigned Size) const {
3208*0a6a1f1dSLionel Sambuc   return validateOperandSize(Constraint, Size);
3209*0a6a1f1dSLionel Sambuc }
3210*0a6a1f1dSLionel Sambuc 
validateOperandSize(StringRef Constraint,unsigned Size) const3211*0a6a1f1dSLionel Sambuc bool X86TargetInfo::validateOperandSize(StringRef Constraint,
3212*0a6a1f1dSLionel Sambuc                                         unsigned Size) const {
3213*0a6a1f1dSLionel Sambuc   switch (Constraint[0]) {
3214*0a6a1f1dSLionel Sambuc   default: break;
3215*0a6a1f1dSLionel Sambuc   case 'y':
3216*0a6a1f1dSLionel Sambuc     return Size <= 64;
3217*0a6a1f1dSLionel Sambuc   case 'f':
3218*0a6a1f1dSLionel Sambuc   case 't':
3219*0a6a1f1dSLionel Sambuc   case 'u':
3220*0a6a1f1dSLionel Sambuc     return Size <= 128;
3221*0a6a1f1dSLionel Sambuc   case 'x':
3222*0a6a1f1dSLionel Sambuc     // 256-bit ymm registers can be used if target supports AVX.
3223*0a6a1f1dSLionel Sambuc     return Size <= (SSELevel >= AVX ? 256U : 128U);
3224*0a6a1f1dSLionel Sambuc   }
3225*0a6a1f1dSLionel Sambuc 
3226*0a6a1f1dSLionel Sambuc   return true;
3227*0a6a1f1dSLionel Sambuc }
3228f4a2713aSLionel Sambuc 
3229f4a2713aSLionel Sambuc std::string
convertConstraint(const char * & Constraint) const3230f4a2713aSLionel Sambuc X86TargetInfo::convertConstraint(const char *&Constraint) const {
3231f4a2713aSLionel Sambuc   switch (*Constraint) {
3232f4a2713aSLionel Sambuc   case 'a': return std::string("{ax}");
3233f4a2713aSLionel Sambuc   case 'b': return std::string("{bx}");
3234f4a2713aSLionel Sambuc   case 'c': return std::string("{cx}");
3235f4a2713aSLionel Sambuc   case 'd': return std::string("{dx}");
3236f4a2713aSLionel Sambuc   case 'S': return std::string("{si}");
3237f4a2713aSLionel Sambuc   case 'D': return std::string("{di}");
3238f4a2713aSLionel Sambuc   case 'p': // address
3239f4a2713aSLionel Sambuc     return std::string("im");
3240f4a2713aSLionel Sambuc   case 't': // top of floating point stack.
3241f4a2713aSLionel Sambuc     return std::string("{st}");
3242f4a2713aSLionel Sambuc   case 'u': // second from top of floating point stack.
3243f4a2713aSLionel Sambuc     return std::string("{st(1)}"); // second from top of floating point stack.
3244f4a2713aSLionel Sambuc   default:
3245f4a2713aSLionel Sambuc     return std::string(1, *Constraint);
3246f4a2713aSLionel Sambuc   }
3247f4a2713aSLionel Sambuc }
3248f4a2713aSLionel Sambuc } // end anonymous namespace
3249f4a2713aSLionel Sambuc 
3250f4a2713aSLionel Sambuc namespace {
3251f4a2713aSLionel Sambuc // X86-32 generic target
3252f4a2713aSLionel Sambuc class X86_32TargetInfo : public X86TargetInfo {
3253f4a2713aSLionel Sambuc public:
X86_32TargetInfo(const llvm::Triple & Triple)3254f4a2713aSLionel Sambuc   X86_32TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
3255f4a2713aSLionel Sambuc     DoubleAlign = LongLongAlign = 32;
3256f4a2713aSLionel Sambuc     LongDoubleWidth = 96;
3257f4a2713aSLionel Sambuc     LongDoubleAlign = 32;
3258f4a2713aSLionel Sambuc     SuitableAlign = 128;
3259*0a6a1f1dSLionel Sambuc     DescriptionString = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128";
3260f4a2713aSLionel Sambuc     SizeType = UnsignedInt;
3261f4a2713aSLionel Sambuc     PtrDiffType = SignedInt;
3262f4a2713aSLionel Sambuc     IntPtrType = SignedInt;
3263f4a2713aSLionel Sambuc     RegParmMax = 3;
3264f4a2713aSLionel Sambuc 
3265f4a2713aSLionel Sambuc     // Use fpret for all types.
3266f4a2713aSLionel Sambuc     RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
3267f4a2713aSLionel Sambuc                              (1 << TargetInfo::Double) |
3268f4a2713aSLionel Sambuc                              (1 << TargetInfo::LongDouble));
3269f4a2713aSLionel Sambuc 
3270f4a2713aSLionel Sambuc     // x86-32 has atomics up to 8 bytes
3271f4a2713aSLionel Sambuc     // FIXME: Check that we actually have cmpxchg8b before setting
3272f4a2713aSLionel Sambuc     // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
3273f4a2713aSLionel Sambuc     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
3274f4a2713aSLionel Sambuc   }
getBuiltinVaListKind() const3275*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
3276f4a2713aSLionel Sambuc     return TargetInfo::CharPtrBuiltinVaList;
3277f4a2713aSLionel Sambuc   }
3278f4a2713aSLionel Sambuc 
getEHDataRegisterNumber(unsigned RegNo) const3279*0a6a1f1dSLionel Sambuc   int getEHDataRegisterNumber(unsigned RegNo) const override {
3280f4a2713aSLionel Sambuc     if (RegNo == 0) return 0;
3281f4a2713aSLionel Sambuc     if (RegNo == 1) return 2;
3282f4a2713aSLionel Sambuc     return -1;
3283f4a2713aSLionel Sambuc   }
validateOperandSize(StringRef Constraint,unsigned Size) const3284*0a6a1f1dSLionel Sambuc   bool validateOperandSize(StringRef Constraint,
3285*0a6a1f1dSLionel Sambuc                            unsigned Size) const override {
3286f4a2713aSLionel Sambuc     switch (Constraint[0]) {
3287f4a2713aSLionel Sambuc     default: break;
3288*0a6a1f1dSLionel Sambuc     case 'R':
3289*0a6a1f1dSLionel Sambuc     case 'q':
3290*0a6a1f1dSLionel Sambuc     case 'Q':
3291f4a2713aSLionel Sambuc     case 'a':
3292f4a2713aSLionel Sambuc     case 'b':
3293f4a2713aSLionel Sambuc     case 'c':
3294f4a2713aSLionel Sambuc     case 'd':
3295*0a6a1f1dSLionel Sambuc     case 'S':
3296*0a6a1f1dSLionel Sambuc     case 'D':
3297f4a2713aSLionel Sambuc       return Size <= 32;
3298*0a6a1f1dSLionel Sambuc     case 'A':
3299*0a6a1f1dSLionel Sambuc       return Size <= 64;
3300f4a2713aSLionel Sambuc     }
3301f4a2713aSLionel Sambuc 
3302*0a6a1f1dSLionel Sambuc     return X86TargetInfo::validateOperandSize(Constraint, Size);
3303f4a2713aSLionel Sambuc   }
3304f4a2713aSLionel Sambuc };
3305f4a2713aSLionel Sambuc } // end anonymous namespace
3306f4a2713aSLionel Sambuc 
3307f4a2713aSLionel Sambuc namespace {
3308f4a2713aSLionel Sambuc class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> {
3309f4a2713aSLionel Sambuc public:
NetBSDI386TargetInfo(const llvm::Triple & Triple)3310f4a2713aSLionel Sambuc   NetBSDI386TargetInfo(const llvm::Triple &Triple)
3311f4a2713aSLionel Sambuc       : NetBSDTargetInfo<X86_32TargetInfo>(Triple) {}
3312f4a2713aSLionel Sambuc 
getFloatEvalMethod() const3313*0a6a1f1dSLionel Sambuc   unsigned getFloatEvalMethod() const override {
3314f4a2713aSLionel Sambuc     unsigned Major, Minor, Micro;
3315f4a2713aSLionel Sambuc     getTriple().getOSVersion(Major, Minor, Micro);
3316f4a2713aSLionel Sambuc     // New NetBSD uses the default rounding mode.
3317f4a2713aSLionel Sambuc     if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0)
3318f4a2713aSLionel Sambuc       return X86_32TargetInfo::getFloatEvalMethod();
3319f4a2713aSLionel Sambuc     // NetBSD before 6.99.26 defaults to "double" rounding.
3320f4a2713aSLionel Sambuc     return 1;
3321f4a2713aSLionel Sambuc   }
3322f4a2713aSLionel Sambuc };
3323f4a2713aSLionel Sambuc } // end anonymous namespace
3324f4a2713aSLionel Sambuc 
3325f4a2713aSLionel Sambuc namespace {
3326f4a2713aSLionel Sambuc class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
3327f4a2713aSLionel Sambuc public:
OpenBSDI386TargetInfo(const llvm::Triple & Triple)3328f4a2713aSLionel Sambuc   OpenBSDI386TargetInfo(const llvm::Triple &Triple)
3329f4a2713aSLionel Sambuc       : OpenBSDTargetInfo<X86_32TargetInfo>(Triple) {
3330f4a2713aSLionel Sambuc     SizeType = UnsignedLong;
3331f4a2713aSLionel Sambuc     IntPtrType = SignedLong;
3332f4a2713aSLionel Sambuc     PtrDiffType = SignedLong;
3333f4a2713aSLionel Sambuc   }
3334f4a2713aSLionel Sambuc };
3335f4a2713aSLionel Sambuc } // end anonymous namespace
3336f4a2713aSLionel Sambuc 
3337f4a2713aSLionel Sambuc namespace {
3338f4a2713aSLionel Sambuc class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> {
3339f4a2713aSLionel Sambuc public:
BitrigI386TargetInfo(const llvm::Triple & Triple)3340f4a2713aSLionel Sambuc   BitrigI386TargetInfo(const llvm::Triple &Triple)
3341f4a2713aSLionel Sambuc       : BitrigTargetInfo<X86_32TargetInfo>(Triple) {
3342f4a2713aSLionel Sambuc     SizeType = UnsignedLong;
3343f4a2713aSLionel Sambuc     IntPtrType = SignedLong;
3344f4a2713aSLionel Sambuc     PtrDiffType = SignedLong;
3345f4a2713aSLionel Sambuc   }
3346f4a2713aSLionel Sambuc };
3347f4a2713aSLionel Sambuc } // end anonymous namespace
3348f4a2713aSLionel Sambuc 
3349f4a2713aSLionel Sambuc namespace {
3350f4a2713aSLionel Sambuc class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
3351f4a2713aSLionel Sambuc public:
DarwinI386TargetInfo(const llvm::Triple & Triple)3352f4a2713aSLionel Sambuc   DarwinI386TargetInfo(const llvm::Triple &Triple)
3353f4a2713aSLionel Sambuc       : DarwinTargetInfo<X86_32TargetInfo>(Triple) {
3354f4a2713aSLionel Sambuc     LongDoubleWidth = 128;
3355f4a2713aSLionel Sambuc     LongDoubleAlign = 128;
3356f4a2713aSLionel Sambuc     SuitableAlign = 128;
3357f4a2713aSLionel Sambuc     MaxVectorAlign = 256;
3358f4a2713aSLionel Sambuc     SizeType = UnsignedLong;
3359f4a2713aSLionel Sambuc     IntPtrType = SignedLong;
3360*0a6a1f1dSLionel Sambuc     DescriptionString = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128";
3361f4a2713aSLionel Sambuc     HasAlignMac68kSupport = true;
3362f4a2713aSLionel Sambuc   }
3363f4a2713aSLionel Sambuc 
3364f4a2713aSLionel Sambuc };
3365f4a2713aSLionel Sambuc } // end anonymous namespace
3366f4a2713aSLionel Sambuc 
3367f4a2713aSLionel Sambuc namespace {
3368f4a2713aSLionel Sambuc // x86-32 Windows target
3369f4a2713aSLionel Sambuc class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
3370f4a2713aSLionel Sambuc public:
WindowsX86_32TargetInfo(const llvm::Triple & Triple)3371f4a2713aSLionel Sambuc   WindowsX86_32TargetInfo(const llvm::Triple &Triple)
3372f4a2713aSLionel Sambuc       : WindowsTargetInfo<X86_32TargetInfo>(Triple) {
3373f4a2713aSLionel Sambuc     WCharType = UnsignedShort;
3374f4a2713aSLionel Sambuc     DoubleAlign = LongLongAlign = 64;
3375*0a6a1f1dSLionel Sambuc     bool IsWinCOFF =
3376*0a6a1f1dSLionel Sambuc         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
3377*0a6a1f1dSLionel Sambuc     DescriptionString = IsWinCOFF ? "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
3378*0a6a1f1dSLionel Sambuc                                   : "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-S32";
3379f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3380*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
3381*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
3382f4a2713aSLionel Sambuc     WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
3383f4a2713aSLionel Sambuc   }
3384f4a2713aSLionel Sambuc };
3385f4a2713aSLionel Sambuc 
3386f4a2713aSLionel Sambuc // x86-32 Windows Visual Studio target
3387*0a6a1f1dSLionel Sambuc class MicrosoftX86_32TargetInfo : public WindowsX86_32TargetInfo {
3388f4a2713aSLionel Sambuc public:
MicrosoftX86_32TargetInfo(const llvm::Triple & Triple)3389*0a6a1f1dSLionel Sambuc   MicrosoftX86_32TargetInfo(const llvm::Triple &Triple)
3390f4a2713aSLionel Sambuc       : WindowsX86_32TargetInfo(Triple) {
3391f4a2713aSLionel Sambuc     LongDoubleWidth = LongDoubleAlign = 64;
3392f4a2713aSLionel Sambuc     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
3393f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3394*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
3395*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
3396f4a2713aSLionel Sambuc     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
3397f4a2713aSLionel Sambuc     WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
3398f4a2713aSLionel Sambuc     // The value of the following reflects processor type.
3399f4a2713aSLionel Sambuc     // 300=386, 400=486, 500=Pentium, 600=Blend (default)
3400f4a2713aSLionel Sambuc     // We lost the original triple, so we use the default.
3401f4a2713aSLionel Sambuc     Builder.defineMacro("_M_IX86", "600");
3402f4a2713aSLionel Sambuc   }
3403f4a2713aSLionel Sambuc };
3404f4a2713aSLionel Sambuc } // end anonymous namespace
3405f4a2713aSLionel Sambuc 
addMinGWDefines(const LangOptions & Opts,MacroBuilder & Builder)3406*0a6a1f1dSLionel Sambuc static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) {
3407*0a6a1f1dSLionel Sambuc   Builder.defineMacro("__MSVCRT__");
3408*0a6a1f1dSLionel Sambuc   Builder.defineMacro("__MINGW32__");
3409*0a6a1f1dSLionel Sambuc 
3410*0a6a1f1dSLionel Sambuc   // Mingw defines __declspec(a) to __attribute__((a)).  Clang supports
3411*0a6a1f1dSLionel Sambuc   // __declspec natively under -fms-extensions, but we define a no-op __declspec
3412*0a6a1f1dSLionel Sambuc   // macro anyway for pre-processor compatibility.
3413*0a6a1f1dSLionel Sambuc   if (Opts.MicrosoftExt)
3414*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__declspec", "__declspec");
3415*0a6a1f1dSLionel Sambuc   else
3416*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__declspec(a)", "__attribute__((a))");
3417*0a6a1f1dSLionel Sambuc 
3418*0a6a1f1dSLionel Sambuc   if (!Opts.MicrosoftExt) {
3419*0a6a1f1dSLionel Sambuc     // Provide macros for all the calling convention keywords.  Provide both
3420*0a6a1f1dSLionel Sambuc     // single and double underscore prefixed variants.  These are available on
3421*0a6a1f1dSLionel Sambuc     // x64 as well as x86, even though they have no effect.
3422*0a6a1f1dSLionel Sambuc     const char *CCs[] = {"cdecl", "stdcall", "fastcall", "thiscall", "pascal"};
3423*0a6a1f1dSLionel Sambuc     for (const char *CC : CCs) {
3424*0a6a1f1dSLionel Sambuc       std::string GCCSpelling = "__attribute__((__";
3425*0a6a1f1dSLionel Sambuc       GCCSpelling += CC;
3426*0a6a1f1dSLionel Sambuc       GCCSpelling += "__))";
3427*0a6a1f1dSLionel Sambuc       Builder.defineMacro(Twine("_") + CC, GCCSpelling);
3428*0a6a1f1dSLionel Sambuc       Builder.defineMacro(Twine("__") + CC, GCCSpelling);
3429*0a6a1f1dSLionel Sambuc     }
3430*0a6a1f1dSLionel Sambuc   }
3431*0a6a1f1dSLionel Sambuc }
3432*0a6a1f1dSLionel Sambuc 
3433f4a2713aSLionel Sambuc namespace {
3434f4a2713aSLionel Sambuc // x86-32 MinGW target
3435f4a2713aSLionel Sambuc class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
3436f4a2713aSLionel Sambuc public:
MinGWX86_32TargetInfo(const llvm::Triple & Triple)3437f4a2713aSLionel Sambuc   MinGWX86_32TargetInfo(const llvm::Triple &Triple)
3438f4a2713aSLionel Sambuc       : WindowsX86_32TargetInfo(Triple) {}
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3439*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
3440*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
3441f4a2713aSLionel Sambuc     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
3442f4a2713aSLionel Sambuc     DefineStd(Builder, "WIN32", Opts);
3443f4a2713aSLionel Sambuc     DefineStd(Builder, "WINNT", Opts);
3444f4a2713aSLionel Sambuc     Builder.defineMacro("_X86_");
3445*0a6a1f1dSLionel Sambuc     addMinGWDefines(Opts, Builder);
3446f4a2713aSLionel Sambuc   }
3447f4a2713aSLionel Sambuc };
3448f4a2713aSLionel Sambuc } // end anonymous namespace
3449f4a2713aSLionel Sambuc 
3450f4a2713aSLionel Sambuc namespace {
3451f4a2713aSLionel Sambuc // x86-32 Cygwin target
3452f4a2713aSLionel Sambuc class CygwinX86_32TargetInfo : public X86_32TargetInfo {
3453f4a2713aSLionel Sambuc public:
CygwinX86_32TargetInfo(const llvm::Triple & Triple)3454f4a2713aSLionel Sambuc   CygwinX86_32TargetInfo(const llvm::Triple &Triple)
3455f4a2713aSLionel Sambuc       : X86_32TargetInfo(Triple) {
3456f4a2713aSLionel Sambuc     TLSSupported = false;
3457f4a2713aSLionel Sambuc     WCharType = UnsignedShort;
3458f4a2713aSLionel Sambuc     DoubleAlign = LongLongAlign = 64;
3459*0a6a1f1dSLionel Sambuc     DescriptionString = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32";
3460f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3461*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
3462*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
3463f4a2713aSLionel Sambuc     X86_32TargetInfo::getTargetDefines(Opts, Builder);
3464f4a2713aSLionel Sambuc     Builder.defineMacro("_X86_");
3465f4a2713aSLionel Sambuc     Builder.defineMacro("__CYGWIN__");
3466f4a2713aSLionel Sambuc     Builder.defineMacro("__CYGWIN32__");
3467f4a2713aSLionel Sambuc     DefineStd(Builder, "unix", Opts);
3468f4a2713aSLionel Sambuc     if (Opts.CPlusPlus)
3469f4a2713aSLionel Sambuc       Builder.defineMacro("_GNU_SOURCE");
3470f4a2713aSLionel Sambuc   }
3471f4a2713aSLionel Sambuc };
3472f4a2713aSLionel Sambuc } // end anonymous namespace
3473f4a2713aSLionel Sambuc 
3474f4a2713aSLionel Sambuc namespace {
3475f4a2713aSLionel Sambuc // x86-32 Haiku target
3476f4a2713aSLionel Sambuc class HaikuX86_32TargetInfo : public X86_32TargetInfo {
3477f4a2713aSLionel Sambuc public:
HaikuX86_32TargetInfo(const llvm::Triple & Triple)3478f4a2713aSLionel Sambuc   HaikuX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) {
3479f4a2713aSLionel Sambuc     SizeType = UnsignedLong;
3480f4a2713aSLionel Sambuc     IntPtrType = SignedLong;
3481f4a2713aSLionel Sambuc     PtrDiffType = SignedLong;
3482f4a2713aSLionel Sambuc     ProcessIDType = SignedLong;
3483f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
3484f4a2713aSLionel Sambuc     this->TLSSupported = false;
3485f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3486*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
3487*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
3488f4a2713aSLionel Sambuc     X86_32TargetInfo::getTargetDefines(Opts, Builder);
3489f4a2713aSLionel Sambuc     Builder.defineMacro("__INTEL__");
3490f4a2713aSLionel Sambuc     Builder.defineMacro("__HAIKU__");
3491f4a2713aSLionel Sambuc   }
3492f4a2713aSLionel Sambuc };
3493f4a2713aSLionel Sambuc } // end anonymous namespace
3494f4a2713aSLionel Sambuc 
3495f4a2713aSLionel Sambuc // RTEMS Target
3496f4a2713aSLionel Sambuc template<typename Target>
3497f4a2713aSLionel Sambuc class RTEMSTargetInfo : public OSTargetInfo<Target> {
3498f4a2713aSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const3499*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
3500*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
3501f4a2713aSLionel Sambuc     // RTEMS defines; list based off of gcc output
3502f4a2713aSLionel Sambuc 
3503f4a2713aSLionel Sambuc     Builder.defineMacro("__rtems__");
3504f4a2713aSLionel Sambuc     Builder.defineMacro("__ELF__");
3505f4a2713aSLionel Sambuc   }
3506f4a2713aSLionel Sambuc 
3507f4a2713aSLionel Sambuc public:
RTEMSTargetInfo(const llvm::Triple & Triple)3508f4a2713aSLionel Sambuc   RTEMSTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
3509f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
3510f4a2713aSLionel Sambuc 
3511f4a2713aSLionel Sambuc     switch (Triple.getArch()) {
3512f4a2713aSLionel Sambuc     default:
3513f4a2713aSLionel Sambuc     case llvm::Triple::x86:
3514f4a2713aSLionel Sambuc       // this->MCountName = ".mcount";
3515f4a2713aSLionel Sambuc       break;
3516f4a2713aSLionel Sambuc     case llvm::Triple::mips:
3517f4a2713aSLionel Sambuc     case llvm::Triple::mipsel:
3518f4a2713aSLionel Sambuc     case llvm::Triple::ppc:
3519f4a2713aSLionel Sambuc     case llvm::Triple::ppc64:
3520f4a2713aSLionel Sambuc     case llvm::Triple::ppc64le:
3521f4a2713aSLionel Sambuc       // this->MCountName = "_mcount";
3522f4a2713aSLionel Sambuc       break;
3523f4a2713aSLionel Sambuc     case llvm::Triple::arm:
3524f4a2713aSLionel Sambuc       // this->MCountName = "__mcount";
3525f4a2713aSLionel Sambuc       break;
3526f4a2713aSLionel Sambuc     }
3527f4a2713aSLionel Sambuc   }
3528f4a2713aSLionel Sambuc };
3529f4a2713aSLionel Sambuc 
3530f4a2713aSLionel Sambuc namespace {
3531f4a2713aSLionel Sambuc // x86-32 RTEMS target
3532f4a2713aSLionel Sambuc class RTEMSX86_32TargetInfo : public X86_32TargetInfo {
3533f4a2713aSLionel Sambuc public:
RTEMSX86_32TargetInfo(const llvm::Triple & Triple)3534f4a2713aSLionel Sambuc   RTEMSX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) {
3535f4a2713aSLionel Sambuc     SizeType = UnsignedLong;
3536f4a2713aSLionel Sambuc     IntPtrType = SignedLong;
3537f4a2713aSLionel Sambuc     PtrDiffType = SignedLong;
3538f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
3539f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3540*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
3541*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
3542f4a2713aSLionel Sambuc     X86_32TargetInfo::getTargetDefines(Opts, Builder);
3543f4a2713aSLionel Sambuc     Builder.defineMacro("__INTEL__");
3544f4a2713aSLionel Sambuc     Builder.defineMacro("__rtems__");
3545f4a2713aSLionel Sambuc   }
3546f4a2713aSLionel Sambuc };
3547f4a2713aSLionel Sambuc } // end anonymous namespace
3548f4a2713aSLionel Sambuc 
3549f4a2713aSLionel Sambuc namespace {
3550f4a2713aSLionel Sambuc // x86-64 generic target
3551f4a2713aSLionel Sambuc class X86_64TargetInfo : public X86TargetInfo {
3552f4a2713aSLionel Sambuc public:
X86_64TargetInfo(const llvm::Triple & Triple)3553f4a2713aSLionel Sambuc   X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
3554*0a6a1f1dSLionel Sambuc     const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32;
3555*0a6a1f1dSLionel Sambuc     LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
3556f4a2713aSLionel Sambuc     LongDoubleWidth = 128;
3557f4a2713aSLionel Sambuc     LongDoubleAlign = 128;
3558f4a2713aSLionel Sambuc     LargeArrayMinWidth = 128;
3559f4a2713aSLionel Sambuc     LargeArrayAlign = 128;
3560f4a2713aSLionel Sambuc     SuitableAlign = 128;
3561*0a6a1f1dSLionel Sambuc     SizeType    = IsX32 ? UnsignedInt      : UnsignedLong;
3562*0a6a1f1dSLionel Sambuc     PtrDiffType = IsX32 ? SignedInt        : SignedLong;
3563*0a6a1f1dSLionel Sambuc     IntPtrType  = IsX32 ? SignedInt        : SignedLong;
3564*0a6a1f1dSLionel Sambuc     IntMaxType  = IsX32 ? SignedLongLong   : SignedLong;
3565*0a6a1f1dSLionel Sambuc     Int64Type   = IsX32 ? SignedLongLong   : SignedLong;
3566f4a2713aSLionel Sambuc     RegParmMax = 6;
3567f4a2713aSLionel Sambuc 
3568*0a6a1f1dSLionel Sambuc     // Pointers are 32-bit in x32.
3569*0a6a1f1dSLionel Sambuc     DescriptionString = (IsX32)
3570*0a6a1f1dSLionel Sambuc                             ? "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128"
3571*0a6a1f1dSLionel Sambuc                             : "e-m:e-i64:64-f80:128-n8:16:32:64-S128";
3572f4a2713aSLionel Sambuc 
3573f4a2713aSLionel Sambuc     // Use fpret only for long double.
3574f4a2713aSLionel Sambuc     RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
3575f4a2713aSLionel Sambuc 
3576f4a2713aSLionel Sambuc     // Use fp2ret for _Complex long double.
3577f4a2713aSLionel Sambuc     ComplexLongDoubleUsesFP2Ret = true;
3578f4a2713aSLionel Sambuc 
3579f4a2713aSLionel Sambuc     // x86-64 has atomics up to 16 bytes.
3580f4a2713aSLionel Sambuc     MaxAtomicPromoteWidth = 128;
3581*0a6a1f1dSLionel Sambuc     MaxAtomicInlineWidth = 128;
3582f4a2713aSLionel Sambuc   }
getBuiltinVaListKind() const3583*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
3584f4a2713aSLionel Sambuc     return TargetInfo::X86_64ABIBuiltinVaList;
3585f4a2713aSLionel Sambuc   }
3586f4a2713aSLionel Sambuc 
getEHDataRegisterNumber(unsigned RegNo) const3587*0a6a1f1dSLionel Sambuc   int getEHDataRegisterNumber(unsigned RegNo) const override {
3588f4a2713aSLionel Sambuc     if (RegNo == 0) return 0;
3589f4a2713aSLionel Sambuc     if (RegNo == 1) return 1;
3590f4a2713aSLionel Sambuc     return -1;
3591f4a2713aSLionel Sambuc   }
3592f4a2713aSLionel Sambuc 
checkCallingConvention(CallingConv CC) const3593*0a6a1f1dSLionel Sambuc   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
3594f4a2713aSLionel Sambuc     return (CC == CC_C ||
3595*0a6a1f1dSLionel Sambuc             CC == CC_X86VectorCall ||
3596f4a2713aSLionel Sambuc             CC == CC_IntelOclBicc ||
3597f4a2713aSLionel Sambuc             CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning;
3598f4a2713aSLionel Sambuc   }
3599f4a2713aSLionel Sambuc 
getDefaultCallingConv(CallingConvMethodType MT) const3600*0a6a1f1dSLionel Sambuc   CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
3601f4a2713aSLionel Sambuc     return CC_C;
3602f4a2713aSLionel Sambuc   }
3603f4a2713aSLionel Sambuc 
3604*0a6a1f1dSLionel Sambuc   // for x32 we need it here explicitly
hasInt128Type() const3605*0a6a1f1dSLionel Sambuc   bool hasInt128Type() const override { return true; }
3606f4a2713aSLionel Sambuc };
3607f4a2713aSLionel Sambuc } // end anonymous namespace
3608f4a2713aSLionel Sambuc 
3609f4a2713aSLionel Sambuc namespace {
3610f4a2713aSLionel Sambuc // x86-64 Windows target
3611f4a2713aSLionel Sambuc class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
3612f4a2713aSLionel Sambuc public:
WindowsX86_64TargetInfo(const llvm::Triple & Triple)3613f4a2713aSLionel Sambuc   WindowsX86_64TargetInfo(const llvm::Triple &Triple)
3614f4a2713aSLionel Sambuc       : WindowsTargetInfo<X86_64TargetInfo>(Triple) {
3615f4a2713aSLionel Sambuc     WCharType = UnsignedShort;
3616f4a2713aSLionel Sambuc     LongWidth = LongAlign = 32;
3617f4a2713aSLionel Sambuc     DoubleAlign = LongLongAlign = 64;
3618f4a2713aSLionel Sambuc     IntMaxType = SignedLongLong;
3619f4a2713aSLionel Sambuc     Int64Type = SignedLongLong;
3620f4a2713aSLionel Sambuc     SizeType = UnsignedLongLong;
3621f4a2713aSLionel Sambuc     PtrDiffType = SignedLongLong;
3622f4a2713aSLionel Sambuc     IntPtrType = SignedLongLong;
3623f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
3624f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3625*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
3626*0a6a1f1dSLionel Sambuc                                 MacroBuilder &Builder) const override {
3627f4a2713aSLionel Sambuc     WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
3628f4a2713aSLionel Sambuc     Builder.defineMacro("_WIN64");
3629f4a2713aSLionel Sambuc   }
getBuiltinVaListKind() const3630*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
3631f4a2713aSLionel Sambuc     return TargetInfo::CharPtrBuiltinVaList;
3632f4a2713aSLionel Sambuc   }
checkCallingConvention(CallingConv CC) const3633*0a6a1f1dSLionel Sambuc   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
3634f4a2713aSLionel Sambuc     return (CC == CC_C ||
3635*0a6a1f1dSLionel Sambuc             CC == CC_X86VectorCall ||
3636f4a2713aSLionel Sambuc             CC == CC_IntelOclBicc ||
3637f4a2713aSLionel Sambuc             CC == CC_X86_64SysV) ? CCCR_OK : CCCR_Warning;
3638f4a2713aSLionel Sambuc   }
3639f4a2713aSLionel Sambuc };
3640f4a2713aSLionel Sambuc } // end anonymous namespace
3641f4a2713aSLionel Sambuc 
3642f4a2713aSLionel Sambuc namespace {
3643f4a2713aSLionel Sambuc // x86-64 Windows Visual Studio target
3644*0a6a1f1dSLionel Sambuc class MicrosoftX86_64TargetInfo : public WindowsX86_64TargetInfo {
3645f4a2713aSLionel Sambuc public:
MicrosoftX86_64TargetInfo(const llvm::Triple & Triple)3646*0a6a1f1dSLionel Sambuc   MicrosoftX86_64TargetInfo(const llvm::Triple &Triple)
3647f4a2713aSLionel Sambuc       : WindowsX86_64TargetInfo(Triple) {
3648f4a2713aSLionel Sambuc     LongDoubleWidth = LongDoubleAlign = 64;
3649f4a2713aSLionel Sambuc     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
3650f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3651*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
3652*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
3653f4a2713aSLionel Sambuc     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
3654f4a2713aSLionel Sambuc     WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
3655f4a2713aSLionel Sambuc     Builder.defineMacro("_M_X64");
3656f4a2713aSLionel Sambuc     Builder.defineMacro("_M_AMD64");
3657f4a2713aSLionel Sambuc   }
3658f4a2713aSLionel Sambuc };
3659f4a2713aSLionel Sambuc } // end anonymous namespace
3660f4a2713aSLionel Sambuc 
3661f4a2713aSLionel Sambuc namespace {
3662f4a2713aSLionel Sambuc // x86-64 MinGW target
3663f4a2713aSLionel Sambuc class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
3664f4a2713aSLionel Sambuc public:
MinGWX86_64TargetInfo(const llvm::Triple & Triple)3665f4a2713aSLionel Sambuc   MinGWX86_64TargetInfo(const llvm::Triple &Triple)
3666f4a2713aSLionel Sambuc       : WindowsX86_64TargetInfo(Triple) {}
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3667*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
3668*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
3669f4a2713aSLionel Sambuc     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
3670f4a2713aSLionel Sambuc     DefineStd(Builder, "WIN64", Opts);
3671f4a2713aSLionel Sambuc     Builder.defineMacro("__MINGW64__");
3672*0a6a1f1dSLionel Sambuc     addMinGWDefines(Opts, Builder);
3673f4a2713aSLionel Sambuc 
3674*0a6a1f1dSLionel Sambuc     // GCC defines this macro when it is using __gxx_personality_seh0.
3675*0a6a1f1dSLionel Sambuc     if (!Opts.SjLjExceptions)
3676*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__SEH__");
3677f4a2713aSLionel Sambuc   }
3678f4a2713aSLionel Sambuc };
3679f4a2713aSLionel Sambuc } // end anonymous namespace
3680f4a2713aSLionel Sambuc 
3681f4a2713aSLionel Sambuc namespace {
3682f4a2713aSLionel Sambuc class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
3683f4a2713aSLionel Sambuc public:
DarwinX86_64TargetInfo(const llvm::Triple & Triple)3684f4a2713aSLionel Sambuc   DarwinX86_64TargetInfo(const llvm::Triple &Triple)
3685f4a2713aSLionel Sambuc       : DarwinTargetInfo<X86_64TargetInfo>(Triple) {
3686f4a2713aSLionel Sambuc     Int64Type = SignedLongLong;
3687f4a2713aSLionel Sambuc     MaxVectorAlign = 256;
3688*0a6a1f1dSLionel Sambuc     // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
3689*0a6a1f1dSLionel Sambuc     llvm::Triple T = llvm::Triple(Triple);
3690*0a6a1f1dSLionel Sambuc     if (T.isiOS())
3691*0a6a1f1dSLionel Sambuc       UseSignedCharForObjCBool = false;
3692*0a6a1f1dSLionel Sambuc     DescriptionString = "e-m:o-i64:64-f80:128-n8:16:32:64-S128";
3693f4a2713aSLionel Sambuc   }
3694f4a2713aSLionel Sambuc };
3695f4a2713aSLionel Sambuc } // end anonymous namespace
3696f4a2713aSLionel Sambuc 
3697f4a2713aSLionel Sambuc namespace {
3698f4a2713aSLionel Sambuc class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
3699f4a2713aSLionel Sambuc public:
OpenBSDX86_64TargetInfo(const llvm::Triple & Triple)3700f4a2713aSLionel Sambuc   OpenBSDX86_64TargetInfo(const llvm::Triple &Triple)
3701f4a2713aSLionel Sambuc       : OpenBSDTargetInfo<X86_64TargetInfo>(Triple) {
3702f4a2713aSLionel Sambuc     IntMaxType = SignedLongLong;
3703f4a2713aSLionel Sambuc     Int64Type = SignedLongLong;
3704f4a2713aSLionel Sambuc   }
3705f4a2713aSLionel Sambuc };
3706f4a2713aSLionel Sambuc } // end anonymous namespace
3707f4a2713aSLionel Sambuc 
3708f4a2713aSLionel Sambuc namespace {
3709f4a2713aSLionel Sambuc class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> {
3710f4a2713aSLionel Sambuc public:
BitrigX86_64TargetInfo(const llvm::Triple & Triple)3711f4a2713aSLionel Sambuc   BitrigX86_64TargetInfo(const llvm::Triple &Triple)
3712f4a2713aSLionel Sambuc       : BitrigTargetInfo<X86_64TargetInfo>(Triple) {
3713f4a2713aSLionel Sambuc     IntMaxType = SignedLongLong;
3714f4a2713aSLionel Sambuc     Int64Type = SignedLongLong;
3715f4a2713aSLionel Sambuc   }
3716f4a2713aSLionel Sambuc };
3717f4a2713aSLionel Sambuc }
3718f4a2713aSLionel Sambuc 
3719f4a2713aSLionel Sambuc 
3720f4a2713aSLionel Sambuc namespace {
3721f4a2713aSLionel Sambuc class ARMTargetInfo : public TargetInfo {
3722f4a2713aSLionel Sambuc   // Possible FPU choices.
3723f4a2713aSLionel Sambuc   enum FPUMode {
3724f4a2713aSLionel Sambuc     VFP2FPU = (1 << 0),
3725f4a2713aSLionel Sambuc     VFP3FPU = (1 << 1),
3726f4a2713aSLionel Sambuc     VFP4FPU = (1 << 2),
3727f4a2713aSLionel Sambuc     NeonFPU = (1 << 3),
3728f4a2713aSLionel Sambuc     FPARMV8 = (1 << 4)
3729f4a2713aSLionel Sambuc   };
3730f4a2713aSLionel Sambuc 
3731f4a2713aSLionel Sambuc   // Possible HWDiv features.
3732f4a2713aSLionel Sambuc   enum HWDivMode {
3733f4a2713aSLionel Sambuc     HWDivThumb = (1 << 0),
3734f4a2713aSLionel Sambuc     HWDivARM = (1 << 1)
3735f4a2713aSLionel Sambuc   };
3736f4a2713aSLionel Sambuc 
FPUModeIsVFP(FPUMode Mode)3737f4a2713aSLionel Sambuc   static bool FPUModeIsVFP(FPUMode Mode) {
3738f4a2713aSLionel Sambuc     return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU | FPARMV8);
3739f4a2713aSLionel Sambuc   }
3740f4a2713aSLionel Sambuc 
3741f4a2713aSLionel Sambuc   static const TargetInfo::GCCRegAlias GCCRegAliases[];
3742f4a2713aSLionel Sambuc   static const char * const GCCRegNames[];
3743f4a2713aSLionel Sambuc 
3744f4a2713aSLionel Sambuc   std::string ABI, CPU;
3745f4a2713aSLionel Sambuc 
3746f4a2713aSLionel Sambuc   enum {
3747f4a2713aSLionel Sambuc     FP_Default,
3748f4a2713aSLionel Sambuc     FP_VFP,
3749f4a2713aSLionel Sambuc     FP_Neon
3750f4a2713aSLionel Sambuc   } FPMath;
3751f4a2713aSLionel Sambuc 
3752f4a2713aSLionel Sambuc   unsigned FPU : 5;
3753f4a2713aSLionel Sambuc 
3754f4a2713aSLionel Sambuc   unsigned IsAAPCS : 1;
3755f4a2713aSLionel Sambuc   unsigned IsThumb : 1;
3756f4a2713aSLionel Sambuc   unsigned HWDiv : 2;
3757f4a2713aSLionel Sambuc 
3758f4a2713aSLionel Sambuc   // Initialized via features.
3759f4a2713aSLionel Sambuc   unsigned SoftFloat : 1;
3760f4a2713aSLionel Sambuc   unsigned SoftFloatABI : 1;
3761f4a2713aSLionel Sambuc 
3762f4a2713aSLionel Sambuc   unsigned CRC : 1;
3763*0a6a1f1dSLionel Sambuc   unsigned Crypto : 1;
3764*0a6a1f1dSLionel Sambuc 
3765*0a6a1f1dSLionel Sambuc   // ACLE 6.5.1 Hardware floating point
3766*0a6a1f1dSLionel Sambuc   enum {
3767*0a6a1f1dSLionel Sambuc     HW_FP_HP = (1 << 1), /// half (16-bit)
3768*0a6a1f1dSLionel Sambuc     HW_FP_SP = (1 << 2), /// single (32-bit)
3769*0a6a1f1dSLionel Sambuc     HW_FP_DP = (1 << 3), /// double (64-bit)
3770*0a6a1f1dSLionel Sambuc   };
3771*0a6a1f1dSLionel Sambuc   uint32_t HW_FP;
3772f4a2713aSLionel Sambuc 
3773f4a2713aSLionel Sambuc   static const Builtin::Info BuiltinInfo[];
3774f4a2713aSLionel Sambuc 
shouldUseInlineAtomic(const llvm::Triple & T)3775f4a2713aSLionel Sambuc   static bool shouldUseInlineAtomic(const llvm::Triple &T) {
3776f4a2713aSLionel Sambuc     StringRef ArchName = T.getArchName();
3777*0a6a1f1dSLionel Sambuc     if (T.getArch() == llvm::Triple::arm ||
3778*0a6a1f1dSLionel Sambuc         T.getArch() == llvm::Triple::armeb) {
3779*0a6a1f1dSLionel Sambuc       StringRef VersionStr;
3780*0a6a1f1dSLionel Sambuc       if (ArchName.startswith("armv"))
3781*0a6a1f1dSLionel Sambuc         VersionStr = ArchName.substr(4, 1);
3782*0a6a1f1dSLionel Sambuc       else if (ArchName.startswith("armebv"))
3783*0a6a1f1dSLionel Sambuc         VersionStr = ArchName.substr(6, 1);
3784*0a6a1f1dSLionel Sambuc       else
3785f4a2713aSLionel Sambuc         return false;
3786f4a2713aSLionel Sambuc       unsigned Version;
3787f4a2713aSLionel Sambuc       if (VersionStr.getAsInteger(10, Version))
3788f4a2713aSLionel Sambuc         return false;
3789f4a2713aSLionel Sambuc       return Version >= 6;
3790f4a2713aSLionel Sambuc     }
3791*0a6a1f1dSLionel Sambuc     assert(T.getArch() == llvm::Triple::thumb ||
3792*0a6a1f1dSLionel Sambuc            T.getArch() == llvm::Triple::thumbeb);
3793*0a6a1f1dSLionel Sambuc     StringRef VersionStr;
3794*0a6a1f1dSLionel Sambuc     if (ArchName.startswith("thumbv"))
3795*0a6a1f1dSLionel Sambuc       VersionStr = ArchName.substr(6, 1);
3796*0a6a1f1dSLionel Sambuc     else if (ArchName.startswith("thumbebv"))
3797*0a6a1f1dSLionel Sambuc       VersionStr = ArchName.substr(8, 1);
3798*0a6a1f1dSLionel Sambuc     else
3799f4a2713aSLionel Sambuc       return false;
3800f4a2713aSLionel Sambuc     unsigned Version;
3801f4a2713aSLionel Sambuc     if (VersionStr.getAsInteger(10, Version))
3802f4a2713aSLionel Sambuc       return false;
3803f4a2713aSLionel Sambuc     return Version >= 7;
3804f4a2713aSLionel Sambuc   }
3805f4a2713aSLionel Sambuc 
setABIAAPCS()3806*0a6a1f1dSLionel Sambuc   void setABIAAPCS() {
3807*0a6a1f1dSLionel Sambuc     IsAAPCS = true;
3808*0a6a1f1dSLionel Sambuc 
3809*0a6a1f1dSLionel Sambuc     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
3810*0a6a1f1dSLionel Sambuc     const llvm::Triple &T = getTriple();
3811*0a6a1f1dSLionel Sambuc 
3812*0a6a1f1dSLionel Sambuc     // size_t is unsigned long on MachO-derived environments and NetBSD.
3813*0a6a1f1dSLionel Sambuc     if (T.isOSBinFormatMachO() || T.getOS() == llvm::Triple::NetBSD)
3814*0a6a1f1dSLionel Sambuc       SizeType = UnsignedLong;
3815*0a6a1f1dSLionel Sambuc     else
3816f4a2713aSLionel Sambuc       SizeType = UnsignedInt;
3817*0a6a1f1dSLionel Sambuc 
3818*0a6a1f1dSLionel Sambuc     switch (T.getOS()) {
3819*0a6a1f1dSLionel Sambuc     case llvm::Triple::NetBSD:
3820*0a6a1f1dSLionel Sambuc       WCharType = SignedInt;
3821*0a6a1f1dSLionel Sambuc       break;
3822*0a6a1f1dSLionel Sambuc     case llvm::Triple::Win32:
3823*0a6a1f1dSLionel Sambuc       WCharType = UnsignedShort;
3824*0a6a1f1dSLionel Sambuc       break;
3825*0a6a1f1dSLionel Sambuc     case llvm::Triple::Linux:
3826*0a6a1f1dSLionel Sambuc     default:
3827f4a2713aSLionel Sambuc       // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
3828f4a2713aSLionel Sambuc       WCharType = UnsignedInt;
3829*0a6a1f1dSLionel Sambuc       break;
3830*0a6a1f1dSLionel Sambuc     }
3831*0a6a1f1dSLionel Sambuc 
3832*0a6a1f1dSLionel Sambuc     UseBitFieldTypeAlignment = true;
3833*0a6a1f1dSLionel Sambuc 
3834*0a6a1f1dSLionel Sambuc     ZeroLengthBitfieldBoundary = 0;
3835*0a6a1f1dSLionel Sambuc 
3836*0a6a1f1dSLionel Sambuc     // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
3837*0a6a1f1dSLionel Sambuc     // so set preferred for small types to 32.
3838*0a6a1f1dSLionel Sambuc     if (T.isOSBinFormatMachO()) {
3839*0a6a1f1dSLionel Sambuc       DescriptionString =
3840*0a6a1f1dSLionel Sambuc           BigEndian ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
3841*0a6a1f1dSLionel Sambuc                     : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64";
3842*0a6a1f1dSLionel Sambuc     } else if (T.isOSWindows()) {
3843*0a6a1f1dSLionel Sambuc       // FIXME: this is invalid for WindowsCE
3844*0a6a1f1dSLionel Sambuc       assert(!BigEndian && "Windows on ARM does not support big endian");
3845*0a6a1f1dSLionel Sambuc       DescriptionString = "e"
3846*0a6a1f1dSLionel Sambuc                           "-m:e"
3847*0a6a1f1dSLionel Sambuc                           "-p:32:32"
3848*0a6a1f1dSLionel Sambuc                           "-i64:64"
3849*0a6a1f1dSLionel Sambuc                           "-v128:64:128"
3850*0a6a1f1dSLionel Sambuc                           "-a:0:32"
3851*0a6a1f1dSLionel Sambuc                           "-n32"
3852*0a6a1f1dSLionel Sambuc                           "-S64";
3853*0a6a1f1dSLionel Sambuc     } else {
3854*0a6a1f1dSLionel Sambuc       DescriptionString =
3855*0a6a1f1dSLionel Sambuc           BigEndian ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
3856*0a6a1f1dSLionel Sambuc                     : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64";
3857*0a6a1f1dSLionel Sambuc     }
3858*0a6a1f1dSLionel Sambuc 
3859*0a6a1f1dSLionel Sambuc     // FIXME: Enumerated types are variable width in straight AAPCS.
3860*0a6a1f1dSLionel Sambuc   }
3861*0a6a1f1dSLionel Sambuc 
setABIAPCS()3862*0a6a1f1dSLionel Sambuc   void setABIAPCS() {
3863*0a6a1f1dSLionel Sambuc     const llvm::Triple &T = getTriple();
3864*0a6a1f1dSLionel Sambuc 
3865*0a6a1f1dSLionel Sambuc     IsAAPCS = false;
3866*0a6a1f1dSLionel Sambuc 
3867*0a6a1f1dSLionel Sambuc     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
3868*0a6a1f1dSLionel Sambuc 
3869*0a6a1f1dSLionel Sambuc     // size_t is unsigned int on FreeBSD.
3870*0a6a1f1dSLionel Sambuc     if (T.getOS() == llvm::Triple::FreeBSD)
3871*0a6a1f1dSLionel Sambuc       SizeType = UnsignedInt;
3872*0a6a1f1dSLionel Sambuc     else
3873*0a6a1f1dSLionel Sambuc       SizeType = UnsignedLong;
3874*0a6a1f1dSLionel Sambuc 
3875*0a6a1f1dSLionel Sambuc     // Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
3876*0a6a1f1dSLionel Sambuc     WCharType = SignedInt;
3877*0a6a1f1dSLionel Sambuc 
3878*0a6a1f1dSLionel Sambuc     // Do not respect the alignment of bit-field types when laying out
3879*0a6a1f1dSLionel Sambuc     // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
3880*0a6a1f1dSLionel Sambuc     UseBitFieldTypeAlignment = false;
3881*0a6a1f1dSLionel Sambuc 
3882*0a6a1f1dSLionel Sambuc     /// gcc forces the alignment to 4 bytes, regardless of the type of the
3883*0a6a1f1dSLionel Sambuc     /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
3884*0a6a1f1dSLionel Sambuc     /// gcc.
3885*0a6a1f1dSLionel Sambuc     ZeroLengthBitfieldBoundary = 32;
3886*0a6a1f1dSLionel Sambuc 
3887*0a6a1f1dSLionel Sambuc     if (T.isOSBinFormatMachO())
3888*0a6a1f1dSLionel Sambuc       DescriptionString =
3889*0a6a1f1dSLionel Sambuc           BigEndian
3890*0a6a1f1dSLionel Sambuc               ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
3891*0a6a1f1dSLionel Sambuc               : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
3892*0a6a1f1dSLionel Sambuc     else
3893*0a6a1f1dSLionel Sambuc       DescriptionString =
3894*0a6a1f1dSLionel Sambuc           BigEndian
3895*0a6a1f1dSLionel Sambuc               ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
3896*0a6a1f1dSLionel Sambuc               : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
3897*0a6a1f1dSLionel Sambuc 
3898*0a6a1f1dSLionel Sambuc     // FIXME: Override "preferred align" for double and long long.
3899*0a6a1f1dSLionel Sambuc   }
3900*0a6a1f1dSLionel Sambuc 
3901*0a6a1f1dSLionel Sambuc public:
ARMTargetInfo(const llvm::Triple & Triple,bool IsBigEndian)3902*0a6a1f1dSLionel Sambuc   ARMTargetInfo(const llvm::Triple &Triple, bool IsBigEndian)
3903*0a6a1f1dSLionel Sambuc       : TargetInfo(Triple), CPU("arm1136j-s"), FPMath(FP_Default),
3904*0a6a1f1dSLionel Sambuc         IsAAPCS(true), HW_FP(0) {
3905*0a6a1f1dSLionel Sambuc     BigEndian = IsBigEndian;
3906*0a6a1f1dSLionel Sambuc 
3907*0a6a1f1dSLionel Sambuc     switch (getTriple().getOS()) {
3908*0a6a1f1dSLionel Sambuc     case llvm::Triple::NetBSD:
3909*0a6a1f1dSLionel Sambuc       PtrDiffType = SignedLong;
3910*0a6a1f1dSLionel Sambuc       break;
3911*0a6a1f1dSLionel Sambuc     default:
3912*0a6a1f1dSLionel Sambuc       PtrDiffType = SignedInt;
3913*0a6a1f1dSLionel Sambuc       break;
3914*0a6a1f1dSLionel Sambuc     }
3915f4a2713aSLionel Sambuc 
3916f4a2713aSLionel Sambuc     // {} in inline assembly are neon specifiers, not assembly variant
3917f4a2713aSLionel Sambuc     // specifiers.
3918f4a2713aSLionel Sambuc     NoAsmVariants = true;
3919f4a2713aSLionel Sambuc 
3920f4a2713aSLionel Sambuc     // FIXME: Should we just treat this as a feature?
3921f4a2713aSLionel Sambuc     IsThumb = getTriple().getArchName().startswith("thumb");
3922*0a6a1f1dSLionel Sambuc 
3923*0a6a1f1dSLionel Sambuc     // FIXME: This duplicates code from the driver that sets the -target-abi
3924*0a6a1f1dSLionel Sambuc     // option - this code is used if -target-abi isn't passed and should
3925*0a6a1f1dSLionel Sambuc     // be unified in some way.
3926*0a6a1f1dSLionel Sambuc     if (Triple.isOSBinFormatMachO()) {
3927*0a6a1f1dSLionel Sambuc       // The backend is hardwired to assume AAPCS for M-class processors, ensure
3928*0a6a1f1dSLionel Sambuc       // the frontend matches that.
3929*0a6a1f1dSLionel Sambuc       if (Triple.getEnvironment() == llvm::Triple::EABI ||
3930*0a6a1f1dSLionel Sambuc           Triple.getOS() == llvm::Triple::UnknownOS ||
3931*0a6a1f1dSLionel Sambuc           StringRef(CPU).startswith("cortex-m")) {
3932*0a6a1f1dSLionel Sambuc         setABI("aapcs");
3933f4a2713aSLionel Sambuc       } else {
3934*0a6a1f1dSLionel Sambuc         setABI("apcs-gnu");
3935*0a6a1f1dSLionel Sambuc       }
3936*0a6a1f1dSLionel Sambuc     } else if (Triple.isOSWindows()) {
3937*0a6a1f1dSLionel Sambuc       // FIXME: this is invalid for WindowsCE
3938*0a6a1f1dSLionel Sambuc       setABI("aapcs");
3939*0a6a1f1dSLionel Sambuc     } else {
3940*0a6a1f1dSLionel Sambuc       // Select the default based on the platform.
3941*0a6a1f1dSLionel Sambuc       switch (Triple.getEnvironment()) {
3942*0a6a1f1dSLionel Sambuc       case llvm::Triple::Android:
3943*0a6a1f1dSLionel Sambuc       case llvm::Triple::GNUEABI:
3944*0a6a1f1dSLionel Sambuc       case llvm::Triple::GNUEABIHF:
3945*0a6a1f1dSLionel Sambuc         setABI("aapcs-linux");
3946*0a6a1f1dSLionel Sambuc         break;
3947*0a6a1f1dSLionel Sambuc       case llvm::Triple::EABIHF:
3948*0a6a1f1dSLionel Sambuc       case llvm::Triple::EABI:
3949*0a6a1f1dSLionel Sambuc         setABI("aapcs");
3950*0a6a1f1dSLionel Sambuc         break;
3951*0a6a1f1dSLionel Sambuc       case llvm::Triple::GNU:
3952*0a6a1f1dSLionel Sambuc 	setABI("apcs-gnu");
3953*0a6a1f1dSLionel Sambuc 	break;
3954*0a6a1f1dSLionel Sambuc       default:
3955*0a6a1f1dSLionel Sambuc         if (Triple.getOS() == llvm::Triple::NetBSD)
3956*0a6a1f1dSLionel Sambuc           setABI("apcs-gnu");
3957*0a6a1f1dSLionel Sambuc         else
3958*0a6a1f1dSLionel Sambuc           setABI("aapcs");
3959*0a6a1f1dSLionel Sambuc         break;
3960*0a6a1f1dSLionel Sambuc       }
3961f4a2713aSLionel Sambuc     }
3962f4a2713aSLionel Sambuc 
3963f4a2713aSLionel Sambuc     // ARM targets default to using the ARM C++ ABI.
3964f4a2713aSLionel Sambuc     TheCXXABI.set(TargetCXXABI::GenericARM);
3965f4a2713aSLionel Sambuc 
3966f4a2713aSLionel Sambuc     // ARM has atomics up to 8 bytes
3967f4a2713aSLionel Sambuc     MaxAtomicPromoteWidth = 64;
3968f4a2713aSLionel Sambuc     if (shouldUseInlineAtomic(getTriple()))
3969f4a2713aSLionel Sambuc       MaxAtomicInlineWidth = 64;
3970f4a2713aSLionel Sambuc 
3971f4a2713aSLionel Sambuc     // Do force alignment of members that follow zero length bitfields.  If
3972f4a2713aSLionel Sambuc     // the alignment of the zero-length bitfield is greater than the member
3973f4a2713aSLionel Sambuc     // that follows it, `bar', `bar' will be aligned as the  type of the
3974f4a2713aSLionel Sambuc     // zero length bitfield.
3975f4a2713aSLionel Sambuc     UseZeroLengthBitfieldAlignment = true;
3976f4a2713aSLionel Sambuc   }
getABI() const3977*0a6a1f1dSLionel Sambuc   StringRef getABI() const override { return ABI; }
setABI(const std::string & Name)3978*0a6a1f1dSLionel Sambuc   bool setABI(const std::string &Name) override {
3979f4a2713aSLionel Sambuc     ABI = Name;
3980f4a2713aSLionel Sambuc 
3981f4a2713aSLionel Sambuc     // The defaults (above) are for AAPCS, check if we need to change them.
3982f4a2713aSLionel Sambuc     //
3983f4a2713aSLionel Sambuc     // FIXME: We need support for -meabi... we could just mangle it into the
3984f4a2713aSLionel Sambuc     // name.
3985f4a2713aSLionel Sambuc     if (Name == "apcs-gnu") {
3986*0a6a1f1dSLionel Sambuc       setABIAPCS();
3987f4a2713aSLionel Sambuc       return true;
3988f4a2713aSLionel Sambuc     }
3989*0a6a1f1dSLionel Sambuc     if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
3990*0a6a1f1dSLionel Sambuc       setABIAAPCS();
3991*0a6a1f1dSLionel Sambuc       return true;
3992*0a6a1f1dSLionel Sambuc     }
3993*0a6a1f1dSLionel Sambuc     return false;
3994*0a6a1f1dSLionel Sambuc   }
3995f4a2713aSLionel Sambuc 
getDefaultFeatures(llvm::StringMap<bool> & Features) const3996*0a6a1f1dSLionel Sambuc   void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
3997f4a2713aSLionel Sambuc     StringRef ArchName = getTriple().getArchName();
3998f4a2713aSLionel Sambuc     if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
3999f4a2713aSLionel Sambuc       Features["vfp2"] = true;
4000*0a6a1f1dSLionel Sambuc     else if (CPU == "cortex-a8" || CPU == "cortex-a9") {
4001f4a2713aSLionel Sambuc       Features["vfp3"] = true;
4002f4a2713aSLionel Sambuc       Features["neon"] = true;
4003f4a2713aSLionel Sambuc     }
4004f4a2713aSLionel Sambuc     else if (CPU == "cortex-a5") {
4005f4a2713aSLionel Sambuc       Features["vfp4"] = true;
4006f4a2713aSLionel Sambuc       Features["neon"] = true;
4007*0a6a1f1dSLionel Sambuc     } else if (CPU == "swift" || CPU == "cortex-a7" ||
4008*0a6a1f1dSLionel Sambuc                CPU == "cortex-a12" || CPU == "cortex-a15" ||
4009*0a6a1f1dSLionel Sambuc                CPU == "cortex-a17" || CPU == "krait") {
4010f4a2713aSLionel Sambuc       Features["vfp4"] = true;
4011f4a2713aSLionel Sambuc       Features["neon"] = true;
4012f4a2713aSLionel Sambuc       Features["hwdiv"] = true;
4013f4a2713aSLionel Sambuc       Features["hwdiv-arm"] = true;
4014*0a6a1f1dSLionel Sambuc     } else if (CPU == "cyclone") {
4015*0a6a1f1dSLionel Sambuc       Features["v8fp"] = true;
4016*0a6a1f1dSLionel Sambuc       Features["neon"] = true;
4017*0a6a1f1dSLionel Sambuc       Features["hwdiv"] = true;
4018*0a6a1f1dSLionel Sambuc       Features["hwdiv-arm"] = true;
4019f4a2713aSLionel Sambuc     } else if (CPU == "cortex-a53" || CPU == "cortex-a57") {
4020f4a2713aSLionel Sambuc       Features["fp-armv8"] = true;
4021f4a2713aSLionel Sambuc       Features["neon"] = true;
4022f4a2713aSLionel Sambuc       Features["hwdiv"] = true;
4023f4a2713aSLionel Sambuc       Features["hwdiv-arm"] = true;
4024f4a2713aSLionel Sambuc       Features["crc"] = true;
4025*0a6a1f1dSLionel Sambuc       Features["crypto"] = true;
4026*0a6a1f1dSLionel Sambuc     } else if (CPU == "cortex-r5" ||
4027f4a2713aSLionel Sambuc                // Enable the hwdiv extension for all v8a AArch32 cores by
4028f4a2713aSLionel Sambuc                // default.
4029f4a2713aSLionel Sambuc                ArchName == "armv8a" || ArchName == "armv8" ||
4030*0a6a1f1dSLionel Sambuc                ArchName == "armebv8a" || ArchName == "armebv8" ||
4031*0a6a1f1dSLionel Sambuc                ArchName == "thumbv8a" || ArchName == "thumbv8" ||
4032*0a6a1f1dSLionel Sambuc                ArchName == "thumbebv8a" || ArchName == "thumbebv8") {
4033f4a2713aSLionel Sambuc       Features["hwdiv"] = true;
4034f4a2713aSLionel Sambuc       Features["hwdiv-arm"] = true;
4035*0a6a1f1dSLionel Sambuc     } else if (CPU == "cortex-m3" || CPU == "cortex-m4" || CPU == "cortex-m7") {
4036*0a6a1f1dSLionel Sambuc       Features["hwdiv"] = true;
4037f4a2713aSLionel Sambuc     }
4038f4a2713aSLionel Sambuc   }
4039f4a2713aSLionel Sambuc 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)4040*0a6a1f1dSLionel Sambuc   bool handleTargetFeatures(std::vector<std::string> &Features,
4041*0a6a1f1dSLionel Sambuc                             DiagnosticsEngine &Diags) override {
4042f4a2713aSLionel Sambuc     FPU = 0;
4043f4a2713aSLionel Sambuc     CRC = 0;
4044*0a6a1f1dSLionel Sambuc     Crypto = 0;
4045f4a2713aSLionel Sambuc     SoftFloat = SoftFloatABI = false;
4046f4a2713aSLionel Sambuc     HWDiv = 0;
4047*0a6a1f1dSLionel Sambuc 
4048*0a6a1f1dSLionel Sambuc     for (const auto &Feature : Features) {
4049*0a6a1f1dSLionel Sambuc       if (Feature == "+soft-float") {
4050f4a2713aSLionel Sambuc         SoftFloat = true;
4051*0a6a1f1dSLionel Sambuc       } else if (Feature == "+soft-float-abi") {
4052f4a2713aSLionel Sambuc         SoftFloatABI = true;
4053*0a6a1f1dSLionel Sambuc       } else if (Feature == "+vfp2") {
4054f4a2713aSLionel Sambuc         FPU |= VFP2FPU;
4055*0a6a1f1dSLionel Sambuc         HW_FP = HW_FP_SP | HW_FP_DP;
4056*0a6a1f1dSLionel Sambuc       } else if (Feature == "+vfp3") {
4057f4a2713aSLionel Sambuc         FPU |= VFP3FPU;
4058*0a6a1f1dSLionel Sambuc         HW_FP = HW_FP_SP | HW_FP_DP;
4059*0a6a1f1dSLionel Sambuc       } else if (Feature == "+vfp4") {
4060f4a2713aSLionel Sambuc         FPU |= VFP4FPU;
4061*0a6a1f1dSLionel Sambuc         HW_FP = HW_FP_SP | HW_FP_DP | HW_FP_HP;
4062*0a6a1f1dSLionel Sambuc       } else if (Feature == "+fp-armv8") {
4063f4a2713aSLionel Sambuc         FPU |= FPARMV8;
4064*0a6a1f1dSLionel Sambuc         HW_FP = HW_FP_SP | HW_FP_DP | HW_FP_HP;
4065*0a6a1f1dSLionel Sambuc       } else if (Feature == "+neon") {
4066f4a2713aSLionel Sambuc         FPU |= NeonFPU;
4067*0a6a1f1dSLionel Sambuc         HW_FP = HW_FP_SP | HW_FP_DP;
4068*0a6a1f1dSLionel Sambuc       } else if (Feature == "+hwdiv") {
4069f4a2713aSLionel Sambuc         HWDiv |= HWDivThumb;
4070*0a6a1f1dSLionel Sambuc       } else if (Feature == "+hwdiv-arm") {
4071f4a2713aSLionel Sambuc         HWDiv |= HWDivARM;
4072*0a6a1f1dSLionel Sambuc       } else if (Feature == "+crc") {
4073f4a2713aSLionel Sambuc         CRC = 1;
4074*0a6a1f1dSLionel Sambuc       } else if (Feature == "+crypto") {
4075*0a6a1f1dSLionel Sambuc         Crypto = 1;
4076*0a6a1f1dSLionel Sambuc       } else if (Feature == "+fp-only-sp") {
4077*0a6a1f1dSLionel Sambuc         HW_FP &= ~HW_FP_DP;
4078*0a6a1f1dSLionel Sambuc       }
4079f4a2713aSLionel Sambuc     }
4080f4a2713aSLionel Sambuc 
4081f4a2713aSLionel Sambuc     if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
4082f4a2713aSLionel Sambuc       Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
4083f4a2713aSLionel Sambuc       return false;
4084f4a2713aSLionel Sambuc     }
4085f4a2713aSLionel Sambuc 
4086f4a2713aSLionel Sambuc     if (FPMath == FP_Neon)
4087f4a2713aSLionel Sambuc       Features.push_back("+neonfp");
4088f4a2713aSLionel Sambuc     else if (FPMath == FP_VFP)
4089f4a2713aSLionel Sambuc       Features.push_back("-neonfp");
4090f4a2713aSLionel Sambuc 
4091f4a2713aSLionel Sambuc     // Remove front-end specific options which the backend handles differently.
4092*0a6a1f1dSLionel Sambuc     const StringRef FrontEndFeatures[] = { "+soft-float", "+soft-float-abi" };
4093*0a6a1f1dSLionel Sambuc     for (const auto &FEFeature : FrontEndFeatures) {
4094*0a6a1f1dSLionel Sambuc       auto Feature = std::find(Features.begin(), Features.end(), FEFeature);
4095*0a6a1f1dSLionel Sambuc       if (Feature != Features.end())
4096*0a6a1f1dSLionel Sambuc         Features.erase(Feature);
4097*0a6a1f1dSLionel Sambuc     }
4098*0a6a1f1dSLionel Sambuc 
4099f4a2713aSLionel Sambuc     return true;
4100f4a2713aSLionel Sambuc   }
4101f4a2713aSLionel Sambuc 
hasFeature(StringRef Feature) const4102*0a6a1f1dSLionel Sambuc   bool hasFeature(StringRef Feature) const override {
4103f4a2713aSLionel Sambuc     return llvm::StringSwitch<bool>(Feature)
4104f4a2713aSLionel Sambuc         .Case("arm", true)
4105f4a2713aSLionel Sambuc         .Case("softfloat", SoftFloat)
4106f4a2713aSLionel Sambuc         .Case("thumb", IsThumb)
4107f4a2713aSLionel Sambuc         .Case("neon", (FPU & NeonFPU) && !SoftFloat)
4108f4a2713aSLionel Sambuc         .Case("hwdiv", HWDiv & HWDivThumb)
4109f4a2713aSLionel Sambuc         .Case("hwdiv-arm", HWDiv & HWDivARM)
4110f4a2713aSLionel Sambuc         .Default(false);
4111f4a2713aSLionel Sambuc   }
4112f4a2713aSLionel Sambuc   // FIXME: Should we actually have some table instead of these switches?
getCPUDefineSuffix(StringRef Name)4113f4a2713aSLionel Sambuc   static const char *getCPUDefineSuffix(StringRef Name) {
4114f4a2713aSLionel Sambuc     return llvm::StringSwitch<const char *>(Name)
4115f4a2713aSLionel Sambuc         .Cases("arm8", "arm810", "4")
4116*0a6a1f1dSLionel Sambuc         .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110",
4117*0a6a1f1dSLionel Sambuc                "4")
4118f4a2713aSLionel Sambuc         .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
4119f4a2713aSLionel Sambuc         .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
4120f4a2713aSLionel Sambuc         .Case("ep9312", "4T")
4121f4a2713aSLionel Sambuc         .Cases("arm10tdmi", "arm1020t", "5T")
4122f4a2713aSLionel Sambuc         .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
4123f4a2713aSLionel Sambuc         .Case("arm926ej-s", "5TEJ")
4124f4a2713aSLionel Sambuc         .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
4125f4a2713aSLionel Sambuc         .Cases("xscale", "iwmmxt", "5TE")
4126f4a2713aSLionel Sambuc         .Case("arm1136j-s", "6J")
4127f4a2713aSLionel Sambuc         .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
4128f4a2713aSLionel Sambuc         .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
4129f4a2713aSLionel Sambuc         .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
4130f4a2713aSLionel Sambuc         .Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A")
4131*0a6a1f1dSLionel Sambuc         .Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait",
4132*0a6a1f1dSLionel Sambuc                "7A")
4133f4a2713aSLionel Sambuc         .Cases("cortex-r4", "cortex-r5", "7R")
4134f4a2713aSLionel Sambuc         .Case("swift", "7S")
4135*0a6a1f1dSLionel Sambuc         .Case("cyclone", "8A")
4136*0a6a1f1dSLionel Sambuc         .Case("cortex-m3", "7M")
4137*0a6a1f1dSLionel Sambuc         .Cases("cortex-m4", "cortex-m7", "7EM")
4138f4a2713aSLionel Sambuc         .Case("cortex-m0", "6M")
4139f4a2713aSLionel Sambuc         .Cases("cortex-a53", "cortex-a57", "8A")
4140*0a6a1f1dSLionel Sambuc         .Default(nullptr);
4141f4a2713aSLionel Sambuc   }
getCPUProfile(StringRef Name)4142f4a2713aSLionel Sambuc   static const char *getCPUProfile(StringRef Name) {
4143f4a2713aSLionel Sambuc     return llvm::StringSwitch<const char *>(Name)
4144f4a2713aSLionel Sambuc         .Cases("cortex-a5", "cortex-a7", "cortex-a8", "A")
4145*0a6a1f1dSLionel Sambuc         .Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait",
4146*0a6a1f1dSLionel Sambuc                "A")
4147f4a2713aSLionel Sambuc         .Cases("cortex-a53", "cortex-a57", "A")
4148*0a6a1f1dSLionel Sambuc         .Cases("cortex-m3", "cortex-m4", "cortex-m0", "cortex-m7", "M")
4149f4a2713aSLionel Sambuc         .Cases("cortex-r4", "cortex-r5", "R")
4150f4a2713aSLionel Sambuc         .Default("");
4151f4a2713aSLionel Sambuc   }
setCPU(const std::string & Name)4152*0a6a1f1dSLionel Sambuc   bool setCPU(const std::string &Name) override {
4153f4a2713aSLionel Sambuc     if (!getCPUDefineSuffix(Name))
4154f4a2713aSLionel Sambuc       return false;
4155f4a2713aSLionel Sambuc 
4156*0a6a1f1dSLionel Sambuc     // Cortex M does not support 8 byte atomics, while general Thumb2 does.
4157*0a6a1f1dSLionel Sambuc     StringRef Profile = getCPUProfile(Name);
4158*0a6a1f1dSLionel Sambuc     if (Profile == "M" && MaxAtomicInlineWidth) {
4159*0a6a1f1dSLionel Sambuc       MaxAtomicPromoteWidth = 32;
4160*0a6a1f1dSLionel Sambuc       MaxAtomicInlineWidth = 32;
4161*0a6a1f1dSLionel Sambuc     }
4162*0a6a1f1dSLionel Sambuc 
4163f4a2713aSLionel Sambuc     CPU = Name;
4164f4a2713aSLionel Sambuc     return true;
4165f4a2713aSLionel Sambuc   }
4166*0a6a1f1dSLionel Sambuc   bool setFPMath(StringRef Name) override;
supportsThumb(StringRef ArchName,StringRef CPUArch,unsigned CPUArchVer) const4167*0a6a1f1dSLionel Sambuc   bool supportsThumb(StringRef ArchName, StringRef CPUArch,
4168*0a6a1f1dSLionel Sambuc                      unsigned CPUArchVer) const {
4169*0a6a1f1dSLionel Sambuc     return CPUArchVer >= 7 || (CPUArch.find('T') != StringRef::npos) ||
4170*0a6a1f1dSLionel Sambuc            (CPUArch.find('M') != StringRef::npos);
4171*0a6a1f1dSLionel Sambuc   }
supportsThumb2(StringRef ArchName,StringRef CPUArch,unsigned CPUArchVer) const4172*0a6a1f1dSLionel Sambuc   bool supportsThumb2(StringRef ArchName, StringRef CPUArch,
4173*0a6a1f1dSLionel Sambuc                       unsigned CPUArchVer) const {
4174*0a6a1f1dSLionel Sambuc     // We check both CPUArchVer and ArchName because when only triple is
4175*0a6a1f1dSLionel Sambuc     // specified, the default CPU is arm1136j-s.
4176*0a6a1f1dSLionel Sambuc     return ArchName.endswith("v6t2") || ArchName.endswith("v7") ||
4177*0a6a1f1dSLionel Sambuc            ArchName.endswith("v8") || CPUArch == "6T2" || CPUArchVer >= 7;
4178*0a6a1f1dSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4179*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
4180*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
4181f4a2713aSLionel Sambuc     // Target identification.
4182f4a2713aSLionel Sambuc     Builder.defineMacro("__arm");
4183f4a2713aSLionel Sambuc     Builder.defineMacro("__arm__");
4184f4a2713aSLionel Sambuc 
4185f4a2713aSLionel Sambuc     // Target properties.
4186f4a2713aSLionel Sambuc     Builder.defineMacro("__REGISTER_PREFIX__", "");
4187f4a2713aSLionel Sambuc 
4188f4a2713aSLionel Sambuc     StringRef CPUArch = getCPUDefineSuffix(CPU);
4189f4a2713aSLionel Sambuc     unsigned int CPUArchVer;
4190*0a6a1f1dSLionel Sambuc     if (CPUArch.substr(0, 1).getAsInteger<unsigned int>(10, CPUArchVer))
4191f4a2713aSLionel Sambuc       llvm_unreachable("Invalid char for architecture version number");
4192f4a2713aSLionel Sambuc     Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
4193*0a6a1f1dSLionel Sambuc 
4194*0a6a1f1dSLionel Sambuc     // ACLE 6.4.1 ARM/Thumb instruction set architecture
4195f4a2713aSLionel Sambuc     StringRef CPUProfile = getCPUProfile(CPU);
4196*0a6a1f1dSLionel Sambuc     StringRef ArchName = getTriple().getArchName();
4197*0a6a1f1dSLionel Sambuc 
4198*0a6a1f1dSLionel Sambuc     // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
4199*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
4200*0a6a1f1dSLionel Sambuc     if (CPUArch[0] >= '8') {
4201*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN");
4202*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING");
4203*0a6a1f1dSLionel Sambuc     }
4204*0a6a1f1dSLionel Sambuc 
4205*0a6a1f1dSLionel Sambuc     // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
4206*0a6a1f1dSLionel Sambuc     // is not defined for the M-profile.
4207*0a6a1f1dSLionel Sambuc     // NOTE that the deffault profile is assumed to be 'A'
4208*0a6a1f1dSLionel Sambuc     if (CPUProfile.empty() || CPUProfile != "M")
4209*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
4210*0a6a1f1dSLionel Sambuc 
4211*0a6a1f1dSLionel Sambuc     // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supporst the original
4212*0a6a1f1dSLionel Sambuc     // Thumb ISA (including v6-M).  It is set to 2 if the core supports the
4213*0a6a1f1dSLionel Sambuc     // Thumb-2 ISA as found in the v6T2 architecture and all v7 architecture.
4214*0a6a1f1dSLionel Sambuc     if (supportsThumb2(ArchName, CPUArch, CPUArchVer))
4215*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
4216*0a6a1f1dSLionel Sambuc     else if (supportsThumb(ArchName, CPUArch, CPUArchVer))
4217*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
4218*0a6a1f1dSLionel Sambuc 
4219*0a6a1f1dSLionel Sambuc     // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
4220*0a6a1f1dSLionel Sambuc     // instruction set such as ARM or Thumb.
4221*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_32BIT_STATE", "1");
4222*0a6a1f1dSLionel Sambuc 
4223*0a6a1f1dSLionel Sambuc     // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
4224*0a6a1f1dSLionel Sambuc 
4225*0a6a1f1dSLionel Sambuc     // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
4226f4a2713aSLionel Sambuc     if (!CPUProfile.empty())
4227*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
4228*0a6a1f1dSLionel Sambuc 
4229*0a6a1f1dSLionel Sambuc     // ACLE 6.5.1 Hardware Floating Point
4230*0a6a1f1dSLionel Sambuc     if (HW_FP)
4231*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_FP", "0x" + llvm::utohexstr(HW_FP));
4232*0a6a1f1dSLionel Sambuc 
4233*0a6a1f1dSLionel Sambuc     // ACLE predefines.
4234*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_ACLE", "200");
4235f4a2713aSLionel Sambuc 
4236f4a2713aSLionel Sambuc     // Subtarget options.
4237f4a2713aSLionel Sambuc 
4238f4a2713aSLionel Sambuc     // FIXME: It's more complicated than this and we don't really support
4239f4a2713aSLionel Sambuc     // interworking.
4240*0a6a1f1dSLionel Sambuc     // Windows on ARM does not "support" interworking
4241*0a6a1f1dSLionel Sambuc     if (5 <= CPUArchVer && CPUArchVer <= 8 && !getTriple().isOSWindows())
4242f4a2713aSLionel Sambuc       Builder.defineMacro("__THUMB_INTERWORK__");
4243f4a2713aSLionel Sambuc 
4244f4a2713aSLionel Sambuc     if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
4245f4a2713aSLionel Sambuc       // Embedded targets on Darwin follow AAPCS, but not EABI.
4246*0a6a1f1dSLionel Sambuc       // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
4247*0a6a1f1dSLionel Sambuc       if (!getTriple().isOSDarwin() && !getTriple().isOSWindows())
4248f4a2713aSLionel Sambuc         Builder.defineMacro("__ARM_EABI__");
4249f4a2713aSLionel Sambuc       Builder.defineMacro("__ARM_PCS", "1");
4250f4a2713aSLionel Sambuc 
4251f4a2713aSLionel Sambuc       if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp")
4252f4a2713aSLionel Sambuc         Builder.defineMacro("__ARM_PCS_VFP", "1");
4253f4a2713aSLionel Sambuc     }
4254f4a2713aSLionel Sambuc 
4255f4a2713aSLionel Sambuc     if (SoftFloat)
4256f4a2713aSLionel Sambuc       Builder.defineMacro("__SOFTFP__");
4257f4a2713aSLionel Sambuc 
4258f4a2713aSLionel Sambuc     if (CPU == "xscale")
4259f4a2713aSLionel Sambuc       Builder.defineMacro("__XSCALE__");
4260f4a2713aSLionel Sambuc 
4261f4a2713aSLionel Sambuc     if (IsThumb) {
4262f4a2713aSLionel Sambuc       Builder.defineMacro("__THUMBEL__");
4263f4a2713aSLionel Sambuc       Builder.defineMacro("__thumb__");
4264*0a6a1f1dSLionel Sambuc       if (supportsThumb2(ArchName, CPUArch, CPUArchVer))
4265f4a2713aSLionel Sambuc         Builder.defineMacro("__thumb2__");
4266f4a2713aSLionel Sambuc     }
4267f4a2713aSLionel Sambuc     if (((HWDiv & HWDivThumb) && IsThumb) || ((HWDiv & HWDivARM) && !IsThumb))
4268f4a2713aSLionel Sambuc       Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
4269f4a2713aSLionel Sambuc 
4270f4a2713aSLionel Sambuc     // Note, this is always on in gcc, even though it doesn't make sense.
4271f4a2713aSLionel Sambuc     Builder.defineMacro("__APCS_32__");
4272f4a2713aSLionel Sambuc 
4273f4a2713aSLionel Sambuc     if (FPUModeIsVFP((FPUMode) FPU)) {
4274f4a2713aSLionel Sambuc       Builder.defineMacro("__VFP_FP__");
4275f4a2713aSLionel Sambuc       if (FPU & VFP2FPU)
4276f4a2713aSLionel Sambuc         Builder.defineMacro("__ARM_VFPV2__");
4277f4a2713aSLionel Sambuc       if (FPU & VFP3FPU)
4278f4a2713aSLionel Sambuc         Builder.defineMacro("__ARM_VFPV3__");
4279f4a2713aSLionel Sambuc       if (FPU & VFP4FPU)
4280f4a2713aSLionel Sambuc         Builder.defineMacro("__ARM_VFPV4__");
4281f4a2713aSLionel Sambuc     }
4282f4a2713aSLionel Sambuc 
4283f4a2713aSLionel Sambuc     // This only gets set when Neon instructions are actually available, unlike
4284f4a2713aSLionel Sambuc     // the VFP define, hence the soft float and arch check. This is subtly
4285f4a2713aSLionel Sambuc     // different from gcc, we follow the intent which was that it should be set
4286f4a2713aSLionel Sambuc     // when Neon instructions are actually available.
4287*0a6a1f1dSLionel Sambuc     if ((FPU & NeonFPU) && !SoftFloat && CPUArchVer >= 7) {
4288*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_NEON");
4289f4a2713aSLionel Sambuc       Builder.defineMacro("__ARM_NEON__");
4290*0a6a1f1dSLionel Sambuc     }
4291*0a6a1f1dSLionel Sambuc 
4292*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
4293*0a6a1f1dSLionel Sambuc                         Opts.ShortWChar ? "2" : "4");
4294*0a6a1f1dSLionel Sambuc 
4295*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
4296*0a6a1f1dSLionel Sambuc                         Opts.ShortEnums ? "1" : "4");
4297f4a2713aSLionel Sambuc 
4298f4a2713aSLionel Sambuc     if (CRC)
4299f4a2713aSLionel Sambuc       Builder.defineMacro("__ARM_FEATURE_CRC32");
4300f4a2713aSLionel Sambuc 
4301*0a6a1f1dSLionel Sambuc     if (Crypto)
4302*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_FEATURE_CRYPTO");
4303*0a6a1f1dSLionel Sambuc 
4304f4a2713aSLionel Sambuc     if (CPUArchVer >= 6 && CPUArch != "6M") {
4305f4a2713aSLionel Sambuc       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
4306f4a2713aSLionel Sambuc       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
4307f4a2713aSLionel Sambuc       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
4308f4a2713aSLionel Sambuc       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
4309f4a2713aSLionel Sambuc     }
4310*0a6a1f1dSLionel Sambuc 
4311*0a6a1f1dSLionel Sambuc     bool is5EOrAbove = (CPUArchVer >= 6 ||
4312*0a6a1f1dSLionel Sambuc                         (CPUArchVer == 5 &&
4313*0a6a1f1dSLionel Sambuc                          CPUArch.find('E') != StringRef::npos));
4314*0a6a1f1dSLionel Sambuc     bool is32Bit = (!IsThumb || supportsThumb2(ArchName, CPUArch, CPUArchVer));
4315*0a6a1f1dSLionel Sambuc     if (is5EOrAbove && is32Bit && (CPUProfile != "M" || CPUArch  == "7EM"))
4316*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_FEATURE_DSP");
4317f4a2713aSLionel Sambuc   }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const4318*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
4319*0a6a1f1dSLionel Sambuc                          unsigned &NumRecords) const override {
4320f4a2713aSLionel Sambuc     Records = BuiltinInfo;
4321f4a2713aSLionel Sambuc     NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
4322f4a2713aSLionel Sambuc   }
isCLZForZeroUndef() const4323*0a6a1f1dSLionel Sambuc   bool isCLZForZeroUndef() const override { return false; }
getBuiltinVaListKind() const4324*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
4325f4a2713aSLionel Sambuc     return IsAAPCS ? AAPCSABIBuiltinVaList : TargetInfo::VoidPtrBuiltinVaList;
4326f4a2713aSLionel Sambuc   }
4327*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char * const *&Names,
4328*0a6a1f1dSLionel Sambuc                       unsigned &NumNames) const override;
4329*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
4330*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const4331*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
4332*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &Info) const override {
4333f4a2713aSLionel Sambuc     switch (*Name) {
4334f4a2713aSLionel Sambuc     default: break;
4335f4a2713aSLionel Sambuc     case 'l': // r0-r7
4336f4a2713aSLionel Sambuc     case 'h': // r8-r15
4337f4a2713aSLionel Sambuc     case 'w': // VFP Floating point register single precision
4338f4a2713aSLionel Sambuc     case 'P': // VFP Floating point register double precision
4339f4a2713aSLionel Sambuc       Info.setAllowsRegister();
4340f4a2713aSLionel Sambuc       return true;
4341*0a6a1f1dSLionel Sambuc     case 'I':
4342*0a6a1f1dSLionel Sambuc     case 'J':
4343*0a6a1f1dSLionel Sambuc     case 'K':
4344*0a6a1f1dSLionel Sambuc     case 'L':
4345*0a6a1f1dSLionel Sambuc     case 'M':
4346*0a6a1f1dSLionel Sambuc       // FIXME
4347*0a6a1f1dSLionel Sambuc       return true;
4348f4a2713aSLionel Sambuc     case 'Q': // A memory address that is a single base register.
4349f4a2713aSLionel Sambuc       Info.setAllowsMemory();
4350f4a2713aSLionel Sambuc       return true;
4351f4a2713aSLionel Sambuc     case 'U': // a memory reference...
4352f4a2713aSLionel Sambuc       switch (Name[1]) {
4353f4a2713aSLionel Sambuc       case 'q': // ...ARMV4 ldrsb
4354f4a2713aSLionel Sambuc       case 'v': // ...VFP load/store (reg+constant offset)
4355f4a2713aSLionel Sambuc       case 'y': // ...iWMMXt load/store
4356f4a2713aSLionel Sambuc       case 't': // address valid for load/store opaque types wider
4357f4a2713aSLionel Sambuc                 // than 128-bits
4358f4a2713aSLionel Sambuc       case 'n': // valid address for Neon doubleword vector load/store
4359f4a2713aSLionel Sambuc       case 'm': // valid address for Neon element and structure load/store
4360f4a2713aSLionel Sambuc       case 's': // valid address for non-offset loads/stores of quad-word
4361f4a2713aSLionel Sambuc                 // values in four ARM registers
4362f4a2713aSLionel Sambuc         Info.setAllowsMemory();
4363f4a2713aSLionel Sambuc         Name++;
4364f4a2713aSLionel Sambuc         return true;
4365f4a2713aSLionel Sambuc       }
4366f4a2713aSLionel Sambuc     }
4367f4a2713aSLionel Sambuc     return false;
4368f4a2713aSLionel Sambuc   }
convertConstraint(const char * & Constraint) const4369*0a6a1f1dSLionel Sambuc   std::string convertConstraint(const char *&Constraint) const override {
4370f4a2713aSLionel Sambuc     std::string R;
4371f4a2713aSLionel Sambuc     switch (*Constraint) {
4372f4a2713aSLionel Sambuc     case 'U':   // Two-character constraint; add "^" hint for later parsing.
4373f4a2713aSLionel Sambuc       R = std::string("^") + std::string(Constraint, 2);
4374f4a2713aSLionel Sambuc       Constraint++;
4375f4a2713aSLionel Sambuc       break;
4376f4a2713aSLionel Sambuc     case 'p': // 'p' should be translated to 'r' by default.
4377f4a2713aSLionel Sambuc       R = std::string("r");
4378f4a2713aSLionel Sambuc       break;
4379f4a2713aSLionel Sambuc     default:
4380f4a2713aSLionel Sambuc       return std::string(1, *Constraint);
4381f4a2713aSLionel Sambuc     }
4382f4a2713aSLionel Sambuc     return R;
4383f4a2713aSLionel Sambuc   }
4384*0a6a1f1dSLionel Sambuc   bool
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const4385*0a6a1f1dSLionel Sambuc   validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
4386*0a6a1f1dSLionel Sambuc                              std::string &SuggestedModifier) const override {
4387f4a2713aSLionel Sambuc     bool isOutput = (Constraint[0] == '=');
4388f4a2713aSLionel Sambuc     bool isInOut = (Constraint[0] == '+');
4389f4a2713aSLionel Sambuc 
4390f4a2713aSLionel Sambuc     // Strip off constraint modifiers.
4391f4a2713aSLionel Sambuc     while (Constraint[0] == '=' ||
4392f4a2713aSLionel Sambuc            Constraint[0] == '+' ||
4393f4a2713aSLionel Sambuc            Constraint[0] == '&')
4394f4a2713aSLionel Sambuc       Constraint = Constraint.substr(1);
4395f4a2713aSLionel Sambuc 
4396f4a2713aSLionel Sambuc     switch (Constraint[0]) {
4397f4a2713aSLionel Sambuc     default: break;
4398f4a2713aSLionel Sambuc     case 'r': {
4399f4a2713aSLionel Sambuc       switch (Modifier) {
4400f4a2713aSLionel Sambuc       default:
4401*0a6a1f1dSLionel Sambuc         return (isInOut || isOutput || Size <= 64);
4402f4a2713aSLionel Sambuc       case 'q':
4403f4a2713aSLionel Sambuc         // A register of size 32 cannot fit a vector type.
4404f4a2713aSLionel Sambuc         return false;
4405f4a2713aSLionel Sambuc       }
4406f4a2713aSLionel Sambuc     }
4407f4a2713aSLionel Sambuc     }
4408f4a2713aSLionel Sambuc 
4409f4a2713aSLionel Sambuc     return true;
4410f4a2713aSLionel Sambuc   }
getClobbers() const4411*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override {
4412f4a2713aSLionel Sambuc     // FIXME: Is this really right?
4413f4a2713aSLionel Sambuc     return "";
4414f4a2713aSLionel Sambuc   }
4415f4a2713aSLionel Sambuc 
checkCallingConvention(CallingConv CC) const4416*0a6a1f1dSLionel Sambuc   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
4417f4a2713aSLionel Sambuc     return (CC == CC_AAPCS || CC == CC_AAPCS_VFP) ? CCCR_OK : CCCR_Warning;
4418f4a2713aSLionel Sambuc   }
4419f4a2713aSLionel Sambuc 
getEHDataRegisterNumber(unsigned RegNo) const4420*0a6a1f1dSLionel Sambuc   int getEHDataRegisterNumber(unsigned RegNo) const override {
4421f4a2713aSLionel Sambuc     if (RegNo == 0) return 0;
4422f4a2713aSLionel Sambuc     if (RegNo == 1) return 1;
4423f4a2713aSLionel Sambuc     return -1;
4424f4a2713aSLionel Sambuc   }
4425f4a2713aSLionel Sambuc };
4426f4a2713aSLionel Sambuc 
setFPMath(StringRef Name)4427f4a2713aSLionel Sambuc bool ARMTargetInfo::setFPMath(StringRef Name) {
4428f4a2713aSLionel Sambuc   if (Name == "neon") {
4429f4a2713aSLionel Sambuc     FPMath = FP_Neon;
4430f4a2713aSLionel Sambuc     return true;
4431f4a2713aSLionel Sambuc   } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
4432f4a2713aSLionel Sambuc              Name == "vfp4") {
4433f4a2713aSLionel Sambuc     FPMath = FP_VFP;
4434f4a2713aSLionel Sambuc     return true;
4435f4a2713aSLionel Sambuc   }
4436f4a2713aSLionel Sambuc   return false;
4437f4a2713aSLionel Sambuc }
4438f4a2713aSLionel Sambuc 
4439f4a2713aSLionel Sambuc const char * const ARMTargetInfo::GCCRegNames[] = {
4440f4a2713aSLionel Sambuc   // Integer registers
4441f4a2713aSLionel Sambuc   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
4442f4a2713aSLionel Sambuc   "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
4443f4a2713aSLionel Sambuc 
4444f4a2713aSLionel Sambuc   // Float registers
4445f4a2713aSLionel Sambuc   "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
4446f4a2713aSLionel Sambuc   "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
4447f4a2713aSLionel Sambuc   "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
4448f4a2713aSLionel Sambuc   "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
4449f4a2713aSLionel Sambuc 
4450f4a2713aSLionel Sambuc   // Double registers
4451f4a2713aSLionel Sambuc   "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
4452f4a2713aSLionel Sambuc   "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
4453f4a2713aSLionel Sambuc   "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
4454f4a2713aSLionel Sambuc   "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
4455f4a2713aSLionel Sambuc 
4456f4a2713aSLionel Sambuc   // Quad registers
4457f4a2713aSLionel Sambuc   "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
4458f4a2713aSLionel Sambuc   "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
4459f4a2713aSLionel Sambuc };
4460f4a2713aSLionel Sambuc 
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const4461f4a2713aSLionel Sambuc void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
4462f4a2713aSLionel Sambuc                                    unsigned &NumNames) const {
4463f4a2713aSLionel Sambuc   Names = GCCRegNames;
4464f4a2713aSLionel Sambuc   NumNames = llvm::array_lengthof(GCCRegNames);
4465f4a2713aSLionel Sambuc }
4466f4a2713aSLionel Sambuc 
4467f4a2713aSLionel Sambuc const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
4468f4a2713aSLionel Sambuc   { { "a1" }, "r0" },
4469f4a2713aSLionel Sambuc   { { "a2" }, "r1" },
4470f4a2713aSLionel Sambuc   { { "a3" }, "r2" },
4471f4a2713aSLionel Sambuc   { { "a4" }, "r3" },
4472f4a2713aSLionel Sambuc   { { "v1" }, "r4" },
4473f4a2713aSLionel Sambuc   { { "v2" }, "r5" },
4474f4a2713aSLionel Sambuc   { { "v3" }, "r6" },
4475f4a2713aSLionel Sambuc   { { "v4" }, "r7" },
4476f4a2713aSLionel Sambuc   { { "v5" }, "r8" },
4477f4a2713aSLionel Sambuc   { { "v6", "rfp" }, "r9" },
4478f4a2713aSLionel Sambuc   { { "sl" }, "r10" },
4479f4a2713aSLionel Sambuc   { { "fp" }, "r11" },
4480f4a2713aSLionel Sambuc   { { "ip" }, "r12" },
4481f4a2713aSLionel Sambuc   { { "r13" }, "sp" },
4482f4a2713aSLionel Sambuc   { { "r14" }, "lr" },
4483f4a2713aSLionel Sambuc   { { "r15" }, "pc" },
4484f4a2713aSLionel Sambuc   // The S, D and Q registers overlap, but aren't really aliases; we
4485f4a2713aSLionel Sambuc   // don't want to substitute one of these for a different-sized one.
4486f4a2713aSLionel Sambuc };
4487f4a2713aSLionel Sambuc 
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const4488f4a2713aSLionel Sambuc void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
4489f4a2713aSLionel Sambuc                                        unsigned &NumAliases) const {
4490f4a2713aSLionel Sambuc   Aliases = GCCRegAliases;
4491f4a2713aSLionel Sambuc   NumAliases = llvm::array_lengthof(GCCRegAliases);
4492f4a2713aSLionel Sambuc }
4493f4a2713aSLionel Sambuc 
4494f4a2713aSLionel Sambuc const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
4495f4a2713aSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
4496f4a2713aSLionel Sambuc #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
4497f4a2713aSLionel Sambuc                                               ALL_LANGUAGES },
4498*0a6a1f1dSLionel Sambuc #include "clang/Basic/BuiltinsNEON.def"
4499*0a6a1f1dSLionel Sambuc 
4500*0a6a1f1dSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
4501*0a6a1f1dSLionel Sambuc #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) { #ID, TYPE, ATTRS, 0, LANG },
4502*0a6a1f1dSLionel Sambuc #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
4503*0a6a1f1dSLionel Sambuc                                               ALL_LANGUAGES },
4504f4a2713aSLionel Sambuc #include "clang/Basic/BuiltinsARM.def"
4505f4a2713aSLionel Sambuc };
4506*0a6a1f1dSLionel Sambuc 
4507*0a6a1f1dSLionel Sambuc class ARMleTargetInfo : public ARMTargetInfo {
4508*0a6a1f1dSLionel Sambuc public:
ARMleTargetInfo(const llvm::Triple & Triple)4509*0a6a1f1dSLionel Sambuc   ARMleTargetInfo(const llvm::Triple &Triple)
4510*0a6a1f1dSLionel Sambuc     : ARMTargetInfo(Triple, false) { }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4511*0a6a1f1dSLionel Sambuc   virtual void getTargetDefines(const LangOptions &Opts,
4512*0a6a1f1dSLionel Sambuc                                 MacroBuilder &Builder) const {
4513*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARMEL__");
4514*0a6a1f1dSLionel Sambuc     ARMTargetInfo::getTargetDefines(Opts, Builder);
4515*0a6a1f1dSLionel Sambuc   }
4516*0a6a1f1dSLionel Sambuc };
4517*0a6a1f1dSLionel Sambuc 
4518*0a6a1f1dSLionel Sambuc class ARMbeTargetInfo : public ARMTargetInfo {
4519*0a6a1f1dSLionel Sambuc public:
ARMbeTargetInfo(const llvm::Triple & Triple)4520*0a6a1f1dSLionel Sambuc   ARMbeTargetInfo(const llvm::Triple &Triple)
4521*0a6a1f1dSLionel Sambuc     : ARMTargetInfo(Triple, true) { }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4522*0a6a1f1dSLionel Sambuc   virtual void getTargetDefines(const LangOptions &Opts,
4523*0a6a1f1dSLionel Sambuc                                 MacroBuilder &Builder) const {
4524*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARMEB__");
4525*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_BIG_ENDIAN");
4526*0a6a1f1dSLionel Sambuc     ARMTargetInfo::getTargetDefines(Opts, Builder);
4527*0a6a1f1dSLionel Sambuc   }
4528*0a6a1f1dSLionel Sambuc };
4529f4a2713aSLionel Sambuc } // end anonymous namespace.
4530f4a2713aSLionel Sambuc 
4531f4a2713aSLionel Sambuc namespace {
4532*0a6a1f1dSLionel Sambuc class WindowsARMTargetInfo : public WindowsTargetInfo<ARMleTargetInfo> {
4533*0a6a1f1dSLionel Sambuc   const llvm::Triple Triple;
4534*0a6a1f1dSLionel Sambuc public:
WindowsARMTargetInfo(const llvm::Triple & Triple)4535*0a6a1f1dSLionel Sambuc   WindowsARMTargetInfo(const llvm::Triple &Triple)
4536*0a6a1f1dSLionel Sambuc     : WindowsTargetInfo<ARMleTargetInfo>(Triple), Triple(Triple) {
4537*0a6a1f1dSLionel Sambuc     TLSSupported = false;
4538*0a6a1f1dSLionel Sambuc     WCharType = UnsignedShort;
4539*0a6a1f1dSLionel Sambuc     SizeType = UnsignedInt;
4540*0a6a1f1dSLionel Sambuc     UserLabelPrefix = "";
4541*0a6a1f1dSLionel Sambuc   }
getVisualStudioDefines(const LangOptions & Opts,MacroBuilder & Builder) const4542*0a6a1f1dSLionel Sambuc   void getVisualStudioDefines(const LangOptions &Opts,
4543f4a2713aSLionel Sambuc                               MacroBuilder &Builder) const {
4544*0a6a1f1dSLionel Sambuc     WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
4545*0a6a1f1dSLionel Sambuc 
4546*0a6a1f1dSLionel Sambuc     // FIXME: this is invalid for WindowsCE
4547*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_M_ARM_NT", "1");
4548*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_M_ARMT", "_M_ARM");
4549*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_M_THUMB", "_M_ARM");
4550*0a6a1f1dSLionel Sambuc 
4551*0a6a1f1dSLionel Sambuc     assert((Triple.getArch() == llvm::Triple::arm ||
4552*0a6a1f1dSLionel Sambuc             Triple.getArch() == llvm::Triple::thumb) &&
4553*0a6a1f1dSLionel Sambuc            "invalid architecture for Windows ARM target info");
4554*0a6a1f1dSLionel Sambuc     unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
4555*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
4556*0a6a1f1dSLionel Sambuc 
4557*0a6a1f1dSLionel Sambuc     // TODO map the complete set of values
4558*0a6a1f1dSLionel Sambuc     // 31: VFPv3 40: VFPv4
4559*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_M_ARM_FP", "31");
4560*0a6a1f1dSLionel Sambuc   }
getBuiltinVaListKind() const4561*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
4562*0a6a1f1dSLionel Sambuc     return TargetInfo::CharPtrBuiltinVaList;
4563*0a6a1f1dSLionel Sambuc   }
4564*0a6a1f1dSLionel Sambuc };
4565*0a6a1f1dSLionel Sambuc 
4566*0a6a1f1dSLionel Sambuc // Windows ARM + Itanium C++ ABI Target
4567*0a6a1f1dSLionel Sambuc class ItaniumWindowsARMleTargetInfo : public WindowsARMTargetInfo {
4568*0a6a1f1dSLionel Sambuc public:
ItaniumWindowsARMleTargetInfo(const llvm::Triple & Triple)4569*0a6a1f1dSLionel Sambuc   ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple)
4570*0a6a1f1dSLionel Sambuc     : WindowsARMTargetInfo(Triple) {
4571*0a6a1f1dSLionel Sambuc     TheCXXABI.set(TargetCXXABI::GenericARM);
4572*0a6a1f1dSLionel Sambuc   }
4573*0a6a1f1dSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4574*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
4575*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
4576*0a6a1f1dSLionel Sambuc     WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
4577*0a6a1f1dSLionel Sambuc 
4578*0a6a1f1dSLionel Sambuc     if (Opts.MSVCCompat)
4579*0a6a1f1dSLionel Sambuc       WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
4580*0a6a1f1dSLionel Sambuc   }
4581*0a6a1f1dSLionel Sambuc };
4582*0a6a1f1dSLionel Sambuc 
4583*0a6a1f1dSLionel Sambuc // Windows ARM, MS (C++) ABI
4584*0a6a1f1dSLionel Sambuc class MicrosoftARMleTargetInfo : public WindowsARMTargetInfo {
4585*0a6a1f1dSLionel Sambuc public:
MicrosoftARMleTargetInfo(const llvm::Triple & Triple)4586*0a6a1f1dSLionel Sambuc   MicrosoftARMleTargetInfo(const llvm::Triple &Triple)
4587*0a6a1f1dSLionel Sambuc     : WindowsARMTargetInfo(Triple) {
4588*0a6a1f1dSLionel Sambuc     TheCXXABI.set(TargetCXXABI::Microsoft);
4589*0a6a1f1dSLionel Sambuc   }
4590*0a6a1f1dSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4591*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
4592*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
4593*0a6a1f1dSLionel Sambuc     WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
4594*0a6a1f1dSLionel Sambuc     WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
4595*0a6a1f1dSLionel Sambuc   }
4596*0a6a1f1dSLionel Sambuc };
4597*0a6a1f1dSLionel Sambuc }
4598*0a6a1f1dSLionel Sambuc 
4599*0a6a1f1dSLionel Sambuc 
4600*0a6a1f1dSLionel Sambuc namespace {
4601*0a6a1f1dSLionel Sambuc class DarwinARMTargetInfo :
4602*0a6a1f1dSLionel Sambuc   public DarwinTargetInfo<ARMleTargetInfo> {
4603*0a6a1f1dSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const4604*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
4605*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
4606f4a2713aSLionel Sambuc     getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
4607f4a2713aSLionel Sambuc   }
4608f4a2713aSLionel Sambuc 
4609f4a2713aSLionel Sambuc public:
DarwinARMTargetInfo(const llvm::Triple & Triple)4610f4a2713aSLionel Sambuc   DarwinARMTargetInfo(const llvm::Triple &Triple)
4611*0a6a1f1dSLionel Sambuc       : DarwinTargetInfo<ARMleTargetInfo>(Triple) {
4612f4a2713aSLionel Sambuc     HasAlignMac68kSupport = true;
4613f4a2713aSLionel Sambuc     // iOS always has 64-bit atomic instructions.
4614*0a6a1f1dSLionel Sambuc     // FIXME: This should be based off of the target features in
4615*0a6a1f1dSLionel Sambuc     // ARMleTargetInfo.
4616f4a2713aSLionel Sambuc     MaxAtomicInlineWidth = 64;
4617f4a2713aSLionel Sambuc 
4618f4a2713aSLionel Sambuc     // Darwin on iOS uses a variant of the ARM C++ ABI.
4619f4a2713aSLionel Sambuc     TheCXXABI.set(TargetCXXABI::iOS);
4620f4a2713aSLionel Sambuc   }
4621f4a2713aSLionel Sambuc };
4622f4a2713aSLionel Sambuc } // end anonymous namespace.
4623f4a2713aSLionel Sambuc 
4624f4a2713aSLionel Sambuc 
4625f4a2713aSLionel Sambuc namespace {
4626*0a6a1f1dSLionel Sambuc class AArch64TargetInfo : public TargetInfo {
4627*0a6a1f1dSLionel Sambuc   virtual void setDescriptionString() = 0;
4628*0a6a1f1dSLionel Sambuc   static const TargetInfo::GCCRegAlias GCCRegAliases[];
4629*0a6a1f1dSLionel Sambuc   static const char *const GCCRegNames[];
4630*0a6a1f1dSLionel Sambuc 
4631*0a6a1f1dSLionel Sambuc   enum FPUModeEnum {
4632*0a6a1f1dSLionel Sambuc     FPUMode,
4633*0a6a1f1dSLionel Sambuc     NeonMode
4634*0a6a1f1dSLionel Sambuc   };
4635*0a6a1f1dSLionel Sambuc 
4636*0a6a1f1dSLionel Sambuc   unsigned FPU;
4637*0a6a1f1dSLionel Sambuc   unsigned CRC;
4638*0a6a1f1dSLionel Sambuc   unsigned Crypto;
4639*0a6a1f1dSLionel Sambuc 
4640*0a6a1f1dSLionel Sambuc   static const Builtin::Info BuiltinInfo[];
4641*0a6a1f1dSLionel Sambuc 
4642*0a6a1f1dSLionel Sambuc   std::string ABI;
4643*0a6a1f1dSLionel Sambuc 
4644*0a6a1f1dSLionel Sambuc public:
AArch64TargetInfo(const llvm::Triple & Triple)4645*0a6a1f1dSLionel Sambuc   AArch64TargetInfo(const llvm::Triple &Triple)
4646*0a6a1f1dSLionel Sambuc       : TargetInfo(Triple), ABI("aapcs") {
4647*0a6a1f1dSLionel Sambuc 
4648*0a6a1f1dSLionel Sambuc     if (getTriple().getOS() == llvm::Triple::NetBSD) {
4649*0a6a1f1dSLionel Sambuc       WCharType = SignedInt;
4650*0a6a1f1dSLionel Sambuc 
4651*0a6a1f1dSLionel Sambuc       // NetBSD apparently prefers consistency across ARM targets to consistency
4652*0a6a1f1dSLionel Sambuc       // across 64-bit targets.
4653*0a6a1f1dSLionel Sambuc       Int64Type = SignedLongLong;
4654*0a6a1f1dSLionel Sambuc       IntMaxType = SignedLongLong;
4655*0a6a1f1dSLionel Sambuc     } else {
4656*0a6a1f1dSLionel Sambuc       WCharType = UnsignedInt;
4657*0a6a1f1dSLionel Sambuc       Int64Type = SignedLong;
4658*0a6a1f1dSLionel Sambuc       IntMaxType = SignedLong;
4659*0a6a1f1dSLionel Sambuc     }
4660*0a6a1f1dSLionel Sambuc 
4661*0a6a1f1dSLionel Sambuc     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
4662*0a6a1f1dSLionel Sambuc     MaxVectorAlign = 128;
4663*0a6a1f1dSLionel Sambuc     RegParmMax = 8;
4664*0a6a1f1dSLionel Sambuc     MaxAtomicInlineWidth = 128;
4665*0a6a1f1dSLionel Sambuc     MaxAtomicPromoteWidth = 128;
4666*0a6a1f1dSLionel Sambuc 
4667*0a6a1f1dSLionel Sambuc     LongDoubleWidth = LongDoubleAlign = 128;
4668*0a6a1f1dSLionel Sambuc     LongDoubleFormat = &llvm::APFloat::IEEEquad;
4669*0a6a1f1dSLionel Sambuc 
4670*0a6a1f1dSLionel Sambuc     // {} in inline assembly are neon specifiers, not assembly variant
4671*0a6a1f1dSLionel Sambuc     // specifiers.
4672*0a6a1f1dSLionel Sambuc     NoAsmVariants = true;
4673*0a6a1f1dSLionel Sambuc 
4674*0a6a1f1dSLionel Sambuc     // AArch64 targets default to using the ARM C++ ABI.
4675*0a6a1f1dSLionel Sambuc     TheCXXABI.set(TargetCXXABI::GenericAArch64);
4676*0a6a1f1dSLionel Sambuc   }
4677*0a6a1f1dSLionel Sambuc 
getABI() const4678*0a6a1f1dSLionel Sambuc   StringRef getABI() const override { return ABI; }
setABI(const std::string & Name)4679*0a6a1f1dSLionel Sambuc   bool setABI(const std::string &Name) override {
4680*0a6a1f1dSLionel Sambuc     if (Name != "aapcs" && Name != "darwinpcs")
4681*0a6a1f1dSLionel Sambuc       return false;
4682*0a6a1f1dSLionel Sambuc 
4683*0a6a1f1dSLionel Sambuc     ABI = Name;
4684*0a6a1f1dSLionel Sambuc     return true;
4685*0a6a1f1dSLionel Sambuc   }
4686*0a6a1f1dSLionel Sambuc 
setCPU(const std::string & Name)4687*0a6a1f1dSLionel Sambuc   bool setCPU(const std::string &Name) override {
4688*0a6a1f1dSLionel Sambuc     bool CPUKnown = llvm::StringSwitch<bool>(Name)
4689*0a6a1f1dSLionel Sambuc                         .Case("generic", true)
4690*0a6a1f1dSLionel Sambuc                         .Cases("cortex-a53", "cortex-a57", true)
4691*0a6a1f1dSLionel Sambuc                         .Case("cyclone", true)
4692*0a6a1f1dSLionel Sambuc                         .Default(false);
4693*0a6a1f1dSLionel Sambuc     return CPUKnown;
4694*0a6a1f1dSLionel Sambuc   }
4695*0a6a1f1dSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4696*0a6a1f1dSLionel Sambuc   virtual void getTargetDefines(const LangOptions &Opts,
4697*0a6a1f1dSLionel Sambuc                                 MacroBuilder &Builder) const  override {
4698*0a6a1f1dSLionel Sambuc     // Target identification.
4699*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__aarch64__");
4700*0a6a1f1dSLionel Sambuc 
4701*0a6a1f1dSLionel Sambuc     // Target properties.
4702*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_LP64");
4703*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__LP64__");
4704*0a6a1f1dSLionel Sambuc 
4705*0a6a1f1dSLionel Sambuc     // ACLE predefines. Many can only have one possible value on v8 AArch64.
4706*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_ACLE", "200");
4707*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_ARCH", "8");
4708*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
4709*0a6a1f1dSLionel Sambuc 
4710*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_64BIT_STATE");
4711*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_PCS_AAPCS64");
4712*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_ARCH_ISA_A64");
4713*0a6a1f1dSLionel Sambuc 
4714*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_FEATURE_UNALIGNED");
4715*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_FEATURE_CLZ");
4716*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_FEATURE_FMA");
4717*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_FEATURE_DIV");
4718*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_FEATURE_IDIV"); // As specified in ACLE
4719*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_FEATURE_DIV");  // For backwards compatibility
4720*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN");
4721*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING");
4722*0a6a1f1dSLionel Sambuc 
4723*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
4724*0a6a1f1dSLionel Sambuc 
4725*0a6a1f1dSLionel Sambuc     // 0xe implies support for half, single and double precision operations.
4726*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_FP", "0xe");
4727*0a6a1f1dSLionel Sambuc 
4728*0a6a1f1dSLionel Sambuc     // PCS specifies this for SysV variants, which is all we support. Other ABIs
4729*0a6a1f1dSLionel Sambuc     // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
4730*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_FP16_FORMAT_IEEE");
4731*0a6a1f1dSLionel Sambuc 
4732*0a6a1f1dSLionel Sambuc     if (Opts.FastMath || Opts.FiniteMathOnly)
4733*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_FP_FAST");
4734*0a6a1f1dSLionel Sambuc 
4735*0a6a1f1dSLionel Sambuc     if (Opts.C99 && !Opts.Freestanding)
4736*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_FP_FENV_ROUNDING");
4737*0a6a1f1dSLionel Sambuc 
4738*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", Opts.ShortWChar ? "2" : "4");
4739*0a6a1f1dSLionel Sambuc 
4740*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
4741*0a6a1f1dSLionel Sambuc                         Opts.ShortEnums ? "1" : "4");
4742*0a6a1f1dSLionel Sambuc 
4743*0a6a1f1dSLionel Sambuc     if (FPU == NeonMode) {
4744*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_NEON");
4745*0a6a1f1dSLionel Sambuc       // 64-bit NEON supports half, single and double precision operations.
4746*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_NEON_FP", "0xe");
4747*0a6a1f1dSLionel Sambuc     }
4748*0a6a1f1dSLionel Sambuc 
4749*0a6a1f1dSLionel Sambuc     if (CRC)
4750*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_FEATURE_CRC32");
4751*0a6a1f1dSLionel Sambuc 
4752*0a6a1f1dSLionel Sambuc     if (Crypto)
4753*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__ARM_FEATURE_CRYPTO");
4754*0a6a1f1dSLionel Sambuc   }
4755*0a6a1f1dSLionel Sambuc 
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const4756*0a6a1f1dSLionel Sambuc   virtual void getTargetBuiltins(const Builtin::Info *&Records,
4757*0a6a1f1dSLionel Sambuc                                  unsigned &NumRecords) const override {
4758*0a6a1f1dSLionel Sambuc     Records = BuiltinInfo;
4759*0a6a1f1dSLionel Sambuc     NumRecords = clang::AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin;
4760*0a6a1f1dSLionel Sambuc   }
4761*0a6a1f1dSLionel Sambuc 
hasFeature(StringRef Feature) const4762*0a6a1f1dSLionel Sambuc   bool hasFeature(StringRef Feature) const override {
4763*0a6a1f1dSLionel Sambuc     return Feature == "aarch64" ||
4764*0a6a1f1dSLionel Sambuc       Feature == "arm64" ||
4765*0a6a1f1dSLionel Sambuc       (Feature == "neon" && FPU == NeonMode);
4766*0a6a1f1dSLionel Sambuc   }
4767*0a6a1f1dSLionel Sambuc 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)4768*0a6a1f1dSLionel Sambuc   bool handleTargetFeatures(std::vector<std::string> &Features,
4769*0a6a1f1dSLionel Sambuc                             DiagnosticsEngine &Diags) override {
4770*0a6a1f1dSLionel Sambuc     FPU = FPUMode;
4771*0a6a1f1dSLionel Sambuc     CRC = 0;
4772*0a6a1f1dSLionel Sambuc     Crypto = 0;
4773*0a6a1f1dSLionel Sambuc     for (unsigned i = 0, e = Features.size(); i != e; ++i) {
4774*0a6a1f1dSLionel Sambuc       if (Features[i] == "+neon")
4775*0a6a1f1dSLionel Sambuc         FPU = NeonMode;
4776*0a6a1f1dSLionel Sambuc       if (Features[i] == "+crc")
4777*0a6a1f1dSLionel Sambuc         CRC = 1;
4778*0a6a1f1dSLionel Sambuc       if (Features[i] == "+crypto")
4779*0a6a1f1dSLionel Sambuc         Crypto = 1;
4780*0a6a1f1dSLionel Sambuc     }
4781*0a6a1f1dSLionel Sambuc 
4782*0a6a1f1dSLionel Sambuc     setDescriptionString();
4783*0a6a1f1dSLionel Sambuc 
4784*0a6a1f1dSLionel Sambuc     return true;
4785*0a6a1f1dSLionel Sambuc   }
4786*0a6a1f1dSLionel Sambuc 
isCLZForZeroUndef() const4787*0a6a1f1dSLionel Sambuc   bool isCLZForZeroUndef() const override { return false; }
4788*0a6a1f1dSLionel Sambuc 
getBuiltinVaListKind() const4789*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
4790*0a6a1f1dSLionel Sambuc     return TargetInfo::AArch64ABIBuiltinVaList;
4791*0a6a1f1dSLionel Sambuc   }
4792*0a6a1f1dSLionel Sambuc 
4793*0a6a1f1dSLionel Sambuc   virtual void getGCCRegNames(const char *const *&Names,
4794*0a6a1f1dSLionel Sambuc                               unsigned &NumNames) const override;
4795*0a6a1f1dSLionel Sambuc   virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4796*0a6a1f1dSLionel Sambuc                                 unsigned &NumAliases) const override;
4797*0a6a1f1dSLionel Sambuc 
4798*0a6a1f1dSLionel Sambuc   virtual bool
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const4799*0a6a1f1dSLionel Sambuc   validateAsmConstraint(const char *&Name,
4800*0a6a1f1dSLionel Sambuc                         TargetInfo::ConstraintInfo &Info) const override {
4801*0a6a1f1dSLionel Sambuc     switch (*Name) {
4802*0a6a1f1dSLionel Sambuc     default:
4803*0a6a1f1dSLionel Sambuc       return false;
4804*0a6a1f1dSLionel Sambuc     case 'w': // Floating point and SIMD registers (V0-V31)
4805*0a6a1f1dSLionel Sambuc       Info.setAllowsRegister();
4806*0a6a1f1dSLionel Sambuc       return true;
4807*0a6a1f1dSLionel Sambuc     case 'I': // Constant that can be used with an ADD instruction
4808*0a6a1f1dSLionel Sambuc     case 'J': // Constant that can be used with a SUB instruction
4809*0a6a1f1dSLionel Sambuc     case 'K': // Constant that can be used with a 32-bit logical instruction
4810*0a6a1f1dSLionel Sambuc     case 'L': // Constant that can be used with a 64-bit logical instruction
4811*0a6a1f1dSLionel Sambuc     case 'M': // Constant that can be used as a 32-bit MOV immediate
4812*0a6a1f1dSLionel Sambuc     case 'N': // Constant that can be used as a 64-bit MOV immediate
4813*0a6a1f1dSLionel Sambuc     case 'Y': // Floating point constant zero
4814*0a6a1f1dSLionel Sambuc     case 'Z': // Integer constant zero
4815*0a6a1f1dSLionel Sambuc       return true;
4816*0a6a1f1dSLionel Sambuc     case 'Q': // A memory reference with base register and no offset
4817*0a6a1f1dSLionel Sambuc       Info.setAllowsMemory();
4818*0a6a1f1dSLionel Sambuc       return true;
4819*0a6a1f1dSLionel Sambuc     case 'S': // A symbolic address
4820*0a6a1f1dSLionel Sambuc       Info.setAllowsRegister();
4821*0a6a1f1dSLionel Sambuc       return true;
4822*0a6a1f1dSLionel Sambuc     case 'U':
4823*0a6a1f1dSLionel Sambuc       // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
4824*0a6a1f1dSLionel Sambuc       // Utf: A memory address suitable for ldp/stp in TF mode.
4825*0a6a1f1dSLionel Sambuc       // Usa: An absolute symbolic address.
4826*0a6a1f1dSLionel Sambuc       // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
4827*0a6a1f1dSLionel Sambuc       llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
4828*0a6a1f1dSLionel Sambuc     case 'z': // Zero register, wzr or xzr
4829*0a6a1f1dSLionel Sambuc       Info.setAllowsRegister();
4830*0a6a1f1dSLionel Sambuc       return true;
4831*0a6a1f1dSLionel Sambuc     case 'x': // Floating point and SIMD registers (V0-V15)
4832*0a6a1f1dSLionel Sambuc       Info.setAllowsRegister();
4833*0a6a1f1dSLionel Sambuc       return true;
4834*0a6a1f1dSLionel Sambuc     }
4835*0a6a1f1dSLionel Sambuc     return false;
4836*0a6a1f1dSLionel Sambuc   }
4837*0a6a1f1dSLionel Sambuc 
4838*0a6a1f1dSLionel Sambuc   bool
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const4839*0a6a1f1dSLionel Sambuc   validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
4840*0a6a1f1dSLionel Sambuc                              std::string &SuggestedModifier) const override {
4841*0a6a1f1dSLionel Sambuc     // Strip off constraint modifiers.
4842*0a6a1f1dSLionel Sambuc     while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
4843*0a6a1f1dSLionel Sambuc       Constraint = Constraint.substr(1);
4844*0a6a1f1dSLionel Sambuc 
4845*0a6a1f1dSLionel Sambuc     switch (Constraint[0]) {
4846*0a6a1f1dSLionel Sambuc     default:
4847*0a6a1f1dSLionel Sambuc       return true;
4848*0a6a1f1dSLionel Sambuc     case 'z':
4849*0a6a1f1dSLionel Sambuc     case 'r': {
4850*0a6a1f1dSLionel Sambuc       switch (Modifier) {
4851*0a6a1f1dSLionel Sambuc       case 'x':
4852*0a6a1f1dSLionel Sambuc       case 'w':
4853*0a6a1f1dSLionel Sambuc         // For now assume that the person knows what they're
4854*0a6a1f1dSLionel Sambuc         // doing with the modifier.
4855*0a6a1f1dSLionel Sambuc         return true;
4856*0a6a1f1dSLionel Sambuc       default:
4857*0a6a1f1dSLionel Sambuc         // By default an 'r' constraint will be in the 'x'
4858*0a6a1f1dSLionel Sambuc         // registers.
4859*0a6a1f1dSLionel Sambuc         if (Size == 64)
4860*0a6a1f1dSLionel Sambuc           return true;
4861*0a6a1f1dSLionel Sambuc 
4862*0a6a1f1dSLionel Sambuc         SuggestedModifier = "w";
4863*0a6a1f1dSLionel Sambuc         return false;
4864*0a6a1f1dSLionel Sambuc       }
4865*0a6a1f1dSLionel Sambuc     }
4866*0a6a1f1dSLionel Sambuc     }
4867*0a6a1f1dSLionel Sambuc   }
4868*0a6a1f1dSLionel Sambuc 
getClobbers() const4869*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override { return ""; }
4870*0a6a1f1dSLionel Sambuc 
getEHDataRegisterNumber(unsigned RegNo) const4871*0a6a1f1dSLionel Sambuc   int getEHDataRegisterNumber(unsigned RegNo) const override {
4872*0a6a1f1dSLionel Sambuc     if (RegNo == 0)
4873*0a6a1f1dSLionel Sambuc       return 0;
4874*0a6a1f1dSLionel Sambuc     if (RegNo == 1)
4875*0a6a1f1dSLionel Sambuc       return 1;
4876*0a6a1f1dSLionel Sambuc     return -1;
4877*0a6a1f1dSLionel Sambuc   }
4878*0a6a1f1dSLionel Sambuc };
4879*0a6a1f1dSLionel Sambuc 
4880*0a6a1f1dSLionel Sambuc const char *const AArch64TargetInfo::GCCRegNames[] = {
4881*0a6a1f1dSLionel Sambuc   // 32-bit Integer registers
4882*0a6a1f1dSLionel Sambuc   "w0",  "w1",  "w2",  "w3",  "w4",  "w5",  "w6",  "w7",  "w8",  "w9",  "w10",
4883*0a6a1f1dSLionel Sambuc   "w11", "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21",
4884*0a6a1f1dSLionel Sambuc   "w22", "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
4885*0a6a1f1dSLionel Sambuc 
4886*0a6a1f1dSLionel Sambuc   // 64-bit Integer registers
4887*0a6a1f1dSLionel Sambuc   "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",  "x8",  "x9",  "x10",
4888*0a6a1f1dSLionel Sambuc   "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21",
4889*0a6a1f1dSLionel Sambuc   "x22", "x23", "x24", "x25", "x26", "x27", "x28", "fp",  "lr",  "sp",
4890*0a6a1f1dSLionel Sambuc 
4891*0a6a1f1dSLionel Sambuc   // 32-bit floating point regsisters
4892*0a6a1f1dSLionel Sambuc   "s0",  "s1",  "s2",  "s3",  "s4",  "s5",  "s6",  "s7",  "s8",  "s9",  "s10",
4893*0a6a1f1dSLionel Sambuc   "s11", "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21",
4894*0a6a1f1dSLionel Sambuc   "s22", "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
4895*0a6a1f1dSLionel Sambuc 
4896*0a6a1f1dSLionel Sambuc   // 64-bit floating point regsisters
4897*0a6a1f1dSLionel Sambuc   "d0",  "d1",  "d2",  "d3",  "d4",  "d5",  "d6",  "d7",  "d8",  "d9",  "d10",
4898*0a6a1f1dSLionel Sambuc   "d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21",
4899*0a6a1f1dSLionel Sambuc   "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
4900*0a6a1f1dSLionel Sambuc 
4901*0a6a1f1dSLionel Sambuc   // Vector registers
4902*0a6a1f1dSLionel Sambuc   "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",  "v8",  "v9",  "v10",
4903*0a6a1f1dSLionel Sambuc   "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
4904*0a6a1f1dSLionel Sambuc   "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
4905*0a6a1f1dSLionel Sambuc };
4906*0a6a1f1dSLionel Sambuc 
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const4907*0a6a1f1dSLionel Sambuc void AArch64TargetInfo::getGCCRegNames(const char *const *&Names,
4908*0a6a1f1dSLionel Sambuc                                      unsigned &NumNames) const {
4909*0a6a1f1dSLionel Sambuc   Names = GCCRegNames;
4910*0a6a1f1dSLionel Sambuc   NumNames = llvm::array_lengthof(GCCRegNames);
4911*0a6a1f1dSLionel Sambuc }
4912*0a6a1f1dSLionel Sambuc 
4913*0a6a1f1dSLionel Sambuc const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
4914*0a6a1f1dSLionel Sambuc   { { "w31" }, "wsp" },
4915*0a6a1f1dSLionel Sambuc   { { "x29" }, "fp" },
4916*0a6a1f1dSLionel Sambuc   { { "x30" }, "lr" },
4917*0a6a1f1dSLionel Sambuc   { { "x31" }, "sp" },
4918*0a6a1f1dSLionel Sambuc   // The S/D/Q and W/X registers overlap, but aren't really aliases; we
4919*0a6a1f1dSLionel Sambuc   // don't want to substitute one of these for a different-sized one.
4920*0a6a1f1dSLionel Sambuc };
4921*0a6a1f1dSLionel Sambuc 
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const4922*0a6a1f1dSLionel Sambuc void AArch64TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
4923*0a6a1f1dSLionel Sambuc                                        unsigned &NumAliases) const {
4924*0a6a1f1dSLionel Sambuc   Aliases = GCCRegAliases;
4925*0a6a1f1dSLionel Sambuc   NumAliases = llvm::array_lengthof(GCCRegAliases);
4926*0a6a1f1dSLionel Sambuc }
4927*0a6a1f1dSLionel Sambuc 
4928*0a6a1f1dSLionel Sambuc const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
4929*0a6a1f1dSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS)                                               \
4930*0a6a1f1dSLionel Sambuc   { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
4931*0a6a1f1dSLionel Sambuc #include "clang/Basic/BuiltinsNEON.def"
4932*0a6a1f1dSLionel Sambuc 
4933*0a6a1f1dSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS)                                               \
4934*0a6a1f1dSLionel Sambuc   { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
4935*0a6a1f1dSLionel Sambuc #include "clang/Basic/BuiltinsAArch64.def"
4936*0a6a1f1dSLionel Sambuc };
4937*0a6a1f1dSLionel Sambuc 
4938*0a6a1f1dSLionel Sambuc class AArch64leTargetInfo : public AArch64TargetInfo {
setDescriptionString()4939*0a6a1f1dSLionel Sambuc   void setDescriptionString() override {
4940*0a6a1f1dSLionel Sambuc     if (getTriple().isOSBinFormatMachO())
4941*0a6a1f1dSLionel Sambuc       DescriptionString = "e-m:o-i64:64-i128:128-n32:64-S128";
4942*0a6a1f1dSLionel Sambuc     else
4943*0a6a1f1dSLionel Sambuc       DescriptionString = "e-m:e-i64:64-i128:128-n32:64-S128";
4944*0a6a1f1dSLionel Sambuc   }
4945*0a6a1f1dSLionel Sambuc 
4946*0a6a1f1dSLionel Sambuc public:
AArch64leTargetInfo(const llvm::Triple & Triple)4947*0a6a1f1dSLionel Sambuc   AArch64leTargetInfo(const llvm::Triple &Triple)
4948*0a6a1f1dSLionel Sambuc     : AArch64TargetInfo(Triple) {
4949*0a6a1f1dSLionel Sambuc     BigEndian = false;
4950*0a6a1f1dSLionel Sambuc     }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4951*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
4952*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
4953*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__AARCH64EL__");
4954*0a6a1f1dSLionel Sambuc     AArch64TargetInfo::getTargetDefines(Opts, Builder);
4955*0a6a1f1dSLionel Sambuc   }
4956*0a6a1f1dSLionel Sambuc };
4957*0a6a1f1dSLionel Sambuc 
4958*0a6a1f1dSLionel Sambuc class AArch64beTargetInfo : public AArch64TargetInfo {
setDescriptionString()4959*0a6a1f1dSLionel Sambuc   void setDescriptionString() override {
4960*0a6a1f1dSLionel Sambuc     assert(!getTriple().isOSBinFormatMachO());
4961*0a6a1f1dSLionel Sambuc     DescriptionString = "E-m:e-i64:64-i128:128-n32:64-S128";
4962*0a6a1f1dSLionel Sambuc   }
4963*0a6a1f1dSLionel Sambuc 
4964*0a6a1f1dSLionel Sambuc public:
AArch64beTargetInfo(const llvm::Triple & Triple)4965*0a6a1f1dSLionel Sambuc   AArch64beTargetInfo(const llvm::Triple &Triple)
4966*0a6a1f1dSLionel Sambuc     : AArch64TargetInfo(Triple) { }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4967*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
4968*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
4969*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__AARCH64EB__");
4970*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__AARCH_BIG_ENDIAN");
4971*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_BIG_ENDIAN");
4972*0a6a1f1dSLionel Sambuc     AArch64TargetInfo::getTargetDefines(Opts, Builder);
4973*0a6a1f1dSLionel Sambuc   }
4974*0a6a1f1dSLionel Sambuc };
4975*0a6a1f1dSLionel Sambuc } // end anonymous namespace.
4976*0a6a1f1dSLionel Sambuc 
4977*0a6a1f1dSLionel Sambuc namespace {
4978*0a6a1f1dSLionel Sambuc class DarwinAArch64TargetInfo : public DarwinTargetInfo<AArch64leTargetInfo> {
4979*0a6a1f1dSLionel Sambuc protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const4980*0a6a1f1dSLionel Sambuc   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
4981*0a6a1f1dSLionel Sambuc                     MacroBuilder &Builder) const override {
4982*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__AARCH64_SIMD__");
4983*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM64_ARCH_8__");
4984*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ARM_NEON__");
4985*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__LITTLE_ENDIAN__");
4986*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__REGISTER_PREFIX__", "");
4987*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__arm64", "1");
4988*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__arm64__", "1");
4989*0a6a1f1dSLionel Sambuc 
4990*0a6a1f1dSLionel Sambuc     getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
4991*0a6a1f1dSLionel Sambuc   }
4992*0a6a1f1dSLionel Sambuc 
4993*0a6a1f1dSLionel Sambuc public:
DarwinAArch64TargetInfo(const llvm::Triple & Triple)4994*0a6a1f1dSLionel Sambuc   DarwinAArch64TargetInfo(const llvm::Triple &Triple)
4995*0a6a1f1dSLionel Sambuc       : DarwinTargetInfo<AArch64leTargetInfo>(Triple) {
4996*0a6a1f1dSLionel Sambuc     Int64Type = SignedLongLong;
4997*0a6a1f1dSLionel Sambuc     WCharType = SignedInt;
4998*0a6a1f1dSLionel Sambuc     UseSignedCharForObjCBool = false;
4999*0a6a1f1dSLionel Sambuc 
5000*0a6a1f1dSLionel Sambuc     LongDoubleWidth = LongDoubleAlign = 64;
5001*0a6a1f1dSLionel Sambuc     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
5002*0a6a1f1dSLionel Sambuc 
5003*0a6a1f1dSLionel Sambuc     TheCXXABI.set(TargetCXXABI::iOS64);
5004*0a6a1f1dSLionel Sambuc   }
5005*0a6a1f1dSLionel Sambuc 
getBuiltinVaListKind() const5006*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
5007*0a6a1f1dSLionel Sambuc     return TargetInfo::CharPtrBuiltinVaList;
5008*0a6a1f1dSLionel Sambuc   }
5009*0a6a1f1dSLionel Sambuc };
5010*0a6a1f1dSLionel Sambuc } // end anonymous namespace
5011*0a6a1f1dSLionel Sambuc 
5012*0a6a1f1dSLionel Sambuc namespace {
5013f4a2713aSLionel Sambuc // Hexagon abstract base class
5014f4a2713aSLionel Sambuc class HexagonTargetInfo : public TargetInfo {
5015f4a2713aSLionel Sambuc   static const Builtin::Info BuiltinInfo[];
5016f4a2713aSLionel Sambuc   static const char * const GCCRegNames[];
5017f4a2713aSLionel Sambuc   static const TargetInfo::GCCRegAlias GCCRegAliases[];
5018f4a2713aSLionel Sambuc   std::string CPU;
5019f4a2713aSLionel Sambuc public:
HexagonTargetInfo(const llvm::Triple & Triple)5020f4a2713aSLionel Sambuc   HexagonTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
5021f4a2713aSLionel Sambuc     BigEndian = false;
5022*0a6a1f1dSLionel Sambuc     DescriptionString = "e-m:e-p:32:32-i1:32-i64:64-a:0-n32";
5023f4a2713aSLionel Sambuc 
5024f4a2713aSLionel Sambuc     // {} in inline assembly are packet specifiers, not assembly variant
5025f4a2713aSLionel Sambuc     // specifiers.
5026f4a2713aSLionel Sambuc     NoAsmVariants = true;
5027f4a2713aSLionel Sambuc   }
5028f4a2713aSLionel Sambuc 
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const5029*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
5030*0a6a1f1dSLionel Sambuc                          unsigned &NumRecords) const override {
5031f4a2713aSLionel Sambuc     Records = BuiltinInfo;
5032f4a2713aSLionel Sambuc     NumRecords = clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin;
5033f4a2713aSLionel Sambuc   }
5034f4a2713aSLionel Sambuc 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const5035*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
5036*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &Info) const override {
5037f4a2713aSLionel Sambuc     return true;
5038f4a2713aSLionel Sambuc   }
5039f4a2713aSLionel Sambuc 
5040*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
5041*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override;
5042f4a2713aSLionel Sambuc 
hasFeature(StringRef Feature) const5043*0a6a1f1dSLionel Sambuc   bool hasFeature(StringRef Feature) const override {
5044f4a2713aSLionel Sambuc     return Feature == "hexagon";
5045f4a2713aSLionel Sambuc   }
5046f4a2713aSLionel Sambuc 
getBuiltinVaListKind() const5047*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
5048f4a2713aSLionel Sambuc     return TargetInfo::CharPtrBuiltinVaList;
5049f4a2713aSLionel Sambuc   }
5050*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char * const *&Names,
5051*0a6a1f1dSLionel Sambuc                       unsigned &NumNames) const override;
5052*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
5053*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override;
getClobbers() const5054*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override {
5055f4a2713aSLionel Sambuc     return "";
5056f4a2713aSLionel Sambuc   }
5057f4a2713aSLionel Sambuc 
getHexagonCPUSuffix(StringRef Name)5058f4a2713aSLionel Sambuc   static const char *getHexagonCPUSuffix(StringRef Name) {
5059f4a2713aSLionel Sambuc     return llvm::StringSwitch<const char*>(Name)
5060f4a2713aSLionel Sambuc       .Case("hexagonv4", "4")
5061f4a2713aSLionel Sambuc       .Case("hexagonv5", "5")
5062*0a6a1f1dSLionel Sambuc       .Default(nullptr);
5063f4a2713aSLionel Sambuc   }
5064f4a2713aSLionel Sambuc 
setCPU(const std::string & Name)5065*0a6a1f1dSLionel Sambuc   bool setCPU(const std::string &Name) override {
5066f4a2713aSLionel Sambuc     if (!getHexagonCPUSuffix(Name))
5067f4a2713aSLionel Sambuc       return false;
5068f4a2713aSLionel Sambuc 
5069f4a2713aSLionel Sambuc     CPU = Name;
5070f4a2713aSLionel Sambuc     return true;
5071f4a2713aSLionel Sambuc   }
5072f4a2713aSLionel Sambuc };
5073f4a2713aSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5074f4a2713aSLionel Sambuc void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
5075f4a2713aSLionel Sambuc                                 MacroBuilder &Builder) const {
5076f4a2713aSLionel Sambuc   Builder.defineMacro("qdsp6");
5077f4a2713aSLionel Sambuc   Builder.defineMacro("__qdsp6", "1");
5078f4a2713aSLionel Sambuc   Builder.defineMacro("__qdsp6__", "1");
5079f4a2713aSLionel Sambuc 
5080f4a2713aSLionel Sambuc   Builder.defineMacro("hexagon");
5081f4a2713aSLionel Sambuc   Builder.defineMacro("__hexagon", "1");
5082f4a2713aSLionel Sambuc   Builder.defineMacro("__hexagon__", "1");
5083f4a2713aSLionel Sambuc 
5084f4a2713aSLionel Sambuc   if(CPU == "hexagonv1") {
5085f4a2713aSLionel Sambuc     Builder.defineMacro("__HEXAGON_V1__");
5086f4a2713aSLionel Sambuc     Builder.defineMacro("__HEXAGON_ARCH__", "1");
5087f4a2713aSLionel Sambuc     if(Opts.HexagonQdsp6Compat) {
5088f4a2713aSLionel Sambuc       Builder.defineMacro("__QDSP6_V1__");
5089f4a2713aSLionel Sambuc       Builder.defineMacro("__QDSP6_ARCH__", "1");
5090f4a2713aSLionel Sambuc     }
5091f4a2713aSLionel Sambuc   }
5092f4a2713aSLionel Sambuc   else if(CPU == "hexagonv2") {
5093f4a2713aSLionel Sambuc     Builder.defineMacro("__HEXAGON_V2__");
5094f4a2713aSLionel Sambuc     Builder.defineMacro("__HEXAGON_ARCH__", "2");
5095f4a2713aSLionel Sambuc     if(Opts.HexagonQdsp6Compat) {
5096f4a2713aSLionel Sambuc       Builder.defineMacro("__QDSP6_V2__");
5097f4a2713aSLionel Sambuc       Builder.defineMacro("__QDSP6_ARCH__", "2");
5098f4a2713aSLionel Sambuc     }
5099f4a2713aSLionel Sambuc   }
5100f4a2713aSLionel Sambuc   else if(CPU == "hexagonv3") {
5101f4a2713aSLionel Sambuc     Builder.defineMacro("__HEXAGON_V3__");
5102f4a2713aSLionel Sambuc     Builder.defineMacro("__HEXAGON_ARCH__", "3");
5103f4a2713aSLionel Sambuc     if(Opts.HexagonQdsp6Compat) {
5104f4a2713aSLionel Sambuc       Builder.defineMacro("__QDSP6_V3__");
5105f4a2713aSLionel Sambuc       Builder.defineMacro("__QDSP6_ARCH__", "3");
5106f4a2713aSLionel Sambuc     }
5107f4a2713aSLionel Sambuc   }
5108f4a2713aSLionel Sambuc   else if(CPU == "hexagonv4") {
5109f4a2713aSLionel Sambuc     Builder.defineMacro("__HEXAGON_V4__");
5110f4a2713aSLionel Sambuc     Builder.defineMacro("__HEXAGON_ARCH__", "4");
5111f4a2713aSLionel Sambuc     if(Opts.HexagonQdsp6Compat) {
5112f4a2713aSLionel Sambuc       Builder.defineMacro("__QDSP6_V4__");
5113f4a2713aSLionel Sambuc       Builder.defineMacro("__QDSP6_ARCH__", "4");
5114f4a2713aSLionel Sambuc     }
5115f4a2713aSLionel Sambuc   }
5116f4a2713aSLionel Sambuc   else if(CPU == "hexagonv5") {
5117f4a2713aSLionel Sambuc     Builder.defineMacro("__HEXAGON_V5__");
5118f4a2713aSLionel Sambuc     Builder.defineMacro("__HEXAGON_ARCH__", "5");
5119f4a2713aSLionel Sambuc     if(Opts.HexagonQdsp6Compat) {
5120f4a2713aSLionel Sambuc       Builder.defineMacro("__QDSP6_V5__");
5121f4a2713aSLionel Sambuc       Builder.defineMacro("__QDSP6_ARCH__", "5");
5122f4a2713aSLionel Sambuc     }
5123f4a2713aSLionel Sambuc   }
5124f4a2713aSLionel Sambuc }
5125f4a2713aSLionel Sambuc 
5126f4a2713aSLionel Sambuc const char * const HexagonTargetInfo::GCCRegNames[] = {
5127f4a2713aSLionel Sambuc   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
5128f4a2713aSLionel Sambuc   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
5129f4a2713aSLionel Sambuc   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
5130f4a2713aSLionel Sambuc   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
5131f4a2713aSLionel Sambuc   "p0", "p1", "p2", "p3",
5132f4a2713aSLionel Sambuc   "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
5133f4a2713aSLionel Sambuc };
5134f4a2713aSLionel Sambuc 
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const5135f4a2713aSLionel Sambuc void HexagonTargetInfo::getGCCRegNames(const char * const *&Names,
5136f4a2713aSLionel Sambuc                                    unsigned &NumNames) const {
5137f4a2713aSLionel Sambuc   Names = GCCRegNames;
5138f4a2713aSLionel Sambuc   NumNames = llvm::array_lengthof(GCCRegNames);
5139f4a2713aSLionel Sambuc }
5140f4a2713aSLionel Sambuc 
5141f4a2713aSLionel Sambuc 
5142f4a2713aSLionel Sambuc const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
5143f4a2713aSLionel Sambuc   { { "sp" }, "r29" },
5144f4a2713aSLionel Sambuc   { { "fp" }, "r30" },
5145f4a2713aSLionel Sambuc   { { "lr" }, "r31" },
5146f4a2713aSLionel Sambuc  };
5147f4a2713aSLionel Sambuc 
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const5148f4a2713aSLionel Sambuc void HexagonTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
5149f4a2713aSLionel Sambuc                                      unsigned &NumAliases) const {
5150f4a2713aSLionel Sambuc   Aliases = GCCRegAliases;
5151f4a2713aSLionel Sambuc   NumAliases = llvm::array_lengthof(GCCRegAliases);
5152f4a2713aSLionel Sambuc }
5153f4a2713aSLionel Sambuc 
5154f4a2713aSLionel Sambuc 
5155f4a2713aSLionel Sambuc const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
5156f4a2713aSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
5157f4a2713aSLionel Sambuc #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
5158f4a2713aSLionel Sambuc                                               ALL_LANGUAGES },
5159f4a2713aSLionel Sambuc #include "clang/Basic/BuiltinsHexagon.def"
5160f4a2713aSLionel Sambuc };
5161f4a2713aSLionel Sambuc }
5162f4a2713aSLionel Sambuc 
5163f4a2713aSLionel Sambuc 
5164f4a2713aSLionel Sambuc namespace {
5165f4a2713aSLionel Sambuc // Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit).
5166f4a2713aSLionel Sambuc class SparcTargetInfo : public TargetInfo {
5167f4a2713aSLionel Sambuc   static const TargetInfo::GCCRegAlias GCCRegAliases[];
5168f4a2713aSLionel Sambuc   static const char * const GCCRegNames[];
5169f4a2713aSLionel Sambuc   bool SoftFloat;
5170f4a2713aSLionel Sambuc public:
SparcTargetInfo(const llvm::Triple & Triple)5171f4a2713aSLionel Sambuc   SparcTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {}
5172f4a2713aSLionel Sambuc 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)5173*0a6a1f1dSLionel Sambuc   bool handleTargetFeatures(std::vector<std::string> &Features,
5174*0a6a1f1dSLionel Sambuc                             DiagnosticsEngine &Diags) override {
5175f4a2713aSLionel Sambuc     SoftFloat = false;
5176f4a2713aSLionel Sambuc     for (unsigned i = 0, e = Features.size(); i != e; ++i)
5177f4a2713aSLionel Sambuc       if (Features[i] == "+soft-float")
5178f4a2713aSLionel Sambuc         SoftFloat = true;
5179f4a2713aSLionel Sambuc     return true;
5180f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5181*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
5182*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
5183f4a2713aSLionel Sambuc     DefineStd(Builder, "sparc", Opts);
5184f4a2713aSLionel Sambuc     Builder.defineMacro("__REGISTER_PREFIX__", "");
5185f4a2713aSLionel Sambuc 
5186f4a2713aSLionel Sambuc     if (SoftFloat)
5187f4a2713aSLionel Sambuc       Builder.defineMacro("SOFT_FLOAT", "1");
5188f4a2713aSLionel Sambuc   }
5189f4a2713aSLionel Sambuc 
hasFeature(StringRef Feature) const5190*0a6a1f1dSLionel Sambuc   bool hasFeature(StringRef Feature) const override {
5191f4a2713aSLionel Sambuc     return llvm::StringSwitch<bool>(Feature)
5192f4a2713aSLionel Sambuc              .Case("softfloat", SoftFloat)
5193f4a2713aSLionel Sambuc              .Case("sparc", true)
5194f4a2713aSLionel Sambuc              .Default(false);
5195f4a2713aSLionel Sambuc   }
5196f4a2713aSLionel Sambuc 
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const5197*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
5198*0a6a1f1dSLionel Sambuc                          unsigned &NumRecords) const override {
5199f4a2713aSLionel Sambuc     // FIXME: Implement!
5200f4a2713aSLionel Sambuc   }
getBuiltinVaListKind() const5201*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
5202f4a2713aSLionel Sambuc     return TargetInfo::VoidPtrBuiltinVaList;
5203f4a2713aSLionel Sambuc   }
5204*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char * const *&Names,
5205*0a6a1f1dSLionel Sambuc                       unsigned &NumNames) const override;
5206*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
5207*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const5208*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
5209*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &info) const override {
5210f4a2713aSLionel Sambuc     // FIXME: Implement!
5211*0a6a1f1dSLionel Sambuc     switch (*Name) {
5212*0a6a1f1dSLionel Sambuc     case 'I': // Signed 13-bit constant
5213*0a6a1f1dSLionel Sambuc     case 'J': // Zero
5214*0a6a1f1dSLionel Sambuc     case 'K': // 32-bit constant with the low 12 bits clear
5215*0a6a1f1dSLionel Sambuc     case 'L': // A constant in the range supported by movcc (11-bit signed imm)
5216*0a6a1f1dSLionel Sambuc     case 'M': // A constant in the range supported by movrcc (19-bit signed imm)
5217*0a6a1f1dSLionel Sambuc     case 'N': // Same as 'K' but zext (required for SIMode)
5218*0a6a1f1dSLionel Sambuc     case 'O': // The constant 4096
5219*0a6a1f1dSLionel Sambuc       return true;
5220*0a6a1f1dSLionel Sambuc     }
5221f4a2713aSLionel Sambuc     return false;
5222f4a2713aSLionel Sambuc   }
getClobbers() const5223*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override {
5224f4a2713aSLionel Sambuc     // FIXME: Implement!
5225f4a2713aSLionel Sambuc     return "";
5226f4a2713aSLionel Sambuc   }
5227f4a2713aSLionel Sambuc };
5228f4a2713aSLionel Sambuc 
5229f4a2713aSLionel Sambuc const char * const SparcTargetInfo::GCCRegNames[] = {
5230f4a2713aSLionel Sambuc   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
5231f4a2713aSLionel Sambuc   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
5232f4a2713aSLionel Sambuc   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
5233f4a2713aSLionel Sambuc   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
5234f4a2713aSLionel Sambuc };
5235f4a2713aSLionel Sambuc 
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const5236f4a2713aSLionel Sambuc void SparcTargetInfo::getGCCRegNames(const char * const *&Names,
5237f4a2713aSLionel Sambuc                                      unsigned &NumNames) const {
5238f4a2713aSLionel Sambuc   Names = GCCRegNames;
5239f4a2713aSLionel Sambuc   NumNames = llvm::array_lengthof(GCCRegNames);
5240f4a2713aSLionel Sambuc }
5241f4a2713aSLionel Sambuc 
5242f4a2713aSLionel Sambuc const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
5243f4a2713aSLionel Sambuc   { { "g0" }, "r0" },
5244f4a2713aSLionel Sambuc   { { "g1" }, "r1" },
5245f4a2713aSLionel Sambuc   { { "g2" }, "r2" },
5246f4a2713aSLionel Sambuc   { { "g3" }, "r3" },
5247f4a2713aSLionel Sambuc   { { "g4" }, "r4" },
5248f4a2713aSLionel Sambuc   { { "g5" }, "r5" },
5249f4a2713aSLionel Sambuc   { { "g6" }, "r6" },
5250f4a2713aSLionel Sambuc   { { "g7" }, "r7" },
5251f4a2713aSLionel Sambuc   { { "o0" }, "r8" },
5252f4a2713aSLionel Sambuc   { { "o1" }, "r9" },
5253f4a2713aSLionel Sambuc   { { "o2" }, "r10" },
5254f4a2713aSLionel Sambuc   { { "o3" }, "r11" },
5255f4a2713aSLionel Sambuc   { { "o4" }, "r12" },
5256f4a2713aSLionel Sambuc   { { "o5" }, "r13" },
5257f4a2713aSLionel Sambuc   { { "o6", "sp" }, "r14" },
5258f4a2713aSLionel Sambuc   { { "o7" }, "r15" },
5259f4a2713aSLionel Sambuc   { { "l0" }, "r16" },
5260f4a2713aSLionel Sambuc   { { "l1" }, "r17" },
5261f4a2713aSLionel Sambuc   { { "l2" }, "r18" },
5262f4a2713aSLionel Sambuc   { { "l3" }, "r19" },
5263f4a2713aSLionel Sambuc   { { "l4" }, "r20" },
5264f4a2713aSLionel Sambuc   { { "l5" }, "r21" },
5265f4a2713aSLionel Sambuc   { { "l6" }, "r22" },
5266f4a2713aSLionel Sambuc   { { "l7" }, "r23" },
5267f4a2713aSLionel Sambuc   { { "i0" }, "r24" },
5268f4a2713aSLionel Sambuc   { { "i1" }, "r25" },
5269f4a2713aSLionel Sambuc   { { "i2" }, "r26" },
5270f4a2713aSLionel Sambuc   { { "i3" }, "r27" },
5271f4a2713aSLionel Sambuc   { { "i4" }, "r28" },
5272f4a2713aSLionel Sambuc   { { "i5" }, "r29" },
5273f4a2713aSLionel Sambuc   { { "i6", "fp" }, "r30" },
5274f4a2713aSLionel Sambuc   { { "i7" }, "r31" },
5275f4a2713aSLionel Sambuc };
5276f4a2713aSLionel Sambuc 
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const5277f4a2713aSLionel Sambuc void SparcTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
5278f4a2713aSLionel Sambuc                                        unsigned &NumAliases) const {
5279f4a2713aSLionel Sambuc   Aliases = GCCRegAliases;
5280f4a2713aSLionel Sambuc   NumAliases = llvm::array_lengthof(GCCRegAliases);
5281f4a2713aSLionel Sambuc }
5282f4a2713aSLionel Sambuc 
5283f4a2713aSLionel Sambuc // SPARC v8 is the 32-bit mode selected by Triple::sparc.
5284f4a2713aSLionel Sambuc class SparcV8TargetInfo : public SparcTargetInfo {
5285f4a2713aSLionel Sambuc public:
SparcV8TargetInfo(const llvm::Triple & Triple)5286f4a2713aSLionel Sambuc   SparcV8TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
5287*0a6a1f1dSLionel Sambuc     DescriptionString = "E-m:e-p:32:32-i64:64-f128:64-n32-S64";
5288f4a2713aSLionel Sambuc   }
5289f4a2713aSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5290*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
5291*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
5292f4a2713aSLionel Sambuc     SparcTargetInfo::getTargetDefines(Opts, Builder);
5293f4a2713aSLionel Sambuc     Builder.defineMacro("__sparcv8");
5294f4a2713aSLionel Sambuc   }
5295f4a2713aSLionel Sambuc };
5296f4a2713aSLionel Sambuc 
5297f4a2713aSLionel Sambuc // SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
5298f4a2713aSLionel Sambuc class SparcV9TargetInfo : public SparcTargetInfo {
5299f4a2713aSLionel Sambuc public:
SparcV9TargetInfo(const llvm::Triple & Triple)5300f4a2713aSLionel Sambuc   SparcV9TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
5301f4a2713aSLionel Sambuc     // FIXME: Support Sparc quad-precision long double?
5302*0a6a1f1dSLionel Sambuc     DescriptionString = "E-m:e-i64:64-n32:64-S128";
5303f4a2713aSLionel Sambuc     // This is an LP64 platform.
5304f4a2713aSLionel Sambuc     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
5305f4a2713aSLionel Sambuc 
5306f4a2713aSLionel Sambuc     // OpenBSD uses long long for int64_t and intmax_t.
5307*0a6a1f1dSLionel Sambuc     if (getTriple().getOS() == llvm::Triple::OpenBSD)
5308f4a2713aSLionel Sambuc       IntMaxType = SignedLongLong;
5309*0a6a1f1dSLionel Sambuc     else
5310f4a2713aSLionel Sambuc       IntMaxType = SignedLong;
5311f4a2713aSLionel Sambuc     Int64Type = IntMaxType;
5312*0a6a1f1dSLionel Sambuc 
5313*0a6a1f1dSLionel Sambuc     // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
5314*0a6a1f1dSLionel Sambuc     // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
5315*0a6a1f1dSLionel Sambuc     LongDoubleWidth = 128;
5316*0a6a1f1dSLionel Sambuc     LongDoubleAlign = 128;
5317*0a6a1f1dSLionel Sambuc     LongDoubleFormat = &llvm::APFloat::IEEEquad;
5318*0a6a1f1dSLionel Sambuc     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
5319f4a2713aSLionel Sambuc   }
5320f4a2713aSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5321*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
5322*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
5323f4a2713aSLionel Sambuc     SparcTargetInfo::getTargetDefines(Opts, Builder);
5324f4a2713aSLionel Sambuc     Builder.defineMacro("__sparcv9");
5325f4a2713aSLionel Sambuc     Builder.defineMacro("__arch64__");
5326*0a6a1f1dSLionel Sambuc     // Solaris doesn't need these variants, but the BSDs do.
5327*0a6a1f1dSLionel Sambuc     if (getTriple().getOS() != llvm::Triple::Solaris) {
5328f4a2713aSLionel Sambuc       Builder.defineMacro("__sparc64__");
5329f4a2713aSLionel Sambuc       Builder.defineMacro("__sparc_v9__");
5330f4a2713aSLionel Sambuc       Builder.defineMacro("__sparcv9__");
5331f4a2713aSLionel Sambuc     }
5332f4a2713aSLionel Sambuc   }
5333*0a6a1f1dSLionel Sambuc 
setCPU(const std::string & Name)5334*0a6a1f1dSLionel Sambuc   bool setCPU(const std::string &Name) override {
5335*0a6a1f1dSLionel Sambuc     bool CPUKnown = llvm::StringSwitch<bool>(Name)
5336*0a6a1f1dSLionel Sambuc       .Case("v9", true)
5337*0a6a1f1dSLionel Sambuc       .Case("ultrasparc", true)
5338*0a6a1f1dSLionel Sambuc       .Case("ultrasparc3", true)
5339*0a6a1f1dSLionel Sambuc       .Case("niagara", true)
5340*0a6a1f1dSLionel Sambuc       .Case("niagara2", true)
5341*0a6a1f1dSLionel Sambuc       .Case("niagara3", true)
5342*0a6a1f1dSLionel Sambuc       .Case("niagara4", true)
5343*0a6a1f1dSLionel Sambuc       .Default(false);
5344*0a6a1f1dSLionel Sambuc 
5345*0a6a1f1dSLionel Sambuc     // No need to store the CPU yet.  There aren't any CPU-specific
5346*0a6a1f1dSLionel Sambuc     // macros to define.
5347*0a6a1f1dSLionel Sambuc     return CPUKnown;
5348*0a6a1f1dSLionel Sambuc   }
5349f4a2713aSLionel Sambuc };
5350f4a2713aSLionel Sambuc 
5351f4a2713aSLionel Sambuc } // end anonymous namespace.
5352f4a2713aSLionel Sambuc 
5353f4a2713aSLionel Sambuc namespace {
5354f4a2713aSLionel Sambuc class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
5355f4a2713aSLionel Sambuc public:
SolarisSparcV8TargetInfo(const llvm::Triple & Triple)5356f4a2713aSLionel Sambuc   SolarisSparcV8TargetInfo(const llvm::Triple &Triple)
5357f4a2713aSLionel Sambuc       : SolarisTargetInfo<SparcV8TargetInfo>(Triple) {
5358f4a2713aSLionel Sambuc     SizeType = UnsignedInt;
5359f4a2713aSLionel Sambuc     PtrDiffType = SignedInt;
5360f4a2713aSLionel Sambuc   }
5361f4a2713aSLionel Sambuc };
5362f4a2713aSLionel Sambuc } // end anonymous namespace.
5363f4a2713aSLionel Sambuc 
5364f4a2713aSLionel Sambuc namespace {
5365f4a2713aSLionel Sambuc class SystemZTargetInfo : public TargetInfo {
5366f4a2713aSLionel Sambuc   static const char *const GCCRegNames[];
5367f4a2713aSLionel Sambuc 
5368f4a2713aSLionel Sambuc public:
SystemZTargetInfo(const llvm::Triple & Triple)5369f4a2713aSLionel Sambuc   SystemZTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
5370f4a2713aSLionel Sambuc     TLSSupported = true;
5371f4a2713aSLionel Sambuc     IntWidth = IntAlign = 32;
5372f4a2713aSLionel Sambuc     LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
5373f4a2713aSLionel Sambuc     PointerWidth = PointerAlign = 64;
5374f4a2713aSLionel Sambuc     LongDoubleWidth = 128;
5375f4a2713aSLionel Sambuc     LongDoubleAlign = 64;
5376f4a2713aSLionel Sambuc     LongDoubleFormat = &llvm::APFloat::IEEEquad;
5377f4a2713aSLionel Sambuc     MinGlobalAlign = 16;
5378*0a6a1f1dSLionel Sambuc     DescriptionString = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64";
5379f4a2713aSLionel Sambuc     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
5380f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5381*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
5382*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
5383f4a2713aSLionel Sambuc     Builder.defineMacro("__s390__");
5384f4a2713aSLionel Sambuc     Builder.defineMacro("__s390x__");
5385f4a2713aSLionel Sambuc     Builder.defineMacro("__zarch__");
5386f4a2713aSLionel Sambuc     Builder.defineMacro("__LONG_DOUBLE_128__");
5387f4a2713aSLionel Sambuc   }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const5388*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
5389*0a6a1f1dSLionel Sambuc                          unsigned &NumRecords) const override {
5390f4a2713aSLionel Sambuc     // FIXME: Implement.
5391*0a6a1f1dSLionel Sambuc     Records = nullptr;
5392f4a2713aSLionel Sambuc     NumRecords = 0;
5393f4a2713aSLionel Sambuc   }
5394f4a2713aSLionel Sambuc 
5395*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char *const *&Names,
5396*0a6a1f1dSLionel Sambuc                       unsigned &NumNames) const override;
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const5397*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
5398*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override {
5399f4a2713aSLionel Sambuc     // No aliases.
5400*0a6a1f1dSLionel Sambuc     Aliases = nullptr;
5401f4a2713aSLionel Sambuc     NumAliases = 0;
5402f4a2713aSLionel Sambuc   }
5403*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
5404*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &info) const override;
getClobbers() const5405*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override {
5406f4a2713aSLionel Sambuc     // FIXME: Is this really right?
5407f4a2713aSLionel Sambuc     return "";
5408f4a2713aSLionel Sambuc   }
getBuiltinVaListKind() const5409*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
5410f4a2713aSLionel Sambuc     return TargetInfo::SystemZBuiltinVaList;
5411f4a2713aSLionel Sambuc   }
setCPU(const std::string & Name)5412*0a6a1f1dSLionel Sambuc   bool setCPU(const std::string &Name) override {
5413f4a2713aSLionel Sambuc     bool CPUKnown = llvm::StringSwitch<bool>(Name)
5414f4a2713aSLionel Sambuc       .Case("z10", true)
5415f4a2713aSLionel Sambuc       .Case("z196", true)
5416f4a2713aSLionel Sambuc       .Case("zEC12", true)
5417f4a2713aSLionel Sambuc       .Default(false);
5418f4a2713aSLionel Sambuc 
5419f4a2713aSLionel Sambuc     // No need to store the CPU yet.  There aren't any CPU-specific
5420f4a2713aSLionel Sambuc     // macros to define.
5421f4a2713aSLionel Sambuc     return CPUKnown;
5422f4a2713aSLionel Sambuc   }
5423f4a2713aSLionel Sambuc };
5424f4a2713aSLionel Sambuc 
5425f4a2713aSLionel Sambuc const char *const SystemZTargetInfo::GCCRegNames[] = {
5426f4a2713aSLionel Sambuc   "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
5427f4a2713aSLionel Sambuc   "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
5428f4a2713aSLionel Sambuc   "f0",  "f2",  "f4",  "f6",  "f1",  "f3",  "f5",  "f7",
5429f4a2713aSLionel Sambuc   "f8",  "f10", "f12", "f14", "f9",  "f11", "f13", "f15"
5430f4a2713aSLionel Sambuc };
5431f4a2713aSLionel Sambuc 
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const5432f4a2713aSLionel Sambuc void SystemZTargetInfo::getGCCRegNames(const char *const *&Names,
5433f4a2713aSLionel Sambuc                                        unsigned &NumNames) const {
5434f4a2713aSLionel Sambuc   Names = GCCRegNames;
5435f4a2713aSLionel Sambuc   NumNames = llvm::array_lengthof(GCCRegNames);
5436f4a2713aSLionel Sambuc }
5437f4a2713aSLionel Sambuc 
5438f4a2713aSLionel Sambuc bool SystemZTargetInfo::
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const5439f4a2713aSLionel Sambuc validateAsmConstraint(const char *&Name,
5440f4a2713aSLionel Sambuc                       TargetInfo::ConstraintInfo &Info) const {
5441f4a2713aSLionel Sambuc   switch (*Name) {
5442f4a2713aSLionel Sambuc   default:
5443f4a2713aSLionel Sambuc     return false;
5444f4a2713aSLionel Sambuc 
5445f4a2713aSLionel Sambuc   case 'a': // Address register
5446f4a2713aSLionel Sambuc   case 'd': // Data register (equivalent to 'r')
5447f4a2713aSLionel Sambuc   case 'f': // Floating-point register
5448f4a2713aSLionel Sambuc     Info.setAllowsRegister();
5449f4a2713aSLionel Sambuc     return true;
5450f4a2713aSLionel Sambuc 
5451f4a2713aSLionel Sambuc   case 'I': // Unsigned 8-bit constant
5452f4a2713aSLionel Sambuc   case 'J': // Unsigned 12-bit constant
5453f4a2713aSLionel Sambuc   case 'K': // Signed 16-bit constant
5454f4a2713aSLionel Sambuc   case 'L': // Signed 20-bit displacement (on all targets we support)
5455f4a2713aSLionel Sambuc   case 'M': // 0x7fffffff
5456f4a2713aSLionel Sambuc     return true;
5457f4a2713aSLionel Sambuc 
5458f4a2713aSLionel Sambuc   case 'Q': // Memory with base and unsigned 12-bit displacement
5459f4a2713aSLionel Sambuc   case 'R': // Likewise, plus an index
5460f4a2713aSLionel Sambuc   case 'S': // Memory with base and signed 20-bit displacement
5461f4a2713aSLionel Sambuc   case 'T': // Likewise, plus an index
5462f4a2713aSLionel Sambuc     Info.setAllowsMemory();
5463f4a2713aSLionel Sambuc     return true;
5464f4a2713aSLionel Sambuc   }
5465f4a2713aSLionel Sambuc }
5466f4a2713aSLionel Sambuc }
5467f4a2713aSLionel Sambuc 
5468f4a2713aSLionel Sambuc namespace {
5469f4a2713aSLionel Sambuc   class MSP430TargetInfo : public TargetInfo {
5470f4a2713aSLionel Sambuc     static const char * const GCCRegNames[];
5471f4a2713aSLionel Sambuc   public:
MSP430TargetInfo(const llvm::Triple & Triple)5472f4a2713aSLionel Sambuc     MSP430TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
5473f4a2713aSLionel Sambuc       BigEndian = false;
5474f4a2713aSLionel Sambuc       TLSSupported = false;
5475f4a2713aSLionel Sambuc       IntWidth = 16; IntAlign = 16;
5476f4a2713aSLionel Sambuc       LongWidth = 32; LongLongWidth = 64;
5477f4a2713aSLionel Sambuc       LongAlign = LongLongAlign = 16;
5478f4a2713aSLionel Sambuc       PointerWidth = 16; PointerAlign = 16;
5479f4a2713aSLionel Sambuc       SuitableAlign = 16;
5480f4a2713aSLionel Sambuc       SizeType = UnsignedInt;
5481f4a2713aSLionel Sambuc       IntMaxType = SignedLongLong;
5482f4a2713aSLionel Sambuc       IntPtrType = SignedInt;
5483f4a2713aSLionel Sambuc       PtrDiffType = SignedInt;
5484f4a2713aSLionel Sambuc       SigAtomicType = SignedLong;
5485*0a6a1f1dSLionel Sambuc       DescriptionString = "e-m:e-p:16:16-i32:16:32-a:16-n8:16";
5486f4a2713aSLionel Sambuc     }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5487*0a6a1f1dSLionel Sambuc     void getTargetDefines(const LangOptions &Opts,
5488*0a6a1f1dSLionel Sambuc                           MacroBuilder &Builder) const override {
5489f4a2713aSLionel Sambuc       Builder.defineMacro("MSP430");
5490f4a2713aSLionel Sambuc       Builder.defineMacro("__MSP430__");
5491f4a2713aSLionel Sambuc       // FIXME: defines for different 'flavours' of MCU
5492f4a2713aSLionel Sambuc     }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const5493*0a6a1f1dSLionel Sambuc     void getTargetBuiltins(const Builtin::Info *&Records,
5494*0a6a1f1dSLionel Sambuc                            unsigned &NumRecords) const override {
5495f4a2713aSLionel Sambuc       // FIXME: Implement.
5496*0a6a1f1dSLionel Sambuc       Records = nullptr;
5497f4a2713aSLionel Sambuc       NumRecords = 0;
5498f4a2713aSLionel Sambuc     }
hasFeature(StringRef Feature) const5499*0a6a1f1dSLionel Sambuc     bool hasFeature(StringRef Feature) const override {
5500f4a2713aSLionel Sambuc       return Feature == "msp430";
5501f4a2713aSLionel Sambuc     }
5502*0a6a1f1dSLionel Sambuc     void getGCCRegNames(const char * const *&Names,
5503*0a6a1f1dSLionel Sambuc                         unsigned &NumNames) const override;
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const5504*0a6a1f1dSLionel Sambuc     void getGCCRegAliases(const GCCRegAlias *&Aliases,
5505*0a6a1f1dSLionel Sambuc                           unsigned &NumAliases) const override {
5506f4a2713aSLionel Sambuc       // No aliases.
5507*0a6a1f1dSLionel Sambuc       Aliases = nullptr;
5508f4a2713aSLionel Sambuc       NumAliases = 0;
5509f4a2713aSLionel Sambuc     }
5510*0a6a1f1dSLionel Sambuc     bool
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const5511*0a6a1f1dSLionel Sambuc     validateAsmConstraint(const char *&Name,
5512*0a6a1f1dSLionel Sambuc                           TargetInfo::ConstraintInfo &info) const override {
5513*0a6a1f1dSLionel Sambuc       // FIXME: implement
5514*0a6a1f1dSLionel Sambuc       switch (*Name) {
5515*0a6a1f1dSLionel Sambuc       case 'K': // the constant 1
5516*0a6a1f1dSLionel Sambuc       case 'L': // constant -1^20 .. 1^19
5517*0a6a1f1dSLionel Sambuc       case 'M': // constant 1-4:
5518*0a6a1f1dSLionel Sambuc         return true;
5519*0a6a1f1dSLionel Sambuc       }
5520f4a2713aSLionel Sambuc       // No target constraints for now.
5521f4a2713aSLionel Sambuc       return false;
5522f4a2713aSLionel Sambuc     }
getClobbers() const5523*0a6a1f1dSLionel Sambuc     const char *getClobbers() const override {
5524f4a2713aSLionel Sambuc       // FIXME: Is this really right?
5525f4a2713aSLionel Sambuc       return "";
5526f4a2713aSLionel Sambuc     }
getBuiltinVaListKind() const5527*0a6a1f1dSLionel Sambuc     BuiltinVaListKind getBuiltinVaListKind() const override {
5528f4a2713aSLionel Sambuc       // FIXME: implement
5529f4a2713aSLionel Sambuc       return TargetInfo::CharPtrBuiltinVaList;
5530f4a2713aSLionel Sambuc    }
5531f4a2713aSLionel Sambuc   };
5532f4a2713aSLionel Sambuc 
5533f4a2713aSLionel Sambuc   const char * const MSP430TargetInfo::GCCRegNames[] = {
5534f4a2713aSLionel Sambuc     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
5535f4a2713aSLionel Sambuc     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
5536f4a2713aSLionel Sambuc   };
5537f4a2713aSLionel Sambuc 
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const5538f4a2713aSLionel Sambuc   void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
5539f4a2713aSLionel Sambuc                                         unsigned &NumNames) const {
5540f4a2713aSLionel Sambuc     Names = GCCRegNames;
5541f4a2713aSLionel Sambuc     NumNames = llvm::array_lengthof(GCCRegNames);
5542f4a2713aSLionel Sambuc   }
5543f4a2713aSLionel Sambuc }
5544f4a2713aSLionel Sambuc 
5545f4a2713aSLionel Sambuc namespace {
5546f4a2713aSLionel Sambuc 
5547f4a2713aSLionel Sambuc   // LLVM and Clang cannot be used directly to output native binaries for
5548f4a2713aSLionel Sambuc   // target, but is used to compile C code to llvm bitcode with correct
5549f4a2713aSLionel Sambuc   // type and alignment information.
5550f4a2713aSLionel Sambuc   //
5551f4a2713aSLionel Sambuc   // TCE uses the llvm bitcode as input and uses it for generating customized
5552f4a2713aSLionel Sambuc   // target processor and program binary. TCE co-design environment is
5553f4a2713aSLionel Sambuc   // publicly available in http://tce.cs.tut.fi
5554f4a2713aSLionel Sambuc 
5555f4a2713aSLionel Sambuc   static const unsigned TCEOpenCLAddrSpaceMap[] = {
5556f4a2713aSLionel Sambuc       3, // opencl_global
5557f4a2713aSLionel Sambuc       4, // opencl_local
5558f4a2713aSLionel Sambuc       5, // opencl_constant
5559*0a6a1f1dSLionel Sambuc       // FIXME: generic has to be added to the target
5560*0a6a1f1dSLionel Sambuc       0, // opencl_generic
5561f4a2713aSLionel Sambuc       0, // cuda_device
5562f4a2713aSLionel Sambuc       0, // cuda_constant
5563f4a2713aSLionel Sambuc       0  // cuda_shared
5564f4a2713aSLionel Sambuc   };
5565f4a2713aSLionel Sambuc 
5566f4a2713aSLionel Sambuc   class TCETargetInfo : public TargetInfo{
5567f4a2713aSLionel Sambuc   public:
TCETargetInfo(const llvm::Triple & Triple)5568f4a2713aSLionel Sambuc     TCETargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
5569f4a2713aSLionel Sambuc       TLSSupported = false;
5570f4a2713aSLionel Sambuc       IntWidth = 32;
5571f4a2713aSLionel Sambuc       LongWidth = LongLongWidth = 32;
5572f4a2713aSLionel Sambuc       PointerWidth = 32;
5573f4a2713aSLionel Sambuc       IntAlign = 32;
5574f4a2713aSLionel Sambuc       LongAlign = LongLongAlign = 32;
5575f4a2713aSLionel Sambuc       PointerAlign = 32;
5576f4a2713aSLionel Sambuc       SuitableAlign = 32;
5577f4a2713aSLionel Sambuc       SizeType = UnsignedInt;
5578f4a2713aSLionel Sambuc       IntMaxType = SignedLong;
5579f4a2713aSLionel Sambuc       IntPtrType = SignedInt;
5580f4a2713aSLionel Sambuc       PtrDiffType = SignedInt;
5581f4a2713aSLionel Sambuc       FloatWidth = 32;
5582f4a2713aSLionel Sambuc       FloatAlign = 32;
5583f4a2713aSLionel Sambuc       DoubleWidth = 32;
5584f4a2713aSLionel Sambuc       DoubleAlign = 32;
5585f4a2713aSLionel Sambuc       LongDoubleWidth = 32;
5586f4a2713aSLionel Sambuc       LongDoubleAlign = 32;
5587f4a2713aSLionel Sambuc       FloatFormat = &llvm::APFloat::IEEEsingle;
5588f4a2713aSLionel Sambuc       DoubleFormat = &llvm::APFloat::IEEEsingle;
5589f4a2713aSLionel Sambuc       LongDoubleFormat = &llvm::APFloat::IEEEsingle;
5590*0a6a1f1dSLionel Sambuc       DescriptionString = "E-p:32:32-i8:8:32-i16:16:32-i64:32"
5591*0a6a1f1dSLionel Sambuc                           "-f64:32-v64:32-v128:32-a:0:32-n32";
5592f4a2713aSLionel Sambuc       AddrSpaceMap = &TCEOpenCLAddrSpaceMap;
5593f4a2713aSLionel Sambuc       UseAddrSpaceMapMangling = true;
5594f4a2713aSLionel Sambuc     }
5595f4a2713aSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5596*0a6a1f1dSLionel Sambuc     void getTargetDefines(const LangOptions &Opts,
5597*0a6a1f1dSLionel Sambuc                           MacroBuilder &Builder) const override {
5598f4a2713aSLionel Sambuc       DefineStd(Builder, "tce", Opts);
5599f4a2713aSLionel Sambuc       Builder.defineMacro("__TCE__");
5600f4a2713aSLionel Sambuc       Builder.defineMacro("__TCE_V1__");
5601f4a2713aSLionel Sambuc     }
hasFeature(StringRef Feature) const5602*0a6a1f1dSLionel Sambuc     bool hasFeature(StringRef Feature) const override {
5603f4a2713aSLionel Sambuc       return Feature == "tce";
5604f4a2713aSLionel Sambuc     }
5605f4a2713aSLionel Sambuc 
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const5606*0a6a1f1dSLionel Sambuc     void getTargetBuiltins(const Builtin::Info *&Records,
5607*0a6a1f1dSLionel Sambuc                            unsigned &NumRecords) const override {}
getClobbers() const5608*0a6a1f1dSLionel Sambuc     const char *getClobbers() const override {
5609f4a2713aSLionel Sambuc       return "";
5610f4a2713aSLionel Sambuc     }
getBuiltinVaListKind() const5611*0a6a1f1dSLionel Sambuc     BuiltinVaListKind getBuiltinVaListKind() const override {
5612f4a2713aSLionel Sambuc       return TargetInfo::VoidPtrBuiltinVaList;
5613f4a2713aSLionel Sambuc     }
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const5614*0a6a1f1dSLionel Sambuc     void getGCCRegNames(const char * const *&Names,
5615*0a6a1f1dSLionel Sambuc                         unsigned &NumNames) const override {}
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const5616*0a6a1f1dSLionel Sambuc     bool validateAsmConstraint(const char *&Name,
5617*0a6a1f1dSLionel Sambuc                                TargetInfo::ConstraintInfo &info) const override{
5618f4a2713aSLionel Sambuc       return true;
5619f4a2713aSLionel Sambuc     }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const5620*0a6a1f1dSLionel Sambuc     void getGCCRegAliases(const GCCRegAlias *&Aliases,
5621*0a6a1f1dSLionel Sambuc                           unsigned &NumAliases) const override {}
5622f4a2713aSLionel Sambuc   };
5623f4a2713aSLionel Sambuc }
5624f4a2713aSLionel Sambuc 
5625f4a2713aSLionel Sambuc namespace {
5626f4a2713aSLionel Sambuc class MipsTargetInfoBase : public TargetInfo {
5627f4a2713aSLionel Sambuc   virtual void setDescriptionString() = 0;
5628f4a2713aSLionel Sambuc 
5629f4a2713aSLionel Sambuc   static const Builtin::Info BuiltinInfo[];
5630f4a2713aSLionel Sambuc   std::string CPU;
5631f4a2713aSLionel Sambuc   bool IsMips16;
5632f4a2713aSLionel Sambuc   bool IsMicromips;
5633f4a2713aSLionel Sambuc   bool IsNan2008;
5634f4a2713aSLionel Sambuc   bool IsSingleFloat;
5635f4a2713aSLionel Sambuc   enum MipsFloatABI {
5636f4a2713aSLionel Sambuc     HardFloat, SoftFloat
5637f4a2713aSLionel Sambuc   } FloatABI;
5638f4a2713aSLionel Sambuc   enum DspRevEnum {
5639f4a2713aSLionel Sambuc     NoDSP, DSP1, DSP2
5640f4a2713aSLionel Sambuc   } DspRev;
5641f4a2713aSLionel Sambuc   bool HasMSA;
5642f4a2713aSLionel Sambuc 
5643f4a2713aSLionel Sambuc protected:
5644f4a2713aSLionel Sambuc   bool HasFP64;
5645f4a2713aSLionel Sambuc   std::string ABI;
5646f4a2713aSLionel Sambuc 
5647f4a2713aSLionel Sambuc public:
MipsTargetInfoBase(const llvm::Triple & Triple,const std::string & ABIStr,const std::string & CPUStr)5648f4a2713aSLionel Sambuc   MipsTargetInfoBase(const llvm::Triple &Triple, const std::string &ABIStr,
5649f4a2713aSLionel Sambuc                      const std::string &CPUStr)
5650f4a2713aSLionel Sambuc       : TargetInfo(Triple), CPU(CPUStr), IsMips16(false), IsMicromips(false),
5651f4a2713aSLionel Sambuc         IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat),
5652*0a6a1f1dSLionel Sambuc         DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) {
5653*0a6a1f1dSLionel Sambuc     TheCXXABI.set(TargetCXXABI::GenericMIPS);
5654f4a2713aSLionel Sambuc   }
5655*0a6a1f1dSLionel Sambuc 
isNaN2008Default() const5656*0a6a1f1dSLionel Sambuc   bool isNaN2008Default() const {
5657*0a6a1f1dSLionel Sambuc     return CPU == "mips32r6" || CPU == "mips64r6";
5658*0a6a1f1dSLionel Sambuc   }
5659*0a6a1f1dSLionel Sambuc 
isFP64Default() const5660*0a6a1f1dSLionel Sambuc   bool isFP64Default() const {
5661*0a6a1f1dSLionel Sambuc     return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64";
5662*0a6a1f1dSLionel Sambuc   }
5663*0a6a1f1dSLionel Sambuc 
getABI() const5664*0a6a1f1dSLionel Sambuc   StringRef getABI() const override { return ABI; }
setCPU(const std::string & Name)5665*0a6a1f1dSLionel Sambuc   bool setCPU(const std::string &Name) override {
5666*0a6a1f1dSLionel Sambuc     bool IsMips32 = getTriple().getArch() == llvm::Triple::mips ||
5667*0a6a1f1dSLionel Sambuc                     getTriple().getArch() == llvm::Triple::mipsel;
5668*0a6a1f1dSLionel Sambuc     CPU = Name;
5669*0a6a1f1dSLionel Sambuc     return llvm::StringSwitch<bool>(Name)
5670*0a6a1f1dSLionel Sambuc         .Case("mips1", IsMips32)
5671*0a6a1f1dSLionel Sambuc         .Case("mips2", IsMips32)
5672*0a6a1f1dSLionel Sambuc         .Case("mips3", true)
5673*0a6a1f1dSLionel Sambuc         .Case("mips4", true)
5674*0a6a1f1dSLionel Sambuc         .Case("mips5", true)
5675*0a6a1f1dSLionel Sambuc         .Case("mips32", IsMips32)
5676*0a6a1f1dSLionel Sambuc         .Case("mips32r2", IsMips32)
5677*0a6a1f1dSLionel Sambuc         .Case("mips32r6", IsMips32)
5678*0a6a1f1dSLionel Sambuc         .Case("mips64", true)
5679*0a6a1f1dSLionel Sambuc         .Case("mips64r2", true)
5680*0a6a1f1dSLionel Sambuc         .Case("mips64r6", true)
5681*0a6a1f1dSLionel Sambuc         .Case("octeon", true)
5682*0a6a1f1dSLionel Sambuc         .Default(false);
5683*0a6a1f1dSLionel Sambuc   }
getCPU() const5684*0a6a1f1dSLionel Sambuc   const std::string& getCPU() const { return CPU; }
getDefaultFeatures(llvm::StringMap<bool> & Features) const5685*0a6a1f1dSLionel Sambuc   void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
5686*0a6a1f1dSLionel Sambuc     // The backend enables certain ABI's by default according to the
5687*0a6a1f1dSLionel Sambuc     // architecture.
5688*0a6a1f1dSLionel Sambuc     // Disable both possible defaults so that we don't end up with multiple
5689*0a6a1f1dSLionel Sambuc     // ABI's selected and trigger an assertion.
5690*0a6a1f1dSLionel Sambuc     Features["o32"] = false;
5691*0a6a1f1dSLionel Sambuc     Features["n64"] = false;
5692*0a6a1f1dSLionel Sambuc 
5693f4a2713aSLionel Sambuc     Features[ABI] = true;
5694*0a6a1f1dSLionel Sambuc     if (CPU == "octeon")
5695*0a6a1f1dSLionel Sambuc       Features["mips64r2"] = Features["cnmips"] = true;
5696*0a6a1f1dSLionel Sambuc     else
5697f4a2713aSLionel Sambuc       Features[CPU] = true;
5698f4a2713aSLionel Sambuc   }
5699f4a2713aSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5700*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
5701*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
5702*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__mips__");
5703f4a2713aSLionel Sambuc     Builder.defineMacro("_mips");
5704*0a6a1f1dSLionel Sambuc     if (Opts.GNUMode)
5705*0a6a1f1dSLionel Sambuc       Builder.defineMacro("mips");
5706*0a6a1f1dSLionel Sambuc 
5707f4a2713aSLionel Sambuc     Builder.defineMacro("__REGISTER_PREFIX__", "");
5708f4a2713aSLionel Sambuc 
5709f4a2713aSLionel Sambuc     switch (FloatABI) {
5710f4a2713aSLionel Sambuc     case HardFloat:
5711f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_hard_float", Twine(1));
5712f4a2713aSLionel Sambuc       break;
5713f4a2713aSLionel Sambuc     case SoftFloat:
5714f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_soft_float", Twine(1));
5715f4a2713aSLionel Sambuc       break;
5716f4a2713aSLionel Sambuc     }
5717f4a2713aSLionel Sambuc 
5718f4a2713aSLionel Sambuc     if (IsSingleFloat)
5719f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_single_float", Twine(1));
5720f4a2713aSLionel Sambuc 
5721f4a2713aSLionel Sambuc     Builder.defineMacro("__mips_fpr", HasFP64 ? Twine(64) : Twine(32));
5722f4a2713aSLionel Sambuc     Builder.defineMacro("_MIPS_FPSET",
5723f4a2713aSLionel Sambuc                         Twine(32 / (HasFP64 || IsSingleFloat ? 1 : 2)));
5724f4a2713aSLionel Sambuc 
5725f4a2713aSLionel Sambuc     if (IsMips16)
5726f4a2713aSLionel Sambuc       Builder.defineMacro("__mips16", Twine(1));
5727f4a2713aSLionel Sambuc 
5728f4a2713aSLionel Sambuc     if (IsMicromips)
5729f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_micromips", Twine(1));
5730f4a2713aSLionel Sambuc 
5731f4a2713aSLionel Sambuc     if (IsNan2008)
5732f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_nan2008", Twine(1));
5733f4a2713aSLionel Sambuc 
5734f4a2713aSLionel Sambuc     switch (DspRev) {
5735f4a2713aSLionel Sambuc     default:
5736f4a2713aSLionel Sambuc       break;
5737f4a2713aSLionel Sambuc     case DSP1:
5738f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_dsp_rev", Twine(1));
5739f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_dsp", Twine(1));
5740f4a2713aSLionel Sambuc       break;
5741f4a2713aSLionel Sambuc     case DSP2:
5742f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_dsp_rev", Twine(2));
5743f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_dspr2", Twine(1));
5744f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_dsp", Twine(1));
5745f4a2713aSLionel Sambuc       break;
5746f4a2713aSLionel Sambuc     }
5747f4a2713aSLionel Sambuc 
5748f4a2713aSLionel Sambuc     if (HasMSA)
5749f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_msa", Twine(1));
5750f4a2713aSLionel Sambuc 
5751f4a2713aSLionel Sambuc     Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
5752f4a2713aSLionel Sambuc     Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
5753f4a2713aSLionel Sambuc     Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
5754f4a2713aSLionel Sambuc 
5755f4a2713aSLionel Sambuc     Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");
5756f4a2713aSLionel Sambuc     Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
5757f4a2713aSLionel Sambuc   }
5758f4a2713aSLionel Sambuc 
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const5759*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
5760*0a6a1f1dSLionel Sambuc                          unsigned &NumRecords) const override {
5761f4a2713aSLionel Sambuc     Records = BuiltinInfo;
5762f4a2713aSLionel Sambuc     NumRecords = clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin;
5763f4a2713aSLionel Sambuc   }
hasFeature(StringRef Feature) const5764*0a6a1f1dSLionel Sambuc   bool hasFeature(StringRef Feature) const override {
5765f4a2713aSLionel Sambuc     return llvm::StringSwitch<bool>(Feature)
5766f4a2713aSLionel Sambuc       .Case("mips", true)
5767f4a2713aSLionel Sambuc       .Case("fp64", HasFP64)
5768f4a2713aSLionel Sambuc       .Default(false);
5769f4a2713aSLionel Sambuc   }
getBuiltinVaListKind() const5770*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
5771f4a2713aSLionel Sambuc     return TargetInfo::VoidPtrBuiltinVaList;
5772f4a2713aSLionel Sambuc   }
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const5773*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char * const *&Names,
5774*0a6a1f1dSLionel Sambuc                       unsigned &NumNames) const override {
5775f4a2713aSLionel Sambuc     static const char *const GCCRegNames[] = {
5776f4a2713aSLionel Sambuc       // CPU register names
5777f4a2713aSLionel Sambuc       // Must match second column of GCCRegAliases
5778f4a2713aSLionel Sambuc       "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
5779f4a2713aSLionel Sambuc       "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
5780f4a2713aSLionel Sambuc       "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
5781f4a2713aSLionel Sambuc       "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31",
5782f4a2713aSLionel Sambuc       // Floating point register names
5783f4a2713aSLionel Sambuc       "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
5784f4a2713aSLionel Sambuc       "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
5785f4a2713aSLionel Sambuc       "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
5786f4a2713aSLionel Sambuc       "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
5787f4a2713aSLionel Sambuc       // Hi/lo and condition register names
5788f4a2713aSLionel Sambuc       "hi",   "lo",   "",     "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
5789f4a2713aSLionel Sambuc       "$fcc5","$fcc6","$fcc7",
5790f4a2713aSLionel Sambuc       // MSA register names
5791f4a2713aSLionel Sambuc       "$w0",  "$w1",  "$w2",  "$w3",  "$w4",  "$w5",  "$w6",  "$w7",
5792f4a2713aSLionel Sambuc       "$w8",  "$w9",  "$w10", "$w11", "$w12", "$w13", "$w14", "$w15",
5793f4a2713aSLionel Sambuc       "$w16", "$w17", "$w18", "$w19", "$w20", "$w21", "$w22", "$w23",
5794f4a2713aSLionel Sambuc       "$w24", "$w25", "$w26", "$w27", "$w28", "$w29", "$w30", "$w31",
5795f4a2713aSLionel Sambuc       // MSA control register names
5796f4a2713aSLionel Sambuc       "$msair",      "$msacsr", "$msaaccess", "$msasave", "$msamodify",
5797f4a2713aSLionel Sambuc       "$msarequest", "$msamap", "$msaunmap"
5798f4a2713aSLionel Sambuc     };
5799f4a2713aSLionel Sambuc     Names = GCCRegNames;
5800f4a2713aSLionel Sambuc     NumNames = llvm::array_lengthof(GCCRegNames);
5801f4a2713aSLionel Sambuc   }
5802*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
5803*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override = 0;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const5804*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
5805*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &Info) const override {
5806f4a2713aSLionel Sambuc     switch (*Name) {
5807f4a2713aSLionel Sambuc     default:
5808f4a2713aSLionel Sambuc       return false;
5809f4a2713aSLionel Sambuc     case 'r': // CPU registers.
5810f4a2713aSLionel Sambuc     case 'd': // Equivalent to "r" unless generating MIPS16 code.
5811*0a6a1f1dSLionel Sambuc     case 'y': // Equivalent to "r", backward compatibility only.
5812f4a2713aSLionel Sambuc     case 'f': // floating-point registers.
5813f4a2713aSLionel Sambuc     case 'c': // $25 for indirect jumps
5814f4a2713aSLionel Sambuc     case 'l': // lo register
5815f4a2713aSLionel Sambuc     case 'x': // hilo register pair
5816f4a2713aSLionel Sambuc       Info.setAllowsRegister();
5817f4a2713aSLionel Sambuc       return true;
5818*0a6a1f1dSLionel Sambuc     case 'I': // Signed 16-bit constant
5819*0a6a1f1dSLionel Sambuc     case 'J': // Integer 0
5820*0a6a1f1dSLionel Sambuc     case 'K': // Unsigned 16-bit constant
5821*0a6a1f1dSLionel Sambuc     case 'L': // Signed 32-bit constant, lower 16-bit zeros (for lui)
5822*0a6a1f1dSLionel Sambuc     case 'M': // Constants not loadable via lui, addiu, or ori
5823*0a6a1f1dSLionel Sambuc     case 'N': // Constant -1 to -65535
5824*0a6a1f1dSLionel Sambuc     case 'O': // A signed 15-bit constant
5825*0a6a1f1dSLionel Sambuc     case 'P': // A constant between 1 go 65535
5826*0a6a1f1dSLionel Sambuc       return true;
5827f4a2713aSLionel Sambuc     case 'R': // An address that can be used in a non-macro load or store
5828f4a2713aSLionel Sambuc       Info.setAllowsMemory();
5829f4a2713aSLionel Sambuc       return true;
5830f4a2713aSLionel Sambuc     }
5831f4a2713aSLionel Sambuc   }
5832f4a2713aSLionel Sambuc 
getClobbers() const5833*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override {
5834*0a6a1f1dSLionel Sambuc     // In GCC, $1 is not widely used in generated code (it's used only in a few
5835*0a6a1f1dSLionel Sambuc     // specific situations), so there is no real need for users to add it to
5836*0a6a1f1dSLionel Sambuc     // the clobbers list if they want to use it in their inline assembly code.
5837*0a6a1f1dSLionel Sambuc     //
5838*0a6a1f1dSLionel Sambuc     // In LLVM, $1 is treated as a normal GPR and is always allocatable during
5839*0a6a1f1dSLionel Sambuc     // code generation, so using it in inline assembly without adding it to the
5840*0a6a1f1dSLionel Sambuc     // clobbers list can cause conflicts between the inline assembly code and
5841*0a6a1f1dSLionel Sambuc     // the surrounding generated code.
5842*0a6a1f1dSLionel Sambuc     //
5843*0a6a1f1dSLionel Sambuc     // Another problem is that LLVM is allowed to choose $1 for inline assembly
5844*0a6a1f1dSLionel Sambuc     // operands, which will conflict with the ".set at" assembler option (which
5845*0a6a1f1dSLionel Sambuc     // we use only for inline assembly, in order to maintain compatibility with
5846*0a6a1f1dSLionel Sambuc     // GCC) and will also conflict with the user's usage of $1.
5847*0a6a1f1dSLionel Sambuc     //
5848*0a6a1f1dSLionel Sambuc     // The easiest way to avoid these conflicts and keep $1 as an allocatable
5849*0a6a1f1dSLionel Sambuc     // register for generated code is to automatically clobber $1 for all inline
5850*0a6a1f1dSLionel Sambuc     // assembly code.
5851*0a6a1f1dSLionel Sambuc     //
5852*0a6a1f1dSLionel Sambuc     // FIXME: We should automatically clobber $1 only for inline assembly code
5853*0a6a1f1dSLionel Sambuc     // which actually uses it. This would allow LLVM to use $1 for inline
5854*0a6a1f1dSLionel Sambuc     // assembly operands if the user's assembly code doesn't use it.
5855*0a6a1f1dSLionel Sambuc     return "~{$1}";
5856f4a2713aSLionel Sambuc   }
5857f4a2713aSLionel Sambuc 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)5858*0a6a1f1dSLionel Sambuc   bool handleTargetFeatures(std::vector<std::string> &Features,
5859*0a6a1f1dSLionel Sambuc                             DiagnosticsEngine &Diags) override {
5860f4a2713aSLionel Sambuc     IsMips16 = false;
5861f4a2713aSLionel Sambuc     IsMicromips = false;
5862*0a6a1f1dSLionel Sambuc     IsNan2008 = isNaN2008Default();
5863f4a2713aSLionel Sambuc     IsSingleFloat = false;
5864f4a2713aSLionel Sambuc     FloatABI = HardFloat;
5865f4a2713aSLionel Sambuc     DspRev = NoDSP;
5866*0a6a1f1dSLionel Sambuc     HasFP64 = isFP64Default();
5867f4a2713aSLionel Sambuc 
5868f4a2713aSLionel Sambuc     for (std::vector<std::string>::iterator it = Features.begin(),
5869f4a2713aSLionel Sambuc          ie = Features.end(); it != ie; ++it) {
5870f4a2713aSLionel Sambuc       if (*it == "+single-float")
5871f4a2713aSLionel Sambuc         IsSingleFloat = true;
5872f4a2713aSLionel Sambuc       else if (*it == "+soft-float")
5873f4a2713aSLionel Sambuc         FloatABI = SoftFloat;
5874f4a2713aSLionel Sambuc       else if (*it == "+mips16")
5875f4a2713aSLionel Sambuc         IsMips16 = true;
5876f4a2713aSLionel Sambuc       else if (*it == "+micromips")
5877f4a2713aSLionel Sambuc         IsMicromips = true;
5878f4a2713aSLionel Sambuc       else if (*it == "+dsp")
5879f4a2713aSLionel Sambuc         DspRev = std::max(DspRev, DSP1);
5880f4a2713aSLionel Sambuc       else if (*it == "+dspr2")
5881f4a2713aSLionel Sambuc         DspRev = std::max(DspRev, DSP2);
5882f4a2713aSLionel Sambuc       else if (*it == "+msa")
5883f4a2713aSLionel Sambuc         HasMSA = true;
5884f4a2713aSLionel Sambuc       else if (*it == "+fp64")
5885f4a2713aSLionel Sambuc         HasFP64 = true;
5886f4a2713aSLionel Sambuc       else if (*it == "-fp64")
5887f4a2713aSLionel Sambuc         HasFP64 = false;
5888f4a2713aSLionel Sambuc       else if (*it == "+nan2008")
5889f4a2713aSLionel Sambuc         IsNan2008 = true;
5890*0a6a1f1dSLionel Sambuc       else if (*it == "-nan2008")
5891*0a6a1f1dSLionel Sambuc         IsNan2008 = false;
5892f4a2713aSLionel Sambuc     }
5893f4a2713aSLionel Sambuc 
5894f4a2713aSLionel Sambuc     // Remove front-end specific options.
5895f4a2713aSLionel Sambuc     std::vector<std::string>::iterator it =
5896f4a2713aSLionel Sambuc       std::find(Features.begin(), Features.end(), "+soft-float");
5897f4a2713aSLionel Sambuc     if (it != Features.end())
5898f4a2713aSLionel Sambuc       Features.erase(it);
5899f4a2713aSLionel Sambuc 
5900f4a2713aSLionel Sambuc     setDescriptionString();
5901f4a2713aSLionel Sambuc 
5902f4a2713aSLionel Sambuc     return true;
5903f4a2713aSLionel Sambuc   }
5904f4a2713aSLionel Sambuc 
getEHDataRegisterNumber(unsigned RegNo) const5905*0a6a1f1dSLionel Sambuc   int getEHDataRegisterNumber(unsigned RegNo) const override {
5906f4a2713aSLionel Sambuc     if (RegNo == 0) return 4;
5907f4a2713aSLionel Sambuc     if (RegNo == 1) return 5;
5908f4a2713aSLionel Sambuc     return -1;
5909f4a2713aSLionel Sambuc   }
5910*0a6a1f1dSLionel Sambuc 
isCLZForZeroUndef() const5911*0a6a1f1dSLionel Sambuc   bool isCLZForZeroUndef() const override { return false; }
5912f4a2713aSLionel Sambuc };
5913f4a2713aSLionel Sambuc 
5914f4a2713aSLionel Sambuc const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
5915f4a2713aSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
5916f4a2713aSLionel Sambuc #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
5917f4a2713aSLionel Sambuc                                               ALL_LANGUAGES },
5918f4a2713aSLionel Sambuc #include "clang/Basic/BuiltinsMips.def"
5919f4a2713aSLionel Sambuc };
5920f4a2713aSLionel Sambuc 
5921f4a2713aSLionel Sambuc class Mips32TargetInfoBase : public MipsTargetInfoBase {
5922f4a2713aSLionel Sambuc public:
Mips32TargetInfoBase(const llvm::Triple & Triple)5923f4a2713aSLionel Sambuc   Mips32TargetInfoBase(const llvm::Triple &Triple)
5924*0a6a1f1dSLionel Sambuc       : MipsTargetInfoBase(Triple, "o32", "mips32r2") {
5925f4a2713aSLionel Sambuc     SizeType = UnsignedInt;
5926f4a2713aSLionel Sambuc     PtrDiffType = SignedInt;
5927*0a6a1f1dSLionel Sambuc     Int64Type = SignedLongLong;
5928*0a6a1f1dSLionel Sambuc     IntMaxType = Int64Type;
5929f4a2713aSLionel Sambuc     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
5930f4a2713aSLionel Sambuc   }
setABI(const std::string & Name)5931*0a6a1f1dSLionel Sambuc   bool setABI(const std::string &Name) override {
5932*0a6a1f1dSLionel Sambuc     if (Name == "o32" || Name == "eabi") {
5933f4a2713aSLionel Sambuc       ABI = Name;
5934f4a2713aSLionel Sambuc       return true;
5935*0a6a1f1dSLionel Sambuc     }
5936f4a2713aSLionel Sambuc     return false;
5937f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5938*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
5939*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
5940f4a2713aSLionel Sambuc     MipsTargetInfoBase::getTargetDefines(Opts, Builder);
5941f4a2713aSLionel Sambuc 
5942*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__mips", "32");
5943*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");
5944*0a6a1f1dSLionel Sambuc 
5945*0a6a1f1dSLionel Sambuc     const std::string& CPUStr = getCPU();
5946*0a6a1f1dSLionel Sambuc     if (CPUStr == "mips32")
5947*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__mips_isa_rev", "1");
5948*0a6a1f1dSLionel Sambuc     else if (CPUStr == "mips32r2")
5949*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__mips_isa_rev", "2");
5950*0a6a1f1dSLionel Sambuc     else if (CPUStr == "mips32r6")
5951*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__mips_isa_rev", "6");
5952*0a6a1f1dSLionel Sambuc 
5953f4a2713aSLionel Sambuc     if (ABI == "o32") {
5954f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_o32");
5955f4a2713aSLionel Sambuc       Builder.defineMacro("_ABIO32", "1");
5956f4a2713aSLionel Sambuc       Builder.defineMacro("_MIPS_SIM", "_ABIO32");
5957f4a2713aSLionel Sambuc     }
5958f4a2713aSLionel Sambuc     else if (ABI == "eabi")
5959f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_eabi");
5960f4a2713aSLionel Sambuc     else
5961f4a2713aSLionel Sambuc       llvm_unreachable("Invalid ABI for Mips32.");
5962f4a2713aSLionel Sambuc   }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const5963*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
5964*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override {
5965f4a2713aSLionel Sambuc     static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
5966f4a2713aSLionel Sambuc       { { "at" },  "$1" },
5967f4a2713aSLionel Sambuc       { { "v0" },  "$2" },
5968f4a2713aSLionel Sambuc       { { "v1" },  "$3" },
5969f4a2713aSLionel Sambuc       { { "a0" },  "$4" },
5970f4a2713aSLionel Sambuc       { { "a1" },  "$5" },
5971f4a2713aSLionel Sambuc       { { "a2" },  "$6" },
5972f4a2713aSLionel Sambuc       { { "a3" },  "$7" },
5973f4a2713aSLionel Sambuc       { { "t0" },  "$8" },
5974f4a2713aSLionel Sambuc       { { "t1" },  "$9" },
5975f4a2713aSLionel Sambuc       { { "t2" }, "$10" },
5976f4a2713aSLionel Sambuc       { { "t3" }, "$11" },
5977f4a2713aSLionel Sambuc       { { "t4" }, "$12" },
5978f4a2713aSLionel Sambuc       { { "t5" }, "$13" },
5979f4a2713aSLionel Sambuc       { { "t6" }, "$14" },
5980f4a2713aSLionel Sambuc       { { "t7" }, "$15" },
5981f4a2713aSLionel Sambuc       { { "s0" }, "$16" },
5982f4a2713aSLionel Sambuc       { { "s1" }, "$17" },
5983f4a2713aSLionel Sambuc       { { "s2" }, "$18" },
5984f4a2713aSLionel Sambuc       { { "s3" }, "$19" },
5985f4a2713aSLionel Sambuc       { { "s4" }, "$20" },
5986f4a2713aSLionel Sambuc       { { "s5" }, "$21" },
5987f4a2713aSLionel Sambuc       { { "s6" }, "$22" },
5988f4a2713aSLionel Sambuc       { { "s7" }, "$23" },
5989f4a2713aSLionel Sambuc       { { "t8" }, "$24" },
5990f4a2713aSLionel Sambuc       { { "t9" }, "$25" },
5991f4a2713aSLionel Sambuc       { { "k0" }, "$26" },
5992f4a2713aSLionel Sambuc       { { "k1" }, "$27" },
5993f4a2713aSLionel Sambuc       { { "gp" }, "$28" },
5994f4a2713aSLionel Sambuc       { { "sp","$sp" }, "$29" },
5995f4a2713aSLionel Sambuc       { { "fp","$fp" }, "$30" },
5996f4a2713aSLionel Sambuc       { { "ra" }, "$31" }
5997f4a2713aSLionel Sambuc     };
5998f4a2713aSLionel Sambuc     Aliases = GCCRegAliases;
5999f4a2713aSLionel Sambuc     NumAliases = llvm::array_lengthof(GCCRegAliases);
6000f4a2713aSLionel Sambuc   }
6001f4a2713aSLionel Sambuc };
6002f4a2713aSLionel Sambuc 
6003f4a2713aSLionel Sambuc class Mips32EBTargetInfo : public Mips32TargetInfoBase {
setDescriptionString()6004*0a6a1f1dSLionel Sambuc   void setDescriptionString() override {
6005*0a6a1f1dSLionel Sambuc     DescriptionString = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
6006f4a2713aSLionel Sambuc   }
6007f4a2713aSLionel Sambuc 
6008f4a2713aSLionel Sambuc public:
Mips32EBTargetInfo(const llvm::Triple & Triple)6009f4a2713aSLionel Sambuc   Mips32EBTargetInfo(const llvm::Triple &Triple)
6010f4a2713aSLionel Sambuc       : Mips32TargetInfoBase(Triple) {
6011f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6012*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
6013*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
6014f4a2713aSLionel Sambuc     DefineStd(Builder, "MIPSEB", Opts);
6015f4a2713aSLionel Sambuc     Builder.defineMacro("_MIPSEB");
6016f4a2713aSLionel Sambuc     Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
6017f4a2713aSLionel Sambuc   }
6018f4a2713aSLionel Sambuc };
6019f4a2713aSLionel Sambuc 
6020f4a2713aSLionel Sambuc class Mips32ELTargetInfo : public Mips32TargetInfoBase {
setDescriptionString()6021*0a6a1f1dSLionel Sambuc   void setDescriptionString() override {
6022*0a6a1f1dSLionel Sambuc     DescriptionString = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
6023f4a2713aSLionel Sambuc   }
6024f4a2713aSLionel Sambuc 
6025f4a2713aSLionel Sambuc public:
Mips32ELTargetInfo(const llvm::Triple & Triple)6026f4a2713aSLionel Sambuc   Mips32ELTargetInfo(const llvm::Triple &Triple)
6027f4a2713aSLionel Sambuc       : Mips32TargetInfoBase(Triple) {
6028f4a2713aSLionel Sambuc     BigEndian = false;
6029f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6030*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
6031*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
6032f4a2713aSLionel Sambuc     DefineStd(Builder, "MIPSEL", Opts);
6033f4a2713aSLionel Sambuc     Builder.defineMacro("_MIPSEL");
6034f4a2713aSLionel Sambuc     Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
6035f4a2713aSLionel Sambuc   }
6036f4a2713aSLionel Sambuc };
6037f4a2713aSLionel Sambuc 
6038f4a2713aSLionel Sambuc class Mips64TargetInfoBase : public MipsTargetInfoBase {
6039f4a2713aSLionel Sambuc public:
Mips64TargetInfoBase(const llvm::Triple & Triple)6040f4a2713aSLionel Sambuc   Mips64TargetInfoBase(const llvm::Triple &Triple)
6041*0a6a1f1dSLionel Sambuc       : MipsTargetInfoBase(Triple, "n64", "mips64r2") {
6042f4a2713aSLionel Sambuc     LongDoubleWidth = LongDoubleAlign = 128;
6043f4a2713aSLionel Sambuc     LongDoubleFormat = &llvm::APFloat::IEEEquad;
6044f4a2713aSLionel Sambuc     if (getTriple().getOS() == llvm::Triple::FreeBSD) {
6045f4a2713aSLionel Sambuc       LongDoubleWidth = LongDoubleAlign = 64;
6046f4a2713aSLionel Sambuc       LongDoubleFormat = &llvm::APFloat::IEEEdouble;
6047f4a2713aSLionel Sambuc     }
6048*0a6a1f1dSLionel Sambuc     setN64ABITypes();
6049f4a2713aSLionel Sambuc     SuitableAlign = 128;
6050f4a2713aSLionel Sambuc     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
6051f4a2713aSLionel Sambuc   }
6052*0a6a1f1dSLionel Sambuc 
setN64ABITypes()6053*0a6a1f1dSLionel Sambuc   void setN64ABITypes() {
6054*0a6a1f1dSLionel Sambuc     LongWidth = LongAlign = 64;
6055*0a6a1f1dSLionel Sambuc     PointerWidth = PointerAlign = 64;
6056*0a6a1f1dSLionel Sambuc     SizeType = UnsignedLong;
6057*0a6a1f1dSLionel Sambuc     PtrDiffType = SignedLong;
6058*0a6a1f1dSLionel Sambuc     Int64Type = SignedLong;
6059*0a6a1f1dSLionel Sambuc     IntMaxType = Int64Type;
6060*0a6a1f1dSLionel Sambuc   }
6061*0a6a1f1dSLionel Sambuc 
setN32ABITypes()6062*0a6a1f1dSLionel Sambuc   void setN32ABITypes() {
6063f4a2713aSLionel Sambuc     LongWidth = LongAlign = 32;
6064f4a2713aSLionel Sambuc     PointerWidth = PointerAlign = 32;
6065*0a6a1f1dSLionel Sambuc     SizeType = UnsignedInt;
6066*0a6a1f1dSLionel Sambuc     PtrDiffType = SignedInt;
6067*0a6a1f1dSLionel Sambuc     Int64Type = SignedLongLong;
6068*0a6a1f1dSLionel Sambuc     IntMaxType = Int64Type;
6069*0a6a1f1dSLionel Sambuc   }
6070*0a6a1f1dSLionel Sambuc 
setABI(const std::string & Name)6071*0a6a1f1dSLionel Sambuc   bool setABI(const std::string &Name) override {
6072*0a6a1f1dSLionel Sambuc     if (Name == "n32") {
6073*0a6a1f1dSLionel Sambuc       setN32ABITypes();
6074f4a2713aSLionel Sambuc       ABI = Name;
6075f4a2713aSLionel Sambuc       return true;
6076*0a6a1f1dSLionel Sambuc     }
6077*0a6a1f1dSLionel Sambuc     if (Name == "n64") {
6078*0a6a1f1dSLionel Sambuc       setN64ABITypes();
6079f4a2713aSLionel Sambuc       ABI = Name;
6080f4a2713aSLionel Sambuc       return true;
6081*0a6a1f1dSLionel Sambuc     }
6082f4a2713aSLionel Sambuc     return false;
6083f4a2713aSLionel Sambuc   }
6084*0a6a1f1dSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6085*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
6086*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
6087f4a2713aSLionel Sambuc     MipsTargetInfoBase::getTargetDefines(Opts, Builder);
6088f4a2713aSLionel Sambuc 
6089*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__mips", "64");
6090f4a2713aSLionel Sambuc     Builder.defineMacro("__mips64");
6091f4a2713aSLionel Sambuc     Builder.defineMacro("__mips64__");
6092*0a6a1f1dSLionel Sambuc     Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");
6093*0a6a1f1dSLionel Sambuc 
6094*0a6a1f1dSLionel Sambuc     const std::string& CPUStr = getCPU();
6095*0a6a1f1dSLionel Sambuc     if (CPUStr == "mips64")
6096*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__mips_isa_rev", "1");
6097*0a6a1f1dSLionel Sambuc     else if (CPUStr == "mips64r2")
6098*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__mips_isa_rev", "2");
6099*0a6a1f1dSLionel Sambuc     else if (CPUStr == "mips64r6")
6100*0a6a1f1dSLionel Sambuc       Builder.defineMacro("__mips_isa_rev", "6");
6101f4a2713aSLionel Sambuc 
6102f4a2713aSLionel Sambuc     if (ABI == "n32") {
6103f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_n32");
6104f4a2713aSLionel Sambuc       Builder.defineMacro("_ABIN32", "2");
6105f4a2713aSLionel Sambuc       Builder.defineMacro("_MIPS_SIM", "_ABIN32");
6106f4a2713aSLionel Sambuc     }
6107f4a2713aSLionel Sambuc     else if (ABI == "n64") {
6108f4a2713aSLionel Sambuc       Builder.defineMacro("__mips_n64");
6109f4a2713aSLionel Sambuc       Builder.defineMacro("_ABI64", "3");
6110f4a2713aSLionel Sambuc       Builder.defineMacro("_MIPS_SIM", "_ABI64");
6111f4a2713aSLionel Sambuc     }
6112f4a2713aSLionel Sambuc     else
6113f4a2713aSLionel Sambuc       llvm_unreachable("Invalid ABI for Mips64.");
6114f4a2713aSLionel Sambuc   }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const6115*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
6116*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override {
6117f4a2713aSLionel Sambuc     static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
6118f4a2713aSLionel Sambuc       { { "at" },  "$1" },
6119f4a2713aSLionel Sambuc       { { "v0" },  "$2" },
6120f4a2713aSLionel Sambuc       { { "v1" },  "$3" },
6121f4a2713aSLionel Sambuc       { { "a0" },  "$4" },
6122f4a2713aSLionel Sambuc       { { "a1" },  "$5" },
6123f4a2713aSLionel Sambuc       { { "a2" },  "$6" },
6124f4a2713aSLionel Sambuc       { { "a3" },  "$7" },
6125f4a2713aSLionel Sambuc       { { "a4" },  "$8" },
6126f4a2713aSLionel Sambuc       { { "a5" },  "$9" },
6127f4a2713aSLionel Sambuc       { { "a6" }, "$10" },
6128f4a2713aSLionel Sambuc       { { "a7" }, "$11" },
6129f4a2713aSLionel Sambuc       { { "t0" }, "$12" },
6130f4a2713aSLionel Sambuc       { { "t1" }, "$13" },
6131f4a2713aSLionel Sambuc       { { "t2" }, "$14" },
6132f4a2713aSLionel Sambuc       { { "t3" }, "$15" },
6133f4a2713aSLionel Sambuc       { { "s0" }, "$16" },
6134f4a2713aSLionel Sambuc       { { "s1" }, "$17" },
6135f4a2713aSLionel Sambuc       { { "s2" }, "$18" },
6136f4a2713aSLionel Sambuc       { { "s3" }, "$19" },
6137f4a2713aSLionel Sambuc       { { "s4" }, "$20" },
6138f4a2713aSLionel Sambuc       { { "s5" }, "$21" },
6139f4a2713aSLionel Sambuc       { { "s6" }, "$22" },
6140f4a2713aSLionel Sambuc       { { "s7" }, "$23" },
6141f4a2713aSLionel Sambuc       { { "t8" }, "$24" },
6142f4a2713aSLionel Sambuc       { { "t9" }, "$25" },
6143f4a2713aSLionel Sambuc       { { "k0" }, "$26" },
6144f4a2713aSLionel Sambuc       { { "k1" }, "$27" },
6145f4a2713aSLionel Sambuc       { { "gp" }, "$28" },
6146f4a2713aSLionel Sambuc       { { "sp","$sp" }, "$29" },
6147f4a2713aSLionel Sambuc       { { "fp","$fp" }, "$30" },
6148f4a2713aSLionel Sambuc       { { "ra" }, "$31" }
6149f4a2713aSLionel Sambuc     };
6150f4a2713aSLionel Sambuc     Aliases = GCCRegAliases;
6151f4a2713aSLionel Sambuc     NumAliases = llvm::array_lengthof(GCCRegAliases);
6152f4a2713aSLionel Sambuc   }
6153*0a6a1f1dSLionel Sambuc 
hasInt128Type() const6154*0a6a1f1dSLionel Sambuc   bool hasInt128Type() const override { return true; }
6155f4a2713aSLionel Sambuc };
6156f4a2713aSLionel Sambuc 
6157f4a2713aSLionel Sambuc class Mips64EBTargetInfo : public Mips64TargetInfoBase {
setDescriptionString()6158*0a6a1f1dSLionel Sambuc   void setDescriptionString() override {
6159f4a2713aSLionel Sambuc     if (ABI == "n32")
6160*0a6a1f1dSLionel Sambuc       DescriptionString = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
6161f4a2713aSLionel Sambuc     else
6162*0a6a1f1dSLionel Sambuc       DescriptionString = "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128";
6163f4a2713aSLionel Sambuc 
6164f4a2713aSLionel Sambuc   }
6165f4a2713aSLionel Sambuc 
6166f4a2713aSLionel Sambuc public:
Mips64EBTargetInfo(const llvm::Triple & Triple)6167f4a2713aSLionel Sambuc   Mips64EBTargetInfo(const llvm::Triple &Triple)
6168f4a2713aSLionel Sambuc       : Mips64TargetInfoBase(Triple) {}
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6169*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
6170*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
6171f4a2713aSLionel Sambuc     DefineStd(Builder, "MIPSEB", Opts);
6172f4a2713aSLionel Sambuc     Builder.defineMacro("_MIPSEB");
6173f4a2713aSLionel Sambuc     Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
6174f4a2713aSLionel Sambuc   }
6175f4a2713aSLionel Sambuc };
6176f4a2713aSLionel Sambuc 
6177f4a2713aSLionel Sambuc class Mips64ELTargetInfo : public Mips64TargetInfoBase {
setDescriptionString()6178*0a6a1f1dSLionel Sambuc   void setDescriptionString() override {
6179f4a2713aSLionel Sambuc     if (ABI == "n32")
6180*0a6a1f1dSLionel Sambuc       DescriptionString = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
6181f4a2713aSLionel Sambuc     else
6182*0a6a1f1dSLionel Sambuc       DescriptionString = "e-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128";
6183f4a2713aSLionel Sambuc   }
6184f4a2713aSLionel Sambuc public:
Mips64ELTargetInfo(const llvm::Triple & Triple)6185f4a2713aSLionel Sambuc   Mips64ELTargetInfo(const llvm::Triple &Triple)
6186f4a2713aSLionel Sambuc       : Mips64TargetInfoBase(Triple) {
6187f4a2713aSLionel Sambuc     // Default ABI is n64.
6188f4a2713aSLionel Sambuc     BigEndian = false;
6189f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6190*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
6191*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
6192f4a2713aSLionel Sambuc     DefineStd(Builder, "MIPSEL", Opts);
6193f4a2713aSLionel Sambuc     Builder.defineMacro("_MIPSEL");
6194f4a2713aSLionel Sambuc     Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
6195f4a2713aSLionel Sambuc   }
6196f4a2713aSLionel Sambuc };
6197f4a2713aSLionel Sambuc } // end anonymous namespace.
6198f4a2713aSLionel Sambuc 
6199f4a2713aSLionel Sambuc namespace {
6200f4a2713aSLionel Sambuc class PNaClTargetInfo : public TargetInfo {
6201f4a2713aSLionel Sambuc public:
PNaClTargetInfo(const llvm::Triple & Triple)6202f4a2713aSLionel Sambuc   PNaClTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
6203f4a2713aSLionel Sambuc     BigEndian = false;
6204f4a2713aSLionel Sambuc     this->UserLabelPrefix = "";
6205f4a2713aSLionel Sambuc     this->LongAlign = 32;
6206f4a2713aSLionel Sambuc     this->LongWidth = 32;
6207f4a2713aSLionel Sambuc     this->PointerAlign = 32;
6208f4a2713aSLionel Sambuc     this->PointerWidth = 32;
6209f4a2713aSLionel Sambuc     this->IntMaxType = TargetInfo::SignedLongLong;
6210f4a2713aSLionel Sambuc     this->Int64Type = TargetInfo::SignedLongLong;
6211f4a2713aSLionel Sambuc     this->DoubleAlign = 64;
6212f4a2713aSLionel Sambuc     this->LongDoubleWidth = 64;
6213f4a2713aSLionel Sambuc     this->LongDoubleAlign = 64;
6214f4a2713aSLionel Sambuc     this->SizeType = TargetInfo::UnsignedInt;
6215f4a2713aSLionel Sambuc     this->PtrDiffType = TargetInfo::SignedInt;
6216f4a2713aSLionel Sambuc     this->IntPtrType = TargetInfo::SignedInt;
6217f4a2713aSLionel Sambuc     this->RegParmMax = 0; // Disallow regparm
6218f4a2713aSLionel Sambuc   }
6219f4a2713aSLionel Sambuc 
getDefaultFeatures(llvm::StringMap<bool> & Features) const6220*0a6a1f1dSLionel Sambuc   void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
6221f4a2713aSLionel Sambuc   }
getArchDefines(const LangOptions & Opts,MacroBuilder & Builder) const6222*0a6a1f1dSLionel Sambuc   void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const {
6223f4a2713aSLionel Sambuc     Builder.defineMacro("__le32__");
6224f4a2713aSLionel Sambuc     Builder.defineMacro("__pnacl__");
6225f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6226*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
6227*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
6228f4a2713aSLionel Sambuc     getArchDefines(Opts, Builder);
6229f4a2713aSLionel Sambuc   }
hasFeature(StringRef Feature) const6230*0a6a1f1dSLionel Sambuc   bool hasFeature(StringRef Feature) const override {
6231f4a2713aSLionel Sambuc     return Feature == "pnacl";
6232f4a2713aSLionel Sambuc   }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const6233*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
6234*0a6a1f1dSLionel Sambuc                          unsigned &NumRecords) const override {
6235f4a2713aSLionel Sambuc   }
getBuiltinVaListKind() const6236*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
6237f4a2713aSLionel Sambuc     return TargetInfo::PNaClABIBuiltinVaList;
6238f4a2713aSLionel Sambuc   }
6239*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char * const *&Names,
6240*0a6a1f1dSLionel Sambuc                       unsigned &NumNames) const override;
6241*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
6242*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const6243*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
6244*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &Info) const override {
6245f4a2713aSLionel Sambuc     return false;
6246f4a2713aSLionel Sambuc   }
6247f4a2713aSLionel Sambuc 
getClobbers() const6248*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override {
6249f4a2713aSLionel Sambuc     return "";
6250f4a2713aSLionel Sambuc   }
6251f4a2713aSLionel Sambuc };
6252f4a2713aSLionel Sambuc 
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const6253f4a2713aSLionel Sambuc void PNaClTargetInfo::getGCCRegNames(const char * const *&Names,
6254f4a2713aSLionel Sambuc                                      unsigned &NumNames) const {
6255*0a6a1f1dSLionel Sambuc   Names = nullptr;
6256f4a2713aSLionel Sambuc   NumNames = 0;
6257f4a2713aSLionel Sambuc }
6258f4a2713aSLionel Sambuc 
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const6259f4a2713aSLionel Sambuc void PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
6260f4a2713aSLionel Sambuc                                        unsigned &NumAliases) const {
6261*0a6a1f1dSLionel Sambuc   Aliases = nullptr;
6262f4a2713aSLionel Sambuc   NumAliases = 0;
6263f4a2713aSLionel Sambuc }
6264f4a2713aSLionel Sambuc } // end anonymous namespace.
6265f4a2713aSLionel Sambuc 
6266f4a2713aSLionel Sambuc namespace {
6267*0a6a1f1dSLionel Sambuc class Le64TargetInfo : public TargetInfo {
6268*0a6a1f1dSLionel Sambuc   static const Builtin::Info BuiltinInfo[];
6269*0a6a1f1dSLionel Sambuc 
6270*0a6a1f1dSLionel Sambuc public:
Le64TargetInfo(const llvm::Triple & Triple)6271*0a6a1f1dSLionel Sambuc   Le64TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
6272*0a6a1f1dSLionel Sambuc     BigEndian = false;
6273*0a6a1f1dSLionel Sambuc     NoAsmVariants = true;
6274*0a6a1f1dSLionel Sambuc     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
6275*0a6a1f1dSLionel Sambuc     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
6276*0a6a1f1dSLionel Sambuc     DescriptionString =
6277*0a6a1f1dSLionel Sambuc         "e-m:e-v128:32-v16:16-v32:32-v96:32-n8:16:32:64-S128";
6278*0a6a1f1dSLionel Sambuc   }
6279*0a6a1f1dSLionel Sambuc 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6280*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
6281*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
6282*0a6a1f1dSLionel Sambuc     DefineStd(Builder, "unix", Opts);
6283*0a6a1f1dSLionel Sambuc     defineCPUMacros(Builder, "le64", /*Tuning=*/false);
6284*0a6a1f1dSLionel Sambuc     Builder.defineMacro("__ELF__");
6285*0a6a1f1dSLionel Sambuc   }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const6286*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
6287*0a6a1f1dSLionel Sambuc                          unsigned &NumRecords) const override {
6288*0a6a1f1dSLionel Sambuc     Records = BuiltinInfo;
6289*0a6a1f1dSLionel Sambuc     NumRecords = clang::Le64::LastTSBuiltin - Builtin::FirstTSBuiltin;
6290*0a6a1f1dSLionel Sambuc   }
getBuiltinVaListKind() const6291*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
6292*0a6a1f1dSLionel Sambuc     return TargetInfo::PNaClABIBuiltinVaList;
6293*0a6a1f1dSLionel Sambuc   }
getClobbers() const6294*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override { return ""; }
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const6295*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char *const *&Names,
6296*0a6a1f1dSLionel Sambuc                       unsigned &NumNames) const override {
6297*0a6a1f1dSLionel Sambuc     Names = nullptr;
6298*0a6a1f1dSLionel Sambuc     NumNames = 0;
6299*0a6a1f1dSLionel Sambuc   }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const6300*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
6301*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override {
6302*0a6a1f1dSLionel Sambuc     Aliases = nullptr;
6303*0a6a1f1dSLionel Sambuc     NumAliases = 0;
6304*0a6a1f1dSLionel Sambuc   }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const6305*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
6306*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &Info) const override {
6307*0a6a1f1dSLionel Sambuc     return false;
6308*0a6a1f1dSLionel Sambuc   }
6309*0a6a1f1dSLionel Sambuc 
hasProtectedVisibility() const6310*0a6a1f1dSLionel Sambuc   bool hasProtectedVisibility() const override { return false; }
6311*0a6a1f1dSLionel Sambuc };
6312*0a6a1f1dSLionel Sambuc } // end anonymous namespace.
6313*0a6a1f1dSLionel Sambuc 
6314*0a6a1f1dSLionel Sambuc const Builtin::Info Le64TargetInfo::BuiltinInfo[] = {
6315*0a6a1f1dSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS)                                               \
6316*0a6a1f1dSLionel Sambuc   { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
6317*0a6a1f1dSLionel Sambuc #include "clang/Basic/BuiltinsLe64.def"
6318*0a6a1f1dSLionel Sambuc };
6319*0a6a1f1dSLionel Sambuc 
6320*0a6a1f1dSLionel Sambuc namespace {
6321f4a2713aSLionel Sambuc   static const unsigned SPIRAddrSpaceMap[] = {
6322f4a2713aSLionel Sambuc     1,    // opencl_global
6323f4a2713aSLionel Sambuc     3,    // opencl_local
6324f4a2713aSLionel Sambuc     2,    // opencl_constant
6325*0a6a1f1dSLionel Sambuc     4,    // opencl_generic
6326f4a2713aSLionel Sambuc     0,    // cuda_device
6327f4a2713aSLionel Sambuc     0,    // cuda_constant
6328f4a2713aSLionel Sambuc     0     // cuda_shared
6329f4a2713aSLionel Sambuc   };
6330f4a2713aSLionel Sambuc   class SPIRTargetInfo : public TargetInfo {
6331f4a2713aSLionel Sambuc   public:
SPIRTargetInfo(const llvm::Triple & Triple)6332f4a2713aSLionel Sambuc     SPIRTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
6333f4a2713aSLionel Sambuc       assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
6334f4a2713aSLionel Sambuc         "SPIR target must use unknown OS");
6335f4a2713aSLionel Sambuc       assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
6336f4a2713aSLionel Sambuc         "SPIR target must use unknown environment type");
6337f4a2713aSLionel Sambuc       BigEndian = false;
6338f4a2713aSLionel Sambuc       TLSSupported = false;
6339f4a2713aSLionel Sambuc       LongWidth = LongAlign = 64;
6340f4a2713aSLionel Sambuc       AddrSpaceMap = &SPIRAddrSpaceMap;
6341f4a2713aSLionel Sambuc       UseAddrSpaceMapMangling = true;
6342f4a2713aSLionel Sambuc       // Define available target features
6343f4a2713aSLionel Sambuc       // These must be defined in sorted order!
6344f4a2713aSLionel Sambuc       NoAsmVariants = true;
6345f4a2713aSLionel Sambuc     }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6346*0a6a1f1dSLionel Sambuc     void getTargetDefines(const LangOptions &Opts,
6347*0a6a1f1dSLionel Sambuc                           MacroBuilder &Builder) const override {
6348f4a2713aSLionel Sambuc       DefineStd(Builder, "SPIR", Opts);
6349f4a2713aSLionel Sambuc     }
hasFeature(StringRef Feature) const6350*0a6a1f1dSLionel Sambuc     bool hasFeature(StringRef Feature) const override {
6351f4a2713aSLionel Sambuc       return Feature == "spir";
6352f4a2713aSLionel Sambuc     }
6353f4a2713aSLionel Sambuc 
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const6354*0a6a1f1dSLionel Sambuc     void getTargetBuiltins(const Builtin::Info *&Records,
6355*0a6a1f1dSLionel Sambuc                            unsigned &NumRecords) const override {}
getClobbers() const6356*0a6a1f1dSLionel Sambuc     const char *getClobbers() const override {
6357f4a2713aSLionel Sambuc       return "";
6358f4a2713aSLionel Sambuc     }
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const6359*0a6a1f1dSLionel Sambuc     void getGCCRegNames(const char * const *&Names,
6360*0a6a1f1dSLionel Sambuc                         unsigned &NumNames) const override {}
6361*0a6a1f1dSLionel Sambuc     bool
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const6362*0a6a1f1dSLionel Sambuc     validateAsmConstraint(const char *&Name,
6363*0a6a1f1dSLionel Sambuc                           TargetInfo::ConstraintInfo &info) const override {
6364f4a2713aSLionel Sambuc       return true;
6365f4a2713aSLionel Sambuc     }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const6366*0a6a1f1dSLionel Sambuc     void getGCCRegAliases(const GCCRegAlias *&Aliases,
6367*0a6a1f1dSLionel Sambuc                           unsigned &NumAliases) const override {}
getBuiltinVaListKind() const6368*0a6a1f1dSLionel Sambuc     BuiltinVaListKind getBuiltinVaListKind() const override {
6369f4a2713aSLionel Sambuc       return TargetInfo::VoidPtrBuiltinVaList;
6370f4a2713aSLionel Sambuc     }
6371f4a2713aSLionel Sambuc   };
6372f4a2713aSLionel Sambuc 
6373f4a2713aSLionel Sambuc 
6374f4a2713aSLionel Sambuc   class SPIR32TargetInfo : public SPIRTargetInfo {
6375f4a2713aSLionel Sambuc   public:
SPIR32TargetInfo(const llvm::Triple & Triple)6376f4a2713aSLionel Sambuc     SPIR32TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) {
6377f4a2713aSLionel Sambuc       PointerWidth = PointerAlign = 32;
6378f4a2713aSLionel Sambuc       SizeType     = TargetInfo::UnsignedInt;
6379f4a2713aSLionel Sambuc       PtrDiffType = IntPtrType = TargetInfo::SignedInt;
6380f4a2713aSLionel Sambuc       DescriptionString
6381*0a6a1f1dSLionel Sambuc         = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
6382*0a6a1f1dSLionel Sambuc           "v96:128-v192:256-v256:256-v512:512-v1024:1024";
6383f4a2713aSLionel Sambuc     }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6384*0a6a1f1dSLionel Sambuc     void getTargetDefines(const LangOptions &Opts,
6385*0a6a1f1dSLionel Sambuc                           MacroBuilder &Builder) const override {
6386f4a2713aSLionel Sambuc       DefineStd(Builder, "SPIR32", Opts);
6387f4a2713aSLionel Sambuc     }
6388f4a2713aSLionel Sambuc   };
6389f4a2713aSLionel Sambuc 
6390f4a2713aSLionel Sambuc   class SPIR64TargetInfo : public SPIRTargetInfo {
6391f4a2713aSLionel Sambuc   public:
SPIR64TargetInfo(const llvm::Triple & Triple)6392f4a2713aSLionel Sambuc     SPIR64TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) {
6393f4a2713aSLionel Sambuc       PointerWidth = PointerAlign = 64;
6394f4a2713aSLionel Sambuc       SizeType     = TargetInfo::UnsignedLong;
6395f4a2713aSLionel Sambuc       PtrDiffType = IntPtrType = TargetInfo::SignedLong;
6396*0a6a1f1dSLionel Sambuc       DescriptionString = "e-i64:64-v16:16-v24:32-v32:32-v48:64-"
6397*0a6a1f1dSLionel Sambuc                           "v96:128-v192:256-v256:256-v512:512-v1024:1024";
6398f4a2713aSLionel Sambuc     }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6399*0a6a1f1dSLionel Sambuc     void getTargetDefines(const LangOptions &Opts,
6400*0a6a1f1dSLionel Sambuc                           MacroBuilder &Builder) const override {
6401f4a2713aSLionel Sambuc       DefineStd(Builder, "SPIR64", Opts);
6402f4a2713aSLionel Sambuc     }
6403f4a2713aSLionel Sambuc   };
6404f4a2713aSLionel Sambuc }
6405f4a2713aSLionel Sambuc 
6406f4a2713aSLionel Sambuc namespace {
6407f4a2713aSLionel Sambuc class XCoreTargetInfo : public TargetInfo {
6408f4a2713aSLionel Sambuc   static const Builtin::Info BuiltinInfo[];
6409f4a2713aSLionel Sambuc public:
XCoreTargetInfo(const llvm::Triple & Triple)6410f4a2713aSLionel Sambuc   XCoreTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
6411f4a2713aSLionel Sambuc     BigEndian = false;
6412f4a2713aSLionel Sambuc     NoAsmVariants = true;
6413f4a2713aSLionel Sambuc     LongLongAlign = 32;
6414f4a2713aSLionel Sambuc     SuitableAlign = 32;
6415f4a2713aSLionel Sambuc     DoubleAlign = LongDoubleAlign = 32;
6416f4a2713aSLionel Sambuc     SizeType = UnsignedInt;
6417f4a2713aSLionel Sambuc     PtrDiffType = SignedInt;
6418f4a2713aSLionel Sambuc     IntPtrType = SignedInt;
6419f4a2713aSLionel Sambuc     WCharType = UnsignedChar;
6420f4a2713aSLionel Sambuc     WIntType = UnsignedInt;
6421f4a2713aSLionel Sambuc     UseZeroLengthBitfieldAlignment = true;
6422*0a6a1f1dSLionel Sambuc     DescriptionString = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32"
6423*0a6a1f1dSLionel Sambuc                         "-f64:32-a:0:32-n32";
6424f4a2713aSLionel Sambuc   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6425*0a6a1f1dSLionel Sambuc   void getTargetDefines(const LangOptions &Opts,
6426*0a6a1f1dSLionel Sambuc                         MacroBuilder &Builder) const override {
6427f4a2713aSLionel Sambuc     Builder.defineMacro("__XS1B__");
6428f4a2713aSLionel Sambuc   }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const6429*0a6a1f1dSLionel Sambuc   void getTargetBuiltins(const Builtin::Info *&Records,
6430*0a6a1f1dSLionel Sambuc                          unsigned &NumRecords) const override {
6431f4a2713aSLionel Sambuc     Records = BuiltinInfo;
6432f4a2713aSLionel Sambuc     NumRecords = clang::XCore::LastTSBuiltin-Builtin::FirstTSBuiltin;
6433f4a2713aSLionel Sambuc   }
getBuiltinVaListKind() const6434*0a6a1f1dSLionel Sambuc   BuiltinVaListKind getBuiltinVaListKind() const override {
6435f4a2713aSLionel Sambuc     return TargetInfo::VoidPtrBuiltinVaList;
6436f4a2713aSLionel Sambuc   }
getClobbers() const6437*0a6a1f1dSLionel Sambuc   const char *getClobbers() const override {
6438f4a2713aSLionel Sambuc     return "";
6439f4a2713aSLionel Sambuc   }
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const6440*0a6a1f1dSLionel Sambuc   void getGCCRegNames(const char * const *&Names,
6441*0a6a1f1dSLionel Sambuc                       unsigned &NumNames) const override {
6442f4a2713aSLionel Sambuc     static const char * const GCCRegNames[] = {
6443f4a2713aSLionel Sambuc       "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",
6444f4a2713aSLionel Sambuc       "r8",   "r9",   "r10",  "r11",  "cp",   "dp",   "sp",   "lr"
6445f4a2713aSLionel Sambuc     };
6446f4a2713aSLionel Sambuc     Names = GCCRegNames;
6447f4a2713aSLionel Sambuc     NumNames = llvm::array_lengthof(GCCRegNames);
6448f4a2713aSLionel Sambuc   }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const6449*0a6a1f1dSLionel Sambuc   void getGCCRegAliases(const GCCRegAlias *&Aliases,
6450*0a6a1f1dSLionel Sambuc                         unsigned &NumAliases) const override {
6451*0a6a1f1dSLionel Sambuc     Aliases = nullptr;
6452f4a2713aSLionel Sambuc     NumAliases = 0;
6453f4a2713aSLionel Sambuc   }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const6454*0a6a1f1dSLionel Sambuc   bool validateAsmConstraint(const char *&Name,
6455*0a6a1f1dSLionel Sambuc                              TargetInfo::ConstraintInfo &Info) const override {
6456f4a2713aSLionel Sambuc     return false;
6457f4a2713aSLionel Sambuc   }
getEHDataRegisterNumber(unsigned RegNo) const6458*0a6a1f1dSLionel Sambuc   int getEHDataRegisterNumber(unsigned RegNo) const override {
6459*0a6a1f1dSLionel Sambuc     // R0=ExceptionPointerRegister R1=ExceptionSelectorRegister
6460*0a6a1f1dSLionel Sambuc     return (RegNo < 2)? RegNo : -1;
6461*0a6a1f1dSLionel Sambuc   }
6462f4a2713aSLionel Sambuc };
6463f4a2713aSLionel Sambuc 
6464f4a2713aSLionel Sambuc const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = {
6465f4a2713aSLionel Sambuc #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
6466f4a2713aSLionel Sambuc #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
6467f4a2713aSLionel Sambuc                                               ALL_LANGUAGES },
6468f4a2713aSLionel Sambuc #include "clang/Basic/BuiltinsXCore.def"
6469f4a2713aSLionel Sambuc };
6470f4a2713aSLionel Sambuc } // end anonymous namespace.
6471f4a2713aSLionel Sambuc 
6472f4a2713aSLionel Sambuc 
6473f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6474f4a2713aSLionel Sambuc // Driver code
6475f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6476f4a2713aSLionel Sambuc 
AllocateTarget(const llvm::Triple & Triple)6477f4a2713aSLionel Sambuc static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
6478f4a2713aSLionel Sambuc   llvm::Triple::OSType os = Triple.getOS();
6479f4a2713aSLionel Sambuc 
6480f4a2713aSLionel Sambuc   switch (Triple.getArch()) {
6481f4a2713aSLionel Sambuc   default:
6482*0a6a1f1dSLionel Sambuc     return nullptr;
6483f4a2713aSLionel Sambuc 
6484f4a2713aSLionel Sambuc   case llvm::Triple::xcore:
6485f4a2713aSLionel Sambuc     return new XCoreTargetInfo(Triple);
6486f4a2713aSLionel Sambuc 
6487f4a2713aSLionel Sambuc   case llvm::Triple::hexagon:
6488f4a2713aSLionel Sambuc     return new HexagonTargetInfo(Triple);
6489f4a2713aSLionel Sambuc 
6490f4a2713aSLionel Sambuc   case llvm::Triple::aarch64:
6491*0a6a1f1dSLionel Sambuc     if (Triple.isOSDarwin())
6492*0a6a1f1dSLionel Sambuc       return new DarwinAArch64TargetInfo(Triple);
6493*0a6a1f1dSLionel Sambuc 
6494f4a2713aSLionel Sambuc     switch (os) {
6495*0a6a1f1dSLionel Sambuc     case llvm::Triple::FreeBSD:
6496*0a6a1f1dSLionel Sambuc       return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple);
6497f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6498*0a6a1f1dSLionel Sambuc       return new LinuxTargetInfo<AArch64leTargetInfo>(Triple);
6499*0a6a1f1dSLionel Sambuc     case llvm::Triple::NetBSD:
6500*0a6a1f1dSLionel Sambuc       return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple);
6501f4a2713aSLionel Sambuc     default:
6502*0a6a1f1dSLionel Sambuc       return new AArch64leTargetInfo(Triple);
6503*0a6a1f1dSLionel Sambuc     }
6504*0a6a1f1dSLionel Sambuc 
6505*0a6a1f1dSLionel Sambuc   case llvm::Triple::aarch64_be:
6506*0a6a1f1dSLionel Sambuc     switch (os) {
6507*0a6a1f1dSLionel Sambuc     case llvm::Triple::FreeBSD:
6508*0a6a1f1dSLionel Sambuc       return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple);
6509*0a6a1f1dSLionel Sambuc     case llvm::Triple::Linux:
6510*0a6a1f1dSLionel Sambuc       return new LinuxTargetInfo<AArch64beTargetInfo>(Triple);
6511*0a6a1f1dSLionel Sambuc     case llvm::Triple::NetBSD:
6512*0a6a1f1dSLionel Sambuc       return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple);
6513*0a6a1f1dSLionel Sambuc     default:
6514*0a6a1f1dSLionel Sambuc       return new AArch64beTargetInfo(Triple);
6515f4a2713aSLionel Sambuc     }
6516f4a2713aSLionel Sambuc 
6517f4a2713aSLionel Sambuc   case llvm::Triple::arm:
6518f4a2713aSLionel Sambuc   case llvm::Triple::thumb:
6519*0a6a1f1dSLionel Sambuc     if (Triple.isOSBinFormatMachO())
6520*0a6a1f1dSLionel Sambuc       return new DarwinARMTargetInfo(Triple);
6521*0a6a1f1dSLionel Sambuc 
6522*0a6a1f1dSLionel Sambuc     switch (os) {
6523*0a6a1f1dSLionel Sambuc     case llvm::Triple::Linux:
6524*0a6a1f1dSLionel Sambuc       return new LinuxTargetInfo<ARMleTargetInfo>(Triple);
6525*0a6a1f1dSLionel Sambuc     case llvm::Triple::FreeBSD:
6526*0a6a1f1dSLionel Sambuc       return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple);
6527*0a6a1f1dSLionel Sambuc     case llvm::Triple::Minix:
6528*0a6a1f1dSLionel Sambuc       return new MinixTargetInfo<ARMleTargetInfo>(Triple);
6529*0a6a1f1dSLionel Sambuc     case llvm::Triple::NetBSD:
6530*0a6a1f1dSLionel Sambuc       return new NetBSDTargetInfo<ARMleTargetInfo>(Triple);
6531*0a6a1f1dSLionel Sambuc     case llvm::Triple::OpenBSD:
6532*0a6a1f1dSLionel Sambuc       return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple);
6533*0a6a1f1dSLionel Sambuc     case llvm::Triple::Bitrig:
6534*0a6a1f1dSLionel Sambuc       return new BitrigTargetInfo<ARMleTargetInfo>(Triple);
6535*0a6a1f1dSLionel Sambuc     case llvm::Triple::RTEMS:
6536*0a6a1f1dSLionel Sambuc       return new RTEMSTargetInfo<ARMleTargetInfo>(Triple);
6537*0a6a1f1dSLionel Sambuc     case llvm::Triple::NaCl:
6538*0a6a1f1dSLionel Sambuc       return new NaClTargetInfo<ARMleTargetInfo>(Triple);
6539*0a6a1f1dSLionel Sambuc     case llvm::Triple::Win32:
6540*0a6a1f1dSLionel Sambuc       switch (Triple.getEnvironment()) {
6541*0a6a1f1dSLionel Sambuc       default:
6542*0a6a1f1dSLionel Sambuc         return new ARMleTargetInfo(Triple);
6543*0a6a1f1dSLionel Sambuc       case llvm::Triple::Itanium:
6544*0a6a1f1dSLionel Sambuc         return new ItaniumWindowsARMleTargetInfo(Triple);
6545*0a6a1f1dSLionel Sambuc       case llvm::Triple::MSVC:
6546*0a6a1f1dSLionel Sambuc         return new MicrosoftARMleTargetInfo(Triple);
6547*0a6a1f1dSLionel Sambuc       }
6548*0a6a1f1dSLionel Sambuc     default:
6549*0a6a1f1dSLionel Sambuc       return new ARMleTargetInfo(Triple);
6550*0a6a1f1dSLionel Sambuc     }
6551*0a6a1f1dSLionel Sambuc 
6552*0a6a1f1dSLionel Sambuc   case llvm::Triple::armeb:
6553*0a6a1f1dSLionel Sambuc   case llvm::Triple::thumbeb:
6554f4a2713aSLionel Sambuc     if (Triple.isOSDarwin())
6555f4a2713aSLionel Sambuc       return new DarwinARMTargetInfo(Triple);
6556f4a2713aSLionel Sambuc 
6557f4a2713aSLionel Sambuc     switch (os) {
6558f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6559*0a6a1f1dSLionel Sambuc       return new LinuxTargetInfo<ARMbeTargetInfo>(Triple);
6560f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
6561*0a6a1f1dSLionel Sambuc       return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple);
6562f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6563*0a6a1f1dSLionel Sambuc       return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple);
6564f4a2713aSLionel Sambuc     case llvm::Triple::OpenBSD:
6565*0a6a1f1dSLionel Sambuc       return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple);
6566f4a2713aSLionel Sambuc     case llvm::Triple::Bitrig:
6567*0a6a1f1dSLionel Sambuc       return new BitrigTargetInfo<ARMbeTargetInfo>(Triple);
6568f4a2713aSLionel Sambuc     case llvm::Triple::RTEMS:
6569*0a6a1f1dSLionel Sambuc       return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple);
6570f4a2713aSLionel Sambuc     case llvm::Triple::NaCl:
6571*0a6a1f1dSLionel Sambuc       return new NaClTargetInfo<ARMbeTargetInfo>(Triple);
6572f4a2713aSLionel Sambuc     default:
6573*0a6a1f1dSLionel Sambuc       return new ARMbeTargetInfo(Triple);
6574f4a2713aSLionel Sambuc     }
6575f4a2713aSLionel Sambuc 
6576f4a2713aSLionel Sambuc   case llvm::Triple::msp430:
6577f4a2713aSLionel Sambuc     return new MSP430TargetInfo(Triple);
6578f4a2713aSLionel Sambuc 
6579f4a2713aSLionel Sambuc   case llvm::Triple::mips:
6580f4a2713aSLionel Sambuc     switch (os) {
6581f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6582f4a2713aSLionel Sambuc       return new LinuxTargetInfo<Mips32EBTargetInfo>(Triple);
6583f4a2713aSLionel Sambuc     case llvm::Triple::RTEMS:
6584f4a2713aSLionel Sambuc       return new RTEMSTargetInfo<Mips32EBTargetInfo>(Triple);
6585f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
6586f4a2713aSLionel Sambuc       return new FreeBSDTargetInfo<Mips32EBTargetInfo>(Triple);
6587f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6588f4a2713aSLionel Sambuc       return new NetBSDTargetInfo<Mips32EBTargetInfo>(Triple);
6589f4a2713aSLionel Sambuc     default:
6590f4a2713aSLionel Sambuc       return new Mips32EBTargetInfo(Triple);
6591f4a2713aSLionel Sambuc     }
6592f4a2713aSLionel Sambuc 
6593f4a2713aSLionel Sambuc   case llvm::Triple::mipsel:
6594f4a2713aSLionel Sambuc     switch (os) {
6595f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6596f4a2713aSLionel Sambuc       return new LinuxTargetInfo<Mips32ELTargetInfo>(Triple);
6597f4a2713aSLionel Sambuc     case llvm::Triple::RTEMS:
6598f4a2713aSLionel Sambuc       return new RTEMSTargetInfo<Mips32ELTargetInfo>(Triple);
6599f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
6600f4a2713aSLionel Sambuc       return new FreeBSDTargetInfo<Mips32ELTargetInfo>(Triple);
6601f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6602f4a2713aSLionel Sambuc       return new NetBSDTargetInfo<Mips32ELTargetInfo>(Triple);
6603f4a2713aSLionel Sambuc     case llvm::Triple::NaCl:
6604f4a2713aSLionel Sambuc       return new NaClTargetInfo<Mips32ELTargetInfo>(Triple);
6605f4a2713aSLionel Sambuc     default:
6606f4a2713aSLionel Sambuc       return new Mips32ELTargetInfo(Triple);
6607f4a2713aSLionel Sambuc     }
6608f4a2713aSLionel Sambuc 
6609f4a2713aSLionel Sambuc   case llvm::Triple::mips64:
6610f4a2713aSLionel Sambuc     switch (os) {
6611f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6612f4a2713aSLionel Sambuc       return new LinuxTargetInfo<Mips64EBTargetInfo>(Triple);
6613f4a2713aSLionel Sambuc     case llvm::Triple::RTEMS:
6614f4a2713aSLionel Sambuc       return new RTEMSTargetInfo<Mips64EBTargetInfo>(Triple);
6615f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
6616f4a2713aSLionel Sambuc       return new FreeBSDTargetInfo<Mips64EBTargetInfo>(Triple);
6617f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6618f4a2713aSLionel Sambuc       return new NetBSDTargetInfo<Mips64EBTargetInfo>(Triple);
6619f4a2713aSLionel Sambuc     case llvm::Triple::OpenBSD:
6620f4a2713aSLionel Sambuc       return new OpenBSDTargetInfo<Mips64EBTargetInfo>(Triple);
6621f4a2713aSLionel Sambuc     default:
6622f4a2713aSLionel Sambuc       return new Mips64EBTargetInfo(Triple);
6623f4a2713aSLionel Sambuc     }
6624f4a2713aSLionel Sambuc 
6625f4a2713aSLionel Sambuc   case llvm::Triple::mips64el:
6626f4a2713aSLionel Sambuc     switch (os) {
6627f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6628f4a2713aSLionel Sambuc       return new LinuxTargetInfo<Mips64ELTargetInfo>(Triple);
6629f4a2713aSLionel Sambuc     case llvm::Triple::RTEMS:
6630f4a2713aSLionel Sambuc       return new RTEMSTargetInfo<Mips64ELTargetInfo>(Triple);
6631f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
6632f4a2713aSLionel Sambuc       return new FreeBSDTargetInfo<Mips64ELTargetInfo>(Triple);
6633f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6634f4a2713aSLionel Sambuc       return new NetBSDTargetInfo<Mips64ELTargetInfo>(Triple);
6635f4a2713aSLionel Sambuc     case llvm::Triple::OpenBSD:
6636f4a2713aSLionel Sambuc       return new OpenBSDTargetInfo<Mips64ELTargetInfo>(Triple);
6637f4a2713aSLionel Sambuc     default:
6638f4a2713aSLionel Sambuc       return new Mips64ELTargetInfo(Triple);
6639f4a2713aSLionel Sambuc     }
6640f4a2713aSLionel Sambuc 
6641f4a2713aSLionel Sambuc   case llvm::Triple::le32:
6642f4a2713aSLionel Sambuc     switch (os) {
6643f4a2713aSLionel Sambuc       case llvm::Triple::NaCl:
6644f4a2713aSLionel Sambuc         return new NaClTargetInfo<PNaClTargetInfo>(Triple);
6645f4a2713aSLionel Sambuc       default:
6646*0a6a1f1dSLionel Sambuc         return nullptr;
6647f4a2713aSLionel Sambuc     }
6648f4a2713aSLionel Sambuc 
6649*0a6a1f1dSLionel Sambuc   case llvm::Triple::le64:
6650*0a6a1f1dSLionel Sambuc     return new Le64TargetInfo(Triple);
6651*0a6a1f1dSLionel Sambuc 
6652f4a2713aSLionel Sambuc   case llvm::Triple::ppc:
6653f4a2713aSLionel Sambuc     if (Triple.isOSDarwin())
6654f4a2713aSLionel Sambuc       return new DarwinPPC32TargetInfo(Triple);
6655f4a2713aSLionel Sambuc     switch (os) {
6656f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6657f4a2713aSLionel Sambuc       return new LinuxTargetInfo<PPC32TargetInfo>(Triple);
6658f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
6659f4a2713aSLionel Sambuc       return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple);
6660f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6661f4a2713aSLionel Sambuc       return new NetBSDTargetInfo<PPC32TargetInfo>(Triple);
6662f4a2713aSLionel Sambuc     case llvm::Triple::OpenBSD:
6663f4a2713aSLionel Sambuc       return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple);
6664f4a2713aSLionel Sambuc     case llvm::Triple::RTEMS:
6665f4a2713aSLionel Sambuc       return new RTEMSTargetInfo<PPC32TargetInfo>(Triple);
6666f4a2713aSLionel Sambuc     default:
6667f4a2713aSLionel Sambuc       return new PPC32TargetInfo(Triple);
6668f4a2713aSLionel Sambuc     }
6669f4a2713aSLionel Sambuc 
6670f4a2713aSLionel Sambuc   case llvm::Triple::ppc64:
6671f4a2713aSLionel Sambuc     if (Triple.isOSDarwin())
6672f4a2713aSLionel Sambuc       return new DarwinPPC64TargetInfo(Triple);
6673f4a2713aSLionel Sambuc     switch (os) {
6674f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6675f4a2713aSLionel Sambuc       return new LinuxTargetInfo<PPC64TargetInfo>(Triple);
6676f4a2713aSLionel Sambuc     case llvm::Triple::Lv2:
6677f4a2713aSLionel Sambuc       return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple);
6678f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
6679f4a2713aSLionel Sambuc       return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple);
6680f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6681f4a2713aSLionel Sambuc       return new NetBSDTargetInfo<PPC64TargetInfo>(Triple);
6682f4a2713aSLionel Sambuc     default:
6683f4a2713aSLionel Sambuc       return new PPC64TargetInfo(Triple);
6684f4a2713aSLionel Sambuc     }
6685f4a2713aSLionel Sambuc 
6686f4a2713aSLionel Sambuc   case llvm::Triple::ppc64le:
6687f4a2713aSLionel Sambuc     switch (os) {
6688f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6689f4a2713aSLionel Sambuc       return new LinuxTargetInfo<PPC64TargetInfo>(Triple);
6690*0a6a1f1dSLionel Sambuc     case llvm::Triple::NetBSD:
6691*0a6a1f1dSLionel Sambuc       return new NetBSDTargetInfo<PPC64TargetInfo>(Triple);
6692f4a2713aSLionel Sambuc     default:
6693f4a2713aSLionel Sambuc       return new PPC64TargetInfo(Triple);
6694f4a2713aSLionel Sambuc     }
6695f4a2713aSLionel Sambuc 
6696f4a2713aSLionel Sambuc   case llvm::Triple::nvptx:
6697f4a2713aSLionel Sambuc     return new NVPTX32TargetInfo(Triple);
6698f4a2713aSLionel Sambuc   case llvm::Triple::nvptx64:
6699f4a2713aSLionel Sambuc     return new NVPTX64TargetInfo(Triple);
6700f4a2713aSLionel Sambuc 
6701*0a6a1f1dSLionel Sambuc   case llvm::Triple::amdgcn:
6702f4a2713aSLionel Sambuc   case llvm::Triple::r600:
6703f4a2713aSLionel Sambuc     return new R600TargetInfo(Triple);
6704f4a2713aSLionel Sambuc 
6705f4a2713aSLionel Sambuc   case llvm::Triple::sparc:
6706f4a2713aSLionel Sambuc     switch (os) {
6707f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6708f4a2713aSLionel Sambuc       return new LinuxTargetInfo<SparcV8TargetInfo>(Triple);
6709f4a2713aSLionel Sambuc     case llvm::Triple::Solaris:
6710f4a2713aSLionel Sambuc       return new SolarisSparcV8TargetInfo(Triple);
6711f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6712f4a2713aSLionel Sambuc       return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple);
6713f4a2713aSLionel Sambuc     case llvm::Triple::OpenBSD:
6714f4a2713aSLionel Sambuc       return new OpenBSDTargetInfo<SparcV8TargetInfo>(Triple);
6715f4a2713aSLionel Sambuc     case llvm::Triple::RTEMS:
6716f4a2713aSLionel Sambuc       return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple);
6717f4a2713aSLionel Sambuc     default:
6718f4a2713aSLionel Sambuc       return new SparcV8TargetInfo(Triple);
6719f4a2713aSLionel Sambuc     }
6720f4a2713aSLionel Sambuc 
6721f4a2713aSLionel Sambuc   case llvm::Triple::sparcv9:
6722f4a2713aSLionel Sambuc     switch (os) {
6723f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6724f4a2713aSLionel Sambuc       return new LinuxTargetInfo<SparcV9TargetInfo>(Triple);
6725f4a2713aSLionel Sambuc     case llvm::Triple::Solaris:
6726f4a2713aSLionel Sambuc       return new SolarisTargetInfo<SparcV9TargetInfo>(Triple);
6727f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6728f4a2713aSLionel Sambuc       return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple);
6729f4a2713aSLionel Sambuc     case llvm::Triple::OpenBSD:
6730f4a2713aSLionel Sambuc       return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple);
6731f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
6732f4a2713aSLionel Sambuc       return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple);
6733f4a2713aSLionel Sambuc     default:
6734f4a2713aSLionel Sambuc       return new SparcV9TargetInfo(Triple);
6735f4a2713aSLionel Sambuc     }
6736f4a2713aSLionel Sambuc 
6737f4a2713aSLionel Sambuc   case llvm::Triple::systemz:
6738f4a2713aSLionel Sambuc     switch (os) {
6739f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6740f4a2713aSLionel Sambuc       return new LinuxTargetInfo<SystemZTargetInfo>(Triple);
6741f4a2713aSLionel Sambuc     default:
6742f4a2713aSLionel Sambuc       return new SystemZTargetInfo(Triple);
6743f4a2713aSLionel Sambuc     }
6744f4a2713aSLionel Sambuc 
6745f4a2713aSLionel Sambuc   case llvm::Triple::tce:
6746f4a2713aSLionel Sambuc     return new TCETargetInfo(Triple);
6747f4a2713aSLionel Sambuc 
6748f4a2713aSLionel Sambuc   case llvm::Triple::x86:
6749f4a2713aSLionel Sambuc     if (Triple.isOSDarwin())
6750f4a2713aSLionel Sambuc       return new DarwinI386TargetInfo(Triple);
6751f4a2713aSLionel Sambuc 
6752f4a2713aSLionel Sambuc     switch (os) {
6753f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6754f4a2713aSLionel Sambuc       return new LinuxTargetInfo<X86_32TargetInfo>(Triple);
6755f4a2713aSLionel Sambuc     case llvm::Triple::DragonFly:
6756f4a2713aSLionel Sambuc       return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple);
6757f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6758f4a2713aSLionel Sambuc       return new NetBSDI386TargetInfo(Triple);
6759f4a2713aSLionel Sambuc     case llvm::Triple::OpenBSD:
6760f4a2713aSLionel Sambuc       return new OpenBSDI386TargetInfo(Triple);
6761f4a2713aSLionel Sambuc     case llvm::Triple::Bitrig:
6762f4a2713aSLionel Sambuc       return new BitrigI386TargetInfo(Triple);
6763f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
6764f4a2713aSLionel Sambuc       return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple);
6765f4a2713aSLionel Sambuc     case llvm::Triple::KFreeBSD:
6766f4a2713aSLionel Sambuc       return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple);
6767f4a2713aSLionel Sambuc     case llvm::Triple::Minix:
6768f4a2713aSLionel Sambuc       return new MinixTargetInfo<X86_32TargetInfo>(Triple);
6769f4a2713aSLionel Sambuc     case llvm::Triple::Solaris:
6770f4a2713aSLionel Sambuc       return new SolarisTargetInfo<X86_32TargetInfo>(Triple);
6771*0a6a1f1dSLionel Sambuc     case llvm::Triple::Win32: {
6772*0a6a1f1dSLionel Sambuc       switch (Triple.getEnvironment()) {
6773*0a6a1f1dSLionel Sambuc       default:
6774*0a6a1f1dSLionel Sambuc         return new X86_32TargetInfo(Triple);
6775*0a6a1f1dSLionel Sambuc       case llvm::Triple::Cygnus:
6776f4a2713aSLionel Sambuc         return new CygwinX86_32TargetInfo(Triple);
6777*0a6a1f1dSLionel Sambuc       case llvm::Triple::GNU:
6778f4a2713aSLionel Sambuc         return new MinGWX86_32TargetInfo(Triple);
6779*0a6a1f1dSLionel Sambuc       case llvm::Triple::Itanium:
6780*0a6a1f1dSLionel Sambuc       case llvm::Triple::MSVC:
6781*0a6a1f1dSLionel Sambuc         return new MicrosoftX86_32TargetInfo(Triple);
6782*0a6a1f1dSLionel Sambuc       }
6783*0a6a1f1dSLionel Sambuc     }
6784f4a2713aSLionel Sambuc     case llvm::Triple::Haiku:
6785f4a2713aSLionel Sambuc       return new HaikuX86_32TargetInfo(Triple);
6786f4a2713aSLionel Sambuc     case llvm::Triple::RTEMS:
6787f4a2713aSLionel Sambuc       return new RTEMSX86_32TargetInfo(Triple);
6788f4a2713aSLionel Sambuc     case llvm::Triple::NaCl:
6789f4a2713aSLionel Sambuc       return new NaClTargetInfo<X86_32TargetInfo>(Triple);
6790f4a2713aSLionel Sambuc     default:
6791f4a2713aSLionel Sambuc       return new X86_32TargetInfo(Triple);
6792f4a2713aSLionel Sambuc     }
6793f4a2713aSLionel Sambuc 
6794f4a2713aSLionel Sambuc   case llvm::Triple::x86_64:
6795*0a6a1f1dSLionel Sambuc     if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO())
6796f4a2713aSLionel Sambuc       return new DarwinX86_64TargetInfo(Triple);
6797f4a2713aSLionel Sambuc 
6798f4a2713aSLionel Sambuc     switch (os) {
6799f4a2713aSLionel Sambuc     case llvm::Triple::Linux:
6800f4a2713aSLionel Sambuc       return new LinuxTargetInfo<X86_64TargetInfo>(Triple);
6801f4a2713aSLionel Sambuc     case llvm::Triple::DragonFly:
6802f4a2713aSLionel Sambuc       return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple);
6803f4a2713aSLionel Sambuc     case llvm::Triple::NetBSD:
6804f4a2713aSLionel Sambuc       return new NetBSDTargetInfo<X86_64TargetInfo>(Triple);
6805f4a2713aSLionel Sambuc     case llvm::Triple::OpenBSD:
6806f4a2713aSLionel Sambuc       return new OpenBSDX86_64TargetInfo(Triple);
6807f4a2713aSLionel Sambuc     case llvm::Triple::Bitrig:
6808f4a2713aSLionel Sambuc       return new BitrigX86_64TargetInfo(Triple);
6809f4a2713aSLionel Sambuc     case llvm::Triple::FreeBSD:
6810f4a2713aSLionel Sambuc       return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple);
6811f4a2713aSLionel Sambuc     case llvm::Triple::KFreeBSD:
6812f4a2713aSLionel Sambuc       return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple);
6813f4a2713aSLionel Sambuc     case llvm::Triple::Solaris:
6814f4a2713aSLionel Sambuc       return new SolarisTargetInfo<X86_64TargetInfo>(Triple);
6815*0a6a1f1dSLionel Sambuc     case llvm::Triple::Win32: {
6816*0a6a1f1dSLionel Sambuc       switch (Triple.getEnvironment()) {
6817*0a6a1f1dSLionel Sambuc       default:
6818*0a6a1f1dSLionel Sambuc         return new X86_64TargetInfo(Triple);
6819*0a6a1f1dSLionel Sambuc       case llvm::Triple::GNU:
6820f4a2713aSLionel Sambuc         return new MinGWX86_64TargetInfo(Triple);
6821*0a6a1f1dSLionel Sambuc       case llvm::Triple::MSVC:
6822*0a6a1f1dSLionel Sambuc         return new MicrosoftX86_64TargetInfo(Triple);
6823*0a6a1f1dSLionel Sambuc       }
6824*0a6a1f1dSLionel Sambuc     }
6825f4a2713aSLionel Sambuc     case llvm::Triple::NaCl:
6826f4a2713aSLionel Sambuc       return new NaClTargetInfo<X86_64TargetInfo>(Triple);
6827f4a2713aSLionel Sambuc     default:
6828f4a2713aSLionel Sambuc       return new X86_64TargetInfo(Triple);
6829f4a2713aSLionel Sambuc     }
6830f4a2713aSLionel Sambuc 
6831f4a2713aSLionel Sambuc     case llvm::Triple::spir: {
6832f4a2713aSLionel Sambuc       if (Triple.getOS() != llvm::Triple::UnknownOS ||
6833f4a2713aSLionel Sambuc           Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
6834*0a6a1f1dSLionel Sambuc         return nullptr;
6835f4a2713aSLionel Sambuc       return new SPIR32TargetInfo(Triple);
6836f4a2713aSLionel Sambuc     }
6837f4a2713aSLionel Sambuc     case llvm::Triple::spir64: {
6838f4a2713aSLionel Sambuc       if (Triple.getOS() != llvm::Triple::UnknownOS ||
6839f4a2713aSLionel Sambuc           Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
6840*0a6a1f1dSLionel Sambuc         return nullptr;
6841f4a2713aSLionel Sambuc       return new SPIR64TargetInfo(Triple);
6842f4a2713aSLionel Sambuc     }
6843f4a2713aSLionel Sambuc   }
6844f4a2713aSLionel Sambuc }
6845f4a2713aSLionel Sambuc 
6846f4a2713aSLionel Sambuc /// CreateTargetInfo - Return the target info object for the specified target
6847f4a2713aSLionel Sambuc /// triple.
6848*0a6a1f1dSLionel Sambuc TargetInfo *
CreateTargetInfo(DiagnosticsEngine & Diags,const std::shared_ptr<TargetOptions> & Opts)6849*0a6a1f1dSLionel Sambuc TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
6850*0a6a1f1dSLionel Sambuc                              const std::shared_ptr<TargetOptions> &Opts) {
6851f4a2713aSLionel Sambuc   llvm::Triple Triple(Opts->Triple);
6852f4a2713aSLionel Sambuc 
6853f4a2713aSLionel Sambuc   // Construct the target
6854*0a6a1f1dSLionel Sambuc   std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple));
6855f4a2713aSLionel Sambuc   if (!Target) {
6856f4a2713aSLionel Sambuc     Diags.Report(diag::err_target_unknown_triple) << Triple.str();
6857*0a6a1f1dSLionel Sambuc     return nullptr;
6858f4a2713aSLionel Sambuc   }
6859*0a6a1f1dSLionel Sambuc   Target->TargetOpts = Opts;
6860f4a2713aSLionel Sambuc 
6861f4a2713aSLionel Sambuc   // Set the target CPU if specified.
6862f4a2713aSLionel Sambuc   if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
6863f4a2713aSLionel Sambuc     Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU;
6864*0a6a1f1dSLionel Sambuc     return nullptr;
6865f4a2713aSLionel Sambuc   }
6866f4a2713aSLionel Sambuc 
6867f4a2713aSLionel Sambuc   // Set the target ABI if specified.
6868f4a2713aSLionel Sambuc   if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) {
6869f4a2713aSLionel Sambuc     Diags.Report(diag::err_target_unknown_abi) << Opts->ABI;
6870*0a6a1f1dSLionel Sambuc     return nullptr;
6871f4a2713aSLionel Sambuc   }
6872f4a2713aSLionel Sambuc 
6873f4a2713aSLionel Sambuc   // Set the fp math unit.
6874f4a2713aSLionel Sambuc   if (!Opts->FPMath.empty() && !Target->setFPMath(Opts->FPMath)) {
6875f4a2713aSLionel Sambuc     Diags.Report(diag::err_target_unknown_fpmath) << Opts->FPMath;
6876*0a6a1f1dSLionel Sambuc     return nullptr;
6877f4a2713aSLionel Sambuc   }
6878f4a2713aSLionel Sambuc 
6879f4a2713aSLionel Sambuc   // Compute the default target features, we need the target to handle this
6880f4a2713aSLionel Sambuc   // because features may have dependencies on one another.
6881f4a2713aSLionel Sambuc   llvm::StringMap<bool> Features;
6882f4a2713aSLionel Sambuc   Target->getDefaultFeatures(Features);
6883f4a2713aSLionel Sambuc 
6884f4a2713aSLionel Sambuc   // Apply the user specified deltas.
6885f4a2713aSLionel Sambuc   for (unsigned I = 0, N = Opts->FeaturesAsWritten.size();
6886f4a2713aSLionel Sambuc        I < N; ++I) {
6887f4a2713aSLionel Sambuc     const char *Name = Opts->FeaturesAsWritten[I].c_str();
6888f4a2713aSLionel Sambuc     // Apply the feature via the target.
6889f4a2713aSLionel Sambuc     bool Enabled = Name[0] == '+';
6890f4a2713aSLionel Sambuc     Target->setFeatureEnabled(Features, Name + 1, Enabled);
6891f4a2713aSLionel Sambuc   }
6892f4a2713aSLionel Sambuc 
6893f4a2713aSLionel Sambuc   // Add the features to the compile options.
6894f4a2713aSLionel Sambuc   //
6895f4a2713aSLionel Sambuc   // FIXME: If we are completely confident that we have the right set, we only
6896f4a2713aSLionel Sambuc   // need to pass the minuses.
6897f4a2713aSLionel Sambuc   Opts->Features.clear();
6898f4a2713aSLionel Sambuc   for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
6899f4a2713aSLionel Sambuc          ie = Features.end(); it != ie; ++it)
6900f4a2713aSLionel Sambuc     Opts->Features.push_back((it->second ? "+" : "-") + it->first().str());
6901f4a2713aSLionel Sambuc   if (!Target->handleTargetFeatures(Opts->Features, Diags))
6902*0a6a1f1dSLionel Sambuc     return nullptr;
6903f4a2713aSLionel Sambuc 
6904*0a6a1f1dSLionel Sambuc   return Target.release();
6905f4a2713aSLionel Sambuc }
6906