xref: /aosp_15_r20/external/clang/lib/Basic/Targets.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- Targets.cpp - Implement target feature support -------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file implements construction of a TargetInfo object from a
11*67e74705SXin Li // target triple.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li 
15*67e74705SXin Li #include "clang/Basic/Builtins.h"
16*67e74705SXin Li #include "clang/Basic/Cuda.h"
17*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
18*67e74705SXin Li #include "clang/Basic/LangOptions.h"
19*67e74705SXin Li #include "clang/Basic/MacroBuilder.h"
20*67e74705SXin Li #include "clang/Basic/TargetBuiltins.h"
21*67e74705SXin Li #include "clang/Basic/TargetInfo.h"
22*67e74705SXin Li #include "clang/Basic/TargetOptions.h"
23*67e74705SXin Li #include "clang/Basic/Version.h"
24*67e74705SXin Li #include "llvm/ADT/APFloat.h"
25*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
26*67e74705SXin Li #include "llvm/ADT/StringExtras.h"
27*67e74705SXin Li #include "llvm/ADT/StringRef.h"
28*67e74705SXin Li #include "llvm/ADT/StringSwitch.h"
29*67e74705SXin Li #include "llvm/ADT/Triple.h"
30*67e74705SXin Li #include "llvm/MC/MCSectionMachO.h"
31*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
32*67e74705SXin Li #include "llvm/Support/TargetParser.h"
33*67e74705SXin Li #include <algorithm>
34*67e74705SXin Li #include <memory>
35*67e74705SXin Li 
36*67e74705SXin Li using namespace clang;
37*67e74705SXin Li 
38*67e74705SXin Li //===----------------------------------------------------------------------===//
39*67e74705SXin Li //  Common code shared among targets.
40*67e74705SXin Li //===----------------------------------------------------------------------===//
41*67e74705SXin Li 
42*67e74705SXin Li /// DefineStd - Define a macro name and standard variants.  For example if
43*67e74705SXin Li /// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
44*67e74705SXin Li /// when in GNU mode.
DefineStd(MacroBuilder & Builder,StringRef MacroName,const LangOptions & Opts)45*67e74705SXin Li static void DefineStd(MacroBuilder &Builder, StringRef MacroName,
46*67e74705SXin Li                       const LangOptions &Opts) {
47*67e74705SXin Li   assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
48*67e74705SXin Li 
49*67e74705SXin Li   // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
50*67e74705SXin Li   // in the user's namespace.
51*67e74705SXin Li   if (Opts.GNUMode)
52*67e74705SXin Li     Builder.defineMacro(MacroName);
53*67e74705SXin Li 
54*67e74705SXin Li   // Define __unix.
55*67e74705SXin Li   Builder.defineMacro("__" + MacroName);
56*67e74705SXin Li 
57*67e74705SXin Li   // Define __unix__.
58*67e74705SXin Li   Builder.defineMacro("__" + MacroName + "__");
59*67e74705SXin Li }
60*67e74705SXin Li 
defineCPUMacros(MacroBuilder & Builder,StringRef CPUName,bool Tuning=true)61*67e74705SXin Li static void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName,
62*67e74705SXin Li                             bool Tuning = true) {
63*67e74705SXin Li   Builder.defineMacro("__" + CPUName);
64*67e74705SXin Li   Builder.defineMacro("__" + CPUName + "__");
65*67e74705SXin Li   if (Tuning)
66*67e74705SXin Li     Builder.defineMacro("__tune_" + CPUName + "__");
67*67e74705SXin Li }
68*67e74705SXin Li 
69*67e74705SXin Li static TargetInfo *AllocateTarget(const llvm::Triple &Triple,
70*67e74705SXin Li                                   const TargetOptions &Opts);
71*67e74705SXin Li 
72*67e74705SXin Li //===----------------------------------------------------------------------===//
73*67e74705SXin Li // Defines specific to certain operating systems.
74*67e74705SXin Li //===----------------------------------------------------------------------===//
75*67e74705SXin Li 
76*67e74705SXin Li namespace {
77*67e74705SXin Li template<typename TgtInfo>
78*67e74705SXin Li class OSTargetInfo : public TgtInfo {
79*67e74705SXin Li protected:
80*67e74705SXin Li   virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
81*67e74705SXin Li                             MacroBuilder &Builder) const=0;
82*67e74705SXin Li public:
OSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)83*67e74705SXin Li   OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
84*67e74705SXin Li       : TgtInfo(Triple, Opts) {}
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const85*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
86*67e74705SXin Li                         MacroBuilder &Builder) const override {
87*67e74705SXin Li     TgtInfo::getTargetDefines(Opts, Builder);
88*67e74705SXin Li     getOSDefines(Opts, TgtInfo::getTriple(), Builder);
89*67e74705SXin Li   }
90*67e74705SXin Li 
91*67e74705SXin Li };
92*67e74705SXin Li 
93*67e74705SXin Li // CloudABI Target
94*67e74705SXin Li template <typename Target>
95*67e74705SXin Li class CloudABITargetInfo : public OSTargetInfo<Target> {
96*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const97*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
98*67e74705SXin Li                     MacroBuilder &Builder) const override {
99*67e74705SXin Li     Builder.defineMacro("__CloudABI__");
100*67e74705SXin Li     Builder.defineMacro("__ELF__");
101*67e74705SXin Li 
102*67e74705SXin Li     // CloudABI uses ISO/IEC 10646:2012 for wchar_t, char16_t and char32_t.
103*67e74705SXin Li     Builder.defineMacro("__STDC_ISO_10646__", "201206L");
104*67e74705SXin Li     Builder.defineMacro("__STDC_UTF_16__");
105*67e74705SXin Li     Builder.defineMacro("__STDC_UTF_32__");
106*67e74705SXin Li   }
107*67e74705SXin Li 
108*67e74705SXin Li public:
CloudABITargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)109*67e74705SXin Li   CloudABITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
110*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {}
111*67e74705SXin Li };
112*67e74705SXin Li 
getDarwinDefines(MacroBuilder & Builder,const LangOptions & Opts,const llvm::Triple & Triple,StringRef & PlatformName,VersionTuple & PlatformMinVersion)113*67e74705SXin Li static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
114*67e74705SXin Li                              const llvm::Triple &Triple,
115*67e74705SXin Li                              StringRef &PlatformName,
116*67e74705SXin Li                              VersionTuple &PlatformMinVersion) {
117*67e74705SXin Li   Builder.defineMacro("__APPLE_CC__", "6000");
118*67e74705SXin Li   Builder.defineMacro("__APPLE__");
119*67e74705SXin Li   Builder.defineMacro("OBJC_NEW_PROPERTIES");
120*67e74705SXin Li   // AddressSanitizer doesn't play well with source fortification, which is on
121*67e74705SXin Li   // by default on Darwin.
122*67e74705SXin Li   if (Opts.Sanitize.has(SanitizerKind::Address))
123*67e74705SXin Li     Builder.defineMacro("_FORTIFY_SOURCE", "0");
124*67e74705SXin Li 
125*67e74705SXin Li   // Darwin defines __weak, __strong, and __unsafe_unretained even in C mode.
126*67e74705SXin Li   if (!Opts.ObjC1) {
127*67e74705SXin Li     // __weak is always defined, for use in blocks and with objc pointers.
128*67e74705SXin Li     Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
129*67e74705SXin Li     Builder.defineMacro("__strong", "");
130*67e74705SXin Li     Builder.defineMacro("__unsafe_unretained", "");
131*67e74705SXin Li   }
132*67e74705SXin Li 
133*67e74705SXin Li   if (Opts.Static)
134*67e74705SXin Li     Builder.defineMacro("__STATIC__");
135*67e74705SXin Li   else
136*67e74705SXin Li     Builder.defineMacro("__DYNAMIC__");
137*67e74705SXin Li 
138*67e74705SXin Li   if (Opts.POSIXThreads)
139*67e74705SXin Li     Builder.defineMacro("_REENTRANT");
140*67e74705SXin Li 
141*67e74705SXin Li   // Get the platform type and version number from the triple.
142*67e74705SXin Li   unsigned Maj, Min, Rev;
143*67e74705SXin Li   if (Triple.isMacOSX()) {
144*67e74705SXin Li     Triple.getMacOSXVersion(Maj, Min, Rev);
145*67e74705SXin Li     PlatformName = "macos";
146*67e74705SXin Li   } else {
147*67e74705SXin Li     Triple.getOSVersion(Maj, Min, Rev);
148*67e74705SXin Li     PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
149*67e74705SXin Li   }
150*67e74705SXin Li 
151*67e74705SXin Li   // If -target arch-pc-win32-macho option specified, we're
152*67e74705SXin Li   // generating code for Win32 ABI. No need to emit
153*67e74705SXin Li   // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.
154*67e74705SXin Li   if (PlatformName == "win32") {
155*67e74705SXin Li     PlatformMinVersion = VersionTuple(Maj, Min, Rev);
156*67e74705SXin Li     return;
157*67e74705SXin Li   }
158*67e74705SXin Li 
159*67e74705SXin Li   // Set the appropriate OS version define.
160*67e74705SXin Li   if (Triple.isiOS()) {
161*67e74705SXin Li     assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
162*67e74705SXin Li     char Str[6];
163*67e74705SXin Li     Str[0] = '0' + Maj;
164*67e74705SXin Li     Str[1] = '0' + (Min / 10);
165*67e74705SXin Li     Str[2] = '0' + (Min % 10);
166*67e74705SXin Li     Str[3] = '0' + (Rev / 10);
167*67e74705SXin Li     Str[4] = '0' + (Rev % 10);
168*67e74705SXin Li     Str[5] = '\0';
169*67e74705SXin Li     if (Triple.isTvOS())
170*67e74705SXin Li       Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str);
171*67e74705SXin Li     else
172*67e74705SXin Li       Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
173*67e74705SXin Li                           Str);
174*67e74705SXin Li 
175*67e74705SXin Li   } else if (Triple.isWatchOS()) {
176*67e74705SXin Li     assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
177*67e74705SXin Li     char Str[6];
178*67e74705SXin Li     Str[0] = '0' + Maj;
179*67e74705SXin Li     Str[1] = '0' + (Min / 10);
180*67e74705SXin Li     Str[2] = '0' + (Min % 10);
181*67e74705SXin Li     Str[3] = '0' + (Rev / 10);
182*67e74705SXin Li     Str[4] = '0' + (Rev % 10);
183*67e74705SXin Li     Str[5] = '\0';
184*67e74705SXin Li     Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str);
185*67e74705SXin Li   } else if (Triple.isMacOSX()) {
186*67e74705SXin Li     // Note that the Driver allows versions which aren't representable in the
187*67e74705SXin Li     // define (because we only get a single digit for the minor and micro
188*67e74705SXin Li     // revision numbers). So, we limit them to the maximum representable
189*67e74705SXin Li     // version.
190*67e74705SXin Li     assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
191*67e74705SXin Li     char Str[7];
192*67e74705SXin Li     if (Maj < 10 || (Maj == 10 && Min < 10)) {
193*67e74705SXin Li       Str[0] = '0' + (Maj / 10);
194*67e74705SXin Li       Str[1] = '0' + (Maj % 10);
195*67e74705SXin Li       Str[2] = '0' + std::min(Min, 9U);
196*67e74705SXin Li       Str[3] = '0' + std::min(Rev, 9U);
197*67e74705SXin Li       Str[4] = '\0';
198*67e74705SXin Li     } else {
199*67e74705SXin Li       // Handle versions > 10.9.
200*67e74705SXin Li       Str[0] = '0' + (Maj / 10);
201*67e74705SXin Li       Str[1] = '0' + (Maj % 10);
202*67e74705SXin Li       Str[2] = '0' + (Min / 10);
203*67e74705SXin Li       Str[3] = '0' + (Min % 10);
204*67e74705SXin Li       Str[4] = '0' + (Rev / 10);
205*67e74705SXin Li       Str[5] = '0' + (Rev % 10);
206*67e74705SXin Li       Str[6] = '\0';
207*67e74705SXin Li     }
208*67e74705SXin Li     Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
209*67e74705SXin Li   }
210*67e74705SXin Li 
211*67e74705SXin Li   // Tell users about the kernel if there is one.
212*67e74705SXin Li   if (Triple.isOSDarwin())
213*67e74705SXin Li     Builder.defineMacro("__MACH__");
214*67e74705SXin Li 
215*67e74705SXin Li   // The Watch ABI uses Dwarf EH.
216*67e74705SXin Li   if(Triple.isWatchABI())
217*67e74705SXin Li     Builder.defineMacro("__ARM_DWARF_EH__");
218*67e74705SXin Li 
219*67e74705SXin Li   PlatformMinVersion = VersionTuple(Maj, Min, Rev);
220*67e74705SXin Li }
221*67e74705SXin Li 
222*67e74705SXin Li template<typename Target>
223*67e74705SXin Li class DarwinTargetInfo : public OSTargetInfo<Target> {
224*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const225*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
226*67e74705SXin Li                     MacroBuilder &Builder) const override {
227*67e74705SXin Li     getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
228*67e74705SXin Li                      this->PlatformMinVersion);
229*67e74705SXin Li   }
230*67e74705SXin Li 
231*67e74705SXin Li public:
DarwinTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)232*67e74705SXin Li   DarwinTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
233*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
234*67e74705SXin Li     // By default, no TLS, and we whitelist permitted architecture/OS
235*67e74705SXin Li     // combinations.
236*67e74705SXin Li     this->TLSSupported = false;
237*67e74705SXin Li 
238*67e74705SXin Li     if (Triple.isMacOSX())
239*67e74705SXin Li       this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
240*67e74705SXin Li     else if (Triple.isiOS()) {
241*67e74705SXin Li       // 64-bit iOS supported it from 8 onwards, 32-bit from 9 onwards.
242*67e74705SXin Li       if (Triple.getArch() == llvm::Triple::x86_64 ||
243*67e74705SXin Li           Triple.getArch() == llvm::Triple::aarch64)
244*67e74705SXin Li         this->TLSSupported = !Triple.isOSVersionLT(8);
245*67e74705SXin Li       else if (Triple.getArch() == llvm::Triple::x86 ||
246*67e74705SXin Li                Triple.getArch() == llvm::Triple::arm ||
247*67e74705SXin Li                Triple.getArch() == llvm::Triple::thumb)
248*67e74705SXin Li         this->TLSSupported = !Triple.isOSVersionLT(9);
249*67e74705SXin Li     } else if (Triple.isWatchOS())
250*67e74705SXin Li       this->TLSSupported = !Triple.isOSVersionLT(2);
251*67e74705SXin Li 
252*67e74705SXin Li     this->MCountName = "\01mcount";
253*67e74705SXin Li   }
254*67e74705SXin Li 
isValidSectionSpecifier(StringRef SR) const255*67e74705SXin Li   std::string isValidSectionSpecifier(StringRef SR) const override {
256*67e74705SXin Li     // Let MCSectionMachO validate this.
257*67e74705SXin Li     StringRef Segment, Section;
258*67e74705SXin Li     unsigned TAA, StubSize;
259*67e74705SXin Li     bool HasTAA;
260*67e74705SXin Li     return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
261*67e74705SXin Li                                                        TAA, HasTAA, StubSize);
262*67e74705SXin Li   }
263*67e74705SXin Li 
getStaticInitSectionSpecifier() const264*67e74705SXin Li   const char *getStaticInitSectionSpecifier() const override {
265*67e74705SXin Li     // FIXME: We should return 0 when building kexts.
266*67e74705SXin Li     return "__TEXT,__StaticInit,regular,pure_instructions";
267*67e74705SXin Li   }
268*67e74705SXin Li 
269*67e74705SXin Li   /// Darwin does not support protected visibility.  Darwin's "default"
270*67e74705SXin Li   /// is very similar to ELF's "protected";  Darwin requires a "weak"
271*67e74705SXin Li   /// attribute on declarations that can be dynamically replaced.
hasProtectedVisibility() const272*67e74705SXin Li   bool hasProtectedVisibility() const override {
273*67e74705SXin Li     return false;
274*67e74705SXin Li   }
275*67e74705SXin Li 
getExnObjectAlignment() const276*67e74705SXin Li   unsigned getExnObjectAlignment() const override {
277*67e74705SXin Li     // The alignment of an exception object is 8-bytes for darwin since
278*67e74705SXin Li     // libc++abi doesn't declare _Unwind_Exception with __attribute__((aligned))
279*67e74705SXin Li     // and therefore doesn't guarantee 16-byte alignment.
280*67e74705SXin Li     return  64;
281*67e74705SXin Li   }
282*67e74705SXin Li };
283*67e74705SXin Li 
284*67e74705SXin Li 
285*67e74705SXin Li // DragonFlyBSD Target
286*67e74705SXin Li template<typename Target>
287*67e74705SXin Li class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
288*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const289*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
290*67e74705SXin Li                     MacroBuilder &Builder) const override {
291*67e74705SXin Li     // DragonFly defines; list based off of gcc output
292*67e74705SXin Li     Builder.defineMacro("__DragonFly__");
293*67e74705SXin Li     Builder.defineMacro("__DragonFly_cc_version", "100001");
294*67e74705SXin Li     Builder.defineMacro("__ELF__");
295*67e74705SXin Li     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
296*67e74705SXin Li     Builder.defineMacro("__tune_i386__");
297*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
298*67e74705SXin Li   }
299*67e74705SXin Li public:
DragonFlyBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)300*67e74705SXin Li   DragonFlyBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
301*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
302*67e74705SXin Li     switch (Triple.getArch()) {
303*67e74705SXin Li     default:
304*67e74705SXin Li     case llvm::Triple::x86:
305*67e74705SXin Li     case llvm::Triple::x86_64:
306*67e74705SXin Li       this->MCountName = ".mcount";
307*67e74705SXin Li       break;
308*67e74705SXin Li     }
309*67e74705SXin Li   }
310*67e74705SXin Li };
311*67e74705SXin Li 
312*67e74705SXin Li #ifndef FREEBSD_CC_VERSION
313*67e74705SXin Li #define FREEBSD_CC_VERSION 0U
314*67e74705SXin Li #endif
315*67e74705SXin Li 
316*67e74705SXin Li // FreeBSD Target
317*67e74705SXin Li template<typename Target>
318*67e74705SXin Li class FreeBSDTargetInfo : public OSTargetInfo<Target> {
319*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const320*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
321*67e74705SXin Li                     MacroBuilder &Builder) const override {
322*67e74705SXin Li     // FreeBSD defines; list based off of gcc output
323*67e74705SXin Li 
324*67e74705SXin Li     unsigned Release = Triple.getOSMajorVersion();
325*67e74705SXin Li     if (Release == 0U)
326*67e74705SXin Li       Release = 8U;
327*67e74705SXin Li     unsigned CCVersion = FREEBSD_CC_VERSION;
328*67e74705SXin Li     if (CCVersion == 0U)
329*67e74705SXin Li       CCVersion = Release * 100000U + 1U;
330*67e74705SXin Li 
331*67e74705SXin Li     Builder.defineMacro("__FreeBSD__", Twine(Release));
332*67e74705SXin Li     Builder.defineMacro("__FreeBSD_cc_version", Twine(CCVersion));
333*67e74705SXin Li     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
334*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
335*67e74705SXin Li     Builder.defineMacro("__ELF__");
336*67e74705SXin Li 
337*67e74705SXin Li     // On FreeBSD, wchar_t contains the number of the code point as
338*67e74705SXin Li     // used by the character set of the locale. These character sets are
339*67e74705SXin Li     // not necessarily a superset of ASCII.
340*67e74705SXin Li     //
341*67e74705SXin Li     // FIXME: This is wrong; the macro refers to the numerical values
342*67e74705SXin Li     // of wchar_t *literals*, which are not locale-dependent. However,
343*67e74705SXin Li     // FreeBSD systems apparently depend on us getting this wrong, and
344*67e74705SXin Li     // setting this to 1 is conforming even if all the basic source
345*67e74705SXin Li     // character literals have the same encoding as char and wchar_t.
346*67e74705SXin Li     Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
347*67e74705SXin Li   }
348*67e74705SXin Li public:
FreeBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)349*67e74705SXin Li   FreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
350*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
351*67e74705SXin Li     switch (Triple.getArch()) {
352*67e74705SXin Li     default:
353*67e74705SXin Li     case llvm::Triple::x86:
354*67e74705SXin Li     case llvm::Triple::x86_64:
355*67e74705SXin Li       this->MCountName = ".mcount";
356*67e74705SXin Li       break;
357*67e74705SXin Li     case llvm::Triple::mips:
358*67e74705SXin Li     case llvm::Triple::mipsel:
359*67e74705SXin Li     case llvm::Triple::ppc:
360*67e74705SXin Li     case llvm::Triple::ppc64:
361*67e74705SXin Li     case llvm::Triple::ppc64le:
362*67e74705SXin Li       this->MCountName = "_mcount";
363*67e74705SXin Li       break;
364*67e74705SXin Li     case llvm::Triple::arm:
365*67e74705SXin Li       this->MCountName = "__mcount";
366*67e74705SXin Li       break;
367*67e74705SXin Li     }
368*67e74705SXin Li   }
369*67e74705SXin Li };
370*67e74705SXin Li 
371*67e74705SXin Li // GNU/kFreeBSD Target
372*67e74705SXin Li template<typename Target>
373*67e74705SXin Li class KFreeBSDTargetInfo : public OSTargetInfo<Target> {
374*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const375*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
376*67e74705SXin Li                     MacroBuilder &Builder) const override {
377*67e74705SXin Li     // GNU/kFreeBSD defines; list based off of gcc output
378*67e74705SXin Li 
379*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
380*67e74705SXin Li     Builder.defineMacro("__FreeBSD_kernel__");
381*67e74705SXin Li     Builder.defineMacro("__GLIBC__");
382*67e74705SXin Li     Builder.defineMacro("__ELF__");
383*67e74705SXin Li     if (Opts.POSIXThreads)
384*67e74705SXin Li       Builder.defineMacro("_REENTRANT");
385*67e74705SXin Li     if (Opts.CPlusPlus)
386*67e74705SXin Li       Builder.defineMacro("_GNU_SOURCE");
387*67e74705SXin Li   }
388*67e74705SXin Li public:
KFreeBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)389*67e74705SXin Li   KFreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
390*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {}
391*67e74705SXin Li };
392*67e74705SXin Li 
393*67e74705SXin Li // Haiku Target
394*67e74705SXin Li template<typename Target>
395*67e74705SXin Li class HaikuTargetInfo : public OSTargetInfo<Target> {
396*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const397*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
398*67e74705SXin Li                     MacroBuilder &Builder) const override {
399*67e74705SXin Li     // Haiku defines; list based off of gcc output
400*67e74705SXin Li     Builder.defineMacro("__HAIKU__");
401*67e74705SXin Li     Builder.defineMacro("__ELF__");
402*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
403*67e74705SXin Li   }
404*67e74705SXin Li public:
HaikuTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)405*67e74705SXin Li   HaikuTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
406*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
407*67e74705SXin Li     this->SizeType = TargetInfo::UnsignedLong;
408*67e74705SXin Li     this->IntPtrType = TargetInfo::SignedLong;
409*67e74705SXin Li     this->PtrDiffType = TargetInfo::SignedLong;
410*67e74705SXin Li     this->ProcessIDType = TargetInfo::SignedLong;
411*67e74705SXin Li     this->TLSSupported = false;
412*67e74705SXin Li 
413*67e74705SXin Li   }
414*67e74705SXin Li };
415*67e74705SXin Li 
416*67e74705SXin Li // Minix Target
417*67e74705SXin Li template<typename Target>
418*67e74705SXin Li class MinixTargetInfo : public OSTargetInfo<Target> {
419*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const420*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
421*67e74705SXin Li                     MacroBuilder &Builder) const override {
422*67e74705SXin Li     // Minix defines
423*67e74705SXin Li 
424*67e74705SXin Li     Builder.defineMacro("__minix", "3");
425*67e74705SXin Li     Builder.defineMacro("_EM_WSIZE", "4");
426*67e74705SXin Li     Builder.defineMacro("_EM_PSIZE", "4");
427*67e74705SXin Li     Builder.defineMacro("_EM_SSIZE", "2");
428*67e74705SXin Li     Builder.defineMacro("_EM_LSIZE", "4");
429*67e74705SXin Li     Builder.defineMacro("_EM_FSIZE", "4");
430*67e74705SXin Li     Builder.defineMacro("_EM_DSIZE", "8");
431*67e74705SXin Li     Builder.defineMacro("__ELF__");
432*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
433*67e74705SXin Li   }
434*67e74705SXin Li public:
MinixTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)435*67e74705SXin Li   MinixTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
436*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {}
437*67e74705SXin Li };
438*67e74705SXin Li 
439*67e74705SXin Li // Linux target
440*67e74705SXin Li template<typename Target>
441*67e74705SXin Li class LinuxTargetInfo : public OSTargetInfo<Target> {
442*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const443*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
444*67e74705SXin Li                     MacroBuilder &Builder) const override {
445*67e74705SXin Li     // Linux defines; list based off of gcc output
446*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
447*67e74705SXin Li     DefineStd(Builder, "linux", Opts);
448*67e74705SXin Li     Builder.defineMacro("__gnu_linux__");
449*67e74705SXin Li     Builder.defineMacro("__ELF__");
450*67e74705SXin Li     if (Triple.isAndroid()) {
451*67e74705SXin Li       Builder.defineMacro("__ANDROID__", "1");
452*67e74705SXin Li       unsigned Maj, Min, Rev;
453*67e74705SXin Li       Triple.getEnvironmentVersion(Maj, Min, Rev);
454*67e74705SXin Li       this->PlatformName = "android";
455*67e74705SXin Li       this->PlatformMinVersion = VersionTuple(Maj, Min, Rev);
456*67e74705SXin Li     }
457*67e74705SXin Li     if (Opts.POSIXThreads)
458*67e74705SXin Li       Builder.defineMacro("_REENTRANT");
459*67e74705SXin Li     if (Opts.CPlusPlus)
460*67e74705SXin Li       Builder.defineMacro("_GNU_SOURCE");
461*67e74705SXin Li     if (this->HasFloat128)
462*67e74705SXin Li       Builder.defineMacro("__FLOAT128__");
463*67e74705SXin Li   }
464*67e74705SXin Li public:
LinuxTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)465*67e74705SXin Li   LinuxTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
466*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
467*67e74705SXin Li     this->WIntType = TargetInfo::UnsignedInt;
468*67e74705SXin Li 
469*67e74705SXin Li     switch (Triple.getArch()) {
470*67e74705SXin Li     default:
471*67e74705SXin Li       break;
472*67e74705SXin Li     case llvm::Triple::ppc:
473*67e74705SXin Li     case llvm::Triple::ppc64:
474*67e74705SXin Li     case llvm::Triple::ppc64le:
475*67e74705SXin Li       this->MCountName = "_mcount";
476*67e74705SXin Li       break;
477*67e74705SXin Li     case llvm::Triple::x86:
478*67e74705SXin Li     case llvm::Triple::x86_64:
479*67e74705SXin Li     case llvm::Triple::systemz:
480*67e74705SXin Li       this->HasFloat128 = true;
481*67e74705SXin Li       break;
482*67e74705SXin Li     }
483*67e74705SXin Li   }
484*67e74705SXin Li 
getStaticInitSectionSpecifier() const485*67e74705SXin Li   const char *getStaticInitSectionSpecifier() const override {
486*67e74705SXin Li     return ".text.startup";
487*67e74705SXin Li   }
488*67e74705SXin Li };
489*67e74705SXin Li 
490*67e74705SXin Li // NetBSD Target
491*67e74705SXin Li template<typename Target>
492*67e74705SXin Li class NetBSDTargetInfo : public OSTargetInfo<Target> {
493*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const494*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
495*67e74705SXin Li                     MacroBuilder &Builder) const override {
496*67e74705SXin Li     // NetBSD defines; list based off of gcc output
497*67e74705SXin Li     Builder.defineMacro("__NetBSD__");
498*67e74705SXin Li     Builder.defineMacro("__unix__");
499*67e74705SXin Li     Builder.defineMacro("__ELF__");
500*67e74705SXin Li     if (Opts.POSIXThreads)
501*67e74705SXin Li       Builder.defineMacro("_POSIX_THREADS");
502*67e74705SXin Li 
503*67e74705SXin Li     switch (Triple.getArch()) {
504*67e74705SXin Li     default:
505*67e74705SXin Li       break;
506*67e74705SXin Li     case llvm::Triple::arm:
507*67e74705SXin Li     case llvm::Triple::armeb:
508*67e74705SXin Li     case llvm::Triple::thumb:
509*67e74705SXin Li     case llvm::Triple::thumbeb:
510*67e74705SXin Li       Builder.defineMacro("__ARM_DWARF_EH__");
511*67e74705SXin Li       break;
512*67e74705SXin Li     }
513*67e74705SXin Li   }
514*67e74705SXin Li public:
NetBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)515*67e74705SXin Li   NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
516*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
517*67e74705SXin Li     this->MCountName = "_mcount";
518*67e74705SXin Li   }
519*67e74705SXin Li };
520*67e74705SXin Li 
521*67e74705SXin Li // OpenBSD Target
522*67e74705SXin Li template<typename Target>
523*67e74705SXin Li class OpenBSDTargetInfo : public OSTargetInfo<Target> {
524*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const525*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
526*67e74705SXin Li                     MacroBuilder &Builder) const override {
527*67e74705SXin Li     // OpenBSD defines; list based off of gcc output
528*67e74705SXin Li 
529*67e74705SXin Li     Builder.defineMacro("__OpenBSD__");
530*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
531*67e74705SXin Li     Builder.defineMacro("__ELF__");
532*67e74705SXin Li     if (Opts.POSIXThreads)
533*67e74705SXin Li       Builder.defineMacro("_REENTRANT");
534*67e74705SXin Li   }
535*67e74705SXin Li public:
OpenBSDTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)536*67e74705SXin Li   OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
537*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
538*67e74705SXin Li     this->TLSSupported = false;
539*67e74705SXin Li 
540*67e74705SXin Li       switch (Triple.getArch()) {
541*67e74705SXin Li         default:
542*67e74705SXin Li         case llvm::Triple::x86:
543*67e74705SXin Li         case llvm::Triple::x86_64:
544*67e74705SXin Li         case llvm::Triple::arm:
545*67e74705SXin Li         case llvm::Triple::sparc:
546*67e74705SXin Li           this->MCountName = "__mcount";
547*67e74705SXin Li           break;
548*67e74705SXin Li         case llvm::Triple::mips64:
549*67e74705SXin Li         case llvm::Triple::mips64el:
550*67e74705SXin Li         case llvm::Triple::ppc:
551*67e74705SXin Li         case llvm::Triple::sparcv9:
552*67e74705SXin Li           this->MCountName = "_mcount";
553*67e74705SXin Li           break;
554*67e74705SXin Li       }
555*67e74705SXin Li   }
556*67e74705SXin Li };
557*67e74705SXin Li 
558*67e74705SXin Li // Bitrig Target
559*67e74705SXin Li template<typename Target>
560*67e74705SXin Li class BitrigTargetInfo : public OSTargetInfo<Target> {
561*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const562*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
563*67e74705SXin Li                     MacroBuilder &Builder) const override {
564*67e74705SXin Li     // Bitrig defines; list based off of gcc output
565*67e74705SXin Li 
566*67e74705SXin Li     Builder.defineMacro("__Bitrig__");
567*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
568*67e74705SXin Li     Builder.defineMacro("__ELF__");
569*67e74705SXin Li     if (Opts.POSIXThreads)
570*67e74705SXin Li       Builder.defineMacro("_REENTRANT");
571*67e74705SXin Li 
572*67e74705SXin Li     switch (Triple.getArch()) {
573*67e74705SXin Li     default:
574*67e74705SXin Li       break;
575*67e74705SXin Li     case llvm::Triple::arm:
576*67e74705SXin Li     case llvm::Triple::armeb:
577*67e74705SXin Li     case llvm::Triple::thumb:
578*67e74705SXin Li     case llvm::Triple::thumbeb:
579*67e74705SXin Li       Builder.defineMacro("__ARM_DWARF_EH__");
580*67e74705SXin Li       break;
581*67e74705SXin Li     }
582*67e74705SXin Li   }
583*67e74705SXin Li public:
BitrigTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)584*67e74705SXin Li   BitrigTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
585*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
586*67e74705SXin Li     this->MCountName = "__mcount";
587*67e74705SXin Li   }
588*67e74705SXin Li };
589*67e74705SXin Li 
590*67e74705SXin Li // PSP Target
591*67e74705SXin Li template<typename Target>
592*67e74705SXin Li class PSPTargetInfo : public OSTargetInfo<Target> {
593*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const594*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
595*67e74705SXin Li                     MacroBuilder &Builder) const override {
596*67e74705SXin Li     // PSP defines; list based on the output of the pspdev gcc toolchain.
597*67e74705SXin Li     Builder.defineMacro("PSP");
598*67e74705SXin Li     Builder.defineMacro("_PSP");
599*67e74705SXin Li     Builder.defineMacro("__psp__");
600*67e74705SXin Li     Builder.defineMacro("__ELF__");
601*67e74705SXin Li   }
602*67e74705SXin Li public:
PSPTargetInfo(const llvm::Triple & Triple)603*67e74705SXin Li   PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {}
604*67e74705SXin Li };
605*67e74705SXin Li 
606*67e74705SXin Li // PS3 PPU Target
607*67e74705SXin Li template<typename Target>
608*67e74705SXin Li class PS3PPUTargetInfo : public OSTargetInfo<Target> {
609*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const610*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
611*67e74705SXin Li                     MacroBuilder &Builder) const override {
612*67e74705SXin Li     // PS3 PPU defines.
613*67e74705SXin Li     Builder.defineMacro("__PPC__");
614*67e74705SXin Li     Builder.defineMacro("__PPU__");
615*67e74705SXin Li     Builder.defineMacro("__CELLOS_LV2__");
616*67e74705SXin Li     Builder.defineMacro("__ELF__");
617*67e74705SXin Li     Builder.defineMacro("__LP32__");
618*67e74705SXin Li     Builder.defineMacro("_ARCH_PPC64");
619*67e74705SXin Li     Builder.defineMacro("__powerpc64__");
620*67e74705SXin Li   }
621*67e74705SXin Li public:
PS3PPUTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)622*67e74705SXin Li   PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
623*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
624*67e74705SXin Li     this->LongWidth = this->LongAlign = 32;
625*67e74705SXin Li     this->PointerWidth = this->PointerAlign = 32;
626*67e74705SXin Li     this->IntMaxType = TargetInfo::SignedLongLong;
627*67e74705SXin Li     this->Int64Type = TargetInfo::SignedLongLong;
628*67e74705SXin Li     this->SizeType = TargetInfo::UnsignedInt;
629*67e74705SXin Li     this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64");
630*67e74705SXin Li   }
631*67e74705SXin Li };
632*67e74705SXin Li 
633*67e74705SXin Li template <typename Target>
634*67e74705SXin Li class PS4OSTargetInfo : public OSTargetInfo<Target> {
635*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const636*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
637*67e74705SXin Li                     MacroBuilder &Builder) const override {
638*67e74705SXin Li     Builder.defineMacro("__FreeBSD__", "9");
639*67e74705SXin Li     Builder.defineMacro("__FreeBSD_cc_version", "900001");
640*67e74705SXin Li     Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
641*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
642*67e74705SXin Li     Builder.defineMacro("__ELF__");
643*67e74705SXin Li     Builder.defineMacro("__ORBIS__");
644*67e74705SXin Li   }
645*67e74705SXin Li public:
PS4OSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)646*67e74705SXin Li   PS4OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
647*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
648*67e74705SXin Li     this->WCharType = this->UnsignedShort;
649*67e74705SXin Li 
650*67e74705SXin Li     // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits).
651*67e74705SXin Li     this->MaxTLSAlign = 256;
652*67e74705SXin Li 
653*67e74705SXin Li     // On PS4, do not honor explicit bit field alignment,
654*67e74705SXin Li     // as in "__attribute__((aligned(2))) int b : 1;".
655*67e74705SXin Li     this->UseExplicitBitFieldAlignment = false;
656*67e74705SXin Li 
657*67e74705SXin Li     switch (Triple.getArch()) {
658*67e74705SXin Li     default:
659*67e74705SXin Li     case llvm::Triple::x86_64:
660*67e74705SXin Li       this->MCountName = ".mcount";
661*67e74705SXin Li       break;
662*67e74705SXin Li     }
663*67e74705SXin Li   }
664*67e74705SXin Li };
665*67e74705SXin Li 
666*67e74705SXin Li // Solaris target
667*67e74705SXin Li template<typename Target>
668*67e74705SXin Li class SolarisTargetInfo : public OSTargetInfo<Target> {
669*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const670*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
671*67e74705SXin Li                     MacroBuilder &Builder) const override {
672*67e74705SXin Li     DefineStd(Builder, "sun", Opts);
673*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
674*67e74705SXin Li     Builder.defineMacro("__ELF__");
675*67e74705SXin Li     Builder.defineMacro("__svr4__");
676*67e74705SXin Li     Builder.defineMacro("__SVR4");
677*67e74705SXin Li     // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
678*67e74705SXin Li     // newer, but to 500 for everything else.  feature_test.h has a check to
679*67e74705SXin Li     // ensure that you are not using C99 with an old version of X/Open or C89
680*67e74705SXin Li     // with a new version.
681*67e74705SXin Li     if (Opts.C99)
682*67e74705SXin Li       Builder.defineMacro("_XOPEN_SOURCE", "600");
683*67e74705SXin Li     else
684*67e74705SXin Li       Builder.defineMacro("_XOPEN_SOURCE", "500");
685*67e74705SXin Li     if (Opts.CPlusPlus)
686*67e74705SXin Li       Builder.defineMacro("__C99FEATURES__");
687*67e74705SXin Li     Builder.defineMacro("_LARGEFILE_SOURCE");
688*67e74705SXin Li     Builder.defineMacro("_LARGEFILE64_SOURCE");
689*67e74705SXin Li     Builder.defineMacro("__EXTENSIONS__");
690*67e74705SXin Li     Builder.defineMacro("_REENTRANT");
691*67e74705SXin Li   }
692*67e74705SXin Li public:
SolarisTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)693*67e74705SXin Li   SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
694*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
695*67e74705SXin Li     this->WCharType = this->SignedInt;
696*67e74705SXin Li     // FIXME: WIntType should be SignedLong
697*67e74705SXin Li   }
698*67e74705SXin Li };
699*67e74705SXin Li 
700*67e74705SXin Li // Windows target
701*67e74705SXin Li template<typename Target>
702*67e74705SXin Li class WindowsTargetInfo : public OSTargetInfo<Target> {
703*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const704*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
705*67e74705SXin Li                     MacroBuilder &Builder) const override {
706*67e74705SXin Li     Builder.defineMacro("_WIN32");
707*67e74705SXin Li   }
getVisualStudioDefines(const LangOptions & Opts,MacroBuilder & Builder) const708*67e74705SXin Li   void getVisualStudioDefines(const LangOptions &Opts,
709*67e74705SXin Li                               MacroBuilder &Builder) const {
710*67e74705SXin Li     if (Opts.CPlusPlus) {
711*67e74705SXin Li       if (Opts.RTTIData)
712*67e74705SXin Li         Builder.defineMacro("_CPPRTTI");
713*67e74705SXin Li 
714*67e74705SXin Li       if (Opts.CXXExceptions)
715*67e74705SXin Li         Builder.defineMacro("_CPPUNWIND");
716*67e74705SXin Li     }
717*67e74705SXin Li 
718*67e74705SXin Li     if (Opts.Bool)
719*67e74705SXin Li       Builder.defineMacro("__BOOL_DEFINED");
720*67e74705SXin Li 
721*67e74705SXin Li     if (!Opts.CharIsSigned)
722*67e74705SXin Li       Builder.defineMacro("_CHAR_UNSIGNED");
723*67e74705SXin Li 
724*67e74705SXin Li     // FIXME: POSIXThreads isn't exactly the option this should be defined for,
725*67e74705SXin Li     //        but it works for now.
726*67e74705SXin Li     if (Opts.POSIXThreads)
727*67e74705SXin Li       Builder.defineMacro("_MT");
728*67e74705SXin Li 
729*67e74705SXin Li     if (Opts.MSCompatibilityVersion) {
730*67e74705SXin Li       Builder.defineMacro("_MSC_VER",
731*67e74705SXin Li                           Twine(Opts.MSCompatibilityVersion / 100000));
732*67e74705SXin Li       Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion));
733*67e74705SXin Li       // FIXME We cannot encode the revision information into 32-bits
734*67e74705SXin Li       Builder.defineMacro("_MSC_BUILD", Twine(1));
735*67e74705SXin Li 
736*67e74705SXin Li       if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015))
737*67e74705SXin Li         Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));
738*67e74705SXin Li 
739*67e74705SXin Li       if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) {
740*67e74705SXin Li         if (Opts.CPlusPlus1z)
741*67e74705SXin Li           Builder.defineMacro("_MSVC_LANG", "201403L");
742*67e74705SXin Li         else if (Opts.CPlusPlus14)
743*67e74705SXin Li           Builder.defineMacro("_MSVC_LANG", "201402L");
744*67e74705SXin Li       }
745*67e74705SXin Li     }
746*67e74705SXin Li 
747*67e74705SXin Li     if (Opts.MicrosoftExt) {
748*67e74705SXin Li       Builder.defineMacro("_MSC_EXTENSIONS");
749*67e74705SXin Li 
750*67e74705SXin Li       if (Opts.CPlusPlus11) {
751*67e74705SXin Li         Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
752*67e74705SXin Li         Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
753*67e74705SXin Li         Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
754*67e74705SXin Li       }
755*67e74705SXin Li     }
756*67e74705SXin Li 
757*67e74705SXin Li     Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
758*67e74705SXin Li   }
759*67e74705SXin Li 
760*67e74705SXin Li public:
WindowsTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)761*67e74705SXin Li   WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
762*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {}
763*67e74705SXin Li };
764*67e74705SXin Li 
765*67e74705SXin Li template <typename Target>
766*67e74705SXin Li class NaClTargetInfo : public OSTargetInfo<Target> {
767*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const768*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
769*67e74705SXin Li                     MacroBuilder &Builder) const override {
770*67e74705SXin Li     if (Opts.POSIXThreads)
771*67e74705SXin Li       Builder.defineMacro("_REENTRANT");
772*67e74705SXin Li     if (Opts.CPlusPlus)
773*67e74705SXin Li       Builder.defineMacro("_GNU_SOURCE");
774*67e74705SXin Li 
775*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
776*67e74705SXin Li     Builder.defineMacro("__ELF__");
777*67e74705SXin Li     Builder.defineMacro("__native_client__");
778*67e74705SXin Li   }
779*67e74705SXin Li 
780*67e74705SXin Li public:
NaClTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)781*67e74705SXin Li   NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
782*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
783*67e74705SXin Li     this->LongAlign = 32;
784*67e74705SXin Li     this->LongWidth = 32;
785*67e74705SXin Li     this->PointerAlign = 32;
786*67e74705SXin Li     this->PointerWidth = 32;
787*67e74705SXin Li     this->IntMaxType = TargetInfo::SignedLongLong;
788*67e74705SXin Li     this->Int64Type = TargetInfo::SignedLongLong;
789*67e74705SXin Li     this->DoubleAlign = 64;
790*67e74705SXin Li     this->LongDoubleWidth = 64;
791*67e74705SXin Li     this->LongDoubleAlign = 64;
792*67e74705SXin Li     this->LongLongWidth = 64;
793*67e74705SXin Li     this->LongLongAlign = 64;
794*67e74705SXin Li     this->SizeType = TargetInfo::UnsignedInt;
795*67e74705SXin Li     this->PtrDiffType = TargetInfo::SignedInt;
796*67e74705SXin Li     this->IntPtrType = TargetInfo::SignedInt;
797*67e74705SXin Li     // RegParmMax is inherited from the underlying architecture
798*67e74705SXin Li     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
799*67e74705SXin Li     if (Triple.getArch() == llvm::Triple::arm) {
800*67e74705SXin Li       // Handled in ARM's setABI().
801*67e74705SXin Li     } else if (Triple.getArch() == llvm::Triple::x86) {
802*67e74705SXin Li       this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32-S128");
803*67e74705SXin Li     } else if (Triple.getArch() == llvm::Triple::x86_64) {
804*67e74705SXin Li       this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32:64-S128");
805*67e74705SXin Li     } else if (Triple.getArch() == llvm::Triple::mipsel) {
806*67e74705SXin Li       // Handled on mips' setDataLayout.
807*67e74705SXin Li     } else {
808*67e74705SXin Li       assert(Triple.getArch() == llvm::Triple::le32);
809*67e74705SXin Li       this->resetDataLayout("e-p:32:32-i64:64");
810*67e74705SXin Li     }
811*67e74705SXin Li   }
812*67e74705SXin Li };
813*67e74705SXin Li 
814*67e74705SXin Li // WebAssembly target
815*67e74705SXin Li template <typename Target>
816*67e74705SXin Li class WebAssemblyOSTargetInfo : public OSTargetInfo<Target> {
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const817*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
818*67e74705SXin Li                     MacroBuilder &Builder) const final {
819*67e74705SXin Li     // A common platform macro.
820*67e74705SXin Li     if (Opts.POSIXThreads)
821*67e74705SXin Li       Builder.defineMacro("_REENTRANT");
822*67e74705SXin Li     // Follow g++ convention and predefine _GNU_SOURCE for C++.
823*67e74705SXin Li     if (Opts.CPlusPlus)
824*67e74705SXin Li       Builder.defineMacro("_GNU_SOURCE");
825*67e74705SXin Li   }
826*67e74705SXin Li 
827*67e74705SXin Li   // As an optimization, group static init code together in a section.
getStaticInitSectionSpecifier() const828*67e74705SXin Li   const char *getStaticInitSectionSpecifier() const final {
829*67e74705SXin Li     return ".text.__startup";
830*67e74705SXin Li   }
831*67e74705SXin Li 
832*67e74705SXin Li public:
WebAssemblyOSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)833*67e74705SXin Li   explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple,
834*67e74705SXin Li                                    const TargetOptions &Opts)
835*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
836*67e74705SXin Li     this->MCountName = "__mcount";
837*67e74705SXin Li     this->TheCXXABI.set(TargetCXXABI::WebAssembly);
838*67e74705SXin Li   }
839*67e74705SXin Li };
840*67e74705SXin Li 
841*67e74705SXin Li //===----------------------------------------------------------------------===//
842*67e74705SXin Li // Specific target implementations.
843*67e74705SXin Li //===----------------------------------------------------------------------===//
844*67e74705SXin Li 
845*67e74705SXin Li // PPC abstract base class
846*67e74705SXin Li class PPCTargetInfo : public TargetInfo {
847*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
848*67e74705SXin Li   static const char * const GCCRegNames[];
849*67e74705SXin Li   static const TargetInfo::GCCRegAlias GCCRegAliases[];
850*67e74705SXin Li   std::string CPU;
851*67e74705SXin Li 
852*67e74705SXin Li   // Target cpu features.
853*67e74705SXin Li   bool HasVSX;
854*67e74705SXin Li   bool HasP8Vector;
855*67e74705SXin Li   bool HasP8Crypto;
856*67e74705SXin Li   bool HasDirectMove;
857*67e74705SXin Li   bool HasQPX;
858*67e74705SXin Li   bool HasHTM;
859*67e74705SXin Li   bool HasBPERMD;
860*67e74705SXin Li   bool HasExtDiv;
861*67e74705SXin Li 
862*67e74705SXin Li protected:
863*67e74705SXin Li   std::string ABI;
864*67e74705SXin Li 
865*67e74705SXin Li public:
PPCTargetInfo(const llvm::Triple & Triple,const TargetOptions &)866*67e74705SXin Li   PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
867*67e74705SXin Li     : TargetInfo(Triple), HasVSX(false), HasP8Vector(false),
868*67e74705SXin Li       HasP8Crypto(false), HasDirectMove(false), HasQPX(false), HasHTM(false),
869*67e74705SXin Li       HasBPERMD(false), HasExtDiv(false) {
870*67e74705SXin Li     BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
871*67e74705SXin Li     SimdDefaultAlign = 128;
872*67e74705SXin Li     LongDoubleWidth = LongDoubleAlign = 128;
873*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
874*67e74705SXin Li   }
875*67e74705SXin Li 
876*67e74705SXin Li   /// \brief Flags for architecture specific defines.
877*67e74705SXin Li   typedef enum {
878*67e74705SXin Li     ArchDefineNone  = 0,
879*67e74705SXin Li     ArchDefineName  = 1 << 0, // <name> is substituted for arch name.
880*67e74705SXin Li     ArchDefinePpcgr = 1 << 1,
881*67e74705SXin Li     ArchDefinePpcsq = 1 << 2,
882*67e74705SXin Li     ArchDefine440   = 1 << 3,
883*67e74705SXin Li     ArchDefine603   = 1 << 4,
884*67e74705SXin Li     ArchDefine604   = 1 << 5,
885*67e74705SXin Li     ArchDefinePwr4  = 1 << 6,
886*67e74705SXin Li     ArchDefinePwr5  = 1 << 7,
887*67e74705SXin Li     ArchDefinePwr5x = 1 << 8,
888*67e74705SXin Li     ArchDefinePwr6  = 1 << 9,
889*67e74705SXin Li     ArchDefinePwr6x = 1 << 10,
890*67e74705SXin Li     ArchDefinePwr7  = 1 << 11,
891*67e74705SXin Li     ArchDefinePwr8  = 1 << 12,
892*67e74705SXin Li     ArchDefinePwr9  = 1 << 13,
893*67e74705SXin Li     ArchDefineA2    = 1 << 14,
894*67e74705SXin Li     ArchDefineA2q   = 1 << 15
895*67e74705SXin Li   } ArchDefineTypes;
896*67e74705SXin Li 
897*67e74705SXin Li   // Note: GCC recognizes the following additional cpus:
898*67e74705SXin Li   //  401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801,
899*67e74705SXin Li   //  821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell,
900*67e74705SXin Li   //  titan, rs64.
setCPU(const std::string & Name)901*67e74705SXin Li   bool setCPU(const std::string &Name) override {
902*67e74705SXin Li     bool CPUKnown = llvm::StringSwitch<bool>(Name)
903*67e74705SXin Li       .Case("generic", true)
904*67e74705SXin Li       .Case("440", true)
905*67e74705SXin Li       .Case("450", true)
906*67e74705SXin Li       .Case("601", true)
907*67e74705SXin Li       .Case("602", true)
908*67e74705SXin Li       .Case("603", true)
909*67e74705SXin Li       .Case("603e", true)
910*67e74705SXin Li       .Case("603ev", true)
911*67e74705SXin Li       .Case("604", true)
912*67e74705SXin Li       .Case("604e", true)
913*67e74705SXin Li       .Case("620", true)
914*67e74705SXin Li       .Case("630", true)
915*67e74705SXin Li       .Case("g3", true)
916*67e74705SXin Li       .Case("7400", true)
917*67e74705SXin Li       .Case("g4", true)
918*67e74705SXin Li       .Case("7450", true)
919*67e74705SXin Li       .Case("g4+", true)
920*67e74705SXin Li       .Case("750", true)
921*67e74705SXin Li       .Case("970", true)
922*67e74705SXin Li       .Case("g5", true)
923*67e74705SXin Li       .Case("a2", true)
924*67e74705SXin Li       .Case("a2q", true)
925*67e74705SXin Li       .Case("e500mc", true)
926*67e74705SXin Li       .Case("e5500", true)
927*67e74705SXin Li       .Case("power3", true)
928*67e74705SXin Li       .Case("pwr3", true)
929*67e74705SXin Li       .Case("power4", true)
930*67e74705SXin Li       .Case("pwr4", true)
931*67e74705SXin Li       .Case("power5", true)
932*67e74705SXin Li       .Case("pwr5", true)
933*67e74705SXin Li       .Case("power5x", true)
934*67e74705SXin Li       .Case("pwr5x", true)
935*67e74705SXin Li       .Case("power6", true)
936*67e74705SXin Li       .Case("pwr6", true)
937*67e74705SXin Li       .Case("power6x", true)
938*67e74705SXin Li       .Case("pwr6x", true)
939*67e74705SXin Li       .Case("power7", true)
940*67e74705SXin Li       .Case("pwr7", true)
941*67e74705SXin Li       .Case("power8", true)
942*67e74705SXin Li       .Case("pwr8", true)
943*67e74705SXin Li       .Case("power9", true)
944*67e74705SXin Li       .Case("pwr9", true)
945*67e74705SXin Li       .Case("powerpc", true)
946*67e74705SXin Li       .Case("ppc", true)
947*67e74705SXin Li       .Case("powerpc64", true)
948*67e74705SXin Li       .Case("ppc64", true)
949*67e74705SXin Li       .Case("powerpc64le", true)
950*67e74705SXin Li       .Case("ppc64le", true)
951*67e74705SXin Li       .Default(false);
952*67e74705SXin Li 
953*67e74705SXin Li     if (CPUKnown)
954*67e74705SXin Li       CPU = Name;
955*67e74705SXin Li 
956*67e74705SXin Li     return CPUKnown;
957*67e74705SXin Li   }
958*67e74705SXin Li 
959*67e74705SXin Li 
getABI() const960*67e74705SXin Li   StringRef getABI() const override { return ABI; }
961*67e74705SXin Li 
getTargetBuiltins() const962*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
963*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
964*67e74705SXin Li                              clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin);
965*67e74705SXin Li   }
966*67e74705SXin Li 
isCLZForZeroUndef() const967*67e74705SXin Li   bool isCLZForZeroUndef() const override { return false; }
968*67e74705SXin Li 
969*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
970*67e74705SXin Li                         MacroBuilder &Builder) const override;
971*67e74705SXin Li 
972*67e74705SXin Li   bool
973*67e74705SXin Li   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
974*67e74705SXin Li                  StringRef CPU,
975*67e74705SXin Li                  const std::vector<std::string> &FeaturesVec) const override;
976*67e74705SXin Li 
977*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
978*67e74705SXin Li                             DiagnosticsEngine &Diags) override;
979*67e74705SXin Li   bool hasFeature(StringRef Feature) const override;
980*67e74705SXin Li   void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
981*67e74705SXin Li                          bool Enabled) const override;
982*67e74705SXin Li 
983*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
984*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const985*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
986*67e74705SXin Li                              TargetInfo::ConstraintInfo &Info) const override {
987*67e74705SXin Li     switch (*Name) {
988*67e74705SXin Li     default: return false;
989*67e74705SXin Li     case 'O': // Zero
990*67e74705SXin Li       break;
991*67e74705SXin Li     case 'b': // Base register
992*67e74705SXin Li     case 'f': // Floating point register
993*67e74705SXin Li       Info.setAllowsRegister();
994*67e74705SXin Li       break;
995*67e74705SXin Li     // FIXME: The following are added to allow parsing.
996*67e74705SXin Li     // I just took a guess at what the actions should be.
997*67e74705SXin Li     // Also, is more specific checking needed?  I.e. specific registers?
998*67e74705SXin Li     case 'd': // Floating point register (containing 64-bit value)
999*67e74705SXin Li     case 'v': // Altivec vector register
1000*67e74705SXin Li       Info.setAllowsRegister();
1001*67e74705SXin Li       break;
1002*67e74705SXin Li     case 'w':
1003*67e74705SXin Li       switch (Name[1]) {
1004*67e74705SXin Li         case 'd':// VSX vector register to hold vector double data
1005*67e74705SXin Li         case 'f':// VSX vector register to hold vector float data
1006*67e74705SXin Li         case 's':// VSX vector register to hold scalar float data
1007*67e74705SXin Li         case 'a':// Any VSX register
1008*67e74705SXin Li         case 'c':// An individual CR bit
1009*67e74705SXin Li           break;
1010*67e74705SXin Li         default:
1011*67e74705SXin Li           return false;
1012*67e74705SXin Li       }
1013*67e74705SXin Li       Info.setAllowsRegister();
1014*67e74705SXin Li       Name++; // Skip over 'w'.
1015*67e74705SXin Li       break;
1016*67e74705SXin Li     case 'h': // `MQ', `CTR', or `LINK' register
1017*67e74705SXin Li     case 'q': // `MQ' register
1018*67e74705SXin Li     case 'c': // `CTR' register
1019*67e74705SXin Li     case 'l': // `LINK' register
1020*67e74705SXin Li     case 'x': // `CR' register (condition register) number 0
1021*67e74705SXin Li     case 'y': // `CR' register (condition register)
1022*67e74705SXin Li     case 'z': // `XER[CA]' carry bit (part of the XER register)
1023*67e74705SXin Li       Info.setAllowsRegister();
1024*67e74705SXin Li       break;
1025*67e74705SXin Li     case 'I': // Signed 16-bit constant
1026*67e74705SXin Li     case 'J': // Unsigned 16-bit constant shifted left 16 bits
1027*67e74705SXin Li               //  (use `L' instead for SImode constants)
1028*67e74705SXin Li     case 'K': // Unsigned 16-bit constant
1029*67e74705SXin Li     case 'L': // Signed 16-bit constant shifted left 16 bits
1030*67e74705SXin Li     case 'M': // Constant larger than 31
1031*67e74705SXin Li     case 'N': // Exact power of 2
1032*67e74705SXin Li     case 'P': // Constant whose negation is a signed 16-bit constant
1033*67e74705SXin Li     case 'G': // Floating point constant that can be loaded into a
1034*67e74705SXin Li               // register with one instruction per word
1035*67e74705SXin Li     case 'H': // Integer/Floating point constant that can be loaded
1036*67e74705SXin Li               // into a register using three instructions
1037*67e74705SXin Li       break;
1038*67e74705SXin Li     case 'm': // Memory operand. Note that on PowerPC targets, m can
1039*67e74705SXin Li               // include addresses that update the base register. It
1040*67e74705SXin Li               // is therefore only safe to use `m' in an asm statement
1041*67e74705SXin Li               // if that asm statement accesses the operand exactly once.
1042*67e74705SXin Li               // The asm statement must also use `%U<opno>' as a
1043*67e74705SXin Li               // placeholder for the "update" flag in the corresponding
1044*67e74705SXin Li               // load or store instruction. For example:
1045*67e74705SXin Li               // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
1046*67e74705SXin Li               // is correct but:
1047*67e74705SXin Li               // asm ("st %1,%0" : "=m" (mem) : "r" (val));
1048*67e74705SXin Li               // is not. Use es rather than m if you don't want the base
1049*67e74705SXin Li               // register to be updated.
1050*67e74705SXin Li     case 'e':
1051*67e74705SXin Li       if (Name[1] != 's')
1052*67e74705SXin Li           return false;
1053*67e74705SXin Li               // es: A "stable" memory operand; that is, one which does not
1054*67e74705SXin Li               // include any automodification of the base register. Unlike
1055*67e74705SXin Li               // `m', this constraint can be used in asm statements that
1056*67e74705SXin Li               // might access the operand several times, or that might not
1057*67e74705SXin Li               // access it at all.
1058*67e74705SXin Li       Info.setAllowsMemory();
1059*67e74705SXin Li       Name++; // Skip over 'e'.
1060*67e74705SXin Li       break;
1061*67e74705SXin Li     case 'Q': // Memory operand that is an offset from a register (it is
1062*67e74705SXin Li               // usually better to use `m' or `es' in asm statements)
1063*67e74705SXin Li     case 'Z': // Memory operand that is an indexed or indirect from a
1064*67e74705SXin Li               // register (it is usually better to use `m' or `es' in
1065*67e74705SXin Li               // asm statements)
1066*67e74705SXin Li       Info.setAllowsMemory();
1067*67e74705SXin Li       Info.setAllowsRegister();
1068*67e74705SXin Li       break;
1069*67e74705SXin Li     case 'R': // AIX TOC entry
1070*67e74705SXin Li     case 'a': // Address operand that is an indexed or indirect from a
1071*67e74705SXin Li               // register (`p' is preferable for asm statements)
1072*67e74705SXin Li     case 'S': // Constant suitable as a 64-bit mask operand
1073*67e74705SXin Li     case 'T': // Constant suitable as a 32-bit mask operand
1074*67e74705SXin Li     case 'U': // System V Release 4 small data area reference
1075*67e74705SXin Li     case 't': // AND masks that can be performed by two rldic{l, r}
1076*67e74705SXin Li               // instructions
1077*67e74705SXin Li     case 'W': // Vector constant that does not require memory
1078*67e74705SXin Li     case 'j': // Vector constant that is all zeros.
1079*67e74705SXin Li       break;
1080*67e74705SXin Li     // End FIXME.
1081*67e74705SXin Li     }
1082*67e74705SXin Li     return true;
1083*67e74705SXin Li   }
convertConstraint(const char * & Constraint) const1084*67e74705SXin Li   std::string convertConstraint(const char *&Constraint) const override {
1085*67e74705SXin Li     std::string R;
1086*67e74705SXin Li     switch (*Constraint) {
1087*67e74705SXin Li     case 'e':
1088*67e74705SXin Li     case 'w':
1089*67e74705SXin Li       // Two-character constraint; add "^" hint for later parsing.
1090*67e74705SXin Li       R = std::string("^") + std::string(Constraint, 2);
1091*67e74705SXin Li       Constraint++;
1092*67e74705SXin Li       break;
1093*67e74705SXin Li     default:
1094*67e74705SXin Li       return TargetInfo::convertConstraint(Constraint);
1095*67e74705SXin Li     }
1096*67e74705SXin Li     return R;
1097*67e74705SXin Li   }
getClobbers() const1098*67e74705SXin Li   const char *getClobbers() const override {
1099*67e74705SXin Li     return "";
1100*67e74705SXin Li   }
getEHDataRegisterNumber(unsigned RegNo) const1101*67e74705SXin Li   int getEHDataRegisterNumber(unsigned RegNo) const override {
1102*67e74705SXin Li     if (RegNo == 0) return 3;
1103*67e74705SXin Li     if (RegNo == 1) return 4;
1104*67e74705SXin Li     return -1;
1105*67e74705SXin Li   }
1106*67e74705SXin Li 
hasSjLjLowering() const1107*67e74705SXin Li   bool hasSjLjLowering() const override {
1108*67e74705SXin Li     return true;
1109*67e74705SXin Li   }
1110*67e74705SXin Li 
useFloat128ManglingForLongDouble() const1111*67e74705SXin Li   bool useFloat128ManglingForLongDouble() const override {
1112*67e74705SXin Li     return LongDoubleWidth == 128 &&
1113*67e74705SXin Li            LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble &&
1114*67e74705SXin Li            getTriple().isOSBinFormatELF();
1115*67e74705SXin Li   }
1116*67e74705SXin Li };
1117*67e74705SXin Li 
1118*67e74705SXin Li const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
1119*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS) \
1120*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
1121*67e74705SXin Li #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1122*67e74705SXin Li   { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
1123*67e74705SXin Li #include "clang/Basic/BuiltinsPPC.def"
1124*67e74705SXin Li };
1125*67e74705SXin Li 
1126*67e74705SXin Li /// handleTargetFeatures - Perform initialization based on the user
1127*67e74705SXin Li /// configured set of features.
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)1128*67e74705SXin Li bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
1129*67e74705SXin Li                                          DiagnosticsEngine &Diags) {
1130*67e74705SXin Li   for (const auto &Feature : Features) {
1131*67e74705SXin Li     if (Feature == "+vsx") {
1132*67e74705SXin Li       HasVSX = true;
1133*67e74705SXin Li     } else if (Feature == "+bpermd") {
1134*67e74705SXin Li       HasBPERMD = true;
1135*67e74705SXin Li     } else if (Feature == "+extdiv") {
1136*67e74705SXin Li       HasExtDiv = true;
1137*67e74705SXin Li     } else if (Feature == "+power8-vector") {
1138*67e74705SXin Li       HasP8Vector = true;
1139*67e74705SXin Li     } else if (Feature == "+crypto") {
1140*67e74705SXin Li       HasP8Crypto = true;
1141*67e74705SXin Li     } else if (Feature == "+direct-move") {
1142*67e74705SXin Li       HasDirectMove = true;
1143*67e74705SXin Li     } else if (Feature == "+qpx") {
1144*67e74705SXin Li       HasQPX = true;
1145*67e74705SXin Li     } else if (Feature == "+htm") {
1146*67e74705SXin Li       HasHTM = true;
1147*67e74705SXin Li     } else if (Feature == "+float128") {
1148*67e74705SXin Li       HasFloat128 = true;
1149*67e74705SXin Li     }
1150*67e74705SXin Li     // TODO: Finish this list and add an assert that we've handled them
1151*67e74705SXin Li     // all.
1152*67e74705SXin Li   }
1153*67e74705SXin Li 
1154*67e74705SXin Li   return true;
1155*67e74705SXin Li }
1156*67e74705SXin Li 
1157*67e74705SXin Li /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
1158*67e74705SXin Li /// #defines that are not tied to a specific subtarget.
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1159*67e74705SXin Li void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
1160*67e74705SXin Li                                      MacroBuilder &Builder) const {
1161*67e74705SXin Li   // Target identification.
1162*67e74705SXin Li   Builder.defineMacro("__ppc__");
1163*67e74705SXin Li   Builder.defineMacro("__PPC__");
1164*67e74705SXin Li   Builder.defineMacro("_ARCH_PPC");
1165*67e74705SXin Li   Builder.defineMacro("__powerpc__");
1166*67e74705SXin Li   Builder.defineMacro("__POWERPC__");
1167*67e74705SXin Li   if (PointerWidth == 64) {
1168*67e74705SXin Li     Builder.defineMacro("_ARCH_PPC64");
1169*67e74705SXin Li     Builder.defineMacro("__powerpc64__");
1170*67e74705SXin Li     Builder.defineMacro("__ppc64__");
1171*67e74705SXin Li     Builder.defineMacro("__PPC64__");
1172*67e74705SXin Li   }
1173*67e74705SXin Li 
1174*67e74705SXin Li   // Target properties.
1175*67e74705SXin Li   if (getTriple().getArch() == llvm::Triple::ppc64le) {
1176*67e74705SXin Li     Builder.defineMacro("_LITTLE_ENDIAN");
1177*67e74705SXin Li   } else {
1178*67e74705SXin Li     if (getTriple().getOS() != llvm::Triple::NetBSD &&
1179*67e74705SXin Li         getTriple().getOS() != llvm::Triple::OpenBSD)
1180*67e74705SXin Li       Builder.defineMacro("_BIG_ENDIAN");
1181*67e74705SXin Li   }
1182*67e74705SXin Li 
1183*67e74705SXin Li   // ABI options.
1184*67e74705SXin Li   if (ABI == "elfv1" || ABI == "elfv1-qpx")
1185*67e74705SXin Li     Builder.defineMacro("_CALL_ELF", "1");
1186*67e74705SXin Li   if (ABI == "elfv2")
1187*67e74705SXin Li     Builder.defineMacro("_CALL_ELF", "2");
1188*67e74705SXin Li 
1189*67e74705SXin Li   // Subtarget options.
1190*67e74705SXin Li   Builder.defineMacro("__NATURAL_ALIGNMENT__");
1191*67e74705SXin Li   Builder.defineMacro("__REGISTER_PREFIX__", "");
1192*67e74705SXin Li 
1193*67e74705SXin Li   // FIXME: Should be controlled by command line option.
1194*67e74705SXin Li   if (LongDoubleWidth == 128)
1195*67e74705SXin Li     Builder.defineMacro("__LONG_DOUBLE_128__");
1196*67e74705SXin Li 
1197*67e74705SXin Li   if (Opts.AltiVec) {
1198*67e74705SXin Li     Builder.defineMacro("__VEC__", "10206");
1199*67e74705SXin Li     Builder.defineMacro("__ALTIVEC__");
1200*67e74705SXin Li   }
1201*67e74705SXin Li 
1202*67e74705SXin Li   // CPU identification.
1203*67e74705SXin Li   ArchDefineTypes defs = (ArchDefineTypes)llvm::StringSwitch<int>(CPU)
1204*67e74705SXin Li     .Case("440",   ArchDefineName)
1205*67e74705SXin Li     .Case("450",   ArchDefineName | ArchDefine440)
1206*67e74705SXin Li     .Case("601",   ArchDefineName)
1207*67e74705SXin Li     .Case("602",   ArchDefineName | ArchDefinePpcgr)
1208*67e74705SXin Li     .Case("603",   ArchDefineName | ArchDefinePpcgr)
1209*67e74705SXin Li     .Case("603e",  ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
1210*67e74705SXin Li     .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
1211*67e74705SXin Li     .Case("604",   ArchDefineName | ArchDefinePpcgr)
1212*67e74705SXin Li     .Case("604e",  ArchDefineName | ArchDefine604 | ArchDefinePpcgr)
1213*67e74705SXin Li     .Case("620",   ArchDefineName | ArchDefinePpcgr)
1214*67e74705SXin Li     .Case("630",   ArchDefineName | ArchDefinePpcgr)
1215*67e74705SXin Li     .Case("7400",  ArchDefineName | ArchDefinePpcgr)
1216*67e74705SXin Li     .Case("7450",  ArchDefineName | ArchDefinePpcgr)
1217*67e74705SXin Li     .Case("750",   ArchDefineName | ArchDefinePpcgr)
1218*67e74705SXin Li     .Case("970",   ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
1219*67e74705SXin Li                      | ArchDefinePpcsq)
1220*67e74705SXin Li     .Case("a2",    ArchDefineA2)
1221*67e74705SXin Li     .Case("a2q",   ArchDefineName | ArchDefineA2 | ArchDefineA2q)
1222*67e74705SXin Li     .Case("pwr3",  ArchDefinePpcgr)
1223*67e74705SXin Li     .Case("pwr4",  ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq)
1224*67e74705SXin Li     .Case("pwr5",  ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
1225*67e74705SXin Li                      | ArchDefinePpcsq)
1226*67e74705SXin Li     .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4
1227*67e74705SXin Li                      | ArchDefinePpcgr | ArchDefinePpcsq)
1228*67e74705SXin Li     .Case("pwr6",  ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5
1229*67e74705SXin Li                      | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
1230*67e74705SXin Li     .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x
1231*67e74705SXin Li                      | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
1232*67e74705SXin Li                      | ArchDefinePpcsq)
1233*67e74705SXin Li     .Case("pwr7",  ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6
1234*67e74705SXin Li                      | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
1235*67e74705SXin Li                      | ArchDefinePpcgr | ArchDefinePpcsq)
1236*67e74705SXin Li     .Case("pwr8",  ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x
1237*67e74705SXin Li                      | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
1238*67e74705SXin Li                      | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
1239*67e74705SXin Li     .Case("pwr9",  ArchDefineName | ArchDefinePwr8 | ArchDefinePwr7
1240*67e74705SXin Li                      | ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x
1241*67e74705SXin Li                      | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
1242*67e74705SXin Li                      | ArchDefinePpcsq)
1243*67e74705SXin Li     .Case("power3",  ArchDefinePpcgr)
1244*67e74705SXin Li     .Case("power4",  ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
1245*67e74705SXin Li     .Case("power5",  ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
1246*67e74705SXin Li                        | ArchDefinePpcsq)
1247*67e74705SXin Li     .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
1248*67e74705SXin Li                        | ArchDefinePpcgr | ArchDefinePpcsq)
1249*67e74705SXin Li     .Case("power6",  ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
1250*67e74705SXin Li                        | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
1251*67e74705SXin Li     .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x
1252*67e74705SXin Li                        | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
1253*67e74705SXin Li                        | ArchDefinePpcsq)
1254*67e74705SXin Li     .Case("power7",  ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6
1255*67e74705SXin Li                        | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
1256*67e74705SXin Li                        | ArchDefinePpcgr | ArchDefinePpcsq)
1257*67e74705SXin Li     .Case("power8",  ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x
1258*67e74705SXin Li                        | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
1259*67e74705SXin Li                        | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
1260*67e74705SXin Li     .Case("power9",  ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7
1261*67e74705SXin Li                        | ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x
1262*67e74705SXin Li                        | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
1263*67e74705SXin Li                        | ArchDefinePpcsq)
1264*67e74705SXin Li     .Default(ArchDefineNone);
1265*67e74705SXin Li 
1266*67e74705SXin Li   if (defs & ArchDefineName)
1267*67e74705SXin Li     Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
1268*67e74705SXin Li   if (defs & ArchDefinePpcgr)
1269*67e74705SXin Li     Builder.defineMacro("_ARCH_PPCGR");
1270*67e74705SXin Li   if (defs & ArchDefinePpcsq)
1271*67e74705SXin Li     Builder.defineMacro("_ARCH_PPCSQ");
1272*67e74705SXin Li   if (defs & ArchDefine440)
1273*67e74705SXin Li     Builder.defineMacro("_ARCH_440");
1274*67e74705SXin Li   if (defs & ArchDefine603)
1275*67e74705SXin Li     Builder.defineMacro("_ARCH_603");
1276*67e74705SXin Li   if (defs & ArchDefine604)
1277*67e74705SXin Li     Builder.defineMacro("_ARCH_604");
1278*67e74705SXin Li   if (defs & ArchDefinePwr4)
1279*67e74705SXin Li     Builder.defineMacro("_ARCH_PWR4");
1280*67e74705SXin Li   if (defs & ArchDefinePwr5)
1281*67e74705SXin Li     Builder.defineMacro("_ARCH_PWR5");
1282*67e74705SXin Li   if (defs & ArchDefinePwr5x)
1283*67e74705SXin Li     Builder.defineMacro("_ARCH_PWR5X");
1284*67e74705SXin Li   if (defs & ArchDefinePwr6)
1285*67e74705SXin Li     Builder.defineMacro("_ARCH_PWR6");
1286*67e74705SXin Li   if (defs & ArchDefinePwr6x)
1287*67e74705SXin Li     Builder.defineMacro("_ARCH_PWR6X");
1288*67e74705SXin Li   if (defs & ArchDefinePwr7)
1289*67e74705SXin Li     Builder.defineMacro("_ARCH_PWR7");
1290*67e74705SXin Li   if (defs & ArchDefinePwr8)
1291*67e74705SXin Li     Builder.defineMacro("_ARCH_PWR8");
1292*67e74705SXin Li   if (defs & ArchDefinePwr9)
1293*67e74705SXin Li     Builder.defineMacro("_ARCH_PWR9");
1294*67e74705SXin Li   if (defs & ArchDefineA2)
1295*67e74705SXin Li     Builder.defineMacro("_ARCH_A2");
1296*67e74705SXin Li   if (defs & ArchDefineA2q) {
1297*67e74705SXin Li     Builder.defineMacro("_ARCH_A2Q");
1298*67e74705SXin Li     Builder.defineMacro("_ARCH_QP");
1299*67e74705SXin Li   }
1300*67e74705SXin Li 
1301*67e74705SXin Li   if (getTriple().getVendor() == llvm::Triple::BGQ) {
1302*67e74705SXin Li     Builder.defineMacro("__bg__");
1303*67e74705SXin Li     Builder.defineMacro("__THW_BLUEGENE__");
1304*67e74705SXin Li     Builder.defineMacro("__bgq__");
1305*67e74705SXin Li     Builder.defineMacro("__TOS_BGQ__");
1306*67e74705SXin Li   }
1307*67e74705SXin Li 
1308*67e74705SXin Li   if (HasVSX)
1309*67e74705SXin Li     Builder.defineMacro("__VSX__");
1310*67e74705SXin Li   if (HasP8Vector)
1311*67e74705SXin Li     Builder.defineMacro("__POWER8_VECTOR__");
1312*67e74705SXin Li   if (HasP8Crypto)
1313*67e74705SXin Li     Builder.defineMacro("__CRYPTO__");
1314*67e74705SXin Li   if (HasHTM)
1315*67e74705SXin Li     Builder.defineMacro("__HTM__");
1316*67e74705SXin Li   if (HasFloat128)
1317*67e74705SXin Li     Builder.defineMacro("__FLOAT128__");
1318*67e74705SXin Li 
1319*67e74705SXin Li   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
1320*67e74705SXin Li   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
1321*67e74705SXin Li   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
1322*67e74705SXin Li   if (PointerWidth == 64)
1323*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
1324*67e74705SXin Li 
1325*67e74705SXin Li   // FIXME: The following are not yet generated here by Clang, but are
1326*67e74705SXin Li   //        generated by GCC:
1327*67e74705SXin Li   //
1328*67e74705SXin Li   //   _SOFT_FLOAT_
1329*67e74705SXin Li   //   __RECIP_PRECISION__
1330*67e74705SXin Li   //   __APPLE_ALTIVEC__
1331*67e74705SXin Li   //   __RECIP__
1332*67e74705SXin Li   //   __RECIPF__
1333*67e74705SXin Li   //   __RSQRTE__
1334*67e74705SXin Li   //   __RSQRTEF__
1335*67e74705SXin Li   //   _SOFT_DOUBLE_
1336*67e74705SXin Li   //   __NO_LWSYNC__
1337*67e74705SXin Li   //   __HAVE_BSWAP__
1338*67e74705SXin Li   //   __LONGDOUBLE128
1339*67e74705SXin Li   //   __CMODEL_MEDIUM__
1340*67e74705SXin Li   //   __CMODEL_LARGE__
1341*67e74705SXin Li   //   _CALL_SYSV
1342*67e74705SXin Li   //   _CALL_DARWIN
1343*67e74705SXin Li   //   __NO_FPRS__
1344*67e74705SXin Li }
1345*67e74705SXin Li 
1346*67e74705SXin Li // Handle explicit options being passed to the compiler here: if we've
1347*67e74705SXin Li // explicitly turned off vsx and turned on power8-vector or direct-move then
1348*67e74705SXin Li // go ahead and error since the customer has expressed a somewhat incompatible
1349*67e74705SXin Li // set of options.
ppcUserFeaturesCheck(DiagnosticsEngine & Diags,const std::vector<std::string> & FeaturesVec)1350*67e74705SXin Li static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
1351*67e74705SXin Li                                  const std::vector<std::string> &FeaturesVec) {
1352*67e74705SXin Li 
1353*67e74705SXin Li   if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "-vsx") !=
1354*67e74705SXin Li       FeaturesVec.end()) {
1355*67e74705SXin Li     if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power8-vector") !=
1356*67e74705SXin Li         FeaturesVec.end()) {
1357*67e74705SXin Li       Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower8-vector"
1358*67e74705SXin Li                                                      << "-mno-vsx";
1359*67e74705SXin Li       return false;
1360*67e74705SXin Li     }
1361*67e74705SXin Li 
1362*67e74705SXin Li     if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+direct-move") !=
1363*67e74705SXin Li         FeaturesVec.end()) {
1364*67e74705SXin Li       Diags.Report(diag::err_opt_not_valid_with_opt) << "-mdirect-move"
1365*67e74705SXin Li                                                      << "-mno-vsx";
1366*67e74705SXin Li       return false;
1367*67e74705SXin Li     }
1368*67e74705SXin Li 
1369*67e74705SXin Li     if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") !=
1370*67e74705SXin Li         FeaturesVec.end()) {
1371*67e74705SXin Li       Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128"
1372*67e74705SXin Li                                                      << "-mno-vsx";
1373*67e74705SXin Li       return false;
1374*67e74705SXin Li     }
1375*67e74705SXin Li   }
1376*67e74705SXin Li 
1377*67e74705SXin Li   return true;
1378*67e74705SXin Li }
1379*67e74705SXin Li 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const1380*67e74705SXin Li bool PPCTargetInfo::initFeatureMap(
1381*67e74705SXin Li     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
1382*67e74705SXin Li     const std::vector<std::string> &FeaturesVec) const {
1383*67e74705SXin Li   Features["altivec"] = llvm::StringSwitch<bool>(CPU)
1384*67e74705SXin Li     .Case("7400", true)
1385*67e74705SXin Li     .Case("g4", true)
1386*67e74705SXin Li     .Case("7450", true)
1387*67e74705SXin Li     .Case("g4+", true)
1388*67e74705SXin Li     .Case("970", true)
1389*67e74705SXin Li     .Case("g5", true)
1390*67e74705SXin Li     .Case("pwr6", true)
1391*67e74705SXin Li     .Case("pwr7", true)
1392*67e74705SXin Li     .Case("pwr8", true)
1393*67e74705SXin Li     .Case("pwr9", true)
1394*67e74705SXin Li     .Case("ppc64", true)
1395*67e74705SXin Li     .Case("ppc64le", true)
1396*67e74705SXin Li     .Default(false);
1397*67e74705SXin Li 
1398*67e74705SXin Li   Features["qpx"] = (CPU == "a2q");
1399*67e74705SXin Li   Features["crypto"] = llvm::StringSwitch<bool>(CPU)
1400*67e74705SXin Li     .Case("ppc64le", true)
1401*67e74705SXin Li     .Case("pwr9", true)
1402*67e74705SXin Li     .Case("pwr8", true)
1403*67e74705SXin Li     .Default(false);
1404*67e74705SXin Li   Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)
1405*67e74705SXin Li     .Case("ppc64le", true)
1406*67e74705SXin Li     .Case("pwr9", true)
1407*67e74705SXin Li     .Case("pwr8", true)
1408*67e74705SXin Li     .Default(false);
1409*67e74705SXin Li   Features["bpermd"] = llvm::StringSwitch<bool>(CPU)
1410*67e74705SXin Li     .Case("ppc64le", true)
1411*67e74705SXin Li     .Case("pwr9", true)
1412*67e74705SXin Li     .Case("pwr8", true)
1413*67e74705SXin Li     .Case("pwr7", true)
1414*67e74705SXin Li     .Default(false);
1415*67e74705SXin Li   Features["extdiv"] = llvm::StringSwitch<bool>(CPU)
1416*67e74705SXin Li     .Case("ppc64le", true)
1417*67e74705SXin Li     .Case("pwr9", true)
1418*67e74705SXin Li     .Case("pwr8", true)
1419*67e74705SXin Li     .Case("pwr7", true)
1420*67e74705SXin Li     .Default(false);
1421*67e74705SXin Li   Features["direct-move"] = llvm::StringSwitch<bool>(CPU)
1422*67e74705SXin Li     .Case("ppc64le", true)
1423*67e74705SXin Li     .Case("pwr9", true)
1424*67e74705SXin Li     .Case("pwr8", true)
1425*67e74705SXin Li     .Default(false);
1426*67e74705SXin Li   Features["vsx"] = llvm::StringSwitch<bool>(CPU)
1427*67e74705SXin Li     .Case("ppc64le", true)
1428*67e74705SXin Li     .Case("pwr9", true)
1429*67e74705SXin Li     .Case("pwr8", true)
1430*67e74705SXin Li     .Case("pwr7", true)
1431*67e74705SXin Li     .Default(false);
1432*67e74705SXin Li 
1433*67e74705SXin Li   if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
1434*67e74705SXin Li     return false;
1435*67e74705SXin Li 
1436*67e74705SXin Li   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
1437*67e74705SXin Li }
1438*67e74705SXin Li 
hasFeature(StringRef Feature) const1439*67e74705SXin Li bool PPCTargetInfo::hasFeature(StringRef Feature) const {
1440*67e74705SXin Li   return llvm::StringSwitch<bool>(Feature)
1441*67e74705SXin Li     .Case("powerpc", true)
1442*67e74705SXin Li     .Case("vsx", HasVSX)
1443*67e74705SXin Li     .Case("power8-vector", HasP8Vector)
1444*67e74705SXin Li     .Case("crypto", HasP8Crypto)
1445*67e74705SXin Li     .Case("direct-move", HasDirectMove)
1446*67e74705SXin Li     .Case("qpx", HasQPX)
1447*67e74705SXin Li     .Case("htm", HasHTM)
1448*67e74705SXin Li     .Case("bpermd", HasBPERMD)
1449*67e74705SXin Li     .Case("extdiv", HasExtDiv)
1450*67e74705SXin Li     .Case("float128", HasFloat128)
1451*67e74705SXin Li     .Default(false);
1452*67e74705SXin Li }
1453*67e74705SXin Li 
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const1454*67e74705SXin Li void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
1455*67e74705SXin Li                                       StringRef Name, bool Enabled) const {
1456*67e74705SXin Li   // If we're enabling direct-move or power8-vector go ahead and enable vsx
1457*67e74705SXin Li   // as well. Do the inverse if we're disabling vsx. We'll diagnose any user
1458*67e74705SXin Li   // incompatible options.
1459*67e74705SXin Li   if (Enabled) {
1460*67e74705SXin Li     if (Name == "direct-move") {
1461*67e74705SXin Li       Features[Name] = Features["vsx"] = true;
1462*67e74705SXin Li     } else if (Name == "power8-vector") {
1463*67e74705SXin Li       Features[Name] = Features["vsx"] = true;
1464*67e74705SXin Li     } else if (Name == "float128") {
1465*67e74705SXin Li       Features[Name] = Features["vsx"] = true;
1466*67e74705SXin Li     } else {
1467*67e74705SXin Li       Features[Name] = true;
1468*67e74705SXin Li     }
1469*67e74705SXin Li   } else {
1470*67e74705SXin Li     if (Name == "vsx") {
1471*67e74705SXin Li       Features[Name] = Features["direct-move"] = Features["power8-vector"] =
1472*67e74705SXin Li           Features["float128"] = false;
1473*67e74705SXin Li     } else {
1474*67e74705SXin Li       Features[Name] = false;
1475*67e74705SXin Li     }
1476*67e74705SXin Li   }
1477*67e74705SXin Li }
1478*67e74705SXin Li 
1479*67e74705SXin Li const char * const PPCTargetInfo::GCCRegNames[] = {
1480*67e74705SXin Li   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1481*67e74705SXin Li   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1482*67e74705SXin Li   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1483*67e74705SXin Li   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
1484*67e74705SXin Li   "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1485*67e74705SXin Li   "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1486*67e74705SXin Li   "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1487*67e74705SXin Li   "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1488*67e74705SXin Li   "mq", "lr", "ctr", "ap",
1489*67e74705SXin Li   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
1490*67e74705SXin Li   "xer",
1491*67e74705SXin Li   "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
1492*67e74705SXin Li   "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
1493*67e74705SXin Li   "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
1494*67e74705SXin Li   "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
1495*67e74705SXin Li   "vrsave", "vscr",
1496*67e74705SXin Li   "spe_acc", "spefscr",
1497*67e74705SXin Li   "sfp"
1498*67e74705SXin Li };
1499*67e74705SXin Li 
getGCCRegNames() const1500*67e74705SXin Li ArrayRef<const char*> PPCTargetInfo::getGCCRegNames() const {
1501*67e74705SXin Li   return llvm::makeArrayRef(GCCRegNames);
1502*67e74705SXin Li }
1503*67e74705SXin Li 
1504*67e74705SXin Li const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
1505*67e74705SXin Li   // While some of these aliases do map to different registers
1506*67e74705SXin Li   // they still share the same register name.
1507*67e74705SXin Li   { { "0" }, "r0" },
1508*67e74705SXin Li   { { "1"}, "r1" },
1509*67e74705SXin Li   { { "2" }, "r2" },
1510*67e74705SXin Li   { { "3" }, "r3" },
1511*67e74705SXin Li   { { "4" }, "r4" },
1512*67e74705SXin Li   { { "5" }, "r5" },
1513*67e74705SXin Li   { { "6" }, "r6" },
1514*67e74705SXin Li   { { "7" }, "r7" },
1515*67e74705SXin Li   { { "8" }, "r8" },
1516*67e74705SXin Li   { { "9" }, "r9" },
1517*67e74705SXin Li   { { "10" }, "r10" },
1518*67e74705SXin Li   { { "11" }, "r11" },
1519*67e74705SXin Li   { { "12" }, "r12" },
1520*67e74705SXin Li   { { "13" }, "r13" },
1521*67e74705SXin Li   { { "14" }, "r14" },
1522*67e74705SXin Li   { { "15" }, "r15" },
1523*67e74705SXin Li   { { "16" }, "r16" },
1524*67e74705SXin Li   { { "17" }, "r17" },
1525*67e74705SXin Li   { { "18" }, "r18" },
1526*67e74705SXin Li   { { "19" }, "r19" },
1527*67e74705SXin Li   { { "20" }, "r20" },
1528*67e74705SXin Li   { { "21" }, "r21" },
1529*67e74705SXin Li   { { "22" }, "r22" },
1530*67e74705SXin Li   { { "23" }, "r23" },
1531*67e74705SXin Li   { { "24" }, "r24" },
1532*67e74705SXin Li   { { "25" }, "r25" },
1533*67e74705SXin Li   { { "26" }, "r26" },
1534*67e74705SXin Li   { { "27" }, "r27" },
1535*67e74705SXin Li   { { "28" }, "r28" },
1536*67e74705SXin Li   { { "29" }, "r29" },
1537*67e74705SXin Li   { { "30" }, "r30" },
1538*67e74705SXin Li   { { "31" }, "r31" },
1539*67e74705SXin Li   { { "fr0" }, "f0" },
1540*67e74705SXin Li   { { "fr1" }, "f1" },
1541*67e74705SXin Li   { { "fr2" }, "f2" },
1542*67e74705SXin Li   { { "fr3" }, "f3" },
1543*67e74705SXin Li   { { "fr4" }, "f4" },
1544*67e74705SXin Li   { { "fr5" }, "f5" },
1545*67e74705SXin Li   { { "fr6" }, "f6" },
1546*67e74705SXin Li   { { "fr7" }, "f7" },
1547*67e74705SXin Li   { { "fr8" }, "f8" },
1548*67e74705SXin Li   { { "fr9" }, "f9" },
1549*67e74705SXin Li   { { "fr10" }, "f10" },
1550*67e74705SXin Li   { { "fr11" }, "f11" },
1551*67e74705SXin Li   { { "fr12" }, "f12" },
1552*67e74705SXin Li   { { "fr13" }, "f13" },
1553*67e74705SXin Li   { { "fr14" }, "f14" },
1554*67e74705SXin Li   { { "fr15" }, "f15" },
1555*67e74705SXin Li   { { "fr16" }, "f16" },
1556*67e74705SXin Li   { { "fr17" }, "f17" },
1557*67e74705SXin Li   { { "fr18" }, "f18" },
1558*67e74705SXin Li   { { "fr19" }, "f19" },
1559*67e74705SXin Li   { { "fr20" }, "f20" },
1560*67e74705SXin Li   { { "fr21" }, "f21" },
1561*67e74705SXin Li   { { "fr22" }, "f22" },
1562*67e74705SXin Li   { { "fr23" }, "f23" },
1563*67e74705SXin Li   { { "fr24" }, "f24" },
1564*67e74705SXin Li   { { "fr25" }, "f25" },
1565*67e74705SXin Li   { { "fr26" }, "f26" },
1566*67e74705SXin Li   { { "fr27" }, "f27" },
1567*67e74705SXin Li   { { "fr28" }, "f28" },
1568*67e74705SXin Li   { { "fr29" }, "f29" },
1569*67e74705SXin Li   { { "fr30" }, "f30" },
1570*67e74705SXin Li   { { "fr31" }, "f31" },
1571*67e74705SXin Li   { { "cc" }, "cr0" },
1572*67e74705SXin Li };
1573*67e74705SXin Li 
getGCCRegAliases() const1574*67e74705SXin Li ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
1575*67e74705SXin Li   return llvm::makeArrayRef(GCCRegAliases);
1576*67e74705SXin Li }
1577*67e74705SXin Li 
1578*67e74705SXin Li class PPC32TargetInfo : public PPCTargetInfo {
1579*67e74705SXin Li public:
PPC32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1580*67e74705SXin Li   PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1581*67e74705SXin Li       : PPCTargetInfo(Triple, Opts) {
1582*67e74705SXin Li     resetDataLayout("E-m:e-p:32:32-i64:64-n32");
1583*67e74705SXin Li 
1584*67e74705SXin Li     switch (getTriple().getOS()) {
1585*67e74705SXin Li     case llvm::Triple::Linux:
1586*67e74705SXin Li     case llvm::Triple::FreeBSD:
1587*67e74705SXin Li     case llvm::Triple::NetBSD:
1588*67e74705SXin Li       SizeType = UnsignedInt;
1589*67e74705SXin Li       PtrDiffType = SignedInt;
1590*67e74705SXin Li       IntPtrType = SignedInt;
1591*67e74705SXin Li       break;
1592*67e74705SXin Li     default:
1593*67e74705SXin Li       break;
1594*67e74705SXin Li     }
1595*67e74705SXin Li 
1596*67e74705SXin Li     if (getTriple().getOS() == llvm::Triple::FreeBSD) {
1597*67e74705SXin Li       LongDoubleWidth = LongDoubleAlign = 64;
1598*67e74705SXin Li       LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1599*67e74705SXin Li     }
1600*67e74705SXin Li 
1601*67e74705SXin Li     // PPC32 supports atomics up to 4 bytes.
1602*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
1603*67e74705SXin Li   }
1604*67e74705SXin Li 
getBuiltinVaListKind() const1605*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
1606*67e74705SXin Li     // This is the ELF definition, and is overridden by the Darwin sub-target
1607*67e74705SXin Li     return TargetInfo::PowerABIBuiltinVaList;
1608*67e74705SXin Li   }
1609*67e74705SXin Li };
1610*67e74705SXin Li 
1611*67e74705SXin Li // Note: ABI differences may eventually require us to have a separate
1612*67e74705SXin Li // TargetInfo for little endian.
1613*67e74705SXin Li class PPC64TargetInfo : public PPCTargetInfo {
1614*67e74705SXin Li public:
PPC64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1615*67e74705SXin Li   PPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1616*67e74705SXin Li       : PPCTargetInfo(Triple, Opts) {
1617*67e74705SXin Li     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
1618*67e74705SXin Li     IntMaxType = SignedLong;
1619*67e74705SXin Li     Int64Type = SignedLong;
1620*67e74705SXin Li 
1621*67e74705SXin Li     if ((Triple.getArch() == llvm::Triple::ppc64le)) {
1622*67e74705SXin Li       resetDataLayout("e-m:e-i64:64-n32:64");
1623*67e74705SXin Li       ABI = "elfv2";
1624*67e74705SXin Li     } else {
1625*67e74705SXin Li       resetDataLayout("E-m:e-i64:64-n32:64");
1626*67e74705SXin Li       ABI = "elfv1";
1627*67e74705SXin Li     }
1628*67e74705SXin Li 
1629*67e74705SXin Li     switch (getTriple().getOS()) {
1630*67e74705SXin Li     case llvm::Triple::FreeBSD:
1631*67e74705SXin Li       LongDoubleWidth = LongDoubleAlign = 64;
1632*67e74705SXin Li       LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1633*67e74705SXin Li       break;
1634*67e74705SXin Li     case llvm::Triple::NetBSD:
1635*67e74705SXin Li       IntMaxType = SignedLongLong;
1636*67e74705SXin Li       Int64Type = SignedLongLong;
1637*67e74705SXin Li       break;
1638*67e74705SXin Li     default:
1639*67e74705SXin Li       break;
1640*67e74705SXin Li     }
1641*67e74705SXin Li 
1642*67e74705SXin Li     // PPC64 supports atomics up to 8 bytes.
1643*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
1644*67e74705SXin Li   }
getBuiltinVaListKind() const1645*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
1646*67e74705SXin Li     return TargetInfo::CharPtrBuiltinVaList;
1647*67e74705SXin Li   }
1648*67e74705SXin Li   // PPC64 Linux-specific ABI options.
setABI(const std::string & Name)1649*67e74705SXin Li   bool setABI(const std::string &Name) override {
1650*67e74705SXin Li     if (Name == "elfv1" || Name == "elfv1-qpx" || Name == "elfv2") {
1651*67e74705SXin Li       ABI = Name;
1652*67e74705SXin Li       return true;
1653*67e74705SXin Li     }
1654*67e74705SXin Li     return false;
1655*67e74705SXin Li   }
1656*67e74705SXin Li };
1657*67e74705SXin Li 
1658*67e74705SXin Li class DarwinPPC32TargetInfo : public DarwinTargetInfo<PPC32TargetInfo> {
1659*67e74705SXin Li public:
DarwinPPC32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1660*67e74705SXin Li   DarwinPPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1661*67e74705SXin Li       : DarwinTargetInfo<PPC32TargetInfo>(Triple, Opts) {
1662*67e74705SXin Li     HasAlignMac68kSupport = true;
1663*67e74705SXin Li     BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
1664*67e74705SXin Li     PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726
1665*67e74705SXin Li     LongLongAlign = 32;
1666*67e74705SXin Li     SuitableAlign = 128;
1667*67e74705SXin Li     resetDataLayout("E-m:o-p:32:32-f64:32:64-n32");
1668*67e74705SXin Li   }
getBuiltinVaListKind() const1669*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
1670*67e74705SXin Li     return TargetInfo::CharPtrBuiltinVaList;
1671*67e74705SXin Li   }
1672*67e74705SXin Li };
1673*67e74705SXin Li 
1674*67e74705SXin Li class DarwinPPC64TargetInfo : public DarwinTargetInfo<PPC64TargetInfo> {
1675*67e74705SXin Li public:
DarwinPPC64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1676*67e74705SXin Li   DarwinPPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1677*67e74705SXin Li       : DarwinTargetInfo<PPC64TargetInfo>(Triple, Opts) {
1678*67e74705SXin Li     HasAlignMac68kSupport = true;
1679*67e74705SXin Li     SuitableAlign = 128;
1680*67e74705SXin Li     resetDataLayout("E-m:o-i64:64-n32:64");
1681*67e74705SXin Li   }
1682*67e74705SXin Li };
1683*67e74705SXin Li 
1684*67e74705SXin Li static const unsigned NVPTXAddrSpaceMap[] = {
1685*67e74705SXin Li     1, // opencl_global
1686*67e74705SXin Li     3, // opencl_local
1687*67e74705SXin Li     4, // opencl_constant
1688*67e74705SXin Li     // FIXME: generic has to be added to the target
1689*67e74705SXin Li     0, // opencl_generic
1690*67e74705SXin Li     1, // cuda_device
1691*67e74705SXin Li     4, // cuda_constant
1692*67e74705SXin Li     3, // cuda_shared
1693*67e74705SXin Li };
1694*67e74705SXin Li 
1695*67e74705SXin Li class NVPTXTargetInfo : public TargetInfo {
1696*67e74705SXin Li   static const char *const GCCRegNames[];
1697*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
1698*67e74705SXin Li   CudaArch GPU;
1699*67e74705SXin Li 
1700*67e74705SXin Li public:
NVPTXTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1701*67e74705SXin Li   NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1702*67e74705SXin Li       : TargetInfo(Triple) {
1703*67e74705SXin Li     BigEndian = false;
1704*67e74705SXin Li     TLSSupported = false;
1705*67e74705SXin Li     LongWidth = LongAlign = 64;
1706*67e74705SXin Li     AddrSpaceMap = &NVPTXAddrSpaceMap;
1707*67e74705SXin Li     UseAddrSpaceMapMangling = true;
1708*67e74705SXin Li     // Define available target features
1709*67e74705SXin Li     // These must be defined in sorted order!
1710*67e74705SXin Li     NoAsmVariants = true;
1711*67e74705SXin Li     GPU = CudaArch::SM_20;
1712*67e74705SXin Li 
1713*67e74705SXin Li     // If possible, get a TargetInfo for our host triple, so we can match its
1714*67e74705SXin Li     // types.
1715*67e74705SXin Li     llvm::Triple HostTriple(Opts.HostTriple);
1716*67e74705SXin Li     if (HostTriple.isNVPTX())
1717*67e74705SXin Li       return;
1718*67e74705SXin Li     std::unique_ptr<TargetInfo> HostTarget(
1719*67e74705SXin Li         AllocateTarget(llvm::Triple(Opts.HostTriple), Opts));
1720*67e74705SXin Li     if (!HostTarget) {
1721*67e74705SXin Li       return;
1722*67e74705SXin Li     }
1723*67e74705SXin Li 
1724*67e74705SXin Li     PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0);
1725*67e74705SXin Li     PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0);
1726*67e74705SXin Li     BoolWidth = HostTarget->getBoolWidth();
1727*67e74705SXin Li     BoolAlign = HostTarget->getBoolAlign();
1728*67e74705SXin Li     IntWidth = HostTarget->getIntWidth();
1729*67e74705SXin Li     IntAlign = HostTarget->getIntAlign();
1730*67e74705SXin Li     HalfWidth = HostTarget->getHalfWidth();
1731*67e74705SXin Li     HalfAlign = HostTarget->getHalfAlign();
1732*67e74705SXin Li     FloatWidth = HostTarget->getFloatWidth();
1733*67e74705SXin Li     FloatAlign = HostTarget->getFloatAlign();
1734*67e74705SXin Li     DoubleWidth = HostTarget->getDoubleWidth();
1735*67e74705SXin Li     DoubleAlign = HostTarget->getDoubleAlign();
1736*67e74705SXin Li     LongWidth = HostTarget->getLongWidth();
1737*67e74705SXin Li     LongAlign = HostTarget->getLongAlign();
1738*67e74705SXin Li     LongLongWidth = HostTarget->getLongLongWidth();
1739*67e74705SXin Li     LongLongAlign = HostTarget->getLongLongAlign();
1740*67e74705SXin Li     MinGlobalAlign = HostTarget->getMinGlobalAlign();
1741*67e74705SXin Li     DefaultAlignForAttributeAligned =
1742*67e74705SXin Li         HostTarget->getDefaultAlignForAttributeAligned();
1743*67e74705SXin Li     SizeType = HostTarget->getSizeType();
1744*67e74705SXin Li     IntMaxType = HostTarget->getIntMaxType();
1745*67e74705SXin Li     PtrDiffType = HostTarget->getPtrDiffType(/* AddrSpace = */ 0);
1746*67e74705SXin Li     IntPtrType = HostTarget->getIntPtrType();
1747*67e74705SXin Li     WCharType = HostTarget->getWCharType();
1748*67e74705SXin Li     WIntType = HostTarget->getWIntType();
1749*67e74705SXin Li     Char16Type = HostTarget->getChar16Type();
1750*67e74705SXin Li     Char32Type = HostTarget->getChar32Type();
1751*67e74705SXin Li     Int64Type = HostTarget->getInt64Type();
1752*67e74705SXin Li     SigAtomicType = HostTarget->getSigAtomicType();
1753*67e74705SXin Li     ProcessIDType = HostTarget->getProcessIDType();
1754*67e74705SXin Li 
1755*67e74705SXin Li     UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
1756*67e74705SXin Li     UseZeroLengthBitfieldAlignment =
1757*67e74705SXin Li         HostTarget->useZeroLengthBitfieldAlignment();
1758*67e74705SXin Li     UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
1759*67e74705SXin Li     ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
1760*67e74705SXin Li 
1761*67e74705SXin Li     // Properties intentionally not copied from host:
1762*67e74705SXin Li     // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the
1763*67e74705SXin Li     //   host/device boundary.
1764*67e74705SXin Li     // - SuitableAlign: Not visible across the host/device boundary, and may
1765*67e74705SXin Li     //   correctly be different on host/device, e.g. if host has wider vector
1766*67e74705SXin Li     //   types than device.
1767*67e74705SXin Li     // - LongDoubleWidth, LongDoubleAlign: nvptx's long double type is the same
1768*67e74705SXin Li     //   as its double type, but that's not necessarily true on the host.
1769*67e74705SXin Li     //   TODO: nvcc emits a warning when using long double on device; we should
1770*67e74705SXin Li     //   do the same.
1771*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1772*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
1773*67e74705SXin Li                         MacroBuilder &Builder) const override {
1774*67e74705SXin Li     Builder.defineMacro("__PTX__");
1775*67e74705SXin Li     Builder.defineMacro("__NVPTX__");
1776*67e74705SXin Li     if (Opts.CUDAIsDevice) {
1777*67e74705SXin Li       // Set __CUDA_ARCH__ for the GPU specified.
1778*67e74705SXin Li       std::string CUDAArchCode = [this] {
1779*67e74705SXin Li         switch (GPU) {
1780*67e74705SXin Li         case CudaArch::UNKNOWN:
1781*67e74705SXin Li           assert(false && "No GPU arch when compiling CUDA device code.");
1782*67e74705SXin Li           return "";
1783*67e74705SXin Li         case CudaArch::SM_20:
1784*67e74705SXin Li           return "200";
1785*67e74705SXin Li         case CudaArch::SM_21:
1786*67e74705SXin Li           return "210";
1787*67e74705SXin Li         case CudaArch::SM_30:
1788*67e74705SXin Li           return "300";
1789*67e74705SXin Li         case CudaArch::SM_32:
1790*67e74705SXin Li           return "320";
1791*67e74705SXin Li         case CudaArch::SM_35:
1792*67e74705SXin Li           return "350";
1793*67e74705SXin Li         case CudaArch::SM_37:
1794*67e74705SXin Li           return "370";
1795*67e74705SXin Li         case CudaArch::SM_50:
1796*67e74705SXin Li           return "500";
1797*67e74705SXin Li         case CudaArch::SM_52:
1798*67e74705SXin Li           return "520";
1799*67e74705SXin Li         case CudaArch::SM_53:
1800*67e74705SXin Li           return "530";
1801*67e74705SXin Li         case CudaArch::SM_60:
1802*67e74705SXin Li           return "600";
1803*67e74705SXin Li         case CudaArch::SM_61:
1804*67e74705SXin Li           return "610";
1805*67e74705SXin Li         case CudaArch::SM_62:
1806*67e74705SXin Li           return "620";
1807*67e74705SXin Li         }
1808*67e74705SXin Li         llvm_unreachable("unhandled CudaArch");
1809*67e74705SXin Li       }();
1810*67e74705SXin Li       Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
1811*67e74705SXin Li     }
1812*67e74705SXin Li   }
getTargetBuiltins() const1813*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
1814*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
1815*67e74705SXin Li                          clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin);
1816*67e74705SXin Li   }
hasFeature(StringRef Feature) const1817*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
1818*67e74705SXin Li     return Feature == "ptx" || Feature == "nvptx";
1819*67e74705SXin Li   }
1820*67e74705SXin Li 
1821*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
getGCCRegAliases() const1822*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
1823*67e74705SXin Li     // No aliases.
1824*67e74705SXin Li     return None;
1825*67e74705SXin Li   }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const1826*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
1827*67e74705SXin Li                              TargetInfo::ConstraintInfo &Info) const override {
1828*67e74705SXin Li     switch (*Name) {
1829*67e74705SXin Li     default:
1830*67e74705SXin Li       return false;
1831*67e74705SXin Li     case 'c':
1832*67e74705SXin Li     case 'h':
1833*67e74705SXin Li     case 'r':
1834*67e74705SXin Li     case 'l':
1835*67e74705SXin Li     case 'f':
1836*67e74705SXin Li     case 'd':
1837*67e74705SXin Li       Info.setAllowsRegister();
1838*67e74705SXin Li       return true;
1839*67e74705SXin Li     }
1840*67e74705SXin Li   }
getClobbers() const1841*67e74705SXin Li   const char *getClobbers() const override {
1842*67e74705SXin Li     // FIXME: Is this really right?
1843*67e74705SXin Li     return "";
1844*67e74705SXin Li   }
getBuiltinVaListKind() const1845*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
1846*67e74705SXin Li     // FIXME: implement
1847*67e74705SXin Li     return TargetInfo::CharPtrBuiltinVaList;
1848*67e74705SXin Li   }
setCPU(const std::string & Name)1849*67e74705SXin Li   bool setCPU(const std::string &Name) override {
1850*67e74705SXin Li     GPU = StringToCudaArch(Name);
1851*67e74705SXin Li     return GPU != CudaArch::UNKNOWN;
1852*67e74705SXin Li   }
setSupportedOpenCLOpts()1853*67e74705SXin Li   void setSupportedOpenCLOpts() override {
1854*67e74705SXin Li     auto &Opts = getSupportedOpenCLOpts();
1855*67e74705SXin Li     Opts.cl_clang_storage_class_specifiers = 1;
1856*67e74705SXin Li     Opts.cl_khr_gl_sharing = 1;
1857*67e74705SXin Li     Opts.cl_khr_icd = 1;
1858*67e74705SXin Li 
1859*67e74705SXin Li     Opts.cl_khr_fp64 = 1;
1860*67e74705SXin Li     Opts.cl_khr_byte_addressable_store = 1;
1861*67e74705SXin Li     Opts.cl_khr_global_int32_base_atomics = 1;
1862*67e74705SXin Li     Opts.cl_khr_global_int32_extended_atomics = 1;
1863*67e74705SXin Li     Opts.cl_khr_local_int32_base_atomics = 1;
1864*67e74705SXin Li     Opts.cl_khr_local_int32_extended_atomics = 1;
1865*67e74705SXin Li   }
1866*67e74705SXin Li };
1867*67e74705SXin Li 
1868*67e74705SXin Li const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
1869*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS)                                               \
1870*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
1871*67e74705SXin Li #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
1872*67e74705SXin Li   { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
1873*67e74705SXin Li #include "clang/Basic/BuiltinsNVPTX.def"
1874*67e74705SXin Li };
1875*67e74705SXin Li 
1876*67e74705SXin Li const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"};
1877*67e74705SXin Li 
getGCCRegNames() const1878*67e74705SXin Li ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
1879*67e74705SXin Li   return llvm::makeArrayRef(GCCRegNames);
1880*67e74705SXin Li }
1881*67e74705SXin Li 
1882*67e74705SXin Li class NVPTX32TargetInfo : public NVPTXTargetInfo {
1883*67e74705SXin Li public:
NVPTX32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1884*67e74705SXin Li   NVPTX32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1885*67e74705SXin Li       : NVPTXTargetInfo(Triple, Opts) {
1886*67e74705SXin Li     LongWidth = LongAlign = 32;
1887*67e74705SXin Li     PointerWidth = PointerAlign = 32;
1888*67e74705SXin Li     SizeType = TargetInfo::UnsignedInt;
1889*67e74705SXin Li     PtrDiffType = TargetInfo::SignedInt;
1890*67e74705SXin Li     IntPtrType = TargetInfo::SignedInt;
1891*67e74705SXin Li     resetDataLayout("e-p:32:32-i64:64-v16:16-v32:32-n16:32:64");
1892*67e74705SXin Li   }
1893*67e74705SXin Li };
1894*67e74705SXin Li 
1895*67e74705SXin Li class NVPTX64TargetInfo : public NVPTXTargetInfo {
1896*67e74705SXin Li public:
NVPTX64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1897*67e74705SXin Li   NVPTX64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
1898*67e74705SXin Li       : NVPTXTargetInfo(Triple, Opts) {
1899*67e74705SXin Li     PointerWidth = PointerAlign = 64;
1900*67e74705SXin Li     SizeType = TargetInfo::UnsignedLong;
1901*67e74705SXin Li     PtrDiffType = TargetInfo::SignedLong;
1902*67e74705SXin Li     IntPtrType = TargetInfo::SignedLong;
1903*67e74705SXin Li     resetDataLayout("e-i64:64-v16:16-v32:32-n16:32:64");
1904*67e74705SXin Li   }
1905*67e74705SXin Li };
1906*67e74705SXin Li 
1907*67e74705SXin Li static const unsigned AMDGPUAddrSpaceMap[] = {
1908*67e74705SXin Li   1,    // opencl_global
1909*67e74705SXin Li   3,    // opencl_local
1910*67e74705SXin Li   2,    // opencl_constant
1911*67e74705SXin Li   4,    // opencl_generic
1912*67e74705SXin Li   1,    // cuda_device
1913*67e74705SXin Li   2,    // cuda_constant
1914*67e74705SXin Li   3     // cuda_shared
1915*67e74705SXin Li };
1916*67e74705SXin Li 
1917*67e74705SXin Li // If you edit the description strings, make sure you update
1918*67e74705SXin Li // getPointerWidthV().
1919*67e74705SXin Li 
1920*67e74705SXin Li static const char *const DataLayoutStringR600 =
1921*67e74705SXin Li   "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
1922*67e74705SXin Li   "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
1923*67e74705SXin Li 
1924*67e74705SXin Li static const char *const DataLayoutStringSI =
1925*67e74705SXin Li   "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32"
1926*67e74705SXin Li   "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
1927*67e74705SXin Li   "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
1928*67e74705SXin Li 
1929*67e74705SXin Li class AMDGPUTargetInfo final : public TargetInfo {
1930*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
1931*67e74705SXin Li   static const char * const GCCRegNames[];
1932*67e74705SXin Li 
1933*67e74705SXin Li   /// \brief The GPU profiles supported by the AMDGPU target.
1934*67e74705SXin Li   enum GPUKind {
1935*67e74705SXin Li     GK_NONE,
1936*67e74705SXin Li     GK_R600,
1937*67e74705SXin Li     GK_R600_DOUBLE_OPS,
1938*67e74705SXin Li     GK_R700,
1939*67e74705SXin Li     GK_R700_DOUBLE_OPS,
1940*67e74705SXin Li     GK_EVERGREEN,
1941*67e74705SXin Li     GK_EVERGREEN_DOUBLE_OPS,
1942*67e74705SXin Li     GK_NORTHERN_ISLANDS,
1943*67e74705SXin Li     GK_CAYMAN,
1944*67e74705SXin Li     GK_SOUTHERN_ISLANDS,
1945*67e74705SXin Li     GK_SEA_ISLANDS,
1946*67e74705SXin Li     GK_VOLCANIC_ISLANDS
1947*67e74705SXin Li   } GPU;
1948*67e74705SXin Li 
1949*67e74705SXin Li   bool hasFP64:1;
1950*67e74705SXin Li   bool hasFMAF:1;
1951*67e74705SXin Li   bool hasLDEXPF:1;
1952*67e74705SXin Li 
isAMDGCN(const llvm::Triple & TT)1953*67e74705SXin Li   static bool isAMDGCN(const llvm::Triple &TT) {
1954*67e74705SXin Li     return TT.getArch() == llvm::Triple::amdgcn;
1955*67e74705SXin Li   }
1956*67e74705SXin Li 
1957*67e74705SXin Li public:
AMDGPUTargetInfo(const llvm::Triple & Triple,const TargetOptions &)1958*67e74705SXin Li   AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
1959*67e74705SXin Li     : TargetInfo(Triple) ,
1960*67e74705SXin Li       GPU(isAMDGCN(Triple) ? GK_SOUTHERN_ISLANDS : GK_R600),
1961*67e74705SXin Li       hasFP64(false),
1962*67e74705SXin Li       hasFMAF(false),
1963*67e74705SXin Li       hasLDEXPF(false) {
1964*67e74705SXin Li     if (getTriple().getArch() == llvm::Triple::amdgcn) {
1965*67e74705SXin Li       hasFP64 = true;
1966*67e74705SXin Li       hasFMAF = true;
1967*67e74705SXin Li       hasLDEXPF = true;
1968*67e74705SXin Li     }
1969*67e74705SXin Li 
1970*67e74705SXin Li     resetDataLayout(getTriple().getArch() == llvm::Triple::amdgcn ?
1971*67e74705SXin Li                     DataLayoutStringSI : DataLayoutStringR600);
1972*67e74705SXin Li 
1973*67e74705SXin Li     AddrSpaceMap = &AMDGPUAddrSpaceMap;
1974*67e74705SXin Li     UseAddrSpaceMapMangling = true;
1975*67e74705SXin Li   }
1976*67e74705SXin Li 
getPointerWidthV(unsigned AddrSpace) const1977*67e74705SXin Li   uint64_t getPointerWidthV(unsigned AddrSpace) const override {
1978*67e74705SXin Li     if (GPU <= GK_CAYMAN)
1979*67e74705SXin Li       return 32;
1980*67e74705SXin Li 
1981*67e74705SXin Li     switch(AddrSpace) {
1982*67e74705SXin Li       default:
1983*67e74705SXin Li         return 64;
1984*67e74705SXin Li       case 0:
1985*67e74705SXin Li       case 3:
1986*67e74705SXin Li       case 5:
1987*67e74705SXin Li         return 32;
1988*67e74705SXin Li     }
1989*67e74705SXin Li   }
1990*67e74705SXin Li 
getClobbers() const1991*67e74705SXin Li   const char * getClobbers() const override {
1992*67e74705SXin Li     return "";
1993*67e74705SXin Li   }
1994*67e74705SXin Li 
1995*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
1996*67e74705SXin Li 
getGCCRegAliases() const1997*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
1998*67e74705SXin Li     return None;
1999*67e74705SXin Li   }
2000*67e74705SXin Li 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const2001*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
2002*67e74705SXin Li                              TargetInfo::ConstraintInfo &Info) const override {
2003*67e74705SXin Li     switch (*Name) {
2004*67e74705SXin Li     default: break;
2005*67e74705SXin Li     case 'v': // vgpr
2006*67e74705SXin Li     case 's': // sgpr
2007*67e74705SXin Li       Info.setAllowsRegister();
2008*67e74705SXin Li       return true;
2009*67e74705SXin Li     }
2010*67e74705SXin Li     return false;
2011*67e74705SXin Li   }
2012*67e74705SXin Li 
2013*67e74705SXin Li   bool initFeatureMap(llvm::StringMap<bool> &Features,
2014*67e74705SXin Li                       DiagnosticsEngine &Diags, StringRef CPU,
2015*67e74705SXin Li                       const std::vector<std::string> &FeatureVec) const override;
2016*67e74705SXin Li 
getTargetBuiltins() const2017*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
2018*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
2019*67e74705SXin Li                         clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin);
2020*67e74705SXin Li   }
2021*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const2022*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
2023*67e74705SXin Li                         MacroBuilder &Builder) const override {
2024*67e74705SXin Li     if (getTriple().getArch() == llvm::Triple::amdgcn)
2025*67e74705SXin Li       Builder.defineMacro("__AMDGCN__");
2026*67e74705SXin Li     else
2027*67e74705SXin Li       Builder.defineMacro("__R600__");
2028*67e74705SXin Li 
2029*67e74705SXin Li     if (hasFMAF)
2030*67e74705SXin Li       Builder.defineMacro("__HAS_FMAF__");
2031*67e74705SXin Li     if (hasLDEXPF)
2032*67e74705SXin Li       Builder.defineMacro("__HAS_LDEXPF__");
2033*67e74705SXin Li     if (hasFP64)
2034*67e74705SXin Li       Builder.defineMacro("__HAS_FP64__");
2035*67e74705SXin Li   }
2036*67e74705SXin Li 
getBuiltinVaListKind() const2037*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
2038*67e74705SXin Li     return TargetInfo::CharPtrBuiltinVaList;
2039*67e74705SXin Li   }
2040*67e74705SXin Li 
parseR600Name(StringRef Name)2041*67e74705SXin Li   static GPUKind parseR600Name(StringRef Name) {
2042*67e74705SXin Li     return llvm::StringSwitch<GPUKind>(Name)
2043*67e74705SXin Li       .Case("r600" ,    GK_R600)
2044*67e74705SXin Li       .Case("rv610",    GK_R600)
2045*67e74705SXin Li       .Case("rv620",    GK_R600)
2046*67e74705SXin Li       .Case("rv630",    GK_R600)
2047*67e74705SXin Li       .Case("rv635",    GK_R600)
2048*67e74705SXin Li       .Case("rs780",    GK_R600)
2049*67e74705SXin Li       .Case("rs880",    GK_R600)
2050*67e74705SXin Li       .Case("rv670",    GK_R600_DOUBLE_OPS)
2051*67e74705SXin Li       .Case("rv710",    GK_R700)
2052*67e74705SXin Li       .Case("rv730",    GK_R700)
2053*67e74705SXin Li       .Case("rv740",    GK_R700_DOUBLE_OPS)
2054*67e74705SXin Li       .Case("rv770",    GK_R700_DOUBLE_OPS)
2055*67e74705SXin Li       .Case("palm",     GK_EVERGREEN)
2056*67e74705SXin Li       .Case("cedar",    GK_EVERGREEN)
2057*67e74705SXin Li       .Case("sumo",     GK_EVERGREEN)
2058*67e74705SXin Li       .Case("sumo2",    GK_EVERGREEN)
2059*67e74705SXin Li       .Case("redwood",  GK_EVERGREEN)
2060*67e74705SXin Li       .Case("juniper",  GK_EVERGREEN)
2061*67e74705SXin Li       .Case("hemlock",  GK_EVERGREEN_DOUBLE_OPS)
2062*67e74705SXin Li       .Case("cypress",  GK_EVERGREEN_DOUBLE_OPS)
2063*67e74705SXin Li       .Case("barts",    GK_NORTHERN_ISLANDS)
2064*67e74705SXin Li       .Case("turks",    GK_NORTHERN_ISLANDS)
2065*67e74705SXin Li       .Case("caicos",   GK_NORTHERN_ISLANDS)
2066*67e74705SXin Li       .Case("cayman",   GK_CAYMAN)
2067*67e74705SXin Li       .Case("aruba",    GK_CAYMAN)
2068*67e74705SXin Li       .Default(GK_NONE);
2069*67e74705SXin Li   }
2070*67e74705SXin Li 
parseAMDGCNName(StringRef Name)2071*67e74705SXin Li   static GPUKind parseAMDGCNName(StringRef Name) {
2072*67e74705SXin Li     return llvm::StringSwitch<GPUKind>(Name)
2073*67e74705SXin Li       .Case("tahiti",   GK_SOUTHERN_ISLANDS)
2074*67e74705SXin Li       .Case("pitcairn", GK_SOUTHERN_ISLANDS)
2075*67e74705SXin Li       .Case("verde",    GK_SOUTHERN_ISLANDS)
2076*67e74705SXin Li       .Case("oland",    GK_SOUTHERN_ISLANDS)
2077*67e74705SXin Li       .Case("hainan",   GK_SOUTHERN_ISLANDS)
2078*67e74705SXin Li       .Case("bonaire",  GK_SEA_ISLANDS)
2079*67e74705SXin Li       .Case("kabini",   GK_SEA_ISLANDS)
2080*67e74705SXin Li       .Case("kaveri",   GK_SEA_ISLANDS)
2081*67e74705SXin Li       .Case("hawaii",   GK_SEA_ISLANDS)
2082*67e74705SXin Li       .Case("mullins",  GK_SEA_ISLANDS)
2083*67e74705SXin Li       .Case("tonga",    GK_VOLCANIC_ISLANDS)
2084*67e74705SXin Li       .Case("iceland",  GK_VOLCANIC_ISLANDS)
2085*67e74705SXin Li       .Case("carrizo",  GK_VOLCANIC_ISLANDS)
2086*67e74705SXin Li       .Case("fiji",     GK_VOLCANIC_ISLANDS)
2087*67e74705SXin Li       .Case("stoney",   GK_VOLCANIC_ISLANDS)
2088*67e74705SXin Li       .Default(GK_NONE);
2089*67e74705SXin Li   }
2090*67e74705SXin Li 
setCPU(const std::string & Name)2091*67e74705SXin Li   bool setCPU(const std::string &Name) override {
2092*67e74705SXin Li     if (getTriple().getArch() == llvm::Triple::amdgcn)
2093*67e74705SXin Li       GPU = parseAMDGCNName(Name);
2094*67e74705SXin Li     else
2095*67e74705SXin Li       GPU = parseR600Name(Name);
2096*67e74705SXin Li 
2097*67e74705SXin Li     return GPU != GK_NONE;
2098*67e74705SXin Li   }
2099*67e74705SXin Li 
setSupportedOpenCLOpts()2100*67e74705SXin Li   void setSupportedOpenCLOpts() override {
2101*67e74705SXin Li     auto &Opts = getSupportedOpenCLOpts();
2102*67e74705SXin Li     Opts.cl_clang_storage_class_specifiers = 1;
2103*67e74705SXin Li     Opts.cl_khr_icd = 1;
2104*67e74705SXin Li 
2105*67e74705SXin Li     if (hasFP64)
2106*67e74705SXin Li       Opts.cl_khr_fp64 = 1;
2107*67e74705SXin Li     if (GPU >= GK_EVERGREEN) {
2108*67e74705SXin Li       Opts.cl_khr_byte_addressable_store = 1;
2109*67e74705SXin Li       Opts.cl_khr_global_int32_base_atomics = 1;
2110*67e74705SXin Li       Opts.cl_khr_global_int32_extended_atomics = 1;
2111*67e74705SXin Li       Opts.cl_khr_local_int32_base_atomics = 1;
2112*67e74705SXin Li       Opts.cl_khr_local_int32_extended_atomics = 1;
2113*67e74705SXin Li     }
2114*67e74705SXin Li     if (GPU >= GK_SOUTHERN_ISLANDS) {
2115*67e74705SXin Li       Opts.cl_khr_fp16 = 1;
2116*67e74705SXin Li       Opts.cl_khr_int64_base_atomics = 1;
2117*67e74705SXin Li       Opts.cl_khr_int64_extended_atomics = 1;
2118*67e74705SXin Li       Opts.cl_khr_3d_image_writes = 1;
2119*67e74705SXin Li     }
2120*67e74705SXin Li   }
2121*67e74705SXin Li 
checkCallingConvention(CallingConv CC) const2122*67e74705SXin Li   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
2123*67e74705SXin Li     switch (CC) {
2124*67e74705SXin Li       default:
2125*67e74705SXin Li         return CCCR_Warning;
2126*67e74705SXin Li       case CC_C:
2127*67e74705SXin Li       case CC_OpenCLKernel:
2128*67e74705SXin Li         return CCCR_OK;
2129*67e74705SXin Li     }
2130*67e74705SXin Li   }
2131*67e74705SXin Li };
2132*67e74705SXin Li 
2133*67e74705SXin Li const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = {
2134*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS)                \
2135*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
2136*67e74705SXin Li #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
2137*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE },
2138*67e74705SXin Li #include "clang/Basic/BuiltinsAMDGPU.def"
2139*67e74705SXin Li };
2140*67e74705SXin Li const char * const AMDGPUTargetInfo::GCCRegNames[] = {
2141*67e74705SXin Li   "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
2142*67e74705SXin Li   "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
2143*67e74705SXin Li   "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
2144*67e74705SXin Li   "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
2145*67e74705SXin Li   "v32", "v33", "v34", "v35", "v36", "v37", "v38", "v39",
2146*67e74705SXin Li   "v40", "v41", "v42", "v43", "v44", "v45", "v46", "v47",
2147*67e74705SXin Li   "v48", "v49", "v50", "v51", "v52", "v53", "v54", "v55",
2148*67e74705SXin Li   "v56", "v57", "v58", "v59", "v60", "v61", "v62", "v63",
2149*67e74705SXin Li   "v64", "v65", "v66", "v67", "v68", "v69", "v70", "v71",
2150*67e74705SXin Li   "v72", "v73", "v74", "v75", "v76", "v77", "v78", "v79",
2151*67e74705SXin Li   "v80", "v81", "v82", "v83", "v84", "v85", "v86", "v87",
2152*67e74705SXin Li   "v88", "v89", "v90", "v91", "v92", "v93", "v94", "v95",
2153*67e74705SXin Li   "v96", "v97", "v98", "v99", "v100", "v101", "v102", "v103",
2154*67e74705SXin Li   "v104", "v105", "v106", "v107", "v108", "v109", "v110", "v111",
2155*67e74705SXin Li   "v112", "v113", "v114", "v115", "v116", "v117", "v118", "v119",
2156*67e74705SXin Li   "v120", "v121", "v122", "v123", "v124", "v125", "v126", "v127",
2157*67e74705SXin Li   "v128", "v129", "v130", "v131", "v132", "v133", "v134", "v135",
2158*67e74705SXin Li   "v136", "v137", "v138", "v139", "v140", "v141", "v142", "v143",
2159*67e74705SXin Li   "v144", "v145", "v146", "v147", "v148", "v149", "v150", "v151",
2160*67e74705SXin Li   "v152", "v153", "v154", "v155", "v156", "v157", "v158", "v159",
2161*67e74705SXin Li   "v160", "v161", "v162", "v163", "v164", "v165", "v166", "v167",
2162*67e74705SXin Li   "v168", "v169", "v170", "v171", "v172", "v173", "v174", "v175",
2163*67e74705SXin Li   "v176", "v177", "v178", "v179", "v180", "v181", "v182", "v183",
2164*67e74705SXin Li   "v184", "v185", "v186", "v187", "v188", "v189", "v190", "v191",
2165*67e74705SXin Li   "v192", "v193", "v194", "v195", "v196", "v197", "v198", "v199",
2166*67e74705SXin Li   "v200", "v201", "v202", "v203", "v204", "v205", "v206", "v207",
2167*67e74705SXin Li   "v208", "v209", "v210", "v211", "v212", "v213", "v214", "v215",
2168*67e74705SXin Li   "v216", "v217", "v218", "v219", "v220", "v221", "v222", "v223",
2169*67e74705SXin Li   "v224", "v225", "v226", "v227", "v228", "v229", "v230", "v231",
2170*67e74705SXin Li   "v232", "v233", "v234", "v235", "v236", "v237", "v238", "v239",
2171*67e74705SXin Li   "v240", "v241", "v242", "v243", "v244", "v245", "v246", "v247",
2172*67e74705SXin Li   "v248", "v249", "v250", "v251", "v252", "v253", "v254", "v255",
2173*67e74705SXin Li   "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2174*67e74705SXin Li   "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
2175*67e74705SXin Li   "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
2176*67e74705SXin Li   "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
2177*67e74705SXin Li   "s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39",
2178*67e74705SXin Li   "s40", "s41", "s42", "s43", "s44", "s45", "s46", "s47",
2179*67e74705SXin Li   "s48", "s49", "s50", "s51", "s52", "s53", "s54", "s55",
2180*67e74705SXin Li   "s56", "s57", "s58", "s59", "s60", "s61", "s62", "s63",
2181*67e74705SXin Li   "s64", "s65", "s66", "s67", "s68", "s69", "s70", "s71",
2182*67e74705SXin Li   "s72", "s73", "s74", "s75", "s76", "s77", "s78", "s79",
2183*67e74705SXin Li   "s80", "s81", "s82", "s83", "s84", "s85", "s86", "s87",
2184*67e74705SXin Li   "s88", "s89", "s90", "s91", "s92", "s93", "s94", "s95",
2185*67e74705SXin Li   "s96", "s97", "s98", "s99", "s100", "s101", "s102", "s103",
2186*67e74705SXin Li   "s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111",
2187*67e74705SXin Li   "s112", "s113", "s114", "s115", "s116", "s117", "s118", "s119",
2188*67e74705SXin Li   "s120", "s121", "s122", "s123", "s124", "s125", "s126", "s127",
2189*67e74705SXin Li   "exec", "vcc", "scc", "m0", "flat_scratch", "exec_lo", "exec_hi",
2190*67e74705SXin Li   "vcc_lo", "vcc_hi", "flat_scratch_lo", "flat_scratch_hi"
2191*67e74705SXin Li };
2192*67e74705SXin Li 
getGCCRegNames() const2193*67e74705SXin Li ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const {
2194*67e74705SXin Li   return llvm::makeArrayRef(GCCRegNames);
2195*67e74705SXin Li }
2196*67e74705SXin Li 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeatureVec) const2197*67e74705SXin Li bool AMDGPUTargetInfo::initFeatureMap(
2198*67e74705SXin Li   llvm::StringMap<bool> &Features,
2199*67e74705SXin Li   DiagnosticsEngine &Diags, StringRef CPU,
2200*67e74705SXin Li   const std::vector<std::string> &FeatureVec) const {
2201*67e74705SXin Li 
2202*67e74705SXin Li   // XXX - What does the member GPU mean if device name string passed here?
2203*67e74705SXin Li   if (getTriple().getArch() == llvm::Triple::amdgcn) {
2204*67e74705SXin Li     if (CPU.empty())
2205*67e74705SXin Li       CPU = "tahiti";
2206*67e74705SXin Li 
2207*67e74705SXin Li     switch (parseAMDGCNName(CPU)) {
2208*67e74705SXin Li     case GK_SOUTHERN_ISLANDS:
2209*67e74705SXin Li     case GK_SEA_ISLANDS:
2210*67e74705SXin Li       break;
2211*67e74705SXin Li 
2212*67e74705SXin Li     case GK_VOLCANIC_ISLANDS:
2213*67e74705SXin Li       Features["s-memrealtime"] = true;
2214*67e74705SXin Li       Features["16-bit-insts"] = true;
2215*67e74705SXin Li       break;
2216*67e74705SXin Li 
2217*67e74705SXin Li     case GK_NONE:
2218*67e74705SXin Li       return false;
2219*67e74705SXin Li     default:
2220*67e74705SXin Li       llvm_unreachable("unhandled subtarget");
2221*67e74705SXin Li     }
2222*67e74705SXin Li   } else {
2223*67e74705SXin Li     if (CPU.empty())
2224*67e74705SXin Li       CPU = "r600";
2225*67e74705SXin Li 
2226*67e74705SXin Li     switch (parseR600Name(CPU)) {
2227*67e74705SXin Li     case GK_R600:
2228*67e74705SXin Li     case GK_R700:
2229*67e74705SXin Li     case GK_EVERGREEN:
2230*67e74705SXin Li     case GK_NORTHERN_ISLANDS:
2231*67e74705SXin Li       break;
2232*67e74705SXin Li     case GK_R600_DOUBLE_OPS:
2233*67e74705SXin Li     case GK_R700_DOUBLE_OPS:
2234*67e74705SXin Li     case GK_EVERGREEN_DOUBLE_OPS:
2235*67e74705SXin Li     case GK_CAYMAN:
2236*67e74705SXin Li       Features["fp64"] = true;
2237*67e74705SXin Li       break;
2238*67e74705SXin Li     case GK_NONE:
2239*67e74705SXin Li       return false;
2240*67e74705SXin Li     default:
2241*67e74705SXin Li       llvm_unreachable("unhandled subtarget");
2242*67e74705SXin Li     }
2243*67e74705SXin Li   }
2244*67e74705SXin Li 
2245*67e74705SXin Li   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec);
2246*67e74705SXin Li }
2247*67e74705SXin Li 
2248*67e74705SXin Li // Namespace for x86 abstract base class
2249*67e74705SXin Li const Builtin::Info BuiltinInfo[] = {
2250*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS)                                               \
2251*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
2252*67e74705SXin Li #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
2253*67e74705SXin Li   { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
2254*67e74705SXin Li #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
2255*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE },
2256*67e74705SXin Li #include "clang/Basic/BuiltinsX86.def"
2257*67e74705SXin Li };
2258*67e74705SXin Li 
2259*67e74705SXin Li static const char* const GCCRegNames[] = {
2260*67e74705SXin Li   "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
2261*67e74705SXin Li   "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
2262*67e74705SXin Li   "argp", "flags", "fpcr", "fpsr", "dirflag", "frame",
2263*67e74705SXin Li   "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
2264*67e74705SXin Li   "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
2265*67e74705SXin Li   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2266*67e74705SXin Li   "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
2267*67e74705SXin Li   "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
2268*67e74705SXin Li   "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15",
2269*67e74705SXin Li   "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23",
2270*67e74705SXin Li   "xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31",
2271*67e74705SXin Li   "ymm16", "ymm17", "ymm18", "ymm19", "ymm20", "ymm21", "ymm22", "ymm23",
2272*67e74705SXin Li   "ymm24", "ymm25", "ymm26", "ymm27", "ymm28", "ymm29", "ymm30", "ymm31",
2273*67e74705SXin Li   "zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7",
2274*67e74705SXin Li   "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15",
2275*67e74705SXin Li   "zmm16", "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23",
2276*67e74705SXin Li   "zmm24", "zmm25", "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31",
2277*67e74705SXin Li };
2278*67e74705SXin Li 
2279*67e74705SXin Li const TargetInfo::AddlRegName AddlRegNames[] = {
2280*67e74705SXin Li   { { "al", "ah", "eax", "rax" }, 0 },
2281*67e74705SXin Li   { { "bl", "bh", "ebx", "rbx" }, 3 },
2282*67e74705SXin Li   { { "cl", "ch", "ecx", "rcx" }, 2 },
2283*67e74705SXin Li   { { "dl", "dh", "edx", "rdx" }, 1 },
2284*67e74705SXin Li   { { "esi", "rsi" }, 4 },
2285*67e74705SXin Li   { { "edi", "rdi" }, 5 },
2286*67e74705SXin Li   { { "esp", "rsp" }, 7 },
2287*67e74705SXin Li   { { "ebp", "rbp" }, 6 },
2288*67e74705SXin Li   { { "r8d", "r8w", "r8b" }, 38 },
2289*67e74705SXin Li   { { "r9d", "r9w", "r9b" }, 39 },
2290*67e74705SXin Li   { { "r10d", "r10w", "r10b" }, 40 },
2291*67e74705SXin Li   { { "r11d", "r11w", "r11b" }, 41 },
2292*67e74705SXin Li   { { "r12d", "r12w", "r12b" }, 42 },
2293*67e74705SXin Li   { { "r13d", "r13w", "r13b" }, 43 },
2294*67e74705SXin Li   { { "r14d", "r14w", "r14b" }, 44 },
2295*67e74705SXin Li   { { "r15d", "r15w", "r15b" }, 45 },
2296*67e74705SXin Li };
2297*67e74705SXin Li 
2298*67e74705SXin Li // X86 target abstract base class; x86-32 and x86-64 are very close, so
2299*67e74705SXin Li // most of the implementation can be shared.
2300*67e74705SXin Li class X86TargetInfo : public TargetInfo {
2301*67e74705SXin Li   enum X86SSEEnum {
2302*67e74705SXin Li     NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F
2303*67e74705SXin Li   } SSELevel = NoSSE;
2304*67e74705SXin Li   enum MMX3DNowEnum {
2305*67e74705SXin Li     NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon
2306*67e74705SXin Li   } MMX3DNowLevel = NoMMX3DNow;
2307*67e74705SXin Li   enum XOPEnum {
2308*67e74705SXin Li     NoXOP,
2309*67e74705SXin Li     SSE4A,
2310*67e74705SXin Li     FMA4,
2311*67e74705SXin Li     XOP
2312*67e74705SXin Li   } XOPLevel = NoXOP;
2313*67e74705SXin Li 
2314*67e74705SXin Li   bool HasAES = false;
2315*67e74705SXin Li   bool HasPCLMUL = false;
2316*67e74705SXin Li   bool HasLZCNT = false;
2317*67e74705SXin Li   bool HasRDRND = false;
2318*67e74705SXin Li   bool HasFSGSBASE = false;
2319*67e74705SXin Li   bool HasBMI = false;
2320*67e74705SXin Li   bool HasBMI2 = false;
2321*67e74705SXin Li   bool HasPOPCNT = false;
2322*67e74705SXin Li   bool HasRTM = false;
2323*67e74705SXin Li   bool HasPRFCHW = false;
2324*67e74705SXin Li   bool HasRDSEED = false;
2325*67e74705SXin Li   bool HasADX = false;
2326*67e74705SXin Li   bool HasTBM = false;
2327*67e74705SXin Li   bool HasFMA = false;
2328*67e74705SXin Li   bool HasF16C = false;
2329*67e74705SXin Li   bool HasAVX512CD = false;
2330*67e74705SXin Li   bool HasAVX512ER = false;
2331*67e74705SXin Li   bool HasAVX512PF = false;
2332*67e74705SXin Li   bool HasAVX512DQ = false;
2333*67e74705SXin Li   bool HasAVX512BW = false;
2334*67e74705SXin Li   bool HasAVX512VL = false;
2335*67e74705SXin Li   bool HasAVX512VBMI = false;
2336*67e74705SXin Li   bool HasAVX512IFMA = false;
2337*67e74705SXin Li   bool HasSHA = false;
2338*67e74705SXin Li   bool HasMPX = false;
2339*67e74705SXin Li   bool HasSGX = false;
2340*67e74705SXin Li   bool HasCX16 = false;
2341*67e74705SXin Li   bool HasFXSR = false;
2342*67e74705SXin Li   bool HasXSAVE = false;
2343*67e74705SXin Li   bool HasXSAVEOPT = false;
2344*67e74705SXin Li   bool HasXSAVEC = false;
2345*67e74705SXin Li   bool HasXSAVES = false;
2346*67e74705SXin Li   bool HasMWAITX = false;
2347*67e74705SXin Li   bool HasPKU = false;
2348*67e74705SXin Li   bool HasCLFLUSHOPT = false;
2349*67e74705SXin Li   bool HasPCOMMIT = false;
2350*67e74705SXin Li   bool HasCLWB = false;
2351*67e74705SXin Li   bool HasUMIP = false;
2352*67e74705SXin Li   bool HasMOVBE = false;
2353*67e74705SXin Li   bool HasPREFETCHWT1 = false;
2354*67e74705SXin Li 
2355*67e74705SXin Li   /// \brief Enumeration of all of the X86 CPUs supported by Clang.
2356*67e74705SXin Li   ///
2357*67e74705SXin Li   /// Each enumeration represents a particular CPU supported by Clang. These
2358*67e74705SXin Li   /// loosely correspond to the options passed to '-march' or '-mtune' flags.
2359*67e74705SXin Li   enum CPUKind {
2360*67e74705SXin Li     CK_Generic,
2361*67e74705SXin Li 
2362*67e74705SXin Li     /// \name i386
2363*67e74705SXin Li     /// i386-generation processors.
2364*67e74705SXin Li     //@{
2365*67e74705SXin Li     CK_i386,
2366*67e74705SXin Li     //@}
2367*67e74705SXin Li 
2368*67e74705SXin Li     /// \name i486
2369*67e74705SXin Li     /// i486-generation processors.
2370*67e74705SXin Li     //@{
2371*67e74705SXin Li     CK_i486,
2372*67e74705SXin Li     CK_WinChipC6,
2373*67e74705SXin Li     CK_WinChip2,
2374*67e74705SXin Li     CK_C3,
2375*67e74705SXin Li     //@}
2376*67e74705SXin Li 
2377*67e74705SXin Li     /// \name i586
2378*67e74705SXin Li     /// i586-generation processors, P5 microarchitecture based.
2379*67e74705SXin Li     //@{
2380*67e74705SXin Li     CK_i586,
2381*67e74705SXin Li     CK_Pentium,
2382*67e74705SXin Li     CK_PentiumMMX,
2383*67e74705SXin Li     //@}
2384*67e74705SXin Li 
2385*67e74705SXin Li     /// \name i686
2386*67e74705SXin Li     /// i686-generation processors, P6 / Pentium M microarchitecture based.
2387*67e74705SXin Li     //@{
2388*67e74705SXin Li     CK_i686,
2389*67e74705SXin Li     CK_PentiumPro,
2390*67e74705SXin Li     CK_Pentium2,
2391*67e74705SXin Li     CK_Pentium3,
2392*67e74705SXin Li     CK_Pentium3M,
2393*67e74705SXin Li     CK_PentiumM,
2394*67e74705SXin Li     CK_C3_2,
2395*67e74705SXin Li 
2396*67e74705SXin Li     /// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
2397*67e74705SXin Li     /// Clang however has some logic to suport this.
2398*67e74705SXin Li     // FIXME: Warn, deprecate, and potentially remove this.
2399*67e74705SXin Li     CK_Yonah,
2400*67e74705SXin Li     //@}
2401*67e74705SXin Li 
2402*67e74705SXin Li     /// \name Netburst
2403*67e74705SXin Li     /// Netburst microarchitecture based processors.
2404*67e74705SXin Li     //@{
2405*67e74705SXin Li     CK_Pentium4,
2406*67e74705SXin Li     CK_Pentium4M,
2407*67e74705SXin Li     CK_Prescott,
2408*67e74705SXin Li     CK_Nocona,
2409*67e74705SXin Li     //@}
2410*67e74705SXin Li 
2411*67e74705SXin Li     /// \name Core
2412*67e74705SXin Li     /// Core microarchitecture based processors.
2413*67e74705SXin Li     //@{
2414*67e74705SXin Li     CK_Core2,
2415*67e74705SXin Li 
2416*67e74705SXin Li     /// This enumerator, like \see CK_Yonah, is a bit odd. It is another
2417*67e74705SXin Li     /// codename which GCC no longer accepts as an option to -march, but Clang
2418*67e74705SXin Li     /// has some logic for recognizing it.
2419*67e74705SXin Li     // FIXME: Warn, deprecate, and potentially remove this.
2420*67e74705SXin Li     CK_Penryn,
2421*67e74705SXin Li     //@}
2422*67e74705SXin Li 
2423*67e74705SXin Li     /// \name Atom
2424*67e74705SXin Li     /// Atom processors
2425*67e74705SXin Li     //@{
2426*67e74705SXin Li     CK_Bonnell,
2427*67e74705SXin Li     CK_Silvermont,
2428*67e74705SXin Li     //@}
2429*67e74705SXin Li 
2430*67e74705SXin Li     /// \name Nehalem
2431*67e74705SXin Li     /// Nehalem microarchitecture based processors.
2432*67e74705SXin Li     CK_Nehalem,
2433*67e74705SXin Li 
2434*67e74705SXin Li     /// \name Westmere
2435*67e74705SXin Li     /// Westmere microarchitecture based processors.
2436*67e74705SXin Li     CK_Westmere,
2437*67e74705SXin Li 
2438*67e74705SXin Li     /// \name Sandy Bridge
2439*67e74705SXin Li     /// Sandy Bridge microarchitecture based processors.
2440*67e74705SXin Li     CK_SandyBridge,
2441*67e74705SXin Li 
2442*67e74705SXin Li     /// \name Ivy Bridge
2443*67e74705SXin Li     /// Ivy Bridge microarchitecture based processors.
2444*67e74705SXin Li     CK_IvyBridge,
2445*67e74705SXin Li 
2446*67e74705SXin Li     /// \name Haswell
2447*67e74705SXin Li     /// Haswell microarchitecture based processors.
2448*67e74705SXin Li     CK_Haswell,
2449*67e74705SXin Li 
2450*67e74705SXin Li     /// \name Broadwell
2451*67e74705SXin Li     /// Broadwell microarchitecture based processors.
2452*67e74705SXin Li     CK_Broadwell,
2453*67e74705SXin Li 
2454*67e74705SXin Li     /// \name Skylake Client
2455*67e74705SXin Li     /// Skylake client microarchitecture based processors.
2456*67e74705SXin Li     CK_SkylakeClient,
2457*67e74705SXin Li 
2458*67e74705SXin Li     /// \name Skylake Server
2459*67e74705SXin Li     /// Skylake server microarchitecture based processors.
2460*67e74705SXin Li     CK_SkylakeServer,
2461*67e74705SXin Li 
2462*67e74705SXin Li     /// \name Cannonlake Client
2463*67e74705SXin Li     /// Cannonlake client microarchitecture based processors.
2464*67e74705SXin Li     CK_Cannonlake,
2465*67e74705SXin Li 
2466*67e74705SXin Li     /// \name Knights Landing
2467*67e74705SXin Li     /// Knights Landing processor.
2468*67e74705SXin Li     CK_KNL,
2469*67e74705SXin Li 
2470*67e74705SXin Li     /// \name Lakemont
2471*67e74705SXin Li     /// Lakemont microarchitecture based processors.
2472*67e74705SXin Li     CK_Lakemont,
2473*67e74705SXin Li 
2474*67e74705SXin Li     /// \name K6
2475*67e74705SXin Li     /// K6 architecture processors.
2476*67e74705SXin Li     //@{
2477*67e74705SXin Li     CK_K6,
2478*67e74705SXin Li     CK_K6_2,
2479*67e74705SXin Li     CK_K6_3,
2480*67e74705SXin Li     //@}
2481*67e74705SXin Li 
2482*67e74705SXin Li     /// \name K7
2483*67e74705SXin Li     /// K7 architecture processors.
2484*67e74705SXin Li     //@{
2485*67e74705SXin Li     CK_Athlon,
2486*67e74705SXin Li     CK_AthlonThunderbird,
2487*67e74705SXin Li     CK_Athlon4,
2488*67e74705SXin Li     CK_AthlonXP,
2489*67e74705SXin Li     CK_AthlonMP,
2490*67e74705SXin Li     //@}
2491*67e74705SXin Li 
2492*67e74705SXin Li     /// \name K8
2493*67e74705SXin Li     /// K8 architecture processors.
2494*67e74705SXin Li     //@{
2495*67e74705SXin Li     CK_Athlon64,
2496*67e74705SXin Li     CK_Athlon64SSE3,
2497*67e74705SXin Li     CK_AthlonFX,
2498*67e74705SXin Li     CK_K8,
2499*67e74705SXin Li     CK_K8SSE3,
2500*67e74705SXin Li     CK_Opteron,
2501*67e74705SXin Li     CK_OpteronSSE3,
2502*67e74705SXin Li     CK_AMDFAM10,
2503*67e74705SXin Li     //@}
2504*67e74705SXin Li 
2505*67e74705SXin Li     /// \name Bobcat
2506*67e74705SXin Li     /// Bobcat architecture processors.
2507*67e74705SXin Li     //@{
2508*67e74705SXin Li     CK_BTVER1,
2509*67e74705SXin Li     CK_BTVER2,
2510*67e74705SXin Li     //@}
2511*67e74705SXin Li 
2512*67e74705SXin Li     /// \name Bulldozer
2513*67e74705SXin Li     /// Bulldozer architecture processors.
2514*67e74705SXin Li     //@{
2515*67e74705SXin Li     CK_BDVER1,
2516*67e74705SXin Li     CK_BDVER2,
2517*67e74705SXin Li     CK_BDVER3,
2518*67e74705SXin Li     CK_BDVER4,
2519*67e74705SXin Li     //@}
2520*67e74705SXin Li 
2521*67e74705SXin Li     /// This specification is deprecated and will be removed in the future.
2522*67e74705SXin Li     /// Users should prefer \see CK_K8.
2523*67e74705SXin Li     // FIXME: Warn on this when the CPU is set to it.
2524*67e74705SXin Li     //@{
2525*67e74705SXin Li     CK_x86_64,
2526*67e74705SXin Li     //@}
2527*67e74705SXin Li 
2528*67e74705SXin Li     /// \name Geode
2529*67e74705SXin Li     /// Geode processors.
2530*67e74705SXin Li     //@{
2531*67e74705SXin Li     CK_Geode
2532*67e74705SXin Li     //@}
2533*67e74705SXin Li   } CPU = CK_Generic;
2534*67e74705SXin Li 
getCPUKind(StringRef CPU) const2535*67e74705SXin Li   CPUKind getCPUKind(StringRef CPU) const {
2536*67e74705SXin Li     return llvm::StringSwitch<CPUKind>(CPU)
2537*67e74705SXin Li         .Case("i386", CK_i386)
2538*67e74705SXin Li         .Case("i486", CK_i486)
2539*67e74705SXin Li         .Case("winchip-c6", CK_WinChipC6)
2540*67e74705SXin Li         .Case("winchip2", CK_WinChip2)
2541*67e74705SXin Li         .Case("c3", CK_C3)
2542*67e74705SXin Li         .Case("i586", CK_i586)
2543*67e74705SXin Li         .Case("pentium", CK_Pentium)
2544*67e74705SXin Li         .Case("pentium-mmx", CK_PentiumMMX)
2545*67e74705SXin Li         .Case("i686", CK_i686)
2546*67e74705SXin Li         .Case("pentiumpro", CK_PentiumPro)
2547*67e74705SXin Li         .Case("pentium2", CK_Pentium2)
2548*67e74705SXin Li         .Case("pentium3", CK_Pentium3)
2549*67e74705SXin Li         .Case("pentium3m", CK_Pentium3M)
2550*67e74705SXin Li         .Case("pentium-m", CK_PentiumM)
2551*67e74705SXin Li         .Case("c3-2", CK_C3_2)
2552*67e74705SXin Li         .Case("yonah", CK_Yonah)
2553*67e74705SXin Li         .Case("pentium4", CK_Pentium4)
2554*67e74705SXin Li         .Case("pentium4m", CK_Pentium4M)
2555*67e74705SXin Li         .Case("prescott", CK_Prescott)
2556*67e74705SXin Li         .Case("nocona", CK_Nocona)
2557*67e74705SXin Li         .Case("core2", CK_Core2)
2558*67e74705SXin Li         .Case("penryn", CK_Penryn)
2559*67e74705SXin Li         .Case("bonnell", CK_Bonnell)
2560*67e74705SXin Li         .Case("atom", CK_Bonnell) // Legacy name.
2561*67e74705SXin Li         .Case("silvermont", CK_Silvermont)
2562*67e74705SXin Li         .Case("slm", CK_Silvermont) // Legacy name.
2563*67e74705SXin Li         .Case("nehalem", CK_Nehalem)
2564*67e74705SXin Li         .Case("corei7", CK_Nehalem) // Legacy name.
2565*67e74705SXin Li         .Case("westmere", CK_Westmere)
2566*67e74705SXin Li         .Case("sandybridge", CK_SandyBridge)
2567*67e74705SXin Li         .Case("corei7-avx", CK_SandyBridge) // Legacy name.
2568*67e74705SXin Li         .Case("ivybridge", CK_IvyBridge)
2569*67e74705SXin Li         .Case("core-avx-i", CK_IvyBridge) // Legacy name.
2570*67e74705SXin Li         .Case("haswell", CK_Haswell)
2571*67e74705SXin Li         .Case("core-avx2", CK_Haswell) // Legacy name.
2572*67e74705SXin Li         .Case("broadwell", CK_Broadwell)
2573*67e74705SXin Li         .Case("skylake", CK_SkylakeClient)
2574*67e74705SXin Li         .Case("skylake-avx512", CK_SkylakeServer)
2575*67e74705SXin Li         .Case("skx", CK_SkylakeServer) // Legacy name.
2576*67e74705SXin Li         .Case("cannonlake", CK_Cannonlake)
2577*67e74705SXin Li         .Case("knl", CK_KNL)
2578*67e74705SXin Li         .Case("lakemont", CK_Lakemont)
2579*67e74705SXin Li         .Case("k6", CK_K6)
2580*67e74705SXin Li         .Case("k6-2", CK_K6_2)
2581*67e74705SXin Li         .Case("k6-3", CK_K6_3)
2582*67e74705SXin Li         .Case("athlon", CK_Athlon)
2583*67e74705SXin Li         .Case("athlon-tbird", CK_AthlonThunderbird)
2584*67e74705SXin Li         .Case("athlon-4", CK_Athlon4)
2585*67e74705SXin Li         .Case("athlon-xp", CK_AthlonXP)
2586*67e74705SXin Li         .Case("athlon-mp", CK_AthlonMP)
2587*67e74705SXin Li         .Case("athlon64", CK_Athlon64)
2588*67e74705SXin Li         .Case("athlon64-sse3", CK_Athlon64SSE3)
2589*67e74705SXin Li         .Case("athlon-fx", CK_AthlonFX)
2590*67e74705SXin Li         .Case("k8", CK_K8)
2591*67e74705SXin Li         .Case("k8-sse3", CK_K8SSE3)
2592*67e74705SXin Li         .Case("opteron", CK_Opteron)
2593*67e74705SXin Li         .Case("opteron-sse3", CK_OpteronSSE3)
2594*67e74705SXin Li         .Case("barcelona", CK_AMDFAM10)
2595*67e74705SXin Li         .Case("amdfam10", CK_AMDFAM10)
2596*67e74705SXin Li         .Case("btver1", CK_BTVER1)
2597*67e74705SXin Li         .Case("btver2", CK_BTVER2)
2598*67e74705SXin Li         .Case("bdver1", CK_BDVER1)
2599*67e74705SXin Li         .Case("bdver2", CK_BDVER2)
2600*67e74705SXin Li         .Case("bdver3", CK_BDVER3)
2601*67e74705SXin Li         .Case("bdver4", CK_BDVER4)
2602*67e74705SXin Li         .Case("x86-64", CK_x86_64)
2603*67e74705SXin Li         .Case("geode", CK_Geode)
2604*67e74705SXin Li         .Default(CK_Generic);
2605*67e74705SXin Li   }
2606*67e74705SXin Li 
2607*67e74705SXin Li   enum FPMathKind {
2608*67e74705SXin Li     FP_Default,
2609*67e74705SXin Li     FP_SSE,
2610*67e74705SXin Li     FP_387
2611*67e74705SXin Li   } FPMath = FP_Default;
2612*67e74705SXin Li 
2613*67e74705SXin Li public:
X86TargetInfo(const llvm::Triple & Triple,const TargetOptions &)2614*67e74705SXin Li   X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
2615*67e74705SXin Li       : TargetInfo(Triple) {
2616*67e74705SXin Li     BigEndian = false;
2617*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
2618*67e74705SXin Li   }
getFloatEvalMethod() const2619*67e74705SXin Li   unsigned getFloatEvalMethod() const override {
2620*67e74705SXin Li     // X87 evaluates with 80 bits "long double" precision.
2621*67e74705SXin Li     return SSELevel == NoSSE ? 2 : 0;
2622*67e74705SXin Li   }
getTargetBuiltins() const2623*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
2624*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
2625*67e74705SXin Li                              clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin);
2626*67e74705SXin Li   }
getGCCRegNames() const2627*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override {
2628*67e74705SXin Li     return llvm::makeArrayRef(GCCRegNames);
2629*67e74705SXin Li   }
getGCCRegAliases() const2630*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
2631*67e74705SXin Li     return None;
2632*67e74705SXin Li   }
getGCCAddlRegNames() const2633*67e74705SXin Li   ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override {
2634*67e74705SXin Li     return llvm::makeArrayRef(AddlRegNames);
2635*67e74705SXin Li   }
2636*67e74705SXin Li   bool validateCpuSupports(StringRef Name) const override;
2637*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
2638*67e74705SXin Li                              TargetInfo::ConstraintInfo &info) const override;
2639*67e74705SXin Li 
validateGlobalRegisterVariable(StringRef RegName,unsigned RegSize,bool & HasSizeMismatch) const2640*67e74705SXin Li   bool validateGlobalRegisterVariable(StringRef RegName,
2641*67e74705SXin Li                                       unsigned RegSize,
2642*67e74705SXin Li                                       bool &HasSizeMismatch) const override {
2643*67e74705SXin Li     // esp and ebp are the only 32-bit registers the x86 backend can currently
2644*67e74705SXin Li     // handle.
2645*67e74705SXin Li     if (RegName.equals("esp") || RegName.equals("ebp")) {
2646*67e74705SXin Li       // Check that the register size is 32-bit.
2647*67e74705SXin Li       HasSizeMismatch = RegSize != 32;
2648*67e74705SXin Li       return true;
2649*67e74705SXin Li     }
2650*67e74705SXin Li 
2651*67e74705SXin Li     return false;
2652*67e74705SXin Li   }
2653*67e74705SXin Li 
2654*67e74705SXin Li   bool validateOutputSize(StringRef Constraint, unsigned Size) const override;
2655*67e74705SXin Li 
2656*67e74705SXin Li   bool validateInputSize(StringRef Constraint, unsigned Size) const override;
2657*67e74705SXin Li 
2658*67e74705SXin Li   virtual bool validateOperandSize(StringRef Constraint, unsigned Size) const;
2659*67e74705SXin Li 
2660*67e74705SXin Li   std::string convertConstraint(const char *&Constraint) const override;
getClobbers() const2661*67e74705SXin Li   const char *getClobbers() const override {
2662*67e74705SXin Li     return "~{dirflag},~{fpsr},~{flags}";
2663*67e74705SXin Li   }
2664*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
2665*67e74705SXin Li                         MacroBuilder &Builder) const override;
2666*67e74705SXin Li   static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level,
2667*67e74705SXin Li                           bool Enabled);
2668*67e74705SXin Li   static void setMMXLevel(llvm::StringMap<bool> &Features, MMX3DNowEnum Level,
2669*67e74705SXin Li                           bool Enabled);
2670*67e74705SXin Li   static void setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
2671*67e74705SXin Li                           bool Enabled);
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const2672*67e74705SXin Li   void setFeatureEnabled(llvm::StringMap<bool> &Features,
2673*67e74705SXin Li                          StringRef Name, bool Enabled) const override {
2674*67e74705SXin Li     setFeatureEnabledImpl(Features, Name, Enabled);
2675*67e74705SXin Li   }
2676*67e74705SXin Li   // This exists purely to cut down on the number of virtual calls in
2677*67e74705SXin Li   // initFeatureMap which calls this repeatedly.
2678*67e74705SXin Li   static void setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
2679*67e74705SXin Li                                     StringRef Name, bool Enabled);
2680*67e74705SXin Li   bool
2681*67e74705SXin Li   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
2682*67e74705SXin Li                  StringRef CPU,
2683*67e74705SXin Li                  const std::vector<std::string> &FeaturesVec) const override;
2684*67e74705SXin Li   bool hasFeature(StringRef Feature) const override;
2685*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
2686*67e74705SXin Li                             DiagnosticsEngine &Diags) override;
getABI() const2687*67e74705SXin Li   StringRef getABI() const override {
2688*67e74705SXin Li     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)
2689*67e74705SXin Li       return "avx512";
2690*67e74705SXin Li     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
2691*67e74705SXin Li       return "avx";
2692*67e74705SXin Li     if (getTriple().getArch() == llvm::Triple::x86 &&
2693*67e74705SXin Li              MMX3DNowLevel == NoMMX3DNow)
2694*67e74705SXin Li       return "no-mmx";
2695*67e74705SXin Li     return "";
2696*67e74705SXin Li   }
setCPU(const std::string & Name)2697*67e74705SXin Li   bool setCPU(const std::string &Name) override {
2698*67e74705SXin Li     CPU = getCPUKind(Name);
2699*67e74705SXin Li 
2700*67e74705SXin Li     // Perform any per-CPU checks necessary to determine if this CPU is
2701*67e74705SXin Li     // acceptable.
2702*67e74705SXin Li     // FIXME: This results in terrible diagnostics. Clang just says the CPU is
2703*67e74705SXin Li     // invalid without explaining *why*.
2704*67e74705SXin Li     switch (CPU) {
2705*67e74705SXin Li     case CK_Generic:
2706*67e74705SXin Li       // No processor selected!
2707*67e74705SXin Li       return false;
2708*67e74705SXin Li 
2709*67e74705SXin Li     case CK_i386:
2710*67e74705SXin Li     case CK_i486:
2711*67e74705SXin Li     case CK_WinChipC6:
2712*67e74705SXin Li     case CK_WinChip2:
2713*67e74705SXin Li     case CK_C3:
2714*67e74705SXin Li     case CK_i586:
2715*67e74705SXin Li     case CK_Pentium:
2716*67e74705SXin Li     case CK_PentiumMMX:
2717*67e74705SXin Li     case CK_i686:
2718*67e74705SXin Li     case CK_PentiumPro:
2719*67e74705SXin Li     case CK_Pentium2:
2720*67e74705SXin Li     case CK_Pentium3:
2721*67e74705SXin Li     case CK_Pentium3M:
2722*67e74705SXin Li     case CK_PentiumM:
2723*67e74705SXin Li     case CK_Yonah:
2724*67e74705SXin Li     case CK_C3_2:
2725*67e74705SXin Li     case CK_Pentium4:
2726*67e74705SXin Li     case CK_Pentium4M:
2727*67e74705SXin Li     case CK_Lakemont:
2728*67e74705SXin Li     case CK_Prescott:
2729*67e74705SXin Li     case CK_K6:
2730*67e74705SXin Li     case CK_K6_2:
2731*67e74705SXin Li     case CK_K6_3:
2732*67e74705SXin Li     case CK_Athlon:
2733*67e74705SXin Li     case CK_AthlonThunderbird:
2734*67e74705SXin Li     case CK_Athlon4:
2735*67e74705SXin Li     case CK_AthlonXP:
2736*67e74705SXin Li     case CK_AthlonMP:
2737*67e74705SXin Li     case CK_Geode:
2738*67e74705SXin Li       // Only accept certain architectures when compiling in 32-bit mode.
2739*67e74705SXin Li       if (getTriple().getArch() != llvm::Triple::x86)
2740*67e74705SXin Li         return false;
2741*67e74705SXin Li 
2742*67e74705SXin Li       // Fallthrough
2743*67e74705SXin Li     case CK_Nocona:
2744*67e74705SXin Li     case CK_Core2:
2745*67e74705SXin Li     case CK_Penryn:
2746*67e74705SXin Li     case CK_Bonnell:
2747*67e74705SXin Li     case CK_Silvermont:
2748*67e74705SXin Li     case CK_Nehalem:
2749*67e74705SXin Li     case CK_Westmere:
2750*67e74705SXin Li     case CK_SandyBridge:
2751*67e74705SXin Li     case CK_IvyBridge:
2752*67e74705SXin Li     case CK_Haswell:
2753*67e74705SXin Li     case CK_Broadwell:
2754*67e74705SXin Li     case CK_SkylakeClient:
2755*67e74705SXin Li     case CK_SkylakeServer:
2756*67e74705SXin Li     case CK_Cannonlake:
2757*67e74705SXin Li     case CK_KNL:
2758*67e74705SXin Li     case CK_Athlon64:
2759*67e74705SXin Li     case CK_Athlon64SSE3:
2760*67e74705SXin Li     case CK_AthlonFX:
2761*67e74705SXin Li     case CK_K8:
2762*67e74705SXin Li     case CK_K8SSE3:
2763*67e74705SXin Li     case CK_Opteron:
2764*67e74705SXin Li     case CK_OpteronSSE3:
2765*67e74705SXin Li     case CK_AMDFAM10:
2766*67e74705SXin Li     case CK_BTVER1:
2767*67e74705SXin Li     case CK_BTVER2:
2768*67e74705SXin Li     case CK_BDVER1:
2769*67e74705SXin Li     case CK_BDVER2:
2770*67e74705SXin Li     case CK_BDVER3:
2771*67e74705SXin Li     case CK_BDVER4:
2772*67e74705SXin Li     case CK_x86_64:
2773*67e74705SXin Li       return true;
2774*67e74705SXin Li     }
2775*67e74705SXin Li     llvm_unreachable("Unhandled CPU kind");
2776*67e74705SXin Li   }
2777*67e74705SXin Li 
2778*67e74705SXin Li   bool setFPMath(StringRef Name) override;
2779*67e74705SXin Li 
checkCallingConvention(CallingConv CC) const2780*67e74705SXin Li   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
2781*67e74705SXin Li     // Most of the non-ARM calling conventions are i386 conventions.
2782*67e74705SXin Li     switch (CC) {
2783*67e74705SXin Li     case CC_X86ThisCall:
2784*67e74705SXin Li     case CC_X86FastCall:
2785*67e74705SXin Li     case CC_X86StdCall:
2786*67e74705SXin Li     case CC_X86VectorCall:
2787*67e74705SXin Li     case CC_C:
2788*67e74705SXin Li     case CC_Swift:
2789*67e74705SXin Li     case CC_X86Pascal:
2790*67e74705SXin Li     case CC_IntelOclBicc:
2791*67e74705SXin Li       return CCCR_OK;
2792*67e74705SXin Li     default:
2793*67e74705SXin Li       return CCCR_Warning;
2794*67e74705SXin Li     }
2795*67e74705SXin Li   }
2796*67e74705SXin Li 
getDefaultCallingConv(CallingConvMethodType MT) const2797*67e74705SXin Li   CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
2798*67e74705SXin Li     return MT == CCMT_Member ? CC_X86ThisCall : CC_C;
2799*67e74705SXin Li   }
2800*67e74705SXin Li 
hasSjLjLowering() const2801*67e74705SXin Li   bool hasSjLjLowering() const override {
2802*67e74705SXin Li     return true;
2803*67e74705SXin Li   }
2804*67e74705SXin Li 
setSupportedOpenCLOpts()2805*67e74705SXin Li   void setSupportedOpenCLOpts() override {
2806*67e74705SXin Li     getSupportedOpenCLOpts().setAll();
2807*67e74705SXin Li   }
2808*67e74705SXin Li };
2809*67e74705SXin Li 
setFPMath(StringRef Name)2810*67e74705SXin Li bool X86TargetInfo::setFPMath(StringRef Name) {
2811*67e74705SXin Li   if (Name == "387") {
2812*67e74705SXin Li     FPMath = FP_387;
2813*67e74705SXin Li     return true;
2814*67e74705SXin Li   }
2815*67e74705SXin Li   if (Name == "sse") {
2816*67e74705SXin Li     FPMath = FP_SSE;
2817*67e74705SXin Li     return true;
2818*67e74705SXin Li   }
2819*67e74705SXin Li   return false;
2820*67e74705SXin Li }
2821*67e74705SXin Li 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const2822*67e74705SXin Li bool X86TargetInfo::initFeatureMap(
2823*67e74705SXin Li     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
2824*67e74705SXin Li     const std::vector<std::string> &FeaturesVec) const {
2825*67e74705SXin Li   // FIXME: This *really* should not be here.
2826*67e74705SXin Li   // X86_64 always has SSE2.
2827*67e74705SXin Li   if (getTriple().getArch() == llvm::Triple::x86_64)
2828*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse2", true);
2829*67e74705SXin Li 
2830*67e74705SXin Li   const CPUKind Kind = getCPUKind(CPU);
2831*67e74705SXin Li 
2832*67e74705SXin Li   // Enable X87 for all X86 processors but Lakemont.
2833*67e74705SXin Li   if (Kind != CK_Lakemont)
2834*67e74705SXin Li     setFeatureEnabledImpl(Features, "x87", true);
2835*67e74705SXin Li 
2836*67e74705SXin Li   switch (Kind) {
2837*67e74705SXin Li   case CK_Generic:
2838*67e74705SXin Li   case CK_i386:
2839*67e74705SXin Li   case CK_i486:
2840*67e74705SXin Li   case CK_i586:
2841*67e74705SXin Li   case CK_Pentium:
2842*67e74705SXin Li   case CK_i686:
2843*67e74705SXin Li   case CK_PentiumPro:
2844*67e74705SXin Li   case CK_Lakemont:
2845*67e74705SXin Li     break;
2846*67e74705SXin Li   case CK_PentiumMMX:
2847*67e74705SXin Li   case CK_Pentium2:
2848*67e74705SXin Li   case CK_K6:
2849*67e74705SXin Li   case CK_WinChipC6:
2850*67e74705SXin Li     setFeatureEnabledImpl(Features, "mmx", true);
2851*67e74705SXin Li     break;
2852*67e74705SXin Li   case CK_Pentium3:
2853*67e74705SXin Li   case CK_Pentium3M:
2854*67e74705SXin Li   case CK_C3_2:
2855*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse", true);
2856*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
2857*67e74705SXin Li     break;
2858*67e74705SXin Li   case CK_PentiumM:
2859*67e74705SXin Li   case CK_Pentium4:
2860*67e74705SXin Li   case CK_Pentium4M:
2861*67e74705SXin Li   case CK_x86_64:
2862*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse2", true);
2863*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
2864*67e74705SXin Li     break;
2865*67e74705SXin Li   case CK_Yonah:
2866*67e74705SXin Li   case CK_Prescott:
2867*67e74705SXin Li   case CK_Nocona:
2868*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse3", true);
2869*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
2870*67e74705SXin Li     setFeatureEnabledImpl(Features, "cx16", true);
2871*67e74705SXin Li     break;
2872*67e74705SXin Li   case CK_Core2:
2873*67e74705SXin Li   case CK_Bonnell:
2874*67e74705SXin Li     setFeatureEnabledImpl(Features, "ssse3", true);
2875*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
2876*67e74705SXin Li     setFeatureEnabledImpl(Features, "cx16", true);
2877*67e74705SXin Li     break;
2878*67e74705SXin Li   case CK_Penryn:
2879*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse4.1", true);
2880*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
2881*67e74705SXin Li     setFeatureEnabledImpl(Features, "cx16", true);
2882*67e74705SXin Li     break;
2883*67e74705SXin Li   case CK_Cannonlake:
2884*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512ifma", true);
2885*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512vbmi", true);
2886*67e74705SXin Li     setFeatureEnabledImpl(Features, "sha", true);
2887*67e74705SXin Li     setFeatureEnabledImpl(Features, "umip", true);
2888*67e74705SXin Li     // FALLTHROUGH
2889*67e74705SXin Li   case CK_SkylakeServer:
2890*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512f", true);
2891*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512cd", true);
2892*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512dq", true);
2893*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512bw", true);
2894*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512vl", true);
2895*67e74705SXin Li     setFeatureEnabledImpl(Features, "pku", true);
2896*67e74705SXin Li     setFeatureEnabledImpl(Features, "pcommit", true);
2897*67e74705SXin Li     setFeatureEnabledImpl(Features, "clwb", true);
2898*67e74705SXin Li     // FALLTHROUGH
2899*67e74705SXin Li   case CK_SkylakeClient:
2900*67e74705SXin Li     setFeatureEnabledImpl(Features, "xsavec", true);
2901*67e74705SXin Li     setFeatureEnabledImpl(Features, "xsaves", true);
2902*67e74705SXin Li     setFeatureEnabledImpl(Features, "mpx", true);
2903*67e74705SXin Li     setFeatureEnabledImpl(Features, "sgx", true);
2904*67e74705SXin Li     setFeatureEnabledImpl(Features, "clflushopt", true);
2905*67e74705SXin Li     // FALLTHROUGH
2906*67e74705SXin Li   case CK_Broadwell:
2907*67e74705SXin Li     setFeatureEnabledImpl(Features, "rdseed", true);
2908*67e74705SXin Li     setFeatureEnabledImpl(Features, "adx", true);
2909*67e74705SXin Li     // FALLTHROUGH
2910*67e74705SXin Li   case CK_Haswell:
2911*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx2", true);
2912*67e74705SXin Li     setFeatureEnabledImpl(Features, "lzcnt", true);
2913*67e74705SXin Li     setFeatureEnabledImpl(Features, "bmi", true);
2914*67e74705SXin Li     setFeatureEnabledImpl(Features, "bmi2", true);
2915*67e74705SXin Li     setFeatureEnabledImpl(Features, "rtm", true);
2916*67e74705SXin Li     setFeatureEnabledImpl(Features, "fma", true);
2917*67e74705SXin Li     setFeatureEnabledImpl(Features, "movbe", true);
2918*67e74705SXin Li     // FALLTHROUGH
2919*67e74705SXin Li   case CK_IvyBridge:
2920*67e74705SXin Li     setFeatureEnabledImpl(Features, "rdrnd", true);
2921*67e74705SXin Li     setFeatureEnabledImpl(Features, "f16c", true);
2922*67e74705SXin Li     setFeatureEnabledImpl(Features, "fsgsbase", true);
2923*67e74705SXin Li     // FALLTHROUGH
2924*67e74705SXin Li   case CK_SandyBridge:
2925*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx", true);
2926*67e74705SXin Li     setFeatureEnabledImpl(Features, "xsave", true);
2927*67e74705SXin Li     setFeatureEnabledImpl(Features, "xsaveopt", true);
2928*67e74705SXin Li     // FALLTHROUGH
2929*67e74705SXin Li   case CK_Westmere:
2930*67e74705SXin Li   case CK_Silvermont:
2931*67e74705SXin Li     setFeatureEnabledImpl(Features, "aes", true);
2932*67e74705SXin Li     setFeatureEnabledImpl(Features, "pclmul", true);
2933*67e74705SXin Li     // FALLTHROUGH
2934*67e74705SXin Li   case CK_Nehalem:
2935*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse4.2", true);
2936*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
2937*67e74705SXin Li     setFeatureEnabledImpl(Features, "cx16", true);
2938*67e74705SXin Li     break;
2939*67e74705SXin Li   case CK_KNL:
2940*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512f", true);
2941*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512cd", true);
2942*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512er", true);
2943*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx512pf", true);
2944*67e74705SXin Li     setFeatureEnabledImpl(Features, "prefetchwt1", true);
2945*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
2946*67e74705SXin Li     setFeatureEnabledImpl(Features, "rdseed", true);
2947*67e74705SXin Li     setFeatureEnabledImpl(Features, "adx", true);
2948*67e74705SXin Li     setFeatureEnabledImpl(Features, "lzcnt", true);
2949*67e74705SXin Li     setFeatureEnabledImpl(Features, "bmi", true);
2950*67e74705SXin Li     setFeatureEnabledImpl(Features, "bmi2", true);
2951*67e74705SXin Li     setFeatureEnabledImpl(Features, "rtm", true);
2952*67e74705SXin Li     setFeatureEnabledImpl(Features, "fma", true);
2953*67e74705SXin Li     setFeatureEnabledImpl(Features, "rdrnd", true);
2954*67e74705SXin Li     setFeatureEnabledImpl(Features, "f16c", true);
2955*67e74705SXin Li     setFeatureEnabledImpl(Features, "fsgsbase", true);
2956*67e74705SXin Li     setFeatureEnabledImpl(Features, "aes", true);
2957*67e74705SXin Li     setFeatureEnabledImpl(Features, "pclmul", true);
2958*67e74705SXin Li     setFeatureEnabledImpl(Features, "cx16", true);
2959*67e74705SXin Li     setFeatureEnabledImpl(Features, "xsaveopt", true);
2960*67e74705SXin Li     setFeatureEnabledImpl(Features, "xsave", true);
2961*67e74705SXin Li     setFeatureEnabledImpl(Features, "movbe", true);
2962*67e74705SXin Li     break;
2963*67e74705SXin Li   case CK_K6_2:
2964*67e74705SXin Li   case CK_K6_3:
2965*67e74705SXin Li   case CK_WinChip2:
2966*67e74705SXin Li   case CK_C3:
2967*67e74705SXin Li     setFeatureEnabledImpl(Features, "3dnow", true);
2968*67e74705SXin Li     break;
2969*67e74705SXin Li   case CK_Athlon:
2970*67e74705SXin Li   case CK_AthlonThunderbird:
2971*67e74705SXin Li   case CK_Geode:
2972*67e74705SXin Li     setFeatureEnabledImpl(Features, "3dnowa", true);
2973*67e74705SXin Li     break;
2974*67e74705SXin Li   case CK_Athlon4:
2975*67e74705SXin Li   case CK_AthlonXP:
2976*67e74705SXin Li   case CK_AthlonMP:
2977*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse", true);
2978*67e74705SXin Li     setFeatureEnabledImpl(Features, "3dnowa", true);
2979*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
2980*67e74705SXin Li     break;
2981*67e74705SXin Li   case CK_K8:
2982*67e74705SXin Li   case CK_Opteron:
2983*67e74705SXin Li   case CK_Athlon64:
2984*67e74705SXin Li   case CK_AthlonFX:
2985*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse2", true);
2986*67e74705SXin Li     setFeatureEnabledImpl(Features, "3dnowa", true);
2987*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
2988*67e74705SXin Li     break;
2989*67e74705SXin Li   case CK_AMDFAM10:
2990*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse4a", true);
2991*67e74705SXin Li     setFeatureEnabledImpl(Features, "lzcnt", true);
2992*67e74705SXin Li     setFeatureEnabledImpl(Features, "popcnt", true);
2993*67e74705SXin Li     // FALLTHROUGH
2994*67e74705SXin Li   case CK_K8SSE3:
2995*67e74705SXin Li   case CK_OpteronSSE3:
2996*67e74705SXin Li   case CK_Athlon64SSE3:
2997*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse3", true);
2998*67e74705SXin Li     setFeatureEnabledImpl(Features, "3dnowa", true);
2999*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
3000*67e74705SXin Li     break;
3001*67e74705SXin Li   case CK_BTVER2:
3002*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx", true);
3003*67e74705SXin Li     setFeatureEnabledImpl(Features, "aes", true);
3004*67e74705SXin Li     setFeatureEnabledImpl(Features, "pclmul", true);
3005*67e74705SXin Li     setFeatureEnabledImpl(Features, "bmi", true);
3006*67e74705SXin Li     setFeatureEnabledImpl(Features, "f16c", true);
3007*67e74705SXin Li     setFeatureEnabledImpl(Features, "xsaveopt", true);
3008*67e74705SXin Li     // FALLTHROUGH
3009*67e74705SXin Li   case CK_BTVER1:
3010*67e74705SXin Li     setFeatureEnabledImpl(Features, "ssse3", true);
3011*67e74705SXin Li     setFeatureEnabledImpl(Features, "sse4a", true);
3012*67e74705SXin Li     setFeatureEnabledImpl(Features, "lzcnt", true);
3013*67e74705SXin Li     setFeatureEnabledImpl(Features, "popcnt", true);
3014*67e74705SXin Li     setFeatureEnabledImpl(Features, "prfchw", true);
3015*67e74705SXin Li     setFeatureEnabledImpl(Features, "cx16", true);
3016*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
3017*67e74705SXin Li     break;
3018*67e74705SXin Li   case CK_BDVER4:
3019*67e74705SXin Li     setFeatureEnabledImpl(Features, "avx2", true);
3020*67e74705SXin Li     setFeatureEnabledImpl(Features, "bmi2", true);
3021*67e74705SXin Li     setFeatureEnabledImpl(Features, "mwaitx", true);
3022*67e74705SXin Li     // FALLTHROUGH
3023*67e74705SXin Li   case CK_BDVER3:
3024*67e74705SXin Li     setFeatureEnabledImpl(Features, "fsgsbase", true);
3025*67e74705SXin Li     setFeatureEnabledImpl(Features, "xsaveopt", true);
3026*67e74705SXin Li     // FALLTHROUGH
3027*67e74705SXin Li   case CK_BDVER2:
3028*67e74705SXin Li     setFeatureEnabledImpl(Features, "bmi", true);
3029*67e74705SXin Li     setFeatureEnabledImpl(Features, "fma", true);
3030*67e74705SXin Li     setFeatureEnabledImpl(Features, "f16c", true);
3031*67e74705SXin Li     setFeatureEnabledImpl(Features, "tbm", true);
3032*67e74705SXin Li     // FALLTHROUGH
3033*67e74705SXin Li   case CK_BDVER1:
3034*67e74705SXin Li     // xop implies avx, sse4a and fma4.
3035*67e74705SXin Li     setFeatureEnabledImpl(Features, "xop", true);
3036*67e74705SXin Li     setFeatureEnabledImpl(Features, "lzcnt", true);
3037*67e74705SXin Li     setFeatureEnabledImpl(Features, "aes", true);
3038*67e74705SXin Li     setFeatureEnabledImpl(Features, "pclmul", true);
3039*67e74705SXin Li     setFeatureEnabledImpl(Features, "prfchw", true);
3040*67e74705SXin Li     setFeatureEnabledImpl(Features, "cx16", true);
3041*67e74705SXin Li     setFeatureEnabledImpl(Features, "fxsr", true);
3042*67e74705SXin Li     setFeatureEnabledImpl(Features, "xsave", true);
3043*67e74705SXin Li     break;
3044*67e74705SXin Li   }
3045*67e74705SXin Li   if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec))
3046*67e74705SXin Li     return false;
3047*67e74705SXin Li 
3048*67e74705SXin Li   // Can't do this earlier because we need to be able to explicitly enable
3049*67e74705SXin Li   // or disable these features and the things that they depend upon.
3050*67e74705SXin Li 
3051*67e74705SXin Li   // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
3052*67e74705SXin Li   auto I = Features.find("sse4.2");
3053*67e74705SXin Li   if (I != Features.end() && I->getValue() &&
3054*67e74705SXin Li       std::find(FeaturesVec.begin(), FeaturesVec.end(), "-popcnt") ==
3055*67e74705SXin Li           FeaturesVec.end())
3056*67e74705SXin Li     Features["popcnt"] = true;
3057*67e74705SXin Li 
3058*67e74705SXin Li   // Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled.
3059*67e74705SXin Li   I = Features.find("3dnow");
3060*67e74705SXin Li   if (I != Features.end() && I->getValue() &&
3061*67e74705SXin Li       std::find(FeaturesVec.begin(), FeaturesVec.end(), "-prfchw") ==
3062*67e74705SXin Li           FeaturesVec.end())
3063*67e74705SXin Li     Features["prfchw"] = true;
3064*67e74705SXin Li 
3065*67e74705SXin Li   // Additionally, if SSE is enabled and mmx is not explicitly disabled,
3066*67e74705SXin Li   // then enable MMX.
3067*67e74705SXin Li   I = Features.find("sse");
3068*67e74705SXin Li   if (I != Features.end() && I->getValue() &&
3069*67e74705SXin Li       std::find(FeaturesVec.begin(), FeaturesVec.end(), "-mmx") ==
3070*67e74705SXin Li           FeaturesVec.end())
3071*67e74705SXin Li     Features["mmx"] = true;
3072*67e74705SXin Li 
3073*67e74705SXin Li   return true;
3074*67e74705SXin Li }
3075*67e74705SXin Li 
setSSELevel(llvm::StringMap<bool> & Features,X86SSEEnum Level,bool Enabled)3076*67e74705SXin Li void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
3077*67e74705SXin Li                                 X86SSEEnum Level, bool Enabled) {
3078*67e74705SXin Li   if (Enabled) {
3079*67e74705SXin Li     switch (Level) {
3080*67e74705SXin Li     case AVX512F:
3081*67e74705SXin Li       Features["avx512f"] = true;
3082*67e74705SXin Li     case AVX2:
3083*67e74705SXin Li       Features["avx2"] = true;
3084*67e74705SXin Li     case AVX:
3085*67e74705SXin Li       Features["avx"] = true;
3086*67e74705SXin Li       Features["xsave"] = true;
3087*67e74705SXin Li     case SSE42:
3088*67e74705SXin Li       Features["sse4.2"] = true;
3089*67e74705SXin Li     case SSE41:
3090*67e74705SXin Li       Features["sse4.1"] = true;
3091*67e74705SXin Li     case SSSE3:
3092*67e74705SXin Li       Features["ssse3"] = true;
3093*67e74705SXin Li     case SSE3:
3094*67e74705SXin Li       Features["sse3"] = true;
3095*67e74705SXin Li     case SSE2:
3096*67e74705SXin Li       Features["sse2"] = true;
3097*67e74705SXin Li     case SSE1:
3098*67e74705SXin Li       Features["sse"] = true;
3099*67e74705SXin Li     case NoSSE:
3100*67e74705SXin Li       break;
3101*67e74705SXin Li     }
3102*67e74705SXin Li     return;
3103*67e74705SXin Li   }
3104*67e74705SXin Li 
3105*67e74705SXin Li   switch (Level) {
3106*67e74705SXin Li   case NoSSE:
3107*67e74705SXin Li   case SSE1:
3108*67e74705SXin Li     Features["sse"] = false;
3109*67e74705SXin Li   case SSE2:
3110*67e74705SXin Li     Features["sse2"] = Features["pclmul"] = Features["aes"] =
3111*67e74705SXin Li       Features["sha"] = false;
3112*67e74705SXin Li   case SSE3:
3113*67e74705SXin Li     Features["sse3"] = false;
3114*67e74705SXin Li     setXOPLevel(Features, NoXOP, false);
3115*67e74705SXin Li   case SSSE3:
3116*67e74705SXin Li     Features["ssse3"] = false;
3117*67e74705SXin Li   case SSE41:
3118*67e74705SXin Li     Features["sse4.1"] = false;
3119*67e74705SXin Li   case SSE42:
3120*67e74705SXin Li     Features["sse4.2"] = false;
3121*67e74705SXin Li   case AVX:
3122*67e74705SXin Li     Features["fma"] = Features["avx"] = Features["f16c"] = Features["xsave"] =
3123*67e74705SXin Li       Features["xsaveopt"] = false;
3124*67e74705SXin Li     setXOPLevel(Features, FMA4, false);
3125*67e74705SXin Li   case AVX2:
3126*67e74705SXin Li     Features["avx2"] = false;
3127*67e74705SXin Li   case AVX512F:
3128*67e74705SXin Li     Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] =
3129*67e74705SXin Li       Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] =
3130*67e74705SXin Li       Features["avx512vl"] = Features["avx512vbmi"] =
3131*67e74705SXin Li       Features["avx512ifma"] = false;
3132*67e74705SXin Li   }
3133*67e74705SXin Li }
3134*67e74705SXin Li 
setMMXLevel(llvm::StringMap<bool> & Features,MMX3DNowEnum Level,bool Enabled)3135*67e74705SXin Li void X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features,
3136*67e74705SXin Li                                 MMX3DNowEnum Level, bool Enabled) {
3137*67e74705SXin Li   if (Enabled) {
3138*67e74705SXin Li     switch (Level) {
3139*67e74705SXin Li     case AMD3DNowAthlon:
3140*67e74705SXin Li       Features["3dnowa"] = true;
3141*67e74705SXin Li     case AMD3DNow:
3142*67e74705SXin Li       Features["3dnow"] = true;
3143*67e74705SXin Li     case MMX:
3144*67e74705SXin Li       Features["mmx"] = true;
3145*67e74705SXin Li     case NoMMX3DNow:
3146*67e74705SXin Li       break;
3147*67e74705SXin Li     }
3148*67e74705SXin Li     return;
3149*67e74705SXin Li   }
3150*67e74705SXin Li 
3151*67e74705SXin Li   switch (Level) {
3152*67e74705SXin Li   case NoMMX3DNow:
3153*67e74705SXin Li   case MMX:
3154*67e74705SXin Li     Features["mmx"] = false;
3155*67e74705SXin Li   case AMD3DNow:
3156*67e74705SXin Li     Features["3dnow"] = false;
3157*67e74705SXin Li   case AMD3DNowAthlon:
3158*67e74705SXin Li     Features["3dnowa"] = false;
3159*67e74705SXin Li   }
3160*67e74705SXin Li }
3161*67e74705SXin Li 
setXOPLevel(llvm::StringMap<bool> & Features,XOPEnum Level,bool Enabled)3162*67e74705SXin Li void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
3163*67e74705SXin Li                                 bool Enabled) {
3164*67e74705SXin Li   if (Enabled) {
3165*67e74705SXin Li     switch (Level) {
3166*67e74705SXin Li     case XOP:
3167*67e74705SXin Li       Features["xop"] = true;
3168*67e74705SXin Li     case FMA4:
3169*67e74705SXin Li       Features["fma4"] = true;
3170*67e74705SXin Li       setSSELevel(Features, AVX, true);
3171*67e74705SXin Li     case SSE4A:
3172*67e74705SXin Li       Features["sse4a"] = true;
3173*67e74705SXin Li       setSSELevel(Features, SSE3, true);
3174*67e74705SXin Li     case NoXOP:
3175*67e74705SXin Li       break;
3176*67e74705SXin Li     }
3177*67e74705SXin Li     return;
3178*67e74705SXin Li   }
3179*67e74705SXin Li 
3180*67e74705SXin Li   switch (Level) {
3181*67e74705SXin Li   case NoXOP:
3182*67e74705SXin Li   case SSE4A:
3183*67e74705SXin Li     Features["sse4a"] = false;
3184*67e74705SXin Li   case FMA4:
3185*67e74705SXin Li     Features["fma4"] = false;
3186*67e74705SXin Li   case XOP:
3187*67e74705SXin Li     Features["xop"] = false;
3188*67e74705SXin Li   }
3189*67e74705SXin Li }
3190*67e74705SXin Li 
setFeatureEnabledImpl(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled)3191*67e74705SXin Li void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
3192*67e74705SXin Li                                           StringRef Name, bool Enabled) {
3193*67e74705SXin Li   // This is a bit of a hack to deal with the sse4 target feature when used
3194*67e74705SXin Li   // as part of the target attribute. We handle sse4 correctly everywhere
3195*67e74705SXin Li   // else. See below for more information on how we handle the sse4 options.
3196*67e74705SXin Li   if (Name != "sse4")
3197*67e74705SXin Li     Features[Name] = Enabled;
3198*67e74705SXin Li 
3199*67e74705SXin Li   if (Name == "mmx") {
3200*67e74705SXin Li     setMMXLevel(Features, MMX, Enabled);
3201*67e74705SXin Li   } else if (Name == "sse") {
3202*67e74705SXin Li     setSSELevel(Features, SSE1, Enabled);
3203*67e74705SXin Li   } else if (Name == "sse2") {
3204*67e74705SXin Li     setSSELevel(Features, SSE2, Enabled);
3205*67e74705SXin Li   } else if (Name == "sse3") {
3206*67e74705SXin Li     setSSELevel(Features, SSE3, Enabled);
3207*67e74705SXin Li   } else if (Name == "ssse3") {
3208*67e74705SXin Li     setSSELevel(Features, SSSE3, Enabled);
3209*67e74705SXin Li   } else if (Name == "sse4.2") {
3210*67e74705SXin Li     setSSELevel(Features, SSE42, Enabled);
3211*67e74705SXin Li   } else if (Name == "sse4.1") {
3212*67e74705SXin Li     setSSELevel(Features, SSE41, Enabled);
3213*67e74705SXin Li   } else if (Name == "3dnow") {
3214*67e74705SXin Li     setMMXLevel(Features, AMD3DNow, Enabled);
3215*67e74705SXin Li   } else if (Name == "3dnowa") {
3216*67e74705SXin Li     setMMXLevel(Features, AMD3DNowAthlon, Enabled);
3217*67e74705SXin Li   } else if (Name == "aes") {
3218*67e74705SXin Li     if (Enabled)
3219*67e74705SXin Li       setSSELevel(Features, SSE2, Enabled);
3220*67e74705SXin Li   } else if (Name == "pclmul") {
3221*67e74705SXin Li     if (Enabled)
3222*67e74705SXin Li       setSSELevel(Features, SSE2, Enabled);
3223*67e74705SXin Li   } else if (Name == "avx") {
3224*67e74705SXin Li     setSSELevel(Features, AVX, Enabled);
3225*67e74705SXin Li   } else if (Name == "avx2") {
3226*67e74705SXin Li     setSSELevel(Features, AVX2, Enabled);
3227*67e74705SXin Li   } else if (Name == "avx512f") {
3228*67e74705SXin Li     setSSELevel(Features, AVX512F, Enabled);
3229*67e74705SXin Li   } else if (Name == "avx512cd" || Name == "avx512er" || Name == "avx512pf" ||
3230*67e74705SXin Li              Name == "avx512dq" || Name == "avx512bw" || Name == "avx512vl" ||
3231*67e74705SXin Li              Name == "avx512vbmi" || Name == "avx512ifma") {
3232*67e74705SXin Li     if (Enabled)
3233*67e74705SXin Li       setSSELevel(Features, AVX512F, Enabled);
3234*67e74705SXin Li   } else if (Name == "fma") {
3235*67e74705SXin Li     if (Enabled)
3236*67e74705SXin Li       setSSELevel(Features, AVX, Enabled);
3237*67e74705SXin Li   } else if (Name == "fma4") {
3238*67e74705SXin Li     setXOPLevel(Features, FMA4, Enabled);
3239*67e74705SXin Li   } else if (Name == "xop") {
3240*67e74705SXin Li     setXOPLevel(Features, XOP, Enabled);
3241*67e74705SXin Li   } else if (Name == "sse4a") {
3242*67e74705SXin Li     setXOPLevel(Features, SSE4A, Enabled);
3243*67e74705SXin Li   } else if (Name == "f16c") {
3244*67e74705SXin Li     if (Enabled)
3245*67e74705SXin Li       setSSELevel(Features, AVX, Enabled);
3246*67e74705SXin Li   } else if (Name == "sha") {
3247*67e74705SXin Li     if (Enabled)
3248*67e74705SXin Li       setSSELevel(Features, SSE2, Enabled);
3249*67e74705SXin Li   } else if (Name == "sse4") {
3250*67e74705SXin Li     // We can get here via the __target__ attribute since that's not controlled
3251*67e74705SXin Li     // via the -msse4/-mno-sse4 command line alias. Handle this the same way
3252*67e74705SXin Li     // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if
3253*67e74705SXin Li     // disabled.
3254*67e74705SXin Li     if (Enabled)
3255*67e74705SXin Li       setSSELevel(Features, SSE42, Enabled);
3256*67e74705SXin Li     else
3257*67e74705SXin Li       setSSELevel(Features, SSE41, Enabled);
3258*67e74705SXin Li   } else if (Name == "xsave") {
3259*67e74705SXin Li     if (!Enabled)
3260*67e74705SXin Li       Features["xsaveopt"] = false;
3261*67e74705SXin Li   } else if (Name == "xsaveopt" || Name == "xsavec" || Name == "xsaves") {
3262*67e74705SXin Li     if (Enabled)
3263*67e74705SXin Li       Features["xsave"] = true;
3264*67e74705SXin Li   }
3265*67e74705SXin Li }
3266*67e74705SXin Li 
3267*67e74705SXin Li /// handleTargetFeatures - Perform initialization based on the user
3268*67e74705SXin Li /// configured set of features.
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)3269*67e74705SXin Li bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
3270*67e74705SXin Li                                          DiagnosticsEngine &Diags) {
3271*67e74705SXin Li   for (const auto &Feature : Features) {
3272*67e74705SXin Li     if (Feature[0] != '+')
3273*67e74705SXin Li       continue;
3274*67e74705SXin Li 
3275*67e74705SXin Li     if (Feature == "+aes") {
3276*67e74705SXin Li       HasAES = true;
3277*67e74705SXin Li     } else if (Feature == "+pclmul") {
3278*67e74705SXin Li       HasPCLMUL = true;
3279*67e74705SXin Li     } else if (Feature == "+lzcnt") {
3280*67e74705SXin Li       HasLZCNT = true;
3281*67e74705SXin Li     } else if (Feature == "+rdrnd") {
3282*67e74705SXin Li       HasRDRND = true;
3283*67e74705SXin Li     } else if (Feature == "+fsgsbase") {
3284*67e74705SXin Li       HasFSGSBASE = true;
3285*67e74705SXin Li     } else if (Feature == "+bmi") {
3286*67e74705SXin Li       HasBMI = true;
3287*67e74705SXin Li     } else if (Feature == "+bmi2") {
3288*67e74705SXin Li       HasBMI2 = true;
3289*67e74705SXin Li     } else if (Feature == "+popcnt") {
3290*67e74705SXin Li       HasPOPCNT = true;
3291*67e74705SXin Li     } else if (Feature == "+rtm") {
3292*67e74705SXin Li       HasRTM = true;
3293*67e74705SXin Li     } else if (Feature == "+prfchw") {
3294*67e74705SXin Li       HasPRFCHW = true;
3295*67e74705SXin Li     } else if (Feature == "+rdseed") {
3296*67e74705SXin Li       HasRDSEED = true;
3297*67e74705SXin Li     } else if (Feature == "+adx") {
3298*67e74705SXin Li       HasADX = true;
3299*67e74705SXin Li     } else if (Feature == "+tbm") {
3300*67e74705SXin Li       HasTBM = true;
3301*67e74705SXin Li     } else if (Feature == "+fma") {
3302*67e74705SXin Li       HasFMA = true;
3303*67e74705SXin Li     } else if (Feature == "+f16c") {
3304*67e74705SXin Li       HasF16C = true;
3305*67e74705SXin Li     } else if (Feature == "+avx512cd") {
3306*67e74705SXin Li       HasAVX512CD = true;
3307*67e74705SXin Li     } else if (Feature == "+avx512er") {
3308*67e74705SXin Li       HasAVX512ER = true;
3309*67e74705SXin Li     } else if (Feature == "+avx512pf") {
3310*67e74705SXin Li       HasAVX512PF = true;
3311*67e74705SXin Li     } else if (Feature == "+avx512dq") {
3312*67e74705SXin Li       HasAVX512DQ = true;
3313*67e74705SXin Li     } else if (Feature == "+avx512bw") {
3314*67e74705SXin Li       HasAVX512BW = true;
3315*67e74705SXin Li     } else if (Feature == "+avx512vl") {
3316*67e74705SXin Li       HasAVX512VL = true;
3317*67e74705SXin Li     } else if (Feature == "+avx512vbmi") {
3318*67e74705SXin Li       HasAVX512VBMI = true;
3319*67e74705SXin Li     } else if (Feature == "+avx512ifma") {
3320*67e74705SXin Li       HasAVX512IFMA = true;
3321*67e74705SXin Li     } else if (Feature == "+sha") {
3322*67e74705SXin Li       HasSHA = true;
3323*67e74705SXin Li     } else if (Feature == "+mpx") {
3324*67e74705SXin Li       HasMPX = true;
3325*67e74705SXin Li     } else if (Feature == "+movbe") {
3326*67e74705SXin Li       HasMOVBE = true;
3327*67e74705SXin Li     } else if (Feature == "+sgx") {
3328*67e74705SXin Li       HasSGX = true;
3329*67e74705SXin Li     } else if (Feature == "+cx16") {
3330*67e74705SXin Li       HasCX16 = true;
3331*67e74705SXin Li     } else if (Feature == "+fxsr") {
3332*67e74705SXin Li       HasFXSR = true;
3333*67e74705SXin Li     } else if (Feature == "+xsave") {
3334*67e74705SXin Li       HasXSAVE = true;
3335*67e74705SXin Li     } else if (Feature == "+xsaveopt") {
3336*67e74705SXin Li       HasXSAVEOPT = true;
3337*67e74705SXin Li     } else if (Feature == "+xsavec") {
3338*67e74705SXin Li       HasXSAVEC = true;
3339*67e74705SXin Li     } else if (Feature == "+xsaves") {
3340*67e74705SXin Li       HasXSAVES = true;
3341*67e74705SXin Li     } else if (Feature == "+mwaitx") {
3342*67e74705SXin Li       HasMWAITX = true;
3343*67e74705SXin Li     } else if (Feature == "+pku") {
3344*67e74705SXin Li       HasPKU = true;
3345*67e74705SXin Li     } else if (Feature == "+clflushopt") {
3346*67e74705SXin Li       HasCLFLUSHOPT = true;
3347*67e74705SXin Li     } else if (Feature == "+pcommit") {
3348*67e74705SXin Li       HasPCOMMIT = true;
3349*67e74705SXin Li     } else if (Feature == "+clwb") {
3350*67e74705SXin Li       HasCLWB = true;
3351*67e74705SXin Li     } else if (Feature == "+umip") {
3352*67e74705SXin Li       HasUMIP = true;
3353*67e74705SXin Li     } else if (Feature == "+prefetchwt1") {
3354*67e74705SXin Li       HasPREFETCHWT1 = true;
3355*67e74705SXin Li     }
3356*67e74705SXin Li 
3357*67e74705SXin Li     X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
3358*67e74705SXin Li       .Case("+avx512f", AVX512F)
3359*67e74705SXin Li       .Case("+avx2", AVX2)
3360*67e74705SXin Li       .Case("+avx", AVX)
3361*67e74705SXin Li       .Case("+sse4.2", SSE42)
3362*67e74705SXin Li       .Case("+sse4.1", SSE41)
3363*67e74705SXin Li       .Case("+ssse3", SSSE3)
3364*67e74705SXin Li       .Case("+sse3", SSE3)
3365*67e74705SXin Li       .Case("+sse2", SSE2)
3366*67e74705SXin Li       .Case("+sse", SSE1)
3367*67e74705SXin Li       .Default(NoSSE);
3368*67e74705SXin Li     SSELevel = std::max(SSELevel, Level);
3369*67e74705SXin Li 
3370*67e74705SXin Li     MMX3DNowEnum ThreeDNowLevel =
3371*67e74705SXin Li       llvm::StringSwitch<MMX3DNowEnum>(Feature)
3372*67e74705SXin Li         .Case("+3dnowa", AMD3DNowAthlon)
3373*67e74705SXin Li         .Case("+3dnow", AMD3DNow)
3374*67e74705SXin Li         .Case("+mmx", MMX)
3375*67e74705SXin Li         .Default(NoMMX3DNow);
3376*67e74705SXin Li     MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
3377*67e74705SXin Li 
3378*67e74705SXin Li     XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
3379*67e74705SXin Li         .Case("+xop", XOP)
3380*67e74705SXin Li         .Case("+fma4", FMA4)
3381*67e74705SXin Li         .Case("+sse4a", SSE4A)
3382*67e74705SXin Li         .Default(NoXOP);
3383*67e74705SXin Li     XOPLevel = std::max(XOPLevel, XLevel);
3384*67e74705SXin Li   }
3385*67e74705SXin Li 
3386*67e74705SXin Li   // LLVM doesn't have a separate switch for fpmath, so only accept it if it
3387*67e74705SXin Li   // matches the selected sse level.
3388*67e74705SXin Li   if ((FPMath == FP_SSE && SSELevel < SSE1) ||
3389*67e74705SXin Li       (FPMath == FP_387 && SSELevel >= SSE1)) {
3390*67e74705SXin Li     Diags.Report(diag::err_target_unsupported_fpmath) <<
3391*67e74705SXin Li       (FPMath == FP_SSE ? "sse" : "387");
3392*67e74705SXin Li     return false;
3393*67e74705SXin Li   }
3394*67e74705SXin Li 
3395*67e74705SXin Li   SimdDefaultAlign =
3396*67e74705SXin Li       hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
3397*67e74705SXin Li   return true;
3398*67e74705SXin Li }
3399*67e74705SXin Li 
3400*67e74705SXin Li /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
3401*67e74705SXin Li /// definitions for this particular subtarget.
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3402*67e74705SXin Li void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
3403*67e74705SXin Li                                      MacroBuilder &Builder) const {
3404*67e74705SXin Li   // Target identification.
3405*67e74705SXin Li   if (getTriple().getArch() == llvm::Triple::x86_64) {
3406*67e74705SXin Li     Builder.defineMacro("__amd64__");
3407*67e74705SXin Li     Builder.defineMacro("__amd64");
3408*67e74705SXin Li     Builder.defineMacro("__x86_64");
3409*67e74705SXin Li     Builder.defineMacro("__x86_64__");
3410*67e74705SXin Li     if (getTriple().getArchName() == "x86_64h") {
3411*67e74705SXin Li       Builder.defineMacro("__x86_64h");
3412*67e74705SXin Li       Builder.defineMacro("__x86_64h__");
3413*67e74705SXin Li     }
3414*67e74705SXin Li   } else {
3415*67e74705SXin Li     DefineStd(Builder, "i386", Opts);
3416*67e74705SXin Li   }
3417*67e74705SXin Li 
3418*67e74705SXin Li   // Subtarget options.
3419*67e74705SXin Li   // FIXME: We are hard-coding the tune parameters based on the CPU, but they
3420*67e74705SXin Li   // truly should be based on -mtune options.
3421*67e74705SXin Li   switch (CPU) {
3422*67e74705SXin Li   case CK_Generic:
3423*67e74705SXin Li     break;
3424*67e74705SXin Li   case CK_i386:
3425*67e74705SXin Li     // The rest are coming from the i386 define above.
3426*67e74705SXin Li     Builder.defineMacro("__tune_i386__");
3427*67e74705SXin Li     break;
3428*67e74705SXin Li   case CK_i486:
3429*67e74705SXin Li   case CK_WinChipC6:
3430*67e74705SXin Li   case CK_WinChip2:
3431*67e74705SXin Li   case CK_C3:
3432*67e74705SXin Li     defineCPUMacros(Builder, "i486");
3433*67e74705SXin Li     break;
3434*67e74705SXin Li   case CK_PentiumMMX:
3435*67e74705SXin Li     Builder.defineMacro("__pentium_mmx__");
3436*67e74705SXin Li     Builder.defineMacro("__tune_pentium_mmx__");
3437*67e74705SXin Li     // Fallthrough
3438*67e74705SXin Li   case CK_i586:
3439*67e74705SXin Li   case CK_Pentium:
3440*67e74705SXin Li     defineCPUMacros(Builder, "i586");
3441*67e74705SXin Li     defineCPUMacros(Builder, "pentium");
3442*67e74705SXin Li     break;
3443*67e74705SXin Li   case CK_Pentium3:
3444*67e74705SXin Li   case CK_Pentium3M:
3445*67e74705SXin Li   case CK_PentiumM:
3446*67e74705SXin Li     Builder.defineMacro("__tune_pentium3__");
3447*67e74705SXin Li     // Fallthrough
3448*67e74705SXin Li   case CK_Pentium2:
3449*67e74705SXin Li   case CK_C3_2:
3450*67e74705SXin Li     Builder.defineMacro("__tune_pentium2__");
3451*67e74705SXin Li     // Fallthrough
3452*67e74705SXin Li   case CK_PentiumPro:
3453*67e74705SXin Li     Builder.defineMacro("__tune_i686__");
3454*67e74705SXin Li     Builder.defineMacro("__tune_pentiumpro__");
3455*67e74705SXin Li     // Fallthrough
3456*67e74705SXin Li   case CK_i686:
3457*67e74705SXin Li     Builder.defineMacro("__i686");
3458*67e74705SXin Li     Builder.defineMacro("__i686__");
3459*67e74705SXin Li     // Strangely, __tune_i686__ isn't defined by GCC when CPU == i686.
3460*67e74705SXin Li     Builder.defineMacro("__pentiumpro");
3461*67e74705SXin Li     Builder.defineMacro("__pentiumpro__");
3462*67e74705SXin Li     break;
3463*67e74705SXin Li   case CK_Pentium4:
3464*67e74705SXin Li   case CK_Pentium4M:
3465*67e74705SXin Li     defineCPUMacros(Builder, "pentium4");
3466*67e74705SXin Li     break;
3467*67e74705SXin Li   case CK_Yonah:
3468*67e74705SXin Li   case CK_Prescott:
3469*67e74705SXin Li   case CK_Nocona:
3470*67e74705SXin Li     defineCPUMacros(Builder, "nocona");
3471*67e74705SXin Li     break;
3472*67e74705SXin Li   case CK_Core2:
3473*67e74705SXin Li   case CK_Penryn:
3474*67e74705SXin Li     defineCPUMacros(Builder, "core2");
3475*67e74705SXin Li     break;
3476*67e74705SXin Li   case CK_Bonnell:
3477*67e74705SXin Li     defineCPUMacros(Builder, "atom");
3478*67e74705SXin Li     break;
3479*67e74705SXin Li   case CK_Silvermont:
3480*67e74705SXin Li     defineCPUMacros(Builder, "slm");
3481*67e74705SXin Li     break;
3482*67e74705SXin Li   case CK_Nehalem:
3483*67e74705SXin Li   case CK_Westmere:
3484*67e74705SXin Li   case CK_SandyBridge:
3485*67e74705SXin Li   case CK_IvyBridge:
3486*67e74705SXin Li   case CK_Haswell:
3487*67e74705SXin Li   case CK_Broadwell:
3488*67e74705SXin Li   case CK_SkylakeClient:
3489*67e74705SXin Li     // FIXME: Historically, we defined this legacy name, it would be nice to
3490*67e74705SXin Li     // remove it at some point. We've never exposed fine-grained names for
3491*67e74705SXin Li     // recent primary x86 CPUs, and we should keep it that way.
3492*67e74705SXin Li     defineCPUMacros(Builder, "corei7");
3493*67e74705SXin Li     break;
3494*67e74705SXin Li   case CK_SkylakeServer:
3495*67e74705SXin Li     defineCPUMacros(Builder, "skx");
3496*67e74705SXin Li     break;
3497*67e74705SXin Li   case CK_Cannonlake:
3498*67e74705SXin Li     break;
3499*67e74705SXin Li   case CK_KNL:
3500*67e74705SXin Li     defineCPUMacros(Builder, "knl");
3501*67e74705SXin Li     break;
3502*67e74705SXin Li   case CK_Lakemont:
3503*67e74705SXin Li     Builder.defineMacro("__tune_lakemont__");
3504*67e74705SXin Li     break;
3505*67e74705SXin Li   case CK_K6_2:
3506*67e74705SXin Li     Builder.defineMacro("__k6_2__");
3507*67e74705SXin Li     Builder.defineMacro("__tune_k6_2__");
3508*67e74705SXin Li     // Fallthrough
3509*67e74705SXin Li   case CK_K6_3:
3510*67e74705SXin Li     if (CPU != CK_K6_2) {  // In case of fallthrough
3511*67e74705SXin Li       // FIXME: GCC may be enabling these in cases where some other k6
3512*67e74705SXin Li       // architecture is specified but -m3dnow is explicitly provided. The
3513*67e74705SXin Li       // exact semantics need to be determined and emulated here.
3514*67e74705SXin Li       Builder.defineMacro("__k6_3__");
3515*67e74705SXin Li       Builder.defineMacro("__tune_k6_3__");
3516*67e74705SXin Li     }
3517*67e74705SXin Li     // Fallthrough
3518*67e74705SXin Li   case CK_K6:
3519*67e74705SXin Li     defineCPUMacros(Builder, "k6");
3520*67e74705SXin Li     break;
3521*67e74705SXin Li   case CK_Athlon:
3522*67e74705SXin Li   case CK_AthlonThunderbird:
3523*67e74705SXin Li   case CK_Athlon4:
3524*67e74705SXin Li   case CK_AthlonXP:
3525*67e74705SXin Li   case CK_AthlonMP:
3526*67e74705SXin Li     defineCPUMacros(Builder, "athlon");
3527*67e74705SXin Li     if (SSELevel != NoSSE) {
3528*67e74705SXin Li       Builder.defineMacro("__athlon_sse__");
3529*67e74705SXin Li       Builder.defineMacro("__tune_athlon_sse__");
3530*67e74705SXin Li     }
3531*67e74705SXin Li     break;
3532*67e74705SXin Li   case CK_K8:
3533*67e74705SXin Li   case CK_K8SSE3:
3534*67e74705SXin Li   case CK_x86_64:
3535*67e74705SXin Li   case CK_Opteron:
3536*67e74705SXin Li   case CK_OpteronSSE3:
3537*67e74705SXin Li   case CK_Athlon64:
3538*67e74705SXin Li   case CK_Athlon64SSE3:
3539*67e74705SXin Li   case CK_AthlonFX:
3540*67e74705SXin Li     defineCPUMacros(Builder, "k8");
3541*67e74705SXin Li     break;
3542*67e74705SXin Li   case CK_AMDFAM10:
3543*67e74705SXin Li     defineCPUMacros(Builder, "amdfam10");
3544*67e74705SXin Li     break;
3545*67e74705SXin Li   case CK_BTVER1:
3546*67e74705SXin Li     defineCPUMacros(Builder, "btver1");
3547*67e74705SXin Li     break;
3548*67e74705SXin Li   case CK_BTVER2:
3549*67e74705SXin Li     defineCPUMacros(Builder, "btver2");
3550*67e74705SXin Li     break;
3551*67e74705SXin Li   case CK_BDVER1:
3552*67e74705SXin Li     defineCPUMacros(Builder, "bdver1");
3553*67e74705SXin Li     break;
3554*67e74705SXin Li   case CK_BDVER2:
3555*67e74705SXin Li     defineCPUMacros(Builder, "bdver2");
3556*67e74705SXin Li     break;
3557*67e74705SXin Li   case CK_BDVER3:
3558*67e74705SXin Li     defineCPUMacros(Builder, "bdver3");
3559*67e74705SXin Li     break;
3560*67e74705SXin Li   case CK_BDVER4:
3561*67e74705SXin Li     defineCPUMacros(Builder, "bdver4");
3562*67e74705SXin Li     break;
3563*67e74705SXin Li   case CK_Geode:
3564*67e74705SXin Li     defineCPUMacros(Builder, "geode");
3565*67e74705SXin Li     break;
3566*67e74705SXin Li   }
3567*67e74705SXin Li 
3568*67e74705SXin Li   // Target properties.
3569*67e74705SXin Li   Builder.defineMacro("__REGISTER_PREFIX__", "");
3570*67e74705SXin Li 
3571*67e74705SXin Li   // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
3572*67e74705SXin Li   // functions in glibc header files that use FP Stack inline asm which the
3573*67e74705SXin Li   // backend can't deal with (PR879).
3574*67e74705SXin Li   Builder.defineMacro("__NO_MATH_INLINES");
3575*67e74705SXin Li 
3576*67e74705SXin Li   if (HasAES)
3577*67e74705SXin Li     Builder.defineMacro("__AES__");
3578*67e74705SXin Li 
3579*67e74705SXin Li   if (HasPCLMUL)
3580*67e74705SXin Li     Builder.defineMacro("__PCLMUL__");
3581*67e74705SXin Li 
3582*67e74705SXin Li   if (HasLZCNT)
3583*67e74705SXin Li     Builder.defineMacro("__LZCNT__");
3584*67e74705SXin Li 
3585*67e74705SXin Li   if (HasRDRND)
3586*67e74705SXin Li     Builder.defineMacro("__RDRND__");
3587*67e74705SXin Li 
3588*67e74705SXin Li   if (HasFSGSBASE)
3589*67e74705SXin Li     Builder.defineMacro("__FSGSBASE__");
3590*67e74705SXin Li 
3591*67e74705SXin Li   if (HasBMI)
3592*67e74705SXin Li     Builder.defineMacro("__BMI__");
3593*67e74705SXin Li 
3594*67e74705SXin Li   if (HasBMI2)
3595*67e74705SXin Li     Builder.defineMacro("__BMI2__");
3596*67e74705SXin Li 
3597*67e74705SXin Li   if (HasPOPCNT)
3598*67e74705SXin Li     Builder.defineMacro("__POPCNT__");
3599*67e74705SXin Li 
3600*67e74705SXin Li   if (HasRTM)
3601*67e74705SXin Li     Builder.defineMacro("__RTM__");
3602*67e74705SXin Li 
3603*67e74705SXin Li   if (HasPRFCHW)
3604*67e74705SXin Li     Builder.defineMacro("__PRFCHW__");
3605*67e74705SXin Li 
3606*67e74705SXin Li   if (HasRDSEED)
3607*67e74705SXin Li     Builder.defineMacro("__RDSEED__");
3608*67e74705SXin Li 
3609*67e74705SXin Li   if (HasADX)
3610*67e74705SXin Li     Builder.defineMacro("__ADX__");
3611*67e74705SXin Li 
3612*67e74705SXin Li   if (HasTBM)
3613*67e74705SXin Li     Builder.defineMacro("__TBM__");
3614*67e74705SXin Li 
3615*67e74705SXin Li   if (HasMWAITX)
3616*67e74705SXin Li     Builder.defineMacro("__MWAITX__");
3617*67e74705SXin Li 
3618*67e74705SXin Li   switch (XOPLevel) {
3619*67e74705SXin Li   case XOP:
3620*67e74705SXin Li     Builder.defineMacro("__XOP__");
3621*67e74705SXin Li   case FMA4:
3622*67e74705SXin Li     Builder.defineMacro("__FMA4__");
3623*67e74705SXin Li   case SSE4A:
3624*67e74705SXin Li     Builder.defineMacro("__SSE4A__");
3625*67e74705SXin Li   case NoXOP:
3626*67e74705SXin Li     break;
3627*67e74705SXin Li   }
3628*67e74705SXin Li 
3629*67e74705SXin Li   if (HasFMA)
3630*67e74705SXin Li     Builder.defineMacro("__FMA__");
3631*67e74705SXin Li 
3632*67e74705SXin Li   if (HasF16C)
3633*67e74705SXin Li     Builder.defineMacro("__F16C__");
3634*67e74705SXin Li 
3635*67e74705SXin Li   if (HasAVX512CD)
3636*67e74705SXin Li     Builder.defineMacro("__AVX512CD__");
3637*67e74705SXin Li   if (HasAVX512ER)
3638*67e74705SXin Li     Builder.defineMacro("__AVX512ER__");
3639*67e74705SXin Li   if (HasAVX512PF)
3640*67e74705SXin Li     Builder.defineMacro("__AVX512PF__");
3641*67e74705SXin Li   if (HasAVX512DQ)
3642*67e74705SXin Li     Builder.defineMacro("__AVX512DQ__");
3643*67e74705SXin Li   if (HasAVX512BW)
3644*67e74705SXin Li     Builder.defineMacro("__AVX512BW__");
3645*67e74705SXin Li   if (HasAVX512VL)
3646*67e74705SXin Li     Builder.defineMacro("__AVX512VL__");
3647*67e74705SXin Li   if (HasAVX512VBMI)
3648*67e74705SXin Li     Builder.defineMacro("__AVX512VBMI__");
3649*67e74705SXin Li   if (HasAVX512IFMA)
3650*67e74705SXin Li     Builder.defineMacro("__AVX512IFMA__");
3651*67e74705SXin Li 
3652*67e74705SXin Li   if (HasSHA)
3653*67e74705SXin Li     Builder.defineMacro("__SHA__");
3654*67e74705SXin Li 
3655*67e74705SXin Li   if (HasFXSR)
3656*67e74705SXin Li     Builder.defineMacro("__FXSR__");
3657*67e74705SXin Li   if (HasXSAVE)
3658*67e74705SXin Li     Builder.defineMacro("__XSAVE__");
3659*67e74705SXin Li   if (HasXSAVEOPT)
3660*67e74705SXin Li     Builder.defineMacro("__XSAVEOPT__");
3661*67e74705SXin Li   if (HasXSAVEC)
3662*67e74705SXin Li     Builder.defineMacro("__XSAVEC__");
3663*67e74705SXin Li   if (HasXSAVES)
3664*67e74705SXin Li     Builder.defineMacro("__XSAVES__");
3665*67e74705SXin Li   if (HasPKU)
3666*67e74705SXin Li     Builder.defineMacro("__PKU__");
3667*67e74705SXin Li   if (HasCX16)
3668*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
3669*67e74705SXin Li 
3670*67e74705SXin Li   // Each case falls through to the previous one here.
3671*67e74705SXin Li   switch (SSELevel) {
3672*67e74705SXin Li   case AVX512F:
3673*67e74705SXin Li     Builder.defineMacro("__AVX512F__");
3674*67e74705SXin Li   case AVX2:
3675*67e74705SXin Li     Builder.defineMacro("__AVX2__");
3676*67e74705SXin Li   case AVX:
3677*67e74705SXin Li     Builder.defineMacro("__AVX__");
3678*67e74705SXin Li   case SSE42:
3679*67e74705SXin Li     Builder.defineMacro("__SSE4_2__");
3680*67e74705SXin Li   case SSE41:
3681*67e74705SXin Li     Builder.defineMacro("__SSE4_1__");
3682*67e74705SXin Li   case SSSE3:
3683*67e74705SXin Li     Builder.defineMacro("__SSSE3__");
3684*67e74705SXin Li   case SSE3:
3685*67e74705SXin Li     Builder.defineMacro("__SSE3__");
3686*67e74705SXin Li   case SSE2:
3687*67e74705SXin Li     Builder.defineMacro("__SSE2__");
3688*67e74705SXin Li     Builder.defineMacro("__SSE2_MATH__");  // -mfp-math=sse always implied.
3689*67e74705SXin Li   case SSE1:
3690*67e74705SXin Li     Builder.defineMacro("__SSE__");
3691*67e74705SXin Li     Builder.defineMacro("__SSE_MATH__");   // -mfp-math=sse always implied.
3692*67e74705SXin Li   case NoSSE:
3693*67e74705SXin Li     break;
3694*67e74705SXin Li   }
3695*67e74705SXin Li 
3696*67e74705SXin Li   if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
3697*67e74705SXin Li     switch (SSELevel) {
3698*67e74705SXin Li     case AVX512F:
3699*67e74705SXin Li     case AVX2:
3700*67e74705SXin Li     case AVX:
3701*67e74705SXin Li     case SSE42:
3702*67e74705SXin Li     case SSE41:
3703*67e74705SXin Li     case SSSE3:
3704*67e74705SXin Li     case SSE3:
3705*67e74705SXin Li     case SSE2:
3706*67e74705SXin Li       Builder.defineMacro("_M_IX86_FP", Twine(2));
3707*67e74705SXin Li       break;
3708*67e74705SXin Li     case SSE1:
3709*67e74705SXin Li       Builder.defineMacro("_M_IX86_FP", Twine(1));
3710*67e74705SXin Li       break;
3711*67e74705SXin Li     default:
3712*67e74705SXin Li       Builder.defineMacro("_M_IX86_FP", Twine(0));
3713*67e74705SXin Li     }
3714*67e74705SXin Li   }
3715*67e74705SXin Li 
3716*67e74705SXin Li   // Each case falls through to the previous one here.
3717*67e74705SXin Li   switch (MMX3DNowLevel) {
3718*67e74705SXin Li   case AMD3DNowAthlon:
3719*67e74705SXin Li     Builder.defineMacro("__3dNOW_A__");
3720*67e74705SXin Li   case AMD3DNow:
3721*67e74705SXin Li     Builder.defineMacro("__3dNOW__");
3722*67e74705SXin Li   case MMX:
3723*67e74705SXin Li     Builder.defineMacro("__MMX__");
3724*67e74705SXin Li   case NoMMX3DNow:
3725*67e74705SXin Li     break;
3726*67e74705SXin Li   }
3727*67e74705SXin Li 
3728*67e74705SXin Li   if (CPU >= CK_i486) {
3729*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
3730*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
3731*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
3732*67e74705SXin Li   }
3733*67e74705SXin Li   if (CPU >= CK_i586)
3734*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
3735*67e74705SXin Li }
3736*67e74705SXin Li 
hasFeature(StringRef Feature) const3737*67e74705SXin Li bool X86TargetInfo::hasFeature(StringRef Feature) const {
3738*67e74705SXin Li   return llvm::StringSwitch<bool>(Feature)
3739*67e74705SXin Li       .Case("aes", HasAES)
3740*67e74705SXin Li       .Case("avx", SSELevel >= AVX)
3741*67e74705SXin Li       .Case("avx2", SSELevel >= AVX2)
3742*67e74705SXin Li       .Case("avx512f", SSELevel >= AVX512F)
3743*67e74705SXin Li       .Case("avx512cd", HasAVX512CD)
3744*67e74705SXin Li       .Case("avx512er", HasAVX512ER)
3745*67e74705SXin Li       .Case("avx512pf", HasAVX512PF)
3746*67e74705SXin Li       .Case("avx512dq", HasAVX512DQ)
3747*67e74705SXin Li       .Case("avx512bw", HasAVX512BW)
3748*67e74705SXin Li       .Case("avx512vl", HasAVX512VL)
3749*67e74705SXin Li       .Case("avx512vbmi", HasAVX512VBMI)
3750*67e74705SXin Li       .Case("avx512ifma", HasAVX512IFMA)
3751*67e74705SXin Li       .Case("bmi", HasBMI)
3752*67e74705SXin Li       .Case("bmi2", HasBMI2)
3753*67e74705SXin Li       .Case("clflushopt", HasCLFLUSHOPT)
3754*67e74705SXin Li       .Case("clwb", HasCLWB)
3755*67e74705SXin Li       .Case("cx16", HasCX16)
3756*67e74705SXin Li       .Case("f16c", HasF16C)
3757*67e74705SXin Li       .Case("fma", HasFMA)
3758*67e74705SXin Li       .Case("fma4", XOPLevel >= FMA4)
3759*67e74705SXin Li       .Case("fsgsbase", HasFSGSBASE)
3760*67e74705SXin Li       .Case("fxsr", HasFXSR)
3761*67e74705SXin Li       .Case("lzcnt", HasLZCNT)
3762*67e74705SXin Li       .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
3763*67e74705SXin Li       .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
3764*67e74705SXin Li       .Case("mmx", MMX3DNowLevel >= MMX)
3765*67e74705SXin Li       .Case("movbe", HasMOVBE)
3766*67e74705SXin Li       .Case("mpx", HasMPX)
3767*67e74705SXin Li       .Case("pclmul", HasPCLMUL)
3768*67e74705SXin Li       .Case("pcommit", HasPCOMMIT)
3769*67e74705SXin Li       .Case("pku", HasPKU)
3770*67e74705SXin Li       .Case("popcnt", HasPOPCNT)
3771*67e74705SXin Li       .Case("prefetchwt1", HasPREFETCHWT1)
3772*67e74705SXin Li       .Case("prfchw", HasPRFCHW)
3773*67e74705SXin Li       .Case("rdrnd", HasRDRND)
3774*67e74705SXin Li       .Case("rdseed", HasRDSEED)
3775*67e74705SXin Li       .Case("rtm", HasRTM)
3776*67e74705SXin Li       .Case("sgx", HasSGX)
3777*67e74705SXin Li       .Case("sha", HasSHA)
3778*67e74705SXin Li       .Case("sse", SSELevel >= SSE1)
3779*67e74705SXin Li       .Case("sse2", SSELevel >= SSE2)
3780*67e74705SXin Li       .Case("sse3", SSELevel >= SSE3)
3781*67e74705SXin Li       .Case("ssse3", SSELevel >= SSSE3)
3782*67e74705SXin Li       .Case("sse4.1", SSELevel >= SSE41)
3783*67e74705SXin Li       .Case("sse4.2", SSELevel >= SSE42)
3784*67e74705SXin Li       .Case("sse4a", XOPLevel >= SSE4A)
3785*67e74705SXin Li       .Case("tbm", HasTBM)
3786*67e74705SXin Li       .Case("umip", HasUMIP)
3787*67e74705SXin Li       .Case("x86", true)
3788*67e74705SXin Li       .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
3789*67e74705SXin Li       .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
3790*67e74705SXin Li       .Case("xop", XOPLevel >= XOP)
3791*67e74705SXin Li       .Case("xsave", HasXSAVE)
3792*67e74705SXin Li       .Case("xsavec", HasXSAVEC)
3793*67e74705SXin Li       .Case("xsaves", HasXSAVES)
3794*67e74705SXin Li       .Case("xsaveopt", HasXSAVEOPT)
3795*67e74705SXin Li       .Default(false);
3796*67e74705SXin Li }
3797*67e74705SXin Li 
3798*67e74705SXin Li // We can't use a generic validation scheme for the features accepted here
3799*67e74705SXin Li // versus subtarget features accepted in the target attribute because the
3800*67e74705SXin Li // bitfield structure that's initialized in the runtime only supports the
3801*67e74705SXin Li // below currently rather than the full range of subtarget features. (See
3802*67e74705SXin Li // X86TargetInfo::hasFeature for a somewhat comprehensive list).
validateCpuSupports(StringRef FeatureStr) const3803*67e74705SXin Li bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
3804*67e74705SXin Li   return llvm::StringSwitch<bool>(FeatureStr)
3805*67e74705SXin Li       .Case("cmov", true)
3806*67e74705SXin Li       .Case("mmx", true)
3807*67e74705SXin Li       .Case("popcnt", true)
3808*67e74705SXin Li       .Case("sse", true)
3809*67e74705SXin Li       .Case("sse2", true)
3810*67e74705SXin Li       .Case("sse3", true)
3811*67e74705SXin Li       .Case("ssse3", true)
3812*67e74705SXin Li       .Case("sse4.1", true)
3813*67e74705SXin Li       .Case("sse4.2", true)
3814*67e74705SXin Li       .Case("avx", true)
3815*67e74705SXin Li       .Case("avx2", true)
3816*67e74705SXin Li       .Case("sse4a", true)
3817*67e74705SXin Li       .Case("fma4", true)
3818*67e74705SXin Li       .Case("xop", true)
3819*67e74705SXin Li       .Case("fma", true)
3820*67e74705SXin Li       .Case("avx512f", true)
3821*67e74705SXin Li       .Case("bmi", true)
3822*67e74705SXin Li       .Case("bmi2", true)
3823*67e74705SXin Li       .Case("aes", true)
3824*67e74705SXin Li       .Case("pclmul", true)
3825*67e74705SXin Li       .Case("avx512vl", true)
3826*67e74705SXin Li       .Case("avx512bw", true)
3827*67e74705SXin Li       .Case("avx512dq", true)
3828*67e74705SXin Li       .Case("avx512cd", true)
3829*67e74705SXin Li       .Case("avx512er", true)
3830*67e74705SXin Li       .Case("avx512pf", true)
3831*67e74705SXin Li       .Case("avx512vbmi", true)
3832*67e74705SXin Li       .Case("avx512ifma", true)
3833*67e74705SXin Li       .Default(false);
3834*67e74705SXin Li }
3835*67e74705SXin Li 
3836*67e74705SXin Li bool
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const3837*67e74705SXin Li X86TargetInfo::validateAsmConstraint(const char *&Name,
3838*67e74705SXin Li                                      TargetInfo::ConstraintInfo &Info) const {
3839*67e74705SXin Li   switch (*Name) {
3840*67e74705SXin Li   default: return false;
3841*67e74705SXin Li   // Constant constraints.
3842*67e74705SXin Li   case 'e': // 32-bit signed integer constant for use with sign-extending x86_64
3843*67e74705SXin Li             // instructions.
3844*67e74705SXin Li   case 'Z': // 32-bit unsigned integer constant for use with zero-extending
3845*67e74705SXin Li             // x86_64 instructions.
3846*67e74705SXin Li   case 's':
3847*67e74705SXin Li     Info.setRequiresImmediate();
3848*67e74705SXin Li     return true;
3849*67e74705SXin Li   case 'I':
3850*67e74705SXin Li     Info.setRequiresImmediate(0, 31);
3851*67e74705SXin Li     return true;
3852*67e74705SXin Li   case 'J':
3853*67e74705SXin Li     Info.setRequiresImmediate(0, 63);
3854*67e74705SXin Li     return true;
3855*67e74705SXin Li   case 'K':
3856*67e74705SXin Li     Info.setRequiresImmediate(-128, 127);
3857*67e74705SXin Li     return true;
3858*67e74705SXin Li   case 'L':
3859*67e74705SXin Li     Info.setRequiresImmediate({ int(0xff), int(0xffff), int(0xffffffff) });
3860*67e74705SXin Li     return true;
3861*67e74705SXin Li   case 'M':
3862*67e74705SXin Li     Info.setRequiresImmediate(0, 3);
3863*67e74705SXin Li     return true;
3864*67e74705SXin Li   case 'N':
3865*67e74705SXin Li     Info.setRequiresImmediate(0, 255);
3866*67e74705SXin Li     return true;
3867*67e74705SXin Li   case 'O':
3868*67e74705SXin Li     Info.setRequiresImmediate(0, 127);
3869*67e74705SXin Li     return true;
3870*67e74705SXin Li   // Register constraints.
3871*67e74705SXin Li   case 'Y': // 'Y' is the first character for several 2-character constraints.
3872*67e74705SXin Li     // Shift the pointer to the second character of the constraint.
3873*67e74705SXin Li     Name++;
3874*67e74705SXin Li     switch (*Name) {
3875*67e74705SXin Li     default:
3876*67e74705SXin Li       return false;
3877*67e74705SXin Li     case '0': // First SSE register.
3878*67e74705SXin Li     case 't': // Any SSE register, when SSE2 is enabled.
3879*67e74705SXin Li     case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
3880*67e74705SXin Li     case 'm': // Any MMX register, when inter-unit moves enabled.
3881*67e74705SXin Li       Info.setAllowsRegister();
3882*67e74705SXin Li       return true;
3883*67e74705SXin Li     }
3884*67e74705SXin Li   case 'f': // Any x87 floating point stack register.
3885*67e74705SXin Li     // Constraint 'f' cannot be used for output operands.
3886*67e74705SXin Li     if (Info.ConstraintStr[0] == '=')
3887*67e74705SXin Li       return false;
3888*67e74705SXin Li     Info.setAllowsRegister();
3889*67e74705SXin Li     return true;
3890*67e74705SXin Li   case 'a': // eax.
3891*67e74705SXin Li   case 'b': // ebx.
3892*67e74705SXin Li   case 'c': // ecx.
3893*67e74705SXin Li   case 'd': // edx.
3894*67e74705SXin Li   case 'S': // esi.
3895*67e74705SXin Li   case 'D': // edi.
3896*67e74705SXin Li   case 'A': // edx:eax.
3897*67e74705SXin Li   case 't': // Top of floating point stack.
3898*67e74705SXin Li   case 'u': // Second from top of floating point stack.
3899*67e74705SXin Li   case 'q': // Any register accessible as [r]l: a, b, c, and d.
3900*67e74705SXin Li   case 'y': // Any MMX register.
3901*67e74705SXin Li   case 'x': // Any SSE register.
3902*67e74705SXin Li   case 'Q': // Any register accessible as [r]h: a, b, c, and d.
3903*67e74705SXin Li   case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
3904*67e74705SXin Li   case 'l': // "Index" registers: any general register that can be used as an
3905*67e74705SXin Li             // index in a base+index memory access.
3906*67e74705SXin Li     Info.setAllowsRegister();
3907*67e74705SXin Li     return true;
3908*67e74705SXin Li   // Floating point constant constraints.
3909*67e74705SXin Li   case 'C': // SSE floating point constant.
3910*67e74705SXin Li   case 'G': // x87 floating point constant.
3911*67e74705SXin Li     return true;
3912*67e74705SXin Li   }
3913*67e74705SXin Li }
3914*67e74705SXin Li 
validateOutputSize(StringRef Constraint,unsigned Size) const3915*67e74705SXin Li bool X86TargetInfo::validateOutputSize(StringRef Constraint,
3916*67e74705SXin Li                                        unsigned Size) const {
3917*67e74705SXin Li   // Strip off constraint modifiers.
3918*67e74705SXin Li   while (Constraint[0] == '=' ||
3919*67e74705SXin Li          Constraint[0] == '+' ||
3920*67e74705SXin Li          Constraint[0] == '&')
3921*67e74705SXin Li     Constraint = Constraint.substr(1);
3922*67e74705SXin Li 
3923*67e74705SXin Li   return validateOperandSize(Constraint, Size);
3924*67e74705SXin Li }
3925*67e74705SXin Li 
validateInputSize(StringRef Constraint,unsigned Size) const3926*67e74705SXin Li bool X86TargetInfo::validateInputSize(StringRef Constraint,
3927*67e74705SXin Li                                       unsigned Size) const {
3928*67e74705SXin Li   return validateOperandSize(Constraint, Size);
3929*67e74705SXin Li }
3930*67e74705SXin Li 
validateOperandSize(StringRef Constraint,unsigned Size) const3931*67e74705SXin Li bool X86TargetInfo::validateOperandSize(StringRef Constraint,
3932*67e74705SXin Li                                         unsigned Size) const {
3933*67e74705SXin Li   switch (Constraint[0]) {
3934*67e74705SXin Li   default: break;
3935*67e74705SXin Li   case 'y':
3936*67e74705SXin Li     return Size <= 64;
3937*67e74705SXin Li   case 'f':
3938*67e74705SXin Li   case 't':
3939*67e74705SXin Li   case 'u':
3940*67e74705SXin Li     return Size <= 128;
3941*67e74705SXin Li   case 'x':
3942*67e74705SXin Li     if (SSELevel >= AVX512F)
3943*67e74705SXin Li       // 512-bit zmm registers can be used if target supports AVX512F.
3944*67e74705SXin Li       return Size <= 512U;
3945*67e74705SXin Li     else if (SSELevel >= AVX)
3946*67e74705SXin Li       // 256-bit ymm registers can be used if target supports AVX.
3947*67e74705SXin Li       return Size <= 256U;
3948*67e74705SXin Li     return Size <= 128U;
3949*67e74705SXin Li   case 'Y':
3950*67e74705SXin Li     // 'Y' is the first character for several 2-character constraints.
3951*67e74705SXin Li     switch (Constraint[1]) {
3952*67e74705SXin Li     default: break;
3953*67e74705SXin Li     case 'm':
3954*67e74705SXin Li       // 'Ym' is synonymous with 'y'.
3955*67e74705SXin Li       return Size <= 64;
3956*67e74705SXin Li     case 'i':
3957*67e74705SXin Li     case 't':
3958*67e74705SXin Li       // 'Yi' and 'Yt' are synonymous with 'x' when SSE2 is enabled.
3959*67e74705SXin Li       if (SSELevel >= AVX512F)
3960*67e74705SXin Li         return Size <= 512U;
3961*67e74705SXin Li       else if (SSELevel >= AVX)
3962*67e74705SXin Li         return Size <= 256U;
3963*67e74705SXin Li       return SSELevel >= SSE2 && Size <= 128U;
3964*67e74705SXin Li     }
3965*67e74705SXin Li 
3966*67e74705SXin Li   }
3967*67e74705SXin Li 
3968*67e74705SXin Li   return true;
3969*67e74705SXin Li }
3970*67e74705SXin Li 
3971*67e74705SXin Li std::string
convertConstraint(const char * & Constraint) const3972*67e74705SXin Li X86TargetInfo::convertConstraint(const char *&Constraint) const {
3973*67e74705SXin Li   switch (*Constraint) {
3974*67e74705SXin Li   case 'a': return std::string("{ax}");
3975*67e74705SXin Li   case 'b': return std::string("{bx}");
3976*67e74705SXin Li   case 'c': return std::string("{cx}");
3977*67e74705SXin Li   case 'd': return std::string("{dx}");
3978*67e74705SXin Li   case 'S': return std::string("{si}");
3979*67e74705SXin Li   case 'D': return std::string("{di}");
3980*67e74705SXin Li   case 'p': // address
3981*67e74705SXin Li     return std::string("im");
3982*67e74705SXin Li   case 't': // top of floating point stack.
3983*67e74705SXin Li     return std::string("{st}");
3984*67e74705SXin Li   case 'u': // second from top of floating point stack.
3985*67e74705SXin Li     return std::string("{st(1)}"); // second from top of floating point stack.
3986*67e74705SXin Li   default:
3987*67e74705SXin Li     return std::string(1, *Constraint);
3988*67e74705SXin Li   }
3989*67e74705SXin Li }
3990*67e74705SXin Li 
3991*67e74705SXin Li // X86-32 generic target
3992*67e74705SXin Li class X86_32TargetInfo : public X86TargetInfo {
3993*67e74705SXin Li public:
X86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)3994*67e74705SXin Li   X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
3995*67e74705SXin Li       : X86TargetInfo(Triple, Opts) {
3996*67e74705SXin Li     DoubleAlign = LongLongAlign = 32;
3997*67e74705SXin Li     LongDoubleWidth = 96;
3998*67e74705SXin Li     LongDoubleAlign = 32;
3999*67e74705SXin Li     SuitableAlign = 128;
4000*67e74705SXin Li     resetDataLayout("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128");
4001*67e74705SXin Li     SizeType = UnsignedInt;
4002*67e74705SXin Li     PtrDiffType = SignedInt;
4003*67e74705SXin Li     IntPtrType = SignedInt;
4004*67e74705SXin Li     RegParmMax = 3;
4005*67e74705SXin Li 
4006*67e74705SXin Li     // Use fpret for all types.
4007*67e74705SXin Li     RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
4008*67e74705SXin Li                              (1 << TargetInfo::Double) |
4009*67e74705SXin Li                              (1 << TargetInfo::LongDouble));
4010*67e74705SXin Li 
4011*67e74705SXin Li     // x86-32 has atomics up to 8 bytes
4012*67e74705SXin Li     // FIXME: Check that we actually have cmpxchg8b before setting
4013*67e74705SXin Li     // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
4014*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
4015*67e74705SXin Li   }
getBuiltinVaListKind() const4016*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
4017*67e74705SXin Li     return TargetInfo::CharPtrBuiltinVaList;
4018*67e74705SXin Li   }
4019*67e74705SXin Li 
getEHDataRegisterNumber(unsigned RegNo) const4020*67e74705SXin Li   int getEHDataRegisterNumber(unsigned RegNo) const override {
4021*67e74705SXin Li     if (RegNo == 0) return 0;
4022*67e74705SXin Li     if (RegNo == 1) return 2;
4023*67e74705SXin Li     return -1;
4024*67e74705SXin Li   }
validateOperandSize(StringRef Constraint,unsigned Size) const4025*67e74705SXin Li   bool validateOperandSize(StringRef Constraint,
4026*67e74705SXin Li                            unsigned Size) const override {
4027*67e74705SXin Li     switch (Constraint[0]) {
4028*67e74705SXin Li     default: break;
4029*67e74705SXin Li     case 'R':
4030*67e74705SXin Li     case 'q':
4031*67e74705SXin Li     case 'Q':
4032*67e74705SXin Li     case 'a':
4033*67e74705SXin Li     case 'b':
4034*67e74705SXin Li     case 'c':
4035*67e74705SXin Li     case 'd':
4036*67e74705SXin Li     case 'S':
4037*67e74705SXin Li     case 'D':
4038*67e74705SXin Li       return Size <= 32;
4039*67e74705SXin Li     case 'A':
4040*67e74705SXin Li       return Size <= 64;
4041*67e74705SXin Li     }
4042*67e74705SXin Li 
4043*67e74705SXin Li     return X86TargetInfo::validateOperandSize(Constraint, Size);
4044*67e74705SXin Li   }
4045*67e74705SXin Li };
4046*67e74705SXin Li 
4047*67e74705SXin Li class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> {
4048*67e74705SXin Li public:
NetBSDI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4049*67e74705SXin Li   NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4050*67e74705SXin Li       : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
4051*67e74705SXin Li 
getFloatEvalMethod() const4052*67e74705SXin Li   unsigned getFloatEvalMethod() const override {
4053*67e74705SXin Li     unsigned Major, Minor, Micro;
4054*67e74705SXin Li     getTriple().getOSVersion(Major, Minor, Micro);
4055*67e74705SXin Li     // New NetBSD uses the default rounding mode.
4056*67e74705SXin Li     if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0)
4057*67e74705SXin Li       return X86_32TargetInfo::getFloatEvalMethod();
4058*67e74705SXin Li     // NetBSD before 6.99.26 defaults to "double" rounding.
4059*67e74705SXin Li     return 1;
4060*67e74705SXin Li   }
4061*67e74705SXin Li };
4062*67e74705SXin Li 
4063*67e74705SXin Li class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
4064*67e74705SXin Li public:
OpenBSDI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4065*67e74705SXin Li   OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4066*67e74705SXin Li       : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {
4067*67e74705SXin Li     SizeType = UnsignedLong;
4068*67e74705SXin Li     IntPtrType = SignedLong;
4069*67e74705SXin Li     PtrDiffType = SignedLong;
4070*67e74705SXin Li   }
4071*67e74705SXin Li };
4072*67e74705SXin Li 
4073*67e74705SXin Li class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> {
4074*67e74705SXin Li public:
BitrigI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4075*67e74705SXin Li   BitrigI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4076*67e74705SXin Li       : BitrigTargetInfo<X86_32TargetInfo>(Triple, Opts) {
4077*67e74705SXin Li     SizeType = UnsignedLong;
4078*67e74705SXin Li     IntPtrType = SignedLong;
4079*67e74705SXin Li     PtrDiffType = SignedLong;
4080*67e74705SXin Li   }
4081*67e74705SXin Li };
4082*67e74705SXin Li 
4083*67e74705SXin Li class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
4084*67e74705SXin Li public:
DarwinI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4085*67e74705SXin Li   DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4086*67e74705SXin Li       : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) {
4087*67e74705SXin Li     LongDoubleWidth = 128;
4088*67e74705SXin Li     LongDoubleAlign = 128;
4089*67e74705SXin Li     SuitableAlign = 128;
4090*67e74705SXin Li     MaxVectorAlign = 256;
4091*67e74705SXin Li     // The watchOS simulator uses the builtin bool type for Objective-C.
4092*67e74705SXin Li     llvm::Triple T = llvm::Triple(Triple);
4093*67e74705SXin Li     if (T.isWatchOS())
4094*67e74705SXin Li       UseSignedCharForObjCBool = false;
4095*67e74705SXin Li     SizeType = UnsignedLong;
4096*67e74705SXin Li     IntPtrType = SignedLong;
4097*67e74705SXin Li     resetDataLayout("e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128");
4098*67e74705SXin Li     HasAlignMac68kSupport = true;
4099*67e74705SXin Li   }
4100*67e74705SXin Li 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)4101*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
4102*67e74705SXin Li                             DiagnosticsEngine &Diags) override {
4103*67e74705SXin Li     if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,
4104*67e74705SXin Li                                                                   Diags))
4105*67e74705SXin Li       return false;
4106*67e74705SXin Li     // We now know the features we have: we can decide how to align vectors.
4107*67e74705SXin Li     MaxVectorAlign =
4108*67e74705SXin Li         hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
4109*67e74705SXin Li     return true;
4110*67e74705SXin Li   }
4111*67e74705SXin Li };
4112*67e74705SXin Li 
4113*67e74705SXin Li // x86-32 Windows target
4114*67e74705SXin Li class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
4115*67e74705SXin Li public:
WindowsX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4116*67e74705SXin Li   WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4117*67e74705SXin Li       : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) {
4118*67e74705SXin Li     WCharType = UnsignedShort;
4119*67e74705SXin Li     DoubleAlign = LongLongAlign = 64;
4120*67e74705SXin Li     bool IsWinCOFF =
4121*67e74705SXin Li         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
4122*67e74705SXin Li     resetDataLayout(IsWinCOFF
4123*67e74705SXin Li                         ? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
4124*67e74705SXin Li                         : "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32");
4125*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4126*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4127*67e74705SXin Li                         MacroBuilder &Builder) const override {
4128*67e74705SXin Li     WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
4129*67e74705SXin Li   }
4130*67e74705SXin Li };
4131*67e74705SXin Li 
4132*67e74705SXin Li // x86-32 Windows Visual Studio target
4133*67e74705SXin Li class MicrosoftX86_32TargetInfo : public WindowsX86_32TargetInfo {
4134*67e74705SXin Li public:
MicrosoftX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4135*67e74705SXin Li   MicrosoftX86_32TargetInfo(const llvm::Triple &Triple,
4136*67e74705SXin Li                             const TargetOptions &Opts)
4137*67e74705SXin Li       : WindowsX86_32TargetInfo(Triple, Opts) {
4138*67e74705SXin Li     LongDoubleWidth = LongDoubleAlign = 64;
4139*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
4140*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4141*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4142*67e74705SXin Li                         MacroBuilder &Builder) const override {
4143*67e74705SXin Li     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
4144*67e74705SXin Li     WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
4145*67e74705SXin Li     // The value of the following reflects processor type.
4146*67e74705SXin Li     // 300=386, 400=486, 500=Pentium, 600=Blend (default)
4147*67e74705SXin Li     // We lost the original triple, so we use the default.
4148*67e74705SXin Li     Builder.defineMacro("_M_IX86", "600");
4149*67e74705SXin Li   }
4150*67e74705SXin Li };
4151*67e74705SXin Li 
addCygMingDefines(const LangOptions & Opts,MacroBuilder & Builder)4152*67e74705SXin Li static void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) {
4153*67e74705SXin Li   // Mingw and cygwin define __declspec(a) to __attribute__((a)).  Clang
4154*67e74705SXin Li   // supports __declspec natively under -fms-extensions, but we define a no-op
4155*67e74705SXin Li   // __declspec macro anyway for pre-processor compatibility.
4156*67e74705SXin Li   if (Opts.MicrosoftExt)
4157*67e74705SXin Li     Builder.defineMacro("__declspec", "__declspec");
4158*67e74705SXin Li   else
4159*67e74705SXin Li     Builder.defineMacro("__declspec(a)", "__attribute__((a))");
4160*67e74705SXin Li 
4161*67e74705SXin Li   if (!Opts.MicrosoftExt) {
4162*67e74705SXin Li     // Provide macros for all the calling convention keywords.  Provide both
4163*67e74705SXin Li     // single and double underscore prefixed variants.  These are available on
4164*67e74705SXin Li     // x64 as well as x86, even though they have no effect.
4165*67e74705SXin Li     const char *CCs[] = {"cdecl", "stdcall", "fastcall", "thiscall", "pascal"};
4166*67e74705SXin Li     for (const char *CC : CCs) {
4167*67e74705SXin Li       std::string GCCSpelling = "__attribute__((__";
4168*67e74705SXin Li       GCCSpelling += CC;
4169*67e74705SXin Li       GCCSpelling += "__))";
4170*67e74705SXin Li       Builder.defineMacro(Twine("_") + CC, GCCSpelling);
4171*67e74705SXin Li       Builder.defineMacro(Twine("__") + CC, GCCSpelling);
4172*67e74705SXin Li     }
4173*67e74705SXin Li   }
4174*67e74705SXin Li }
4175*67e74705SXin Li 
addMinGWDefines(const LangOptions & Opts,MacroBuilder & Builder)4176*67e74705SXin Li static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) {
4177*67e74705SXin Li   Builder.defineMacro("__MSVCRT__");
4178*67e74705SXin Li   Builder.defineMacro("__MINGW32__");
4179*67e74705SXin Li   addCygMingDefines(Opts, Builder);
4180*67e74705SXin Li }
4181*67e74705SXin Li 
4182*67e74705SXin Li // x86-32 MinGW target
4183*67e74705SXin Li class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
4184*67e74705SXin Li public:
MinGWX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4185*67e74705SXin Li   MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4186*67e74705SXin Li       : WindowsX86_32TargetInfo(Triple, Opts) {}
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4187*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4188*67e74705SXin Li                         MacroBuilder &Builder) const override {
4189*67e74705SXin Li     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
4190*67e74705SXin Li     DefineStd(Builder, "WIN32", Opts);
4191*67e74705SXin Li     DefineStd(Builder, "WINNT", Opts);
4192*67e74705SXin Li     Builder.defineMacro("_X86_");
4193*67e74705SXin Li     addMinGWDefines(Opts, Builder);
4194*67e74705SXin Li   }
4195*67e74705SXin Li };
4196*67e74705SXin Li 
4197*67e74705SXin Li // x86-32 Cygwin target
4198*67e74705SXin Li class CygwinX86_32TargetInfo : public X86_32TargetInfo {
4199*67e74705SXin Li public:
CygwinX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4200*67e74705SXin Li   CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4201*67e74705SXin Li       : X86_32TargetInfo(Triple, Opts) {
4202*67e74705SXin Li     WCharType = UnsignedShort;
4203*67e74705SXin Li     DoubleAlign = LongLongAlign = 64;
4204*67e74705SXin Li     resetDataLayout("e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32");
4205*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4206*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4207*67e74705SXin Li                         MacroBuilder &Builder) const override {
4208*67e74705SXin Li     X86_32TargetInfo::getTargetDefines(Opts, Builder);
4209*67e74705SXin Li     Builder.defineMacro("_X86_");
4210*67e74705SXin Li     Builder.defineMacro("__CYGWIN__");
4211*67e74705SXin Li     Builder.defineMacro("__CYGWIN32__");
4212*67e74705SXin Li     addCygMingDefines(Opts, Builder);
4213*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
4214*67e74705SXin Li     if (Opts.CPlusPlus)
4215*67e74705SXin Li       Builder.defineMacro("_GNU_SOURCE");
4216*67e74705SXin Li   }
4217*67e74705SXin Li };
4218*67e74705SXin Li 
4219*67e74705SXin Li // x86-32 Haiku target
4220*67e74705SXin Li class HaikuX86_32TargetInfo : public HaikuTargetInfo<X86_32TargetInfo> {
4221*67e74705SXin Li public:
HaikuX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4222*67e74705SXin Li   HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4223*67e74705SXin Li     : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {
4224*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4225*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4226*67e74705SXin Li                         MacroBuilder &Builder) const override {
4227*67e74705SXin Li     HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
4228*67e74705SXin Li     Builder.defineMacro("__INTEL__");
4229*67e74705SXin Li   }
4230*67e74705SXin Li };
4231*67e74705SXin Li 
4232*67e74705SXin Li // X86-32 MCU target
4233*67e74705SXin Li class MCUX86_32TargetInfo : public X86_32TargetInfo {
4234*67e74705SXin Li public:
MCUX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4235*67e74705SXin Li   MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4236*67e74705SXin Li       : X86_32TargetInfo(Triple, Opts) {
4237*67e74705SXin Li     LongDoubleWidth = 64;
4238*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
4239*67e74705SXin Li     resetDataLayout("e-m:e-p:32:32-i64:32-f64:32-f128:32-n8:16:32-a:0:32-S32");
4240*67e74705SXin Li     WIntType = UnsignedInt;
4241*67e74705SXin Li   }
4242*67e74705SXin Li 
checkCallingConvention(CallingConv CC) const4243*67e74705SXin Li   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
4244*67e74705SXin Li     // On MCU we support only C calling convention.
4245*67e74705SXin Li     return CC == CC_C ? CCCR_OK : CCCR_Warning;
4246*67e74705SXin Li   }
4247*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4248*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4249*67e74705SXin Li                         MacroBuilder &Builder) const override {
4250*67e74705SXin Li     X86_32TargetInfo::getTargetDefines(Opts, Builder);
4251*67e74705SXin Li     Builder.defineMacro("__iamcu");
4252*67e74705SXin Li     Builder.defineMacro("__iamcu__");
4253*67e74705SXin Li   }
4254*67e74705SXin Li 
allowsLargerPreferedTypeAlignment() const4255*67e74705SXin Li   bool allowsLargerPreferedTypeAlignment() const override {
4256*67e74705SXin Li     return false;
4257*67e74705SXin Li   }
4258*67e74705SXin Li };
4259*67e74705SXin Li 
4260*67e74705SXin Li // RTEMS Target
4261*67e74705SXin Li template<typename Target>
4262*67e74705SXin Li class RTEMSTargetInfo : public OSTargetInfo<Target> {
4263*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const4264*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
4265*67e74705SXin Li                     MacroBuilder &Builder) const override {
4266*67e74705SXin Li     // RTEMS defines; list based off of gcc output
4267*67e74705SXin Li 
4268*67e74705SXin Li     Builder.defineMacro("__rtems__");
4269*67e74705SXin Li     Builder.defineMacro("__ELF__");
4270*67e74705SXin Li   }
4271*67e74705SXin Li 
4272*67e74705SXin Li public:
RTEMSTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4273*67e74705SXin Li   RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4274*67e74705SXin Li       : OSTargetInfo<Target>(Triple, Opts) {
4275*67e74705SXin Li     switch (Triple.getArch()) {
4276*67e74705SXin Li     default:
4277*67e74705SXin Li     case llvm::Triple::x86:
4278*67e74705SXin Li       // this->MCountName = ".mcount";
4279*67e74705SXin Li       break;
4280*67e74705SXin Li     case llvm::Triple::mips:
4281*67e74705SXin Li     case llvm::Triple::mipsel:
4282*67e74705SXin Li     case llvm::Triple::ppc:
4283*67e74705SXin Li     case llvm::Triple::ppc64:
4284*67e74705SXin Li     case llvm::Triple::ppc64le:
4285*67e74705SXin Li       // this->MCountName = "_mcount";
4286*67e74705SXin Li       break;
4287*67e74705SXin Li     case llvm::Triple::arm:
4288*67e74705SXin Li       // this->MCountName = "__mcount";
4289*67e74705SXin Li       break;
4290*67e74705SXin Li     }
4291*67e74705SXin Li   }
4292*67e74705SXin Li };
4293*67e74705SXin Li 
4294*67e74705SXin Li // x86-32 RTEMS target
4295*67e74705SXin Li class RTEMSX86_32TargetInfo : public X86_32TargetInfo {
4296*67e74705SXin Li public:
RTEMSX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4297*67e74705SXin Li   RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4298*67e74705SXin Li       : X86_32TargetInfo(Triple, Opts) {
4299*67e74705SXin Li     SizeType = UnsignedLong;
4300*67e74705SXin Li     IntPtrType = SignedLong;
4301*67e74705SXin Li     PtrDiffType = SignedLong;
4302*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4303*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4304*67e74705SXin Li                         MacroBuilder &Builder) const override {
4305*67e74705SXin Li     X86_32TargetInfo::getTargetDefines(Opts, Builder);
4306*67e74705SXin Li     Builder.defineMacro("__INTEL__");
4307*67e74705SXin Li     Builder.defineMacro("__rtems__");
4308*67e74705SXin Li   }
4309*67e74705SXin Li };
4310*67e74705SXin Li 
4311*67e74705SXin Li // x86-64 generic target
4312*67e74705SXin Li class X86_64TargetInfo : public X86TargetInfo {
4313*67e74705SXin Li public:
X86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4314*67e74705SXin Li   X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4315*67e74705SXin Li       : X86TargetInfo(Triple, Opts) {
4316*67e74705SXin Li     const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32;
4317*67e74705SXin Li     bool IsWinCOFF =
4318*67e74705SXin Li         getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
4319*67e74705SXin Li     LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
4320*67e74705SXin Li     LongDoubleWidth = 128;
4321*67e74705SXin Li     LongDoubleAlign = 128;
4322*67e74705SXin Li     LargeArrayMinWidth = 128;
4323*67e74705SXin Li     LargeArrayAlign = 128;
4324*67e74705SXin Li     SuitableAlign = 128;
4325*67e74705SXin Li     SizeType    = IsX32 ? UnsignedInt      : UnsignedLong;
4326*67e74705SXin Li     PtrDiffType = IsX32 ? SignedInt        : SignedLong;
4327*67e74705SXin Li     IntPtrType  = IsX32 ? SignedInt        : SignedLong;
4328*67e74705SXin Li     IntMaxType  = IsX32 ? SignedLongLong   : SignedLong;
4329*67e74705SXin Li     Int64Type   = IsX32 ? SignedLongLong   : SignedLong;
4330*67e74705SXin Li     RegParmMax = 6;
4331*67e74705SXin Li 
4332*67e74705SXin Li     // Pointers are 32-bit in x32.
4333*67e74705SXin Li     resetDataLayout(IsX32
4334*67e74705SXin Li                         ? "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128"
4335*67e74705SXin Li                         : IsWinCOFF ? "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
4336*67e74705SXin Li                                     : "e-m:e-i64:64-f80:128-n8:16:32:64-S128");
4337*67e74705SXin Li 
4338*67e74705SXin Li     // Use fpret only for long double.
4339*67e74705SXin Li     RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
4340*67e74705SXin Li 
4341*67e74705SXin Li     // Use fp2ret for _Complex long double.
4342*67e74705SXin Li     ComplexLongDoubleUsesFP2Ret = true;
4343*67e74705SXin Li 
4344*67e74705SXin Li     // Make __builtin_ms_va_list available.
4345*67e74705SXin Li     HasBuiltinMSVaList = true;
4346*67e74705SXin Li 
4347*67e74705SXin Li     // x86-64 has atomics up to 16 bytes.
4348*67e74705SXin Li     MaxAtomicPromoteWidth = 128;
4349*67e74705SXin Li     MaxAtomicInlineWidth = 128;
4350*67e74705SXin Li   }
getBuiltinVaListKind() const4351*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
4352*67e74705SXin Li     return TargetInfo::X86_64ABIBuiltinVaList;
4353*67e74705SXin Li   }
4354*67e74705SXin Li 
getEHDataRegisterNumber(unsigned RegNo) const4355*67e74705SXin Li   int getEHDataRegisterNumber(unsigned RegNo) const override {
4356*67e74705SXin Li     if (RegNo == 0) return 0;
4357*67e74705SXin Li     if (RegNo == 1) return 1;
4358*67e74705SXin Li     return -1;
4359*67e74705SXin Li   }
4360*67e74705SXin Li 
checkCallingConvention(CallingConv CC) const4361*67e74705SXin Li   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
4362*67e74705SXin Li     switch (CC) {
4363*67e74705SXin Li     case CC_C:
4364*67e74705SXin Li     case CC_Swift:
4365*67e74705SXin Li     case CC_X86VectorCall:
4366*67e74705SXin Li     case CC_IntelOclBicc:
4367*67e74705SXin Li     case CC_X86_64Win64:
4368*67e74705SXin Li     case CC_PreserveMost:
4369*67e74705SXin Li     case CC_PreserveAll:
4370*67e74705SXin Li       return CCCR_OK;
4371*67e74705SXin Li     default:
4372*67e74705SXin Li       return CCCR_Warning;
4373*67e74705SXin Li     }
4374*67e74705SXin Li   }
4375*67e74705SXin Li 
getDefaultCallingConv(CallingConvMethodType MT) const4376*67e74705SXin Li   CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
4377*67e74705SXin Li     return CC_C;
4378*67e74705SXin Li   }
4379*67e74705SXin Li 
4380*67e74705SXin Li   // for x32 we need it here explicitly
hasInt128Type() const4381*67e74705SXin Li   bool hasInt128Type() const override { return true; }
getUnwindWordWidth() const4382*67e74705SXin Li   unsigned getUnwindWordWidth() const override { return 64; }
getRegisterWidth() const4383*67e74705SXin Li   unsigned getRegisterWidth() const override { return 64; }
4384*67e74705SXin Li 
validateGlobalRegisterVariable(StringRef RegName,unsigned RegSize,bool & HasSizeMismatch) const4385*67e74705SXin Li   bool validateGlobalRegisterVariable(StringRef RegName,
4386*67e74705SXin Li                                       unsigned RegSize,
4387*67e74705SXin Li                                       bool &HasSizeMismatch) const override {
4388*67e74705SXin Li     // rsp and rbp are the only 64-bit registers the x86 backend can currently
4389*67e74705SXin Li     // handle.
4390*67e74705SXin Li     if (RegName.equals("rsp") || RegName.equals("rbp")) {
4391*67e74705SXin Li       // Check that the register size is 64-bit.
4392*67e74705SXin Li       HasSizeMismatch = RegSize != 64;
4393*67e74705SXin Li       return true;
4394*67e74705SXin Li     }
4395*67e74705SXin Li 
4396*67e74705SXin Li     // Check if the register is a 32-bit register the backend can handle.
4397*67e74705SXin Li     return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,
4398*67e74705SXin Li                                                          HasSizeMismatch);
4399*67e74705SXin Li   }
4400*67e74705SXin Li };
4401*67e74705SXin Li 
4402*67e74705SXin Li // x86-64 Windows target
4403*67e74705SXin Li class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
4404*67e74705SXin Li public:
WindowsX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4405*67e74705SXin Li   WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4406*67e74705SXin Li       : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) {
4407*67e74705SXin Li     WCharType = UnsignedShort;
4408*67e74705SXin Li     LongWidth = LongAlign = 32;
4409*67e74705SXin Li     DoubleAlign = LongLongAlign = 64;
4410*67e74705SXin Li     IntMaxType = SignedLongLong;
4411*67e74705SXin Li     Int64Type = SignedLongLong;
4412*67e74705SXin Li     SizeType = UnsignedLongLong;
4413*67e74705SXin Li     PtrDiffType = SignedLongLong;
4414*67e74705SXin Li     IntPtrType = SignedLongLong;
4415*67e74705SXin Li   }
4416*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4417*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4418*67e74705SXin Li                                 MacroBuilder &Builder) const override {
4419*67e74705SXin Li     WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
4420*67e74705SXin Li     Builder.defineMacro("_WIN64");
4421*67e74705SXin Li   }
4422*67e74705SXin Li 
getBuiltinVaListKind() const4423*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
4424*67e74705SXin Li     return TargetInfo::CharPtrBuiltinVaList;
4425*67e74705SXin Li   }
4426*67e74705SXin Li 
checkCallingConvention(CallingConv CC) const4427*67e74705SXin Li   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
4428*67e74705SXin Li     switch (CC) {
4429*67e74705SXin Li     case CC_X86StdCall:
4430*67e74705SXin Li     case CC_X86ThisCall:
4431*67e74705SXin Li     case CC_X86FastCall:
4432*67e74705SXin Li       return CCCR_Ignore;
4433*67e74705SXin Li     case CC_C:
4434*67e74705SXin Li     case CC_X86VectorCall:
4435*67e74705SXin Li     case CC_IntelOclBicc:
4436*67e74705SXin Li     case CC_X86_64SysV:
4437*67e74705SXin Li       return CCCR_OK;
4438*67e74705SXin Li     default:
4439*67e74705SXin Li       return CCCR_Warning;
4440*67e74705SXin Li     }
4441*67e74705SXin Li   }
4442*67e74705SXin Li };
4443*67e74705SXin Li 
4444*67e74705SXin Li // x86-64 Windows Visual Studio target
4445*67e74705SXin Li class MicrosoftX86_64TargetInfo : public WindowsX86_64TargetInfo {
4446*67e74705SXin Li public:
MicrosoftX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4447*67e74705SXin Li   MicrosoftX86_64TargetInfo(const llvm::Triple &Triple,
4448*67e74705SXin Li                             const TargetOptions &Opts)
4449*67e74705SXin Li       : WindowsX86_64TargetInfo(Triple, Opts) {
4450*67e74705SXin Li     LongDoubleWidth = LongDoubleAlign = 64;
4451*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
4452*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4453*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4454*67e74705SXin Li                         MacroBuilder &Builder) const override {
4455*67e74705SXin Li     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
4456*67e74705SXin Li     WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
4457*67e74705SXin Li     Builder.defineMacro("_M_X64", "100");
4458*67e74705SXin Li     Builder.defineMacro("_M_AMD64", "100");
4459*67e74705SXin Li   }
4460*67e74705SXin Li };
4461*67e74705SXin Li 
4462*67e74705SXin Li // x86-64 MinGW target
4463*67e74705SXin Li class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
4464*67e74705SXin Li public:
MinGWX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4465*67e74705SXin Li   MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4466*67e74705SXin Li       : WindowsX86_64TargetInfo(Triple, Opts) {
4467*67e74705SXin Li     // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
4468*67e74705SXin Li     // with x86 FP ops. Weird.
4469*67e74705SXin Li     LongDoubleWidth = LongDoubleAlign = 128;
4470*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
4471*67e74705SXin Li   }
4472*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4473*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4474*67e74705SXin Li                         MacroBuilder &Builder) const override {
4475*67e74705SXin Li     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
4476*67e74705SXin Li     DefineStd(Builder, "WIN64", Opts);
4477*67e74705SXin Li     Builder.defineMacro("__MINGW64__");
4478*67e74705SXin Li     addMinGWDefines(Opts, Builder);
4479*67e74705SXin Li 
4480*67e74705SXin Li     // GCC defines this macro when it is using __gxx_personality_seh0.
4481*67e74705SXin Li     if (!Opts.SjLjExceptions)
4482*67e74705SXin Li       Builder.defineMacro("__SEH__");
4483*67e74705SXin Li   }
4484*67e74705SXin Li };
4485*67e74705SXin Li 
4486*67e74705SXin Li // x86-64 Cygwin target
4487*67e74705SXin Li class CygwinX86_64TargetInfo : public X86_64TargetInfo {
4488*67e74705SXin Li public:
CygwinX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4489*67e74705SXin Li   CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4490*67e74705SXin Li       : X86_64TargetInfo(Triple, Opts) {
4491*67e74705SXin Li     TLSSupported = false;
4492*67e74705SXin Li     WCharType = UnsignedShort;
4493*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4494*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
4495*67e74705SXin Li                         MacroBuilder &Builder) const override {
4496*67e74705SXin Li     X86_64TargetInfo::getTargetDefines(Opts, Builder);
4497*67e74705SXin Li     Builder.defineMacro("__x86_64__");
4498*67e74705SXin Li     Builder.defineMacro("__CYGWIN__");
4499*67e74705SXin Li     Builder.defineMacro("__CYGWIN64__");
4500*67e74705SXin Li     addCygMingDefines(Opts, Builder);
4501*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
4502*67e74705SXin Li     if (Opts.CPlusPlus)
4503*67e74705SXin Li       Builder.defineMacro("_GNU_SOURCE");
4504*67e74705SXin Li 
4505*67e74705SXin Li     // GCC defines this macro when it is using __gxx_personality_seh0.
4506*67e74705SXin Li     if (!Opts.SjLjExceptions)
4507*67e74705SXin Li       Builder.defineMacro("__SEH__");
4508*67e74705SXin Li   }
4509*67e74705SXin Li };
4510*67e74705SXin Li 
4511*67e74705SXin Li class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
4512*67e74705SXin Li public:
DarwinX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4513*67e74705SXin Li   DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4514*67e74705SXin Li       : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) {
4515*67e74705SXin Li     Int64Type = SignedLongLong;
4516*67e74705SXin Li     // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
4517*67e74705SXin Li     llvm::Triple T = llvm::Triple(Triple);
4518*67e74705SXin Li     if (T.isiOS())
4519*67e74705SXin Li       UseSignedCharForObjCBool = false;
4520*67e74705SXin Li     resetDataLayout("e-m:o-i64:64-f80:128-n8:16:32:64-S128");
4521*67e74705SXin Li   }
4522*67e74705SXin Li 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)4523*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
4524*67e74705SXin Li                             DiagnosticsEngine &Diags) override {
4525*67e74705SXin Li     if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,
4526*67e74705SXin Li                                                                   Diags))
4527*67e74705SXin Li       return false;
4528*67e74705SXin Li     // We now know the features we have: we can decide how to align vectors.
4529*67e74705SXin Li     MaxVectorAlign =
4530*67e74705SXin Li         hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
4531*67e74705SXin Li     return true;
4532*67e74705SXin Li   }
4533*67e74705SXin Li };
4534*67e74705SXin Li 
4535*67e74705SXin Li class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
4536*67e74705SXin Li public:
OpenBSDX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4537*67e74705SXin Li   OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4538*67e74705SXin Li       : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) {
4539*67e74705SXin Li     IntMaxType = SignedLongLong;
4540*67e74705SXin Li     Int64Type = SignedLongLong;
4541*67e74705SXin Li   }
4542*67e74705SXin Li };
4543*67e74705SXin Li 
4544*67e74705SXin Li class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> {
4545*67e74705SXin Li public:
BitrigX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4546*67e74705SXin Li   BitrigX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
4547*67e74705SXin Li       : BitrigTargetInfo<X86_64TargetInfo>(Triple, Opts) {
4548*67e74705SXin Li     IntMaxType = SignedLongLong;
4549*67e74705SXin Li     Int64Type = SignedLongLong;
4550*67e74705SXin Li   }
4551*67e74705SXin Li };
4552*67e74705SXin Li 
4553*67e74705SXin Li class ARMTargetInfo : public TargetInfo {
4554*67e74705SXin Li   // Possible FPU choices.
4555*67e74705SXin Li   enum FPUMode {
4556*67e74705SXin Li     VFP2FPU = (1 << 0),
4557*67e74705SXin Li     VFP3FPU = (1 << 1),
4558*67e74705SXin Li     VFP4FPU = (1 << 2),
4559*67e74705SXin Li     NeonFPU = (1 << 3),
4560*67e74705SXin Li     FPARMV8 = (1 << 4)
4561*67e74705SXin Li   };
4562*67e74705SXin Li 
4563*67e74705SXin Li   // Possible HWDiv features.
4564*67e74705SXin Li   enum HWDivMode {
4565*67e74705SXin Li     HWDivThumb = (1 << 0),
4566*67e74705SXin Li     HWDivARM = (1 << 1)
4567*67e74705SXin Li   };
4568*67e74705SXin Li 
FPUModeIsVFP(FPUMode Mode)4569*67e74705SXin Li   static bool FPUModeIsVFP(FPUMode Mode) {
4570*67e74705SXin Li     return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU | FPARMV8);
4571*67e74705SXin Li   }
4572*67e74705SXin Li 
4573*67e74705SXin Li   static const TargetInfo::GCCRegAlias GCCRegAliases[];
4574*67e74705SXin Li   static const char * const GCCRegNames[];
4575*67e74705SXin Li 
4576*67e74705SXin Li   std::string ABI, CPU;
4577*67e74705SXin Li 
4578*67e74705SXin Li   StringRef CPUProfile;
4579*67e74705SXin Li   StringRef CPUAttr;
4580*67e74705SXin Li 
4581*67e74705SXin Li   enum {
4582*67e74705SXin Li     FP_Default,
4583*67e74705SXin Li     FP_VFP,
4584*67e74705SXin Li     FP_Neon
4585*67e74705SXin Li   } FPMath;
4586*67e74705SXin Li 
4587*67e74705SXin Li   unsigned ArchISA;
4588*67e74705SXin Li   unsigned ArchKind = llvm::ARM::AK_ARMV4T;
4589*67e74705SXin Li   unsigned ArchProfile;
4590*67e74705SXin Li   unsigned ArchVersion;
4591*67e74705SXin Li 
4592*67e74705SXin Li   unsigned FPU : 5;
4593*67e74705SXin Li 
4594*67e74705SXin Li   unsigned IsAAPCS : 1;
4595*67e74705SXin Li   unsigned HWDiv : 2;
4596*67e74705SXin Li 
4597*67e74705SXin Li   // Initialized via features.
4598*67e74705SXin Li   unsigned SoftFloat : 1;
4599*67e74705SXin Li   unsigned SoftFloatABI : 1;
4600*67e74705SXin Li 
4601*67e74705SXin Li   unsigned CRC : 1;
4602*67e74705SXin Li   unsigned Crypto : 1;
4603*67e74705SXin Li   unsigned DSP : 1;
4604*67e74705SXin Li   unsigned Unaligned : 1;
4605*67e74705SXin Li 
4606*67e74705SXin Li   enum {
4607*67e74705SXin Li     LDREX_B = (1 << 0), /// byte (8-bit)
4608*67e74705SXin Li     LDREX_H = (1 << 1), /// half (16-bit)
4609*67e74705SXin Li     LDREX_W = (1 << 2), /// word (32-bit)
4610*67e74705SXin Li     LDREX_D = (1 << 3), /// double (64-bit)
4611*67e74705SXin Li   };
4612*67e74705SXin Li 
4613*67e74705SXin Li   uint32_t LDREX;
4614*67e74705SXin Li 
4615*67e74705SXin Li   // ACLE 6.5.1 Hardware floating point
4616*67e74705SXin Li   enum {
4617*67e74705SXin Li     HW_FP_HP = (1 << 1), /// half (16-bit)
4618*67e74705SXin Li     HW_FP_SP = (1 << 2), /// single (32-bit)
4619*67e74705SXin Li     HW_FP_DP = (1 << 3), /// double (64-bit)
4620*67e74705SXin Li   };
4621*67e74705SXin Li   uint32_t HW_FP;
4622*67e74705SXin Li 
4623*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
4624*67e74705SXin Li 
setABIAAPCS()4625*67e74705SXin Li   void setABIAAPCS() {
4626*67e74705SXin Li     IsAAPCS = true;
4627*67e74705SXin Li 
4628*67e74705SXin Li     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
4629*67e74705SXin Li     const llvm::Triple &T = getTriple();
4630*67e74705SXin Li 
4631*67e74705SXin Li     // size_t is unsigned long on MachO-derived environments, NetBSD and Bitrig.
4632*67e74705SXin Li     if (T.isOSBinFormatMachO() || T.getOS() == llvm::Triple::NetBSD ||
4633*67e74705SXin Li         T.getOS() == llvm::Triple::Bitrig)
4634*67e74705SXin Li       SizeType = UnsignedLong;
4635*67e74705SXin Li     else
4636*67e74705SXin Li       SizeType = UnsignedInt;
4637*67e74705SXin Li 
4638*67e74705SXin Li     switch (T.getOS()) {
4639*67e74705SXin Li     case llvm::Triple::NetBSD:
4640*67e74705SXin Li       WCharType = SignedInt;
4641*67e74705SXin Li       break;
4642*67e74705SXin Li     case llvm::Triple::Win32:
4643*67e74705SXin Li       WCharType = UnsignedShort;
4644*67e74705SXin Li       break;
4645*67e74705SXin Li     case llvm::Triple::Linux:
4646*67e74705SXin Li     default:
4647*67e74705SXin Li       // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
4648*67e74705SXin Li       WCharType = UnsignedInt;
4649*67e74705SXin Li       break;
4650*67e74705SXin Li     }
4651*67e74705SXin Li 
4652*67e74705SXin Li     UseBitFieldTypeAlignment = true;
4653*67e74705SXin Li 
4654*67e74705SXin Li     ZeroLengthBitfieldBoundary = 0;
4655*67e74705SXin Li 
4656*67e74705SXin Li     // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
4657*67e74705SXin Li     // so set preferred for small types to 32.
4658*67e74705SXin Li     if (T.isOSBinFormatMachO()) {
4659*67e74705SXin Li       resetDataLayout(BigEndian
4660*67e74705SXin Li                           ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
4661*67e74705SXin Li                           : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
4662*67e74705SXin Li     } else if (T.isOSWindows()) {
4663*67e74705SXin Li       assert(!BigEndian && "Windows on ARM does not support big endian");
4664*67e74705SXin Li       resetDataLayout("e"
4665*67e74705SXin Li                       "-m:w"
4666*67e74705SXin Li                       "-p:32:32"
4667*67e74705SXin Li                       "-i64:64"
4668*67e74705SXin Li                       "-v128:64:128"
4669*67e74705SXin Li                       "-a:0:32"
4670*67e74705SXin Li                       "-n32"
4671*67e74705SXin Li                       "-S64");
4672*67e74705SXin Li     } else if (T.isOSNaCl()) {
4673*67e74705SXin Li       assert(!BigEndian && "NaCl on ARM does not support big endian");
4674*67e74705SXin Li       resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
4675*67e74705SXin Li     } else {
4676*67e74705SXin Li       resetDataLayout(BigEndian
4677*67e74705SXin Li                           ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
4678*67e74705SXin Li                           : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
4679*67e74705SXin Li     }
4680*67e74705SXin Li 
4681*67e74705SXin Li     // FIXME: Enumerated types are variable width in straight AAPCS.
4682*67e74705SXin Li   }
4683*67e74705SXin Li 
setABIAPCS(bool IsAAPCS16)4684*67e74705SXin Li   void setABIAPCS(bool IsAAPCS16) {
4685*67e74705SXin Li     const llvm::Triple &T = getTriple();
4686*67e74705SXin Li 
4687*67e74705SXin Li     IsAAPCS = false;
4688*67e74705SXin Li 
4689*67e74705SXin Li     if (IsAAPCS16)
4690*67e74705SXin Li       DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
4691*67e74705SXin Li     else
4692*67e74705SXin Li       DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
4693*67e74705SXin Li 
4694*67e74705SXin Li     // size_t is unsigned int on FreeBSD.
4695*67e74705SXin Li     if (T.getOS() == llvm::Triple::FreeBSD)
4696*67e74705SXin Li       SizeType = UnsignedInt;
4697*67e74705SXin Li     else
4698*67e74705SXin Li       SizeType = UnsignedLong;
4699*67e74705SXin Li 
4700*67e74705SXin Li     // Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
4701*67e74705SXin Li     WCharType = SignedInt;
4702*67e74705SXin Li 
4703*67e74705SXin Li     // Do not respect the alignment of bit-field types when laying out
4704*67e74705SXin Li     // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
4705*67e74705SXin Li     UseBitFieldTypeAlignment = false;
4706*67e74705SXin Li 
4707*67e74705SXin Li     /// gcc forces the alignment to 4 bytes, regardless of the type of the
4708*67e74705SXin Li     /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
4709*67e74705SXin Li     /// gcc.
4710*67e74705SXin Li     ZeroLengthBitfieldBoundary = 32;
4711*67e74705SXin Li 
4712*67e74705SXin Li     if (T.isOSBinFormatMachO() && IsAAPCS16) {
4713*67e74705SXin Li       assert(!BigEndian && "AAPCS16 does not support big-endian");
4714*67e74705SXin Li       resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
4715*67e74705SXin Li     } else if (T.isOSBinFormatMachO())
4716*67e74705SXin Li       resetDataLayout(
4717*67e74705SXin Li           BigEndian
4718*67e74705SXin Li               ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
4719*67e74705SXin Li               : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
4720*67e74705SXin Li     else
4721*67e74705SXin Li       resetDataLayout(
4722*67e74705SXin Li           BigEndian
4723*67e74705SXin Li               ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
4724*67e74705SXin Li               : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
4725*67e74705SXin Li 
4726*67e74705SXin Li     // FIXME: Override "preferred align" for double and long long.
4727*67e74705SXin Li   }
4728*67e74705SXin Li 
setArchInfo()4729*67e74705SXin Li   void setArchInfo() {
4730*67e74705SXin Li     StringRef ArchName = getTriple().getArchName();
4731*67e74705SXin Li 
4732*67e74705SXin Li     ArchISA     = llvm::ARM::parseArchISA(ArchName);
4733*67e74705SXin Li     CPU         = llvm::ARM::getDefaultCPU(ArchName);
4734*67e74705SXin Li     unsigned AK = llvm::ARM::parseArch(ArchName);
4735*67e74705SXin Li     if (AK != llvm::ARM::AK_INVALID)
4736*67e74705SXin Li       ArchKind = AK;
4737*67e74705SXin Li     setArchInfo(ArchKind);
4738*67e74705SXin Li   }
4739*67e74705SXin Li 
setArchInfo(unsigned Kind)4740*67e74705SXin Li   void setArchInfo(unsigned Kind) {
4741*67e74705SXin Li     StringRef SubArch;
4742*67e74705SXin Li 
4743*67e74705SXin Li     // cache TargetParser info
4744*67e74705SXin Li     ArchKind    = Kind;
4745*67e74705SXin Li     SubArch     = llvm::ARM::getSubArch(ArchKind);
4746*67e74705SXin Li     ArchProfile = llvm::ARM::parseArchProfile(SubArch);
4747*67e74705SXin Li     ArchVersion = llvm::ARM::parseArchVersion(SubArch);
4748*67e74705SXin Li 
4749*67e74705SXin Li     // cache CPU related strings
4750*67e74705SXin Li     CPUAttr    = getCPUAttr();
4751*67e74705SXin Li     CPUProfile = getCPUProfile();
4752*67e74705SXin Li   }
4753*67e74705SXin Li 
setAtomic()4754*67e74705SXin Li   void setAtomic() {
4755*67e74705SXin Li     // when triple does not specify a sub arch,
4756*67e74705SXin Li     // then we are not using inline atomics
4757*67e74705SXin Li     bool ShouldUseInlineAtomic =
4758*67e74705SXin Li                    (ArchISA == llvm::ARM::IK_ARM   && ArchVersion >= 6) ||
4759*67e74705SXin Li                    (ArchISA == llvm::ARM::IK_THUMB && ArchVersion >= 7);
4760*67e74705SXin Li     // Cortex M does not support 8 byte atomics, while general Thumb2 does.
4761*67e74705SXin Li     if (ArchProfile == llvm::ARM::PK_M) {
4762*67e74705SXin Li       MaxAtomicPromoteWidth = 32;
4763*67e74705SXin Li       if (ShouldUseInlineAtomic)
4764*67e74705SXin Li         MaxAtomicInlineWidth = 32;
4765*67e74705SXin Li     }
4766*67e74705SXin Li     else {
4767*67e74705SXin Li       MaxAtomicPromoteWidth = 64;
4768*67e74705SXin Li       if (ShouldUseInlineAtomic)
4769*67e74705SXin Li         MaxAtomicInlineWidth = 64;
4770*67e74705SXin Li     }
4771*67e74705SXin Li   }
4772*67e74705SXin Li 
isThumb() const4773*67e74705SXin Li   bool isThumb() const {
4774*67e74705SXin Li     return (ArchISA == llvm::ARM::IK_THUMB);
4775*67e74705SXin Li   }
4776*67e74705SXin Li 
supportsThumb() const4777*67e74705SXin Li   bool supportsThumb() const {
4778*67e74705SXin Li     return CPUAttr.count('T') || ArchVersion >= 6;
4779*67e74705SXin Li   }
4780*67e74705SXin Li 
supportsThumb2() const4781*67e74705SXin Li   bool supportsThumb2() const {
4782*67e74705SXin Li     return CPUAttr.equals("6T2") ||
4783*67e74705SXin Li            (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
4784*67e74705SXin Li   }
4785*67e74705SXin Li 
getCPUAttr() const4786*67e74705SXin Li   StringRef getCPUAttr() const {
4787*67e74705SXin Li     // For most sub-arches, the build attribute CPU name is enough.
4788*67e74705SXin Li     // For Cortex variants, it's slightly different.
4789*67e74705SXin Li     switch(ArchKind) {
4790*67e74705SXin Li     default:
4791*67e74705SXin Li       return llvm::ARM::getCPUAttr(ArchKind);
4792*67e74705SXin Li     case llvm::ARM::AK_ARMV6M:
4793*67e74705SXin Li       return "6M";
4794*67e74705SXin Li     case llvm::ARM::AK_ARMV7S:
4795*67e74705SXin Li       return "7S";
4796*67e74705SXin Li     case llvm::ARM::AK_ARMV7A:
4797*67e74705SXin Li       return "7A";
4798*67e74705SXin Li     case llvm::ARM::AK_ARMV7R:
4799*67e74705SXin Li       return "7R";
4800*67e74705SXin Li     case llvm::ARM::AK_ARMV7M:
4801*67e74705SXin Li       return "7M";
4802*67e74705SXin Li     case llvm::ARM::AK_ARMV7EM:
4803*67e74705SXin Li       return "7EM";
4804*67e74705SXin Li     case llvm::ARM::AK_ARMV8A:
4805*67e74705SXin Li       return "8A";
4806*67e74705SXin Li     case llvm::ARM::AK_ARMV8_1A:
4807*67e74705SXin Li       return "8_1A";
4808*67e74705SXin Li     case llvm::ARM::AK_ARMV8_2A:
4809*67e74705SXin Li       return "8_2A";
4810*67e74705SXin Li     case llvm::ARM::AK_ARMV8MBaseline:
4811*67e74705SXin Li       return "8M_BASE";
4812*67e74705SXin Li     case llvm::ARM::AK_ARMV8MMainline:
4813*67e74705SXin Li       return "8M_MAIN";
4814*67e74705SXin Li     }
4815*67e74705SXin Li   }
4816*67e74705SXin Li 
getCPUProfile() const4817*67e74705SXin Li   StringRef getCPUProfile() const {
4818*67e74705SXin Li     switch(ArchProfile) {
4819*67e74705SXin Li     case llvm::ARM::PK_A:
4820*67e74705SXin Li       return "A";
4821*67e74705SXin Li     case llvm::ARM::PK_R:
4822*67e74705SXin Li       return "R";
4823*67e74705SXin Li     case llvm::ARM::PK_M:
4824*67e74705SXin Li       return "M";
4825*67e74705SXin Li     default:
4826*67e74705SXin Li       return "";
4827*67e74705SXin Li     }
4828*67e74705SXin Li   }
4829*67e74705SXin Li 
4830*67e74705SXin Li public:
ARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts,bool IsBigEndian)4831*67e74705SXin Li   ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts,
4832*67e74705SXin Li                 bool IsBigEndian)
4833*67e74705SXin Li       : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
4834*67e74705SXin Li         HW_FP(0) {
4835*67e74705SXin Li     BigEndian = IsBigEndian;
4836*67e74705SXin Li 
4837*67e74705SXin Li     switch (getTriple().getOS()) {
4838*67e74705SXin Li     case llvm::Triple::NetBSD:
4839*67e74705SXin Li       PtrDiffType = SignedLong;
4840*67e74705SXin Li       break;
4841*67e74705SXin Li     default:
4842*67e74705SXin Li       PtrDiffType = SignedInt;
4843*67e74705SXin Li       break;
4844*67e74705SXin Li     }
4845*67e74705SXin Li 
4846*67e74705SXin Li     // Cache arch related info.
4847*67e74705SXin Li     setArchInfo();
4848*67e74705SXin Li 
4849*67e74705SXin Li     // {} in inline assembly are neon specifiers, not assembly variant
4850*67e74705SXin Li     // specifiers.
4851*67e74705SXin Li     NoAsmVariants = true;
4852*67e74705SXin Li 
4853*67e74705SXin Li     // FIXME: This duplicates code from the driver that sets the -target-abi
4854*67e74705SXin Li     // option - this code is used if -target-abi isn't passed and should
4855*67e74705SXin Li     // be unified in some way.
4856*67e74705SXin Li     if (Triple.isOSBinFormatMachO()) {
4857*67e74705SXin Li       // The backend is hardwired to assume AAPCS for M-class processors, ensure
4858*67e74705SXin Li       // the frontend matches that.
4859*67e74705SXin Li       if (Triple.getEnvironment() == llvm::Triple::EABI ||
4860*67e74705SXin Li           Triple.getOS() == llvm::Triple::UnknownOS ||
4861*67e74705SXin Li           StringRef(CPU).startswith("cortex-m")) {
4862*67e74705SXin Li         setABI("aapcs");
4863*67e74705SXin Li       } else if (Triple.isWatchABI()) {
4864*67e74705SXin Li         setABI("aapcs16");
4865*67e74705SXin Li       } else {
4866*67e74705SXin Li         setABI("apcs-gnu");
4867*67e74705SXin Li       }
4868*67e74705SXin Li     } else if (Triple.isOSWindows()) {
4869*67e74705SXin Li       // FIXME: this is invalid for WindowsCE
4870*67e74705SXin Li       setABI("aapcs");
4871*67e74705SXin Li     } else {
4872*67e74705SXin Li       // Select the default based on the platform.
4873*67e74705SXin Li       switch (Triple.getEnvironment()) {
4874*67e74705SXin Li       case llvm::Triple::Android:
4875*67e74705SXin Li       case llvm::Triple::GNUEABI:
4876*67e74705SXin Li       case llvm::Triple::GNUEABIHF:
4877*67e74705SXin Li       case llvm::Triple::MuslEABI:
4878*67e74705SXin Li       case llvm::Triple::MuslEABIHF:
4879*67e74705SXin Li         setABI("aapcs-linux");
4880*67e74705SXin Li         break;
4881*67e74705SXin Li       case llvm::Triple::EABIHF:
4882*67e74705SXin Li       case llvm::Triple::EABI:
4883*67e74705SXin Li         setABI("aapcs");
4884*67e74705SXin Li         break;
4885*67e74705SXin Li       case llvm::Triple::GNU:
4886*67e74705SXin Li         setABI("apcs-gnu");
4887*67e74705SXin Li       break;
4888*67e74705SXin Li       default:
4889*67e74705SXin Li         if (Triple.getOS() == llvm::Triple::NetBSD)
4890*67e74705SXin Li           setABI("apcs-gnu");
4891*67e74705SXin Li         else
4892*67e74705SXin Li           setABI("aapcs");
4893*67e74705SXin Li         break;
4894*67e74705SXin Li       }
4895*67e74705SXin Li     }
4896*67e74705SXin Li 
4897*67e74705SXin Li     // ARM targets default to using the ARM C++ ABI.
4898*67e74705SXin Li     TheCXXABI.set(TargetCXXABI::GenericARM);
4899*67e74705SXin Li 
4900*67e74705SXin Li     // ARM has atomics up to 8 bytes
4901*67e74705SXin Li     setAtomic();
4902*67e74705SXin Li 
4903*67e74705SXin Li     // Do force alignment of members that follow zero length bitfields.  If
4904*67e74705SXin Li     // the alignment of the zero-length bitfield is greater than the member
4905*67e74705SXin Li     // that follows it, `bar', `bar' will be aligned as the  type of the
4906*67e74705SXin Li     // zero length bitfield.
4907*67e74705SXin Li     UseZeroLengthBitfieldAlignment = true;
4908*67e74705SXin Li 
4909*67e74705SXin Li     if (Triple.getOS() == llvm::Triple::Linux ||
4910*67e74705SXin Li         Triple.getOS() == llvm::Triple::UnknownOS)
4911*67e74705SXin Li       this->MCountName =
4912*67e74705SXin Li           Opts.EABIVersion == "gnu" ? "\01__gnu_mcount_nc" : "\01mcount";
4913*67e74705SXin Li   }
4914*67e74705SXin Li 
getABI() const4915*67e74705SXin Li   StringRef getABI() const override { return ABI; }
4916*67e74705SXin Li 
setABI(const std::string & Name)4917*67e74705SXin Li   bool setABI(const std::string &Name) override {
4918*67e74705SXin Li     ABI = Name;
4919*67e74705SXin Li 
4920*67e74705SXin Li     // The defaults (above) are for AAPCS, check if we need to change them.
4921*67e74705SXin Li     //
4922*67e74705SXin Li     // FIXME: We need support for -meabi... we could just mangle it into the
4923*67e74705SXin Li     // name.
4924*67e74705SXin Li     if (Name == "apcs-gnu" || Name == "aapcs16") {
4925*67e74705SXin Li       setABIAPCS(Name == "aapcs16");
4926*67e74705SXin Li       return true;
4927*67e74705SXin Li     }
4928*67e74705SXin Li     if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
4929*67e74705SXin Li       setABIAAPCS();
4930*67e74705SXin Li       return true;
4931*67e74705SXin Li     }
4932*67e74705SXin Li     return false;
4933*67e74705SXin Li   }
4934*67e74705SXin Li 
4935*67e74705SXin Li   // FIXME: This should be based on Arch attributes, not CPU names.
4936*67e74705SXin Li   bool
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const4937*67e74705SXin Li   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
4938*67e74705SXin Li                  StringRef CPU,
4939*67e74705SXin Li                  const std::vector<std::string> &FeaturesVec) const override {
4940*67e74705SXin Li 
4941*67e74705SXin Li     std::vector<const char*> TargetFeatures;
4942*67e74705SXin Li     unsigned Arch = llvm::ARM::parseArch(getTriple().getArchName());
4943*67e74705SXin Li 
4944*67e74705SXin Li     // get default FPU features
4945*67e74705SXin Li     unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
4946*67e74705SXin Li     llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
4947*67e74705SXin Li 
4948*67e74705SXin Li     // get default Extension features
4949*67e74705SXin Li     unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
4950*67e74705SXin Li     llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
4951*67e74705SXin Li 
4952*67e74705SXin Li     for (const char *Feature : TargetFeatures)
4953*67e74705SXin Li       if (Feature[0] == '+')
4954*67e74705SXin Li         Features[Feature+1] = true;
4955*67e74705SXin Li 
4956*67e74705SXin Li     return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
4957*67e74705SXin Li   }
4958*67e74705SXin Li 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)4959*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
4960*67e74705SXin Li                             DiagnosticsEngine &Diags) override {
4961*67e74705SXin Li     FPU = 0;
4962*67e74705SXin Li     CRC = 0;
4963*67e74705SXin Li     Crypto = 0;
4964*67e74705SXin Li     DSP = 0;
4965*67e74705SXin Li     Unaligned = 1;
4966*67e74705SXin Li     SoftFloat = SoftFloatABI = false;
4967*67e74705SXin Li     HWDiv = 0;
4968*67e74705SXin Li 
4969*67e74705SXin Li     // This does not diagnose illegal cases like having both
4970*67e74705SXin Li     // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
4971*67e74705SXin Li     uint32_t HW_FP_remove = 0;
4972*67e74705SXin Li     for (const auto &Feature : Features) {
4973*67e74705SXin Li       if (Feature == "+soft-float") {
4974*67e74705SXin Li         SoftFloat = true;
4975*67e74705SXin Li       } else if (Feature == "+soft-float-abi") {
4976*67e74705SXin Li         SoftFloatABI = true;
4977*67e74705SXin Li       } else if (Feature == "+vfp2") {
4978*67e74705SXin Li         FPU |= VFP2FPU;
4979*67e74705SXin Li         HW_FP |= HW_FP_SP | HW_FP_DP;
4980*67e74705SXin Li       } else if (Feature == "+vfp3") {
4981*67e74705SXin Li         FPU |= VFP3FPU;
4982*67e74705SXin Li         HW_FP |= HW_FP_SP | HW_FP_DP;
4983*67e74705SXin Li       } else if (Feature == "+vfp4") {
4984*67e74705SXin Li         FPU |= VFP4FPU;
4985*67e74705SXin Li         HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
4986*67e74705SXin Li       } else if (Feature == "+fp-armv8") {
4987*67e74705SXin Li         FPU |= FPARMV8;
4988*67e74705SXin Li         HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
4989*67e74705SXin Li       } else if (Feature == "+neon") {
4990*67e74705SXin Li         FPU |= NeonFPU;
4991*67e74705SXin Li         HW_FP |= HW_FP_SP | HW_FP_DP;
4992*67e74705SXin Li       } else if (Feature == "+hwdiv") {
4993*67e74705SXin Li         HWDiv |= HWDivThumb;
4994*67e74705SXin Li       } else if (Feature == "+hwdiv-arm") {
4995*67e74705SXin Li         HWDiv |= HWDivARM;
4996*67e74705SXin Li       } else if (Feature == "+crc") {
4997*67e74705SXin Li         CRC = 1;
4998*67e74705SXin Li       } else if (Feature == "+crypto") {
4999*67e74705SXin Li         Crypto = 1;
5000*67e74705SXin Li       } else if (Feature == "+dsp") {
5001*67e74705SXin Li         DSP = 1;
5002*67e74705SXin Li       } else if (Feature == "+fp-only-sp") {
5003*67e74705SXin Li         HW_FP_remove |= HW_FP_DP;
5004*67e74705SXin Li       } else if (Feature == "+strict-align") {
5005*67e74705SXin Li         Unaligned = 0;
5006*67e74705SXin Li       } else if (Feature == "+fp16") {
5007*67e74705SXin Li         HW_FP |= HW_FP_HP;
5008*67e74705SXin Li       }
5009*67e74705SXin Li     }
5010*67e74705SXin Li     HW_FP &= ~HW_FP_remove;
5011*67e74705SXin Li 
5012*67e74705SXin Li     switch (ArchVersion) {
5013*67e74705SXin Li     case 6:
5014*67e74705SXin Li       if (ArchProfile == llvm::ARM::PK_M)
5015*67e74705SXin Li         LDREX = 0;
5016*67e74705SXin Li       else if (ArchKind == llvm::ARM::AK_ARMV6K)
5017*67e74705SXin Li         LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B ;
5018*67e74705SXin Li       else
5019*67e74705SXin Li         LDREX = LDREX_W;
5020*67e74705SXin Li       break;
5021*67e74705SXin Li     case 7:
5022*67e74705SXin Li       if (ArchProfile == llvm::ARM::PK_M)
5023*67e74705SXin Li         LDREX = LDREX_W | LDREX_H | LDREX_B ;
5024*67e74705SXin Li       else
5025*67e74705SXin Li         LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B ;
5026*67e74705SXin Li       break;
5027*67e74705SXin Li     case 8:
5028*67e74705SXin Li       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B ;
5029*67e74705SXin Li     }
5030*67e74705SXin Li 
5031*67e74705SXin Li     if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
5032*67e74705SXin Li       Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
5033*67e74705SXin Li       return false;
5034*67e74705SXin Li     }
5035*67e74705SXin Li 
5036*67e74705SXin Li     if (FPMath == FP_Neon)
5037*67e74705SXin Li       Features.push_back("+neonfp");
5038*67e74705SXin Li     else if (FPMath == FP_VFP)
5039*67e74705SXin Li       Features.push_back("-neonfp");
5040*67e74705SXin Li 
5041*67e74705SXin Li     // Remove front-end specific options which the backend handles differently.
5042*67e74705SXin Li     auto Feature =
5043*67e74705SXin Li         std::find(Features.begin(), Features.end(), "+soft-float-abi");
5044*67e74705SXin Li     if (Feature != Features.end())
5045*67e74705SXin Li       Features.erase(Feature);
5046*67e74705SXin Li 
5047*67e74705SXin Li     return true;
5048*67e74705SXin Li   }
5049*67e74705SXin Li 
hasFeature(StringRef Feature) const5050*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
5051*67e74705SXin Li     return llvm::StringSwitch<bool>(Feature)
5052*67e74705SXin Li         .Case("arm", true)
5053*67e74705SXin Li         .Case("aarch32", true)
5054*67e74705SXin Li         .Case("softfloat", SoftFloat)
5055*67e74705SXin Li         .Case("thumb", isThumb())
5056*67e74705SXin Li         .Case("neon", (FPU & NeonFPU) && !SoftFloat)
5057*67e74705SXin Li         .Case("hwdiv", HWDiv & HWDivThumb)
5058*67e74705SXin Li         .Case("hwdiv-arm", HWDiv & HWDivARM)
5059*67e74705SXin Li         .Default(false);
5060*67e74705SXin Li   }
5061*67e74705SXin Li 
setCPU(const std::string & Name)5062*67e74705SXin Li   bool setCPU(const std::string &Name) override {
5063*67e74705SXin Li     if (Name != "generic")
5064*67e74705SXin Li       setArchInfo(llvm::ARM::parseCPUArch(Name));
5065*67e74705SXin Li 
5066*67e74705SXin Li     if (ArchKind == llvm::ARM::AK_INVALID)
5067*67e74705SXin Li       return false;
5068*67e74705SXin Li     setAtomic();
5069*67e74705SXin Li     CPU = Name;
5070*67e74705SXin Li     return true;
5071*67e74705SXin Li   }
5072*67e74705SXin Li 
5073*67e74705SXin Li   bool setFPMath(StringRef Name) override;
5074*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5075*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
5076*67e74705SXin Li                         MacroBuilder &Builder) const override {
5077*67e74705SXin Li     // Target identification.
5078*67e74705SXin Li     Builder.defineMacro("__arm");
5079*67e74705SXin Li     Builder.defineMacro("__arm__");
5080*67e74705SXin Li     // For bare-metal none-eabi.
5081*67e74705SXin Li     if (getTriple().getOS() == llvm::Triple::UnknownOS &&
5082*67e74705SXin Li         getTriple().getEnvironment() == llvm::Triple::EABI)
5083*67e74705SXin Li       Builder.defineMacro("__ELF__");
5084*67e74705SXin Li 
5085*67e74705SXin Li     // Target properties.
5086*67e74705SXin Li     Builder.defineMacro("__REGISTER_PREFIX__", "");
5087*67e74705SXin Li 
5088*67e74705SXin Li     // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
5089*67e74705SXin Li     // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
5090*67e74705SXin Li     if (getTriple().isWatchABI())
5091*67e74705SXin Li       Builder.defineMacro("__ARM_ARCH_7K__", "2");
5092*67e74705SXin Li 
5093*67e74705SXin Li     if (!CPUAttr.empty())
5094*67e74705SXin Li       Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
5095*67e74705SXin Li 
5096*67e74705SXin Li     // ACLE 6.4.1 ARM/Thumb instruction set architecture
5097*67e74705SXin Li     // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
5098*67e74705SXin Li     Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
5099*67e74705SXin Li 
5100*67e74705SXin Li     if (ArchVersion >= 8) {
5101*67e74705SXin Li       // ACLE 6.5.7 Crypto Extension
5102*67e74705SXin Li       if (Crypto)
5103*67e74705SXin Li         Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
5104*67e74705SXin Li       // ACLE 6.5.8 CRC32 Extension
5105*67e74705SXin Li       if (CRC)
5106*67e74705SXin Li         Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
5107*67e74705SXin Li       // ACLE 6.5.10 Numeric Maximum and Minimum
5108*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
5109*67e74705SXin Li       // ACLE 6.5.9 Directed Rounding
5110*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
5111*67e74705SXin Li     }
5112*67e74705SXin Li 
5113*67e74705SXin Li     // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
5114*67e74705SXin Li     // is not defined for the M-profile.
5115*67e74705SXin Li     // NOTE that the default profile is assumed to be 'A'
5116*67e74705SXin Li     if (CPUProfile.empty() || ArchProfile != llvm::ARM::PK_M)
5117*67e74705SXin Li       Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
5118*67e74705SXin Li 
5119*67e74705SXin Li     // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
5120*67e74705SXin Li     // Thumb ISA (including v6-M and v8-M Baseline).  It is set to 2 if the
5121*67e74705SXin Li     // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
5122*67e74705SXin Li     // v7 and v8 architectures excluding v8-M Baseline.
5123*67e74705SXin Li     if (supportsThumb2())
5124*67e74705SXin Li       Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
5125*67e74705SXin Li     else if (supportsThumb())
5126*67e74705SXin Li       Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
5127*67e74705SXin Li 
5128*67e74705SXin Li     // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
5129*67e74705SXin Li     // instruction set such as ARM or Thumb.
5130*67e74705SXin Li     Builder.defineMacro("__ARM_32BIT_STATE", "1");
5131*67e74705SXin Li 
5132*67e74705SXin Li     // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
5133*67e74705SXin Li 
5134*67e74705SXin Li     // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
5135*67e74705SXin Li     if (!CPUProfile.empty())
5136*67e74705SXin Li       Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
5137*67e74705SXin Li 
5138*67e74705SXin Li     // ACLE 6.4.3 Unaligned access supported in hardware
5139*67e74705SXin Li     if (Unaligned)
5140*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
5141*67e74705SXin Li 
5142*67e74705SXin Li     // ACLE 6.4.4 LDREX/STREX
5143*67e74705SXin Li     if (LDREX)
5144*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + llvm::utohexstr(LDREX));
5145*67e74705SXin Li 
5146*67e74705SXin Li     // ACLE 6.4.5 CLZ
5147*67e74705SXin Li     if (ArchVersion == 5 ||
5148*67e74705SXin Li        (ArchVersion == 6 && CPUProfile != "M") ||
5149*67e74705SXin Li         ArchVersion >  6)
5150*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
5151*67e74705SXin Li 
5152*67e74705SXin Li     // ACLE 6.5.1 Hardware Floating Point
5153*67e74705SXin Li     if (HW_FP)
5154*67e74705SXin Li       Builder.defineMacro("__ARM_FP", "0x" + llvm::utohexstr(HW_FP));
5155*67e74705SXin Li 
5156*67e74705SXin Li     // ACLE predefines.
5157*67e74705SXin Li     Builder.defineMacro("__ARM_ACLE", "200");
5158*67e74705SXin Li 
5159*67e74705SXin Li     // FP16 support (we currently only support IEEE format).
5160*67e74705SXin Li     Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
5161*67e74705SXin Li     Builder.defineMacro("__ARM_FP16_ARGS", "1");
5162*67e74705SXin Li 
5163*67e74705SXin Li     // ACLE 6.5.3 Fused multiply-accumulate (FMA)
5164*67e74705SXin Li     if (ArchVersion >= 7 && (FPU & VFP4FPU))
5165*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_FMA", "1");
5166*67e74705SXin Li 
5167*67e74705SXin Li     // Subtarget options.
5168*67e74705SXin Li 
5169*67e74705SXin Li     // FIXME: It's more complicated than this and we don't really support
5170*67e74705SXin Li     // interworking.
5171*67e74705SXin Li     // Windows on ARM does not "support" interworking
5172*67e74705SXin Li     if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
5173*67e74705SXin Li       Builder.defineMacro("__THUMB_INTERWORK__");
5174*67e74705SXin Li 
5175*67e74705SXin Li     if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
5176*67e74705SXin Li       // Embedded targets on Darwin follow AAPCS, but not EABI.
5177*67e74705SXin Li       // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
5178*67e74705SXin Li       if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
5179*67e74705SXin Li         Builder.defineMacro("__ARM_EABI__");
5180*67e74705SXin Li       Builder.defineMacro("__ARM_PCS", "1");
5181*67e74705SXin Li     }
5182*67e74705SXin Li 
5183*67e74705SXin Li     if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" ||
5184*67e74705SXin Li         ABI == "aapcs16")
5185*67e74705SXin Li       Builder.defineMacro("__ARM_PCS_VFP", "1");
5186*67e74705SXin Li 
5187*67e74705SXin Li     if (SoftFloat)
5188*67e74705SXin Li       Builder.defineMacro("__SOFTFP__");
5189*67e74705SXin Li 
5190*67e74705SXin Li     if (CPU == "xscale")
5191*67e74705SXin Li       Builder.defineMacro("__XSCALE__");
5192*67e74705SXin Li 
5193*67e74705SXin Li     if (isThumb()) {
5194*67e74705SXin Li       Builder.defineMacro("__THUMBEL__");
5195*67e74705SXin Li       Builder.defineMacro("__thumb__");
5196*67e74705SXin Li       if (supportsThumb2())
5197*67e74705SXin Li         Builder.defineMacro("__thumb2__");
5198*67e74705SXin Li     }
5199*67e74705SXin Li 
5200*67e74705SXin Li     // ACLE 6.4.9 32-bit SIMD instructions
5201*67e74705SXin Li     if (ArchVersion >= 6 && (CPUProfile != "M" || CPUAttr == "7EM"))
5202*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
5203*67e74705SXin Li 
5204*67e74705SXin Li     // ACLE 6.4.10 Hardware Integer Divide
5205*67e74705SXin Li     if (((HWDiv & HWDivThumb) && isThumb()) ||
5206*67e74705SXin Li         ((HWDiv & HWDivARM) && !isThumb())) {
5207*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
5208*67e74705SXin Li       Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
5209*67e74705SXin Li     }
5210*67e74705SXin Li 
5211*67e74705SXin Li     // Note, this is always on in gcc, even though it doesn't make sense.
5212*67e74705SXin Li     Builder.defineMacro("__APCS_32__");
5213*67e74705SXin Li 
5214*67e74705SXin Li     if (FPUModeIsVFP((FPUMode) FPU)) {
5215*67e74705SXin Li       Builder.defineMacro("__VFP_FP__");
5216*67e74705SXin Li       if (FPU & VFP2FPU)
5217*67e74705SXin Li         Builder.defineMacro("__ARM_VFPV2__");
5218*67e74705SXin Li       if (FPU & VFP3FPU)
5219*67e74705SXin Li         Builder.defineMacro("__ARM_VFPV3__");
5220*67e74705SXin Li       if (FPU & VFP4FPU)
5221*67e74705SXin Li         Builder.defineMacro("__ARM_VFPV4__");
5222*67e74705SXin Li     }
5223*67e74705SXin Li 
5224*67e74705SXin Li     // This only gets set when Neon instructions are actually available, unlike
5225*67e74705SXin Li     // the VFP define, hence the soft float and arch check. This is subtly
5226*67e74705SXin Li     // different from gcc, we follow the intent which was that it should be set
5227*67e74705SXin Li     // when Neon instructions are actually available.
5228*67e74705SXin Li     if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
5229*67e74705SXin Li       Builder.defineMacro("__ARM_NEON", "1");
5230*67e74705SXin Li       Builder.defineMacro("__ARM_NEON__");
5231*67e74705SXin Li       // current AArch32 NEON implementations do not support double-precision
5232*67e74705SXin Li       // floating-point even when it is present in VFP.
5233*67e74705SXin Li       Builder.defineMacro("__ARM_NEON_FP",
5234*67e74705SXin Li                           "0x" + llvm::utohexstr(HW_FP & ~HW_FP_DP));
5235*67e74705SXin Li     }
5236*67e74705SXin Li 
5237*67e74705SXin Li     Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
5238*67e74705SXin Li                         Opts.ShortWChar ? "2" : "4");
5239*67e74705SXin Li 
5240*67e74705SXin Li     Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
5241*67e74705SXin Li                         Opts.ShortEnums ? "1" : "4");
5242*67e74705SXin Li 
5243*67e74705SXin Li     if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
5244*67e74705SXin Li       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
5245*67e74705SXin Li       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
5246*67e74705SXin Li       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
5247*67e74705SXin Li       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
5248*67e74705SXin Li     }
5249*67e74705SXin Li 
5250*67e74705SXin Li     // ACLE 6.4.7 DSP instructions
5251*67e74705SXin Li     if (DSP) {
5252*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_DSP", "1");
5253*67e74705SXin Li     }
5254*67e74705SXin Li 
5255*67e74705SXin Li     // ACLE 6.4.8 Saturation instructions
5256*67e74705SXin Li     bool SAT = false;
5257*67e74705SXin Li     if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6 ) {
5258*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_SAT", "1");
5259*67e74705SXin Li       SAT = true;
5260*67e74705SXin Li     }
5261*67e74705SXin Li 
5262*67e74705SXin Li     // ACLE 6.4.6 Q (saturation) flag
5263*67e74705SXin Li     if (DSP || SAT)
5264*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
5265*67e74705SXin Li 
5266*67e74705SXin Li     if (Opts.UnsafeFPMath)
5267*67e74705SXin Li       Builder.defineMacro("__ARM_FP_FAST", "1");
5268*67e74705SXin Li 
5269*67e74705SXin Li     if (ArchKind == llvm::ARM::AK_ARMV8_1A)
5270*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
5271*67e74705SXin Li   }
5272*67e74705SXin Li 
getTargetBuiltins() const5273*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
5274*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
5275*67e74705SXin Li                              clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin);
5276*67e74705SXin Li   }
isCLZForZeroUndef() const5277*67e74705SXin Li   bool isCLZForZeroUndef() const override { return false; }
getBuiltinVaListKind() const5278*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
5279*67e74705SXin Li     return IsAAPCS
5280*67e74705SXin Li                ? AAPCSABIBuiltinVaList
5281*67e74705SXin Li                : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
5282*67e74705SXin Li                                            : TargetInfo::VoidPtrBuiltinVaList);
5283*67e74705SXin Li   }
5284*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
5285*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const5286*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
5287*67e74705SXin Li                              TargetInfo::ConstraintInfo &Info) const override {
5288*67e74705SXin Li     switch (*Name) {
5289*67e74705SXin Li     default: break;
5290*67e74705SXin Li     case 'l': // r0-r7
5291*67e74705SXin Li     case 'h': // r8-r15
5292*67e74705SXin Li     case 't': // VFP Floating point register single precision
5293*67e74705SXin Li     case 'w': // VFP Floating point register double precision
5294*67e74705SXin Li       Info.setAllowsRegister();
5295*67e74705SXin Li       return true;
5296*67e74705SXin Li     case 'I':
5297*67e74705SXin Li     case 'J':
5298*67e74705SXin Li     case 'K':
5299*67e74705SXin Li     case 'L':
5300*67e74705SXin Li     case 'M':
5301*67e74705SXin Li       // FIXME
5302*67e74705SXin Li       return true;
5303*67e74705SXin Li     case 'Q': // A memory address that is a single base register.
5304*67e74705SXin Li       Info.setAllowsMemory();
5305*67e74705SXin Li       return true;
5306*67e74705SXin Li     case 'U': // a memory reference...
5307*67e74705SXin Li       switch (Name[1]) {
5308*67e74705SXin Li       case 'q': // ...ARMV4 ldrsb
5309*67e74705SXin Li       case 'v': // ...VFP load/store (reg+constant offset)
5310*67e74705SXin Li       case 'y': // ...iWMMXt load/store
5311*67e74705SXin Li       case 't': // address valid for load/store opaque types wider
5312*67e74705SXin Li                 // than 128-bits
5313*67e74705SXin Li       case 'n': // valid address for Neon doubleword vector load/store
5314*67e74705SXin Li       case 'm': // valid address for Neon element and structure load/store
5315*67e74705SXin Li       case 's': // valid address for non-offset loads/stores of quad-word
5316*67e74705SXin Li                 // values in four ARM registers
5317*67e74705SXin Li         Info.setAllowsMemory();
5318*67e74705SXin Li         Name++;
5319*67e74705SXin Li         return true;
5320*67e74705SXin Li       }
5321*67e74705SXin Li     }
5322*67e74705SXin Li     return false;
5323*67e74705SXin Li   }
convertConstraint(const char * & Constraint) const5324*67e74705SXin Li   std::string convertConstraint(const char *&Constraint) const override {
5325*67e74705SXin Li     std::string R;
5326*67e74705SXin Li     switch (*Constraint) {
5327*67e74705SXin Li     case 'U':   // Two-character constraint; add "^" hint for later parsing.
5328*67e74705SXin Li       R = std::string("^") + std::string(Constraint, 2);
5329*67e74705SXin Li       Constraint++;
5330*67e74705SXin Li       break;
5331*67e74705SXin Li     case 'p': // 'p' should be translated to 'r' by default.
5332*67e74705SXin Li       R = std::string("r");
5333*67e74705SXin Li       break;
5334*67e74705SXin Li     default:
5335*67e74705SXin Li       return std::string(1, *Constraint);
5336*67e74705SXin Li     }
5337*67e74705SXin Li     return R;
5338*67e74705SXin Li   }
5339*67e74705SXin Li   bool
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const5340*67e74705SXin Li   validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
5341*67e74705SXin Li                              std::string &SuggestedModifier) const override {
5342*67e74705SXin Li     bool isOutput = (Constraint[0] == '=');
5343*67e74705SXin Li     bool isInOut = (Constraint[0] == '+');
5344*67e74705SXin Li 
5345*67e74705SXin Li     // Strip off constraint modifiers.
5346*67e74705SXin Li     while (Constraint[0] == '=' ||
5347*67e74705SXin Li            Constraint[0] == '+' ||
5348*67e74705SXin Li            Constraint[0] == '&')
5349*67e74705SXin Li       Constraint = Constraint.substr(1);
5350*67e74705SXin Li 
5351*67e74705SXin Li     switch (Constraint[0]) {
5352*67e74705SXin Li     default: break;
5353*67e74705SXin Li     case 'r': {
5354*67e74705SXin Li       switch (Modifier) {
5355*67e74705SXin Li       default:
5356*67e74705SXin Li         return (isInOut || isOutput || Size <= 64);
5357*67e74705SXin Li       case 'q':
5358*67e74705SXin Li         // A register of size 32 cannot fit a vector type.
5359*67e74705SXin Li         return false;
5360*67e74705SXin Li       }
5361*67e74705SXin Li     }
5362*67e74705SXin Li     }
5363*67e74705SXin Li 
5364*67e74705SXin Li     return true;
5365*67e74705SXin Li   }
getClobbers() const5366*67e74705SXin Li   const char *getClobbers() const override {
5367*67e74705SXin Li     // FIXME: Is this really right?
5368*67e74705SXin Li     return "";
5369*67e74705SXin Li   }
5370*67e74705SXin Li 
checkCallingConvention(CallingConv CC) const5371*67e74705SXin Li   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
5372*67e74705SXin Li     switch (CC) {
5373*67e74705SXin Li     case CC_AAPCS:
5374*67e74705SXin Li     case CC_AAPCS_VFP:
5375*67e74705SXin Li     case CC_Swift:
5376*67e74705SXin Li       return CCCR_OK;
5377*67e74705SXin Li     default:
5378*67e74705SXin Li       return CCCR_Warning;
5379*67e74705SXin Li     }
5380*67e74705SXin Li   }
5381*67e74705SXin Li 
getEHDataRegisterNumber(unsigned RegNo) const5382*67e74705SXin Li   int getEHDataRegisterNumber(unsigned RegNo) const override {
5383*67e74705SXin Li     if (RegNo == 0) return 0;
5384*67e74705SXin Li     if (RegNo == 1) return 1;
5385*67e74705SXin Li     return -1;
5386*67e74705SXin Li   }
5387*67e74705SXin Li 
hasSjLjLowering() const5388*67e74705SXin Li   bool hasSjLjLowering() const override {
5389*67e74705SXin Li     return true;
5390*67e74705SXin Li   }
5391*67e74705SXin Li };
5392*67e74705SXin Li 
setFPMath(StringRef Name)5393*67e74705SXin Li bool ARMTargetInfo::setFPMath(StringRef Name) {
5394*67e74705SXin Li   if (Name == "neon") {
5395*67e74705SXin Li     FPMath = FP_Neon;
5396*67e74705SXin Li     return true;
5397*67e74705SXin Li   } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
5398*67e74705SXin Li              Name == "vfp4") {
5399*67e74705SXin Li     FPMath = FP_VFP;
5400*67e74705SXin Li     return true;
5401*67e74705SXin Li   }
5402*67e74705SXin Li   return false;
5403*67e74705SXin Li }
5404*67e74705SXin Li 
5405*67e74705SXin Li const char * const ARMTargetInfo::GCCRegNames[] = {
5406*67e74705SXin Li   // Integer registers
5407*67e74705SXin Li   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
5408*67e74705SXin Li   "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
5409*67e74705SXin Li 
5410*67e74705SXin Li   // Float registers
5411*67e74705SXin Li   "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
5412*67e74705SXin Li   "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
5413*67e74705SXin Li   "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
5414*67e74705SXin Li   "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
5415*67e74705SXin Li 
5416*67e74705SXin Li   // Double registers
5417*67e74705SXin Li   "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
5418*67e74705SXin Li   "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
5419*67e74705SXin Li   "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
5420*67e74705SXin Li   "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
5421*67e74705SXin Li 
5422*67e74705SXin Li   // Quad registers
5423*67e74705SXin Li   "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
5424*67e74705SXin Li   "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
5425*67e74705SXin Li };
5426*67e74705SXin Li 
getGCCRegNames() const5427*67e74705SXin Li ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
5428*67e74705SXin Li   return llvm::makeArrayRef(GCCRegNames);
5429*67e74705SXin Li }
5430*67e74705SXin Li 
5431*67e74705SXin Li const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
5432*67e74705SXin Li   { { "a1" }, "r0" },
5433*67e74705SXin Li   { { "a2" }, "r1" },
5434*67e74705SXin Li   { { "a3" }, "r2" },
5435*67e74705SXin Li   { { "a4" }, "r3" },
5436*67e74705SXin Li   { { "v1" }, "r4" },
5437*67e74705SXin Li   { { "v2" }, "r5" },
5438*67e74705SXin Li   { { "v3" }, "r6" },
5439*67e74705SXin Li   { { "v4" }, "r7" },
5440*67e74705SXin Li   { { "v5" }, "r8" },
5441*67e74705SXin Li   { { "v6", "rfp" }, "r9" },
5442*67e74705SXin Li   { { "sl" }, "r10" },
5443*67e74705SXin Li   { { "fp" }, "r11" },
5444*67e74705SXin Li   { { "ip" }, "r12" },
5445*67e74705SXin Li   { { "r13" }, "sp" },
5446*67e74705SXin Li   { { "r14" }, "lr" },
5447*67e74705SXin Li   { { "r15" }, "pc" },
5448*67e74705SXin Li   // The S, D and Q registers overlap, but aren't really aliases; we
5449*67e74705SXin Li   // don't want to substitute one of these for a different-sized one.
5450*67e74705SXin Li };
5451*67e74705SXin Li 
getGCCRegAliases() const5452*67e74705SXin Li ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
5453*67e74705SXin Li   return llvm::makeArrayRef(GCCRegAliases);
5454*67e74705SXin Li }
5455*67e74705SXin Li 
5456*67e74705SXin Li const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
5457*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS) \
5458*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
5459*67e74705SXin Li #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
5460*67e74705SXin Li   { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
5461*67e74705SXin Li #include "clang/Basic/BuiltinsNEON.def"
5462*67e74705SXin Li 
5463*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS) \
5464*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
5465*67e74705SXin Li #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
5466*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, LANG, nullptr },
5467*67e74705SXin Li #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
5468*67e74705SXin Li   { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
5469*67e74705SXin Li #include "clang/Basic/BuiltinsARM.def"
5470*67e74705SXin Li };
5471*67e74705SXin Li 
5472*67e74705SXin Li class ARMleTargetInfo : public ARMTargetInfo {
5473*67e74705SXin Li public:
ARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5474*67e74705SXin Li   ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5475*67e74705SXin Li       : ARMTargetInfo(Triple, Opts, /*BigEndian=*/false) {}
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5476*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
5477*67e74705SXin Li                         MacroBuilder &Builder) const override {
5478*67e74705SXin Li     Builder.defineMacro("__ARMEL__");
5479*67e74705SXin Li     ARMTargetInfo::getTargetDefines(Opts, Builder);
5480*67e74705SXin Li   }
5481*67e74705SXin Li };
5482*67e74705SXin Li 
5483*67e74705SXin Li class ARMbeTargetInfo : public ARMTargetInfo {
5484*67e74705SXin Li public:
ARMbeTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5485*67e74705SXin Li   ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5486*67e74705SXin Li       : ARMTargetInfo(Triple, Opts, /*BigEndian=*/true) {}
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5487*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
5488*67e74705SXin Li                         MacroBuilder &Builder) const override {
5489*67e74705SXin Li     Builder.defineMacro("__ARMEB__");
5490*67e74705SXin Li     Builder.defineMacro("__ARM_BIG_ENDIAN");
5491*67e74705SXin Li     ARMTargetInfo::getTargetDefines(Opts, Builder);
5492*67e74705SXin Li   }
5493*67e74705SXin Li };
5494*67e74705SXin Li 
5495*67e74705SXin Li class WindowsARMTargetInfo : public WindowsTargetInfo<ARMleTargetInfo> {
5496*67e74705SXin Li   const llvm::Triple Triple;
5497*67e74705SXin Li public:
WindowsARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5498*67e74705SXin Li   WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5499*67e74705SXin Li       : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
5500*67e74705SXin Li     WCharType = UnsignedShort;
5501*67e74705SXin Li     SizeType = UnsignedInt;
5502*67e74705SXin Li   }
getVisualStudioDefines(const LangOptions & Opts,MacroBuilder & Builder) const5503*67e74705SXin Li   void getVisualStudioDefines(const LangOptions &Opts,
5504*67e74705SXin Li                               MacroBuilder &Builder) const {
5505*67e74705SXin Li     WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
5506*67e74705SXin Li 
5507*67e74705SXin Li     // FIXME: this is invalid for WindowsCE
5508*67e74705SXin Li     Builder.defineMacro("_M_ARM_NT", "1");
5509*67e74705SXin Li     Builder.defineMacro("_M_ARMT", "_M_ARM");
5510*67e74705SXin Li     Builder.defineMacro("_M_THUMB", "_M_ARM");
5511*67e74705SXin Li 
5512*67e74705SXin Li     assert((Triple.getArch() == llvm::Triple::arm ||
5513*67e74705SXin Li             Triple.getArch() == llvm::Triple::thumb) &&
5514*67e74705SXin Li            "invalid architecture for Windows ARM target info");
5515*67e74705SXin Li     unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
5516*67e74705SXin Li     Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
5517*67e74705SXin Li 
5518*67e74705SXin Li     // TODO map the complete set of values
5519*67e74705SXin Li     // 31: VFPv3 40: VFPv4
5520*67e74705SXin Li     Builder.defineMacro("_M_ARM_FP", "31");
5521*67e74705SXin Li   }
getBuiltinVaListKind() const5522*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
5523*67e74705SXin Li     return TargetInfo::CharPtrBuiltinVaList;
5524*67e74705SXin Li   }
checkCallingConvention(CallingConv CC) const5525*67e74705SXin Li   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
5526*67e74705SXin Li     switch (CC) {
5527*67e74705SXin Li     case CC_X86StdCall:
5528*67e74705SXin Li     case CC_X86ThisCall:
5529*67e74705SXin Li     case CC_X86FastCall:
5530*67e74705SXin Li     case CC_X86VectorCall:
5531*67e74705SXin Li       return CCCR_Ignore;
5532*67e74705SXin Li     case CC_C:
5533*67e74705SXin Li       return CCCR_OK;
5534*67e74705SXin Li     default:
5535*67e74705SXin Li       return CCCR_Warning;
5536*67e74705SXin Li     }
5537*67e74705SXin Li   }
5538*67e74705SXin Li };
5539*67e74705SXin Li 
5540*67e74705SXin Li // Windows ARM + Itanium C++ ABI Target
5541*67e74705SXin Li class ItaniumWindowsARMleTargetInfo : public WindowsARMTargetInfo {
5542*67e74705SXin Li public:
ItaniumWindowsARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5543*67e74705SXin Li   ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple,
5544*67e74705SXin Li                                 const TargetOptions &Opts)
5545*67e74705SXin Li       : WindowsARMTargetInfo(Triple, Opts) {
5546*67e74705SXin Li     TheCXXABI.set(TargetCXXABI::GenericARM);
5547*67e74705SXin Li   }
5548*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5549*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
5550*67e74705SXin Li                         MacroBuilder &Builder) const override {
5551*67e74705SXin Li     WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
5552*67e74705SXin Li 
5553*67e74705SXin Li     if (Opts.MSVCCompat)
5554*67e74705SXin Li       WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
5555*67e74705SXin Li   }
5556*67e74705SXin Li };
5557*67e74705SXin Li 
5558*67e74705SXin Li // Windows ARM, MS (C++) ABI
5559*67e74705SXin Li class MicrosoftARMleTargetInfo : public WindowsARMTargetInfo {
5560*67e74705SXin Li public:
MicrosoftARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5561*67e74705SXin Li   MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
5562*67e74705SXin Li                            const TargetOptions &Opts)
5563*67e74705SXin Li       : WindowsARMTargetInfo(Triple, Opts) {
5564*67e74705SXin Li     TheCXXABI.set(TargetCXXABI::Microsoft);
5565*67e74705SXin Li   }
5566*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5567*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
5568*67e74705SXin Li                         MacroBuilder &Builder) const override {
5569*67e74705SXin Li     WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
5570*67e74705SXin Li     WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
5571*67e74705SXin Li   }
5572*67e74705SXin Li };
5573*67e74705SXin Li 
5574*67e74705SXin Li // ARM MinGW target
5575*67e74705SXin Li class MinGWARMTargetInfo : public WindowsARMTargetInfo {
5576*67e74705SXin Li public:
MinGWARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5577*67e74705SXin Li   MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5578*67e74705SXin Li       : WindowsARMTargetInfo(Triple, Opts) {
5579*67e74705SXin Li     TheCXXABI.set(TargetCXXABI::GenericARM);
5580*67e74705SXin Li   }
5581*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5582*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
5583*67e74705SXin Li                         MacroBuilder &Builder) const override {
5584*67e74705SXin Li     WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
5585*67e74705SXin Li     DefineStd(Builder, "WIN32", Opts);
5586*67e74705SXin Li     DefineStd(Builder, "WINNT", Opts);
5587*67e74705SXin Li     Builder.defineMacro("_ARM_");
5588*67e74705SXin Li     addMinGWDefines(Opts, Builder);
5589*67e74705SXin Li   }
5590*67e74705SXin Li };
5591*67e74705SXin Li 
5592*67e74705SXin Li // ARM Cygwin target
5593*67e74705SXin Li class CygwinARMTargetInfo : public ARMleTargetInfo {
5594*67e74705SXin Li public:
CygwinARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5595*67e74705SXin Li   CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5596*67e74705SXin Li       : ARMleTargetInfo(Triple, Opts) {
5597*67e74705SXin Li     TLSSupported = false;
5598*67e74705SXin Li     WCharType = UnsignedShort;
5599*67e74705SXin Li     DoubleAlign = LongLongAlign = 64;
5600*67e74705SXin Li     resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
5601*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5602*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
5603*67e74705SXin Li                         MacroBuilder &Builder) const override {
5604*67e74705SXin Li     ARMleTargetInfo::getTargetDefines(Opts, Builder);
5605*67e74705SXin Li     Builder.defineMacro("_ARM_");
5606*67e74705SXin Li     Builder.defineMacro("__CYGWIN__");
5607*67e74705SXin Li     Builder.defineMacro("__CYGWIN32__");
5608*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
5609*67e74705SXin Li     if (Opts.CPlusPlus)
5610*67e74705SXin Li       Builder.defineMacro("_GNU_SOURCE");
5611*67e74705SXin Li   }
5612*67e74705SXin Li };
5613*67e74705SXin Li 
5614*67e74705SXin Li class DarwinARMTargetInfo : public DarwinTargetInfo<ARMleTargetInfo> {
5615*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const5616*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
5617*67e74705SXin Li                     MacroBuilder &Builder) const override {
5618*67e74705SXin Li     getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
5619*67e74705SXin Li   }
5620*67e74705SXin Li 
5621*67e74705SXin Li public:
DarwinARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5622*67e74705SXin Li   DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5623*67e74705SXin Li       : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
5624*67e74705SXin Li     HasAlignMac68kSupport = true;
5625*67e74705SXin Li     // iOS always has 64-bit atomic instructions.
5626*67e74705SXin Li     // FIXME: This should be based off of the target features in
5627*67e74705SXin Li     // ARMleTargetInfo.
5628*67e74705SXin Li     MaxAtomicInlineWidth = 64;
5629*67e74705SXin Li 
5630*67e74705SXin Li     if (Triple.isWatchABI()) {
5631*67e74705SXin Li       // Darwin on iOS uses a variant of the ARM C++ ABI.
5632*67e74705SXin Li       TheCXXABI.set(TargetCXXABI::WatchOS);
5633*67e74705SXin Li 
5634*67e74705SXin Li       // The 32-bit ABI is silent on what ptrdiff_t should be, but given that
5635*67e74705SXin Li       // size_t is long, it's a bit weird for it to be int.
5636*67e74705SXin Li       PtrDiffType = SignedLong;
5637*67e74705SXin Li 
5638*67e74705SXin Li       // BOOL should be a real boolean on the new ABI
5639*67e74705SXin Li       UseSignedCharForObjCBool = false;
5640*67e74705SXin Li     } else
5641*67e74705SXin Li       TheCXXABI.set(TargetCXXABI::iOS);
5642*67e74705SXin Li   }
5643*67e74705SXin Li };
5644*67e74705SXin Li 
5645*67e74705SXin Li class AArch64TargetInfo : public TargetInfo {
5646*67e74705SXin Li   virtual void setDataLayout() = 0;
5647*67e74705SXin Li   static const TargetInfo::GCCRegAlias GCCRegAliases[];
5648*67e74705SXin Li   static const char *const GCCRegNames[];
5649*67e74705SXin Li 
5650*67e74705SXin Li   enum FPUModeEnum {
5651*67e74705SXin Li     FPUMode,
5652*67e74705SXin Li     NeonMode
5653*67e74705SXin Li   };
5654*67e74705SXin Li 
5655*67e74705SXin Li   unsigned FPU;
5656*67e74705SXin Li   unsigned CRC;
5657*67e74705SXin Li   unsigned Crypto;
5658*67e74705SXin Li   unsigned Unaligned;
5659*67e74705SXin Li   unsigned V8_1A;
5660*67e74705SXin Li 
5661*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
5662*67e74705SXin Li 
5663*67e74705SXin Li   std::string ABI;
5664*67e74705SXin Li 
5665*67e74705SXin Li public:
AArch64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5666*67e74705SXin Li   AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
5667*67e74705SXin Li       : TargetInfo(Triple), ABI("aapcs") {
5668*67e74705SXin Li     if (getTriple().getOS() == llvm::Triple::NetBSD) {
5669*67e74705SXin Li       WCharType = SignedInt;
5670*67e74705SXin Li 
5671*67e74705SXin Li       // NetBSD apparently prefers consistency across ARM targets to consistency
5672*67e74705SXin Li       // across 64-bit targets.
5673*67e74705SXin Li       Int64Type = SignedLongLong;
5674*67e74705SXin Li       IntMaxType = SignedLongLong;
5675*67e74705SXin Li     } else {
5676*67e74705SXin Li       WCharType = UnsignedInt;
5677*67e74705SXin Li       Int64Type = SignedLong;
5678*67e74705SXin Li       IntMaxType = SignedLong;
5679*67e74705SXin Li     }
5680*67e74705SXin Li 
5681*67e74705SXin Li     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
5682*67e74705SXin Li     MaxVectorAlign = 128;
5683*67e74705SXin Li     MaxAtomicInlineWidth = 128;
5684*67e74705SXin Li     MaxAtomicPromoteWidth = 128;
5685*67e74705SXin Li 
5686*67e74705SXin Li     LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
5687*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEquad;
5688*67e74705SXin Li 
5689*67e74705SXin Li     // {} in inline assembly are neon specifiers, not assembly variant
5690*67e74705SXin Li     // specifiers.
5691*67e74705SXin Li     NoAsmVariants = true;
5692*67e74705SXin Li 
5693*67e74705SXin Li     // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
5694*67e74705SXin Li     // contributes to the alignment of the containing aggregate in the same way
5695*67e74705SXin Li     // a plain (non bit-field) member of that type would, without exception for
5696*67e74705SXin Li     // zero-sized or anonymous bit-fields."
5697*67e74705SXin Li     assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
5698*67e74705SXin Li     UseZeroLengthBitfieldAlignment = true;
5699*67e74705SXin Li 
5700*67e74705SXin Li     // AArch64 targets default to using the ARM C++ ABI.
5701*67e74705SXin Li     TheCXXABI.set(TargetCXXABI::GenericAArch64);
5702*67e74705SXin Li 
5703*67e74705SXin Li     if (Triple.getOS() == llvm::Triple::Linux ||
5704*67e74705SXin Li         Triple.getOS() == llvm::Triple::UnknownOS)
5705*67e74705SXin Li       this->MCountName = Opts.EABIVersion == "gnu" ? "\01_mcount" : "mcount";
5706*67e74705SXin Li   }
5707*67e74705SXin Li 
getABI() const5708*67e74705SXin Li   StringRef getABI() const override { return ABI; }
setABI(const std::string & Name)5709*67e74705SXin Li   bool setABI(const std::string &Name) override {
5710*67e74705SXin Li     if (Name != "aapcs" && Name != "darwinpcs")
5711*67e74705SXin Li       return false;
5712*67e74705SXin Li 
5713*67e74705SXin Li     ABI = Name;
5714*67e74705SXin Li     return true;
5715*67e74705SXin Li   }
5716*67e74705SXin Li 
setCPU(const std::string & Name)5717*67e74705SXin Li   bool setCPU(const std::string &Name) override {
5718*67e74705SXin Li     bool CPUKnown = llvm::StringSwitch<bool>(Name)
5719*67e74705SXin Li                         .Case("generic", true)
5720*67e74705SXin Li                         .Cases("cortex-a53", "cortex-a57", "cortex-a72",
5721*67e74705SXin Li                                "cortex-a35", "exynos-m1", true)
5722*67e74705SXin Li                         .Case("cortex-a73", true)
5723*67e74705SXin Li                         .Case("cyclone", true)
5724*67e74705SXin Li                         .Case("kryo", true)
5725*67e74705SXin Li                         .Case("vulcan", true)
5726*67e74705SXin Li                         .Default(false);
5727*67e74705SXin Li     return CPUKnown;
5728*67e74705SXin Li   }
5729*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const5730*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
5731*67e74705SXin Li                         MacroBuilder &Builder) const override {
5732*67e74705SXin Li     // Target identification.
5733*67e74705SXin Li     Builder.defineMacro("__aarch64__");
5734*67e74705SXin Li 
5735*67e74705SXin Li     // Target properties.
5736*67e74705SXin Li     Builder.defineMacro("_LP64");
5737*67e74705SXin Li     Builder.defineMacro("__LP64__");
5738*67e74705SXin Li 
5739*67e74705SXin Li     // ACLE predefines. Many can only have one possible value on v8 AArch64.
5740*67e74705SXin Li     Builder.defineMacro("__ARM_ACLE", "200");
5741*67e74705SXin Li     Builder.defineMacro("__ARM_ARCH", "8");
5742*67e74705SXin Li     Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
5743*67e74705SXin Li 
5744*67e74705SXin Li     Builder.defineMacro("__ARM_64BIT_STATE", "1");
5745*67e74705SXin Li     Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
5746*67e74705SXin Li     Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
5747*67e74705SXin Li 
5748*67e74705SXin Li     Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
5749*67e74705SXin Li     Builder.defineMacro("__ARM_FEATURE_FMA", "1");
5750*67e74705SXin Li     Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
5751*67e74705SXin Li     Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
5752*67e74705SXin Li     Builder.defineMacro("__ARM_FEATURE_DIV");  // For backwards compatibility
5753*67e74705SXin Li     Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
5754*67e74705SXin Li     Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
5755*67e74705SXin Li 
5756*67e74705SXin Li     Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
5757*67e74705SXin Li 
5758*67e74705SXin Li     // 0xe implies support for half, single and double precision operations.
5759*67e74705SXin Li     Builder.defineMacro("__ARM_FP", "0xE");
5760*67e74705SXin Li 
5761*67e74705SXin Li     // PCS specifies this for SysV variants, which is all we support. Other ABIs
5762*67e74705SXin Li     // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
5763*67e74705SXin Li     Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
5764*67e74705SXin Li     Builder.defineMacro("__ARM_FP16_ARGS", "1");
5765*67e74705SXin Li 
5766*67e74705SXin Li     if (Opts.UnsafeFPMath)
5767*67e74705SXin Li       Builder.defineMacro("__ARM_FP_FAST", "1");
5768*67e74705SXin Li 
5769*67e74705SXin Li     Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", Opts.ShortWChar ? "2" : "4");
5770*67e74705SXin Li 
5771*67e74705SXin Li     Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
5772*67e74705SXin Li                         Opts.ShortEnums ? "1" : "4");
5773*67e74705SXin Li 
5774*67e74705SXin Li     if (FPU == NeonMode) {
5775*67e74705SXin Li       Builder.defineMacro("__ARM_NEON", "1");
5776*67e74705SXin Li       // 64-bit NEON supports half, single and double precision operations.
5777*67e74705SXin Li       Builder.defineMacro("__ARM_NEON_FP", "0xE");
5778*67e74705SXin Li     }
5779*67e74705SXin Li 
5780*67e74705SXin Li     if (CRC)
5781*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
5782*67e74705SXin Li 
5783*67e74705SXin Li     if (Crypto)
5784*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
5785*67e74705SXin Li 
5786*67e74705SXin Li     if (Unaligned)
5787*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
5788*67e74705SXin Li 
5789*67e74705SXin Li     if (V8_1A)
5790*67e74705SXin Li       Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
5791*67e74705SXin Li 
5792*67e74705SXin Li     // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
5793*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
5794*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
5795*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
5796*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
5797*67e74705SXin Li   }
5798*67e74705SXin Li 
getTargetBuiltins() const5799*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
5800*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
5801*67e74705SXin Li                        clang::AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin);
5802*67e74705SXin Li   }
5803*67e74705SXin Li 
hasFeature(StringRef Feature) const5804*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
5805*67e74705SXin Li     return Feature == "aarch64" ||
5806*67e74705SXin Li       Feature == "arm64" ||
5807*67e74705SXin Li       Feature == "arm" ||
5808*67e74705SXin Li       (Feature == "neon" && FPU == NeonMode);
5809*67e74705SXin Li   }
5810*67e74705SXin Li 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)5811*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
5812*67e74705SXin Li                             DiagnosticsEngine &Diags) override {
5813*67e74705SXin Li     FPU = FPUMode;
5814*67e74705SXin Li     CRC = 0;
5815*67e74705SXin Li     Crypto = 0;
5816*67e74705SXin Li     Unaligned = 1;
5817*67e74705SXin Li     V8_1A = 0;
5818*67e74705SXin Li 
5819*67e74705SXin Li     for (const auto &Feature : Features) {
5820*67e74705SXin Li       if (Feature == "+neon")
5821*67e74705SXin Li         FPU = NeonMode;
5822*67e74705SXin Li       if (Feature == "+crc")
5823*67e74705SXin Li         CRC = 1;
5824*67e74705SXin Li       if (Feature == "+crypto")
5825*67e74705SXin Li         Crypto = 1;
5826*67e74705SXin Li       if (Feature == "+strict-align")
5827*67e74705SXin Li         Unaligned = 0;
5828*67e74705SXin Li       if (Feature == "+v8.1a")
5829*67e74705SXin Li         V8_1A = 1;
5830*67e74705SXin Li     }
5831*67e74705SXin Li 
5832*67e74705SXin Li     setDataLayout();
5833*67e74705SXin Li 
5834*67e74705SXin Li     return true;
5835*67e74705SXin Li   }
5836*67e74705SXin Li 
checkCallingConvention(CallingConv CC) const5837*67e74705SXin Li   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
5838*67e74705SXin Li     switch (CC) {
5839*67e74705SXin Li     case CC_C:
5840*67e74705SXin Li     case CC_Swift:
5841*67e74705SXin Li     case CC_PreserveMost:
5842*67e74705SXin Li     case CC_PreserveAll:
5843*67e74705SXin Li       return CCCR_OK;
5844*67e74705SXin Li     default:
5845*67e74705SXin Li       return CCCR_Warning;
5846*67e74705SXin Li     }
5847*67e74705SXin Li   }
5848*67e74705SXin Li 
isCLZForZeroUndef() const5849*67e74705SXin Li   bool isCLZForZeroUndef() const override { return false; }
5850*67e74705SXin Li 
getBuiltinVaListKind() const5851*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
5852*67e74705SXin Li     return TargetInfo::AArch64ABIBuiltinVaList;
5853*67e74705SXin Li   }
5854*67e74705SXin Li 
5855*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
5856*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
5857*67e74705SXin Li 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const5858*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
5859*67e74705SXin Li                              TargetInfo::ConstraintInfo &Info) const override {
5860*67e74705SXin Li     switch (*Name) {
5861*67e74705SXin Li     default:
5862*67e74705SXin Li       return false;
5863*67e74705SXin Li     case 'w': // Floating point and SIMD registers (V0-V31)
5864*67e74705SXin Li       Info.setAllowsRegister();
5865*67e74705SXin Li       return true;
5866*67e74705SXin Li     case 'I': // Constant that can be used with an ADD instruction
5867*67e74705SXin Li     case 'J': // Constant that can be used with a SUB instruction
5868*67e74705SXin Li     case 'K': // Constant that can be used with a 32-bit logical instruction
5869*67e74705SXin Li     case 'L': // Constant that can be used with a 64-bit logical instruction
5870*67e74705SXin Li     case 'M': // Constant that can be used as a 32-bit MOV immediate
5871*67e74705SXin Li     case 'N': // Constant that can be used as a 64-bit MOV immediate
5872*67e74705SXin Li     case 'Y': // Floating point constant zero
5873*67e74705SXin Li     case 'Z': // Integer constant zero
5874*67e74705SXin Li       return true;
5875*67e74705SXin Li     case 'Q': // A memory reference with base register and no offset
5876*67e74705SXin Li       Info.setAllowsMemory();
5877*67e74705SXin Li       return true;
5878*67e74705SXin Li     case 'S': // A symbolic address
5879*67e74705SXin Li       Info.setAllowsRegister();
5880*67e74705SXin Li       return true;
5881*67e74705SXin Li     case 'U':
5882*67e74705SXin Li       // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
5883*67e74705SXin Li       // Utf: A memory address suitable for ldp/stp in TF mode.
5884*67e74705SXin Li       // Usa: An absolute symbolic address.
5885*67e74705SXin Li       // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
5886*67e74705SXin Li       llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
5887*67e74705SXin Li     case 'z': // Zero register, wzr or xzr
5888*67e74705SXin Li       Info.setAllowsRegister();
5889*67e74705SXin Li       return true;
5890*67e74705SXin Li     case 'x': // Floating point and SIMD registers (V0-V15)
5891*67e74705SXin Li       Info.setAllowsRegister();
5892*67e74705SXin Li       return true;
5893*67e74705SXin Li     }
5894*67e74705SXin Li     return false;
5895*67e74705SXin Li   }
5896*67e74705SXin Li 
5897*67e74705SXin Li   bool
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const5898*67e74705SXin Li   validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
5899*67e74705SXin Li                              std::string &SuggestedModifier) const override {
5900*67e74705SXin Li     // Strip off constraint modifiers.
5901*67e74705SXin Li     while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
5902*67e74705SXin Li       Constraint = Constraint.substr(1);
5903*67e74705SXin Li 
5904*67e74705SXin Li     switch (Constraint[0]) {
5905*67e74705SXin Li     default:
5906*67e74705SXin Li       return true;
5907*67e74705SXin Li     case 'z':
5908*67e74705SXin Li     case 'r': {
5909*67e74705SXin Li       switch (Modifier) {
5910*67e74705SXin Li       case 'x':
5911*67e74705SXin Li       case 'w':
5912*67e74705SXin Li         // For now assume that the person knows what they're
5913*67e74705SXin Li         // doing with the modifier.
5914*67e74705SXin Li         return true;
5915*67e74705SXin Li       default:
5916*67e74705SXin Li         // By default an 'r' constraint will be in the 'x'
5917*67e74705SXin Li         // registers.
5918*67e74705SXin Li         if (Size == 64)
5919*67e74705SXin Li           return true;
5920*67e74705SXin Li 
5921*67e74705SXin Li         SuggestedModifier = "w";
5922*67e74705SXin Li         return false;
5923*67e74705SXin Li       }
5924*67e74705SXin Li     }
5925*67e74705SXin Li     }
5926*67e74705SXin Li   }
5927*67e74705SXin Li 
getClobbers() const5928*67e74705SXin Li   const char *getClobbers() const override { return ""; }
5929*67e74705SXin Li 
getEHDataRegisterNumber(unsigned RegNo) const5930*67e74705SXin Li   int getEHDataRegisterNumber(unsigned RegNo) const override {
5931*67e74705SXin Li     if (RegNo == 0)
5932*67e74705SXin Li       return 0;
5933*67e74705SXin Li     if (RegNo == 1)
5934*67e74705SXin Li       return 1;
5935*67e74705SXin Li     return -1;
5936*67e74705SXin Li   }
5937*67e74705SXin Li };
5938*67e74705SXin Li 
5939*67e74705SXin Li const char *const AArch64TargetInfo::GCCRegNames[] = {
5940*67e74705SXin Li   // 32-bit Integer registers
5941*67e74705SXin Li   "w0",  "w1",  "w2",  "w3",  "w4",  "w5",  "w6",  "w7",  "w8",  "w9",  "w10",
5942*67e74705SXin Li   "w11", "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21",
5943*67e74705SXin Li   "w22", "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
5944*67e74705SXin Li 
5945*67e74705SXin Li   // 64-bit Integer registers
5946*67e74705SXin Li   "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",  "x8",  "x9",  "x10",
5947*67e74705SXin Li   "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21",
5948*67e74705SXin Li   "x22", "x23", "x24", "x25", "x26", "x27", "x28", "fp",  "lr",  "sp",
5949*67e74705SXin Li 
5950*67e74705SXin Li   // 32-bit floating point regsisters
5951*67e74705SXin Li   "s0",  "s1",  "s2",  "s3",  "s4",  "s5",  "s6",  "s7",  "s8",  "s9",  "s10",
5952*67e74705SXin Li   "s11", "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21",
5953*67e74705SXin Li   "s22", "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
5954*67e74705SXin Li 
5955*67e74705SXin Li   // 64-bit floating point regsisters
5956*67e74705SXin Li   "d0",  "d1",  "d2",  "d3",  "d4",  "d5",  "d6",  "d7",  "d8",  "d9",  "d10",
5957*67e74705SXin Li   "d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21",
5958*67e74705SXin Li   "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
5959*67e74705SXin Li 
5960*67e74705SXin Li   // Vector registers
5961*67e74705SXin Li   "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",  "v8",  "v9",  "v10",
5962*67e74705SXin Li   "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
5963*67e74705SXin Li   "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
5964*67e74705SXin Li };
5965*67e74705SXin Li 
getGCCRegNames() const5966*67e74705SXin Li ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
5967*67e74705SXin Li   return llvm::makeArrayRef(GCCRegNames);
5968*67e74705SXin Li }
5969*67e74705SXin Li 
5970*67e74705SXin Li const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
5971*67e74705SXin Li   { { "w31" }, "wsp" },
5972*67e74705SXin Li   { { "x29" }, "fp" },
5973*67e74705SXin Li   { { "x30" }, "lr" },
5974*67e74705SXin Li   { { "x31" }, "sp" },
5975*67e74705SXin Li   // The S/D/Q and W/X registers overlap, but aren't really aliases; we
5976*67e74705SXin Li   // don't want to substitute one of these for a different-sized one.
5977*67e74705SXin Li };
5978*67e74705SXin Li 
getGCCRegAliases() const5979*67e74705SXin Li ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
5980*67e74705SXin Li   return llvm::makeArrayRef(GCCRegAliases);
5981*67e74705SXin Li }
5982*67e74705SXin Li 
5983*67e74705SXin Li const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
5984*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS)                                               \
5985*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
5986*67e74705SXin Li #include "clang/Basic/BuiltinsNEON.def"
5987*67e74705SXin Li 
5988*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS)                                               \
5989*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
5990*67e74705SXin Li #include "clang/Basic/BuiltinsAArch64.def"
5991*67e74705SXin Li };
5992*67e74705SXin Li 
5993*67e74705SXin Li class AArch64leTargetInfo : public AArch64TargetInfo {
setDataLayout()5994*67e74705SXin Li   void setDataLayout() override {
5995*67e74705SXin Li     if (getTriple().isOSBinFormatMachO())
5996*67e74705SXin Li       resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
5997*67e74705SXin Li     else
5998*67e74705SXin Li       resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
5999*67e74705SXin Li   }
6000*67e74705SXin Li 
6001*67e74705SXin Li public:
AArch64leTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6002*67e74705SXin Li   AArch64leTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6003*67e74705SXin Li       : AArch64TargetInfo(Triple, Opts) {
6004*67e74705SXin Li     BigEndian = false;
6005*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6006*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
6007*67e74705SXin Li                         MacroBuilder &Builder) const override {
6008*67e74705SXin Li     Builder.defineMacro("__AARCH64EL__");
6009*67e74705SXin Li     AArch64TargetInfo::getTargetDefines(Opts, Builder);
6010*67e74705SXin Li   }
6011*67e74705SXin Li };
6012*67e74705SXin Li 
6013*67e74705SXin Li class AArch64beTargetInfo : public AArch64TargetInfo {
setDataLayout()6014*67e74705SXin Li   void setDataLayout() override {
6015*67e74705SXin Li     assert(!getTriple().isOSBinFormatMachO());
6016*67e74705SXin Li     resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
6017*67e74705SXin Li   }
6018*67e74705SXin Li 
6019*67e74705SXin Li public:
AArch64beTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6020*67e74705SXin Li   AArch64beTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6021*67e74705SXin Li       : AArch64TargetInfo(Triple, Opts) {}
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6022*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
6023*67e74705SXin Li                         MacroBuilder &Builder) const override {
6024*67e74705SXin Li     Builder.defineMacro("__AARCH64EB__");
6025*67e74705SXin Li     Builder.defineMacro("__AARCH_BIG_ENDIAN");
6026*67e74705SXin Li     Builder.defineMacro("__ARM_BIG_ENDIAN");
6027*67e74705SXin Li     AArch64TargetInfo::getTargetDefines(Opts, Builder);
6028*67e74705SXin Li   }
6029*67e74705SXin Li };
6030*67e74705SXin Li 
6031*67e74705SXin Li class DarwinAArch64TargetInfo : public DarwinTargetInfo<AArch64leTargetInfo> {
6032*67e74705SXin Li protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const6033*67e74705SXin Li   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
6034*67e74705SXin Li                     MacroBuilder &Builder) const override {
6035*67e74705SXin Li     Builder.defineMacro("__AARCH64_SIMD__");
6036*67e74705SXin Li     Builder.defineMacro("__ARM64_ARCH_8__");
6037*67e74705SXin Li     Builder.defineMacro("__ARM_NEON__");
6038*67e74705SXin Li     Builder.defineMacro("__LITTLE_ENDIAN__");
6039*67e74705SXin Li     Builder.defineMacro("__REGISTER_PREFIX__", "");
6040*67e74705SXin Li     Builder.defineMacro("__arm64", "1");
6041*67e74705SXin Li     Builder.defineMacro("__arm64__", "1");
6042*67e74705SXin Li 
6043*67e74705SXin Li     getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
6044*67e74705SXin Li   }
6045*67e74705SXin Li 
6046*67e74705SXin Li public:
DarwinAArch64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6047*67e74705SXin Li   DarwinAArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6048*67e74705SXin Li       : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
6049*67e74705SXin Li     Int64Type = SignedLongLong;
6050*67e74705SXin Li     WCharType = SignedInt;
6051*67e74705SXin Li     UseSignedCharForObjCBool = false;
6052*67e74705SXin Li 
6053*67e74705SXin Li     LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
6054*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
6055*67e74705SXin Li 
6056*67e74705SXin Li     TheCXXABI.set(TargetCXXABI::iOS64);
6057*67e74705SXin Li   }
6058*67e74705SXin Li 
getBuiltinVaListKind() const6059*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
6060*67e74705SXin Li     return TargetInfo::CharPtrBuiltinVaList;
6061*67e74705SXin Li   }
6062*67e74705SXin Li };
6063*67e74705SXin Li 
6064*67e74705SXin Li // Hexagon abstract base class
6065*67e74705SXin Li class HexagonTargetInfo : public TargetInfo {
6066*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
6067*67e74705SXin Li   static const char * const GCCRegNames[];
6068*67e74705SXin Li   static const TargetInfo::GCCRegAlias GCCRegAliases[];
6069*67e74705SXin Li   std::string CPU;
6070*67e74705SXin Li   bool HasHVX, HasHVXDouble;
6071*67e74705SXin Li 
6072*67e74705SXin Li public:
HexagonTargetInfo(const llvm::Triple & Triple,const TargetOptions &)6073*67e74705SXin Li   HexagonTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
6074*67e74705SXin Li       : TargetInfo(Triple) {
6075*67e74705SXin Li     BigEndian = false;
6076*67e74705SXin Li     // Specify the vector alignment explicitly. For v512x1, the calculated
6077*67e74705SXin Li     // alignment would be 512*alignment(i1), which is 512 bytes, instead of
6078*67e74705SXin Li     // the required minimum of 64 bytes.
6079*67e74705SXin Li     resetDataLayout("e-m:e-p:32:32:32-a:0-n16:32-"
6080*67e74705SXin Li         "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-"
6081*67e74705SXin Li         "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048");
6082*67e74705SXin Li     SizeType    = UnsignedInt;
6083*67e74705SXin Li     PtrDiffType = SignedInt;
6084*67e74705SXin Li     IntPtrType  = SignedInt;
6085*67e74705SXin Li 
6086*67e74705SXin Li     // {} in inline assembly are packet specifiers, not assembly variant
6087*67e74705SXin Li     // specifiers.
6088*67e74705SXin Li     NoAsmVariants = true;
6089*67e74705SXin Li 
6090*67e74705SXin Li     LargeArrayMinWidth = 64;
6091*67e74705SXin Li     LargeArrayAlign = 64;
6092*67e74705SXin Li     UseBitFieldTypeAlignment = true;
6093*67e74705SXin Li     ZeroLengthBitfieldBoundary = 32;
6094*67e74705SXin Li     HasHVX = HasHVXDouble = false;
6095*67e74705SXin Li   }
6096*67e74705SXin Li 
getTargetBuiltins() const6097*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
6098*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
6099*67e74705SXin Li                          clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin);
6100*67e74705SXin Li   }
6101*67e74705SXin Li 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const6102*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
6103*67e74705SXin Li                              TargetInfo::ConstraintInfo &Info) const override {
6104*67e74705SXin Li     switch (*Name) {
6105*67e74705SXin Li       case 'v':
6106*67e74705SXin Li       case 'q':
6107*67e74705SXin Li         if (HasHVX) {
6108*67e74705SXin Li           Info.setAllowsRegister();
6109*67e74705SXin Li           return true;
6110*67e74705SXin Li         }
6111*67e74705SXin Li         break;
6112*67e74705SXin Li       case 's':
6113*67e74705SXin Li         // Relocatable constant.
6114*67e74705SXin Li         return true;
6115*67e74705SXin Li     }
6116*67e74705SXin Li     return false;
6117*67e74705SXin Li   }
6118*67e74705SXin Li 
6119*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
6120*67e74705SXin Li                         MacroBuilder &Builder) const override;
6121*67e74705SXin Li 
isCLZForZeroUndef() const6122*67e74705SXin Li   bool isCLZForZeroUndef() const override { return false; }
6123*67e74705SXin Li 
hasFeature(StringRef Feature) const6124*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
6125*67e74705SXin Li     return llvm::StringSwitch<bool>(Feature)
6126*67e74705SXin Li       .Case("hexagon", true)
6127*67e74705SXin Li       .Case("hvx", HasHVX)
6128*67e74705SXin Li       .Case("hvx-double", HasHVXDouble)
6129*67e74705SXin Li       .Default(false);
6130*67e74705SXin Li   }
6131*67e74705SXin Li 
6132*67e74705SXin Li   bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
6133*67e74705SXin Li         StringRef CPU, const std::vector<std::string> &FeaturesVec)
6134*67e74705SXin Li         const override;
6135*67e74705SXin Li 
6136*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
6137*67e74705SXin Li                             DiagnosticsEngine &Diags) override;
6138*67e74705SXin Li 
getBuiltinVaListKind() const6139*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
6140*67e74705SXin Li     return TargetInfo::CharPtrBuiltinVaList;
6141*67e74705SXin Li   }
6142*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
6143*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
getClobbers() const6144*67e74705SXin Li   const char *getClobbers() const override {
6145*67e74705SXin Li     return "";
6146*67e74705SXin Li   }
6147*67e74705SXin Li 
getHexagonCPUSuffix(StringRef Name)6148*67e74705SXin Li   static const char *getHexagonCPUSuffix(StringRef Name) {
6149*67e74705SXin Li     return llvm::StringSwitch<const char*>(Name)
6150*67e74705SXin Li       .Case("hexagonv4", "4")
6151*67e74705SXin Li       .Case("hexagonv5", "5")
6152*67e74705SXin Li       .Case("hexagonv55", "55")
6153*67e74705SXin Li       .Case("hexagonv60", "60")
6154*67e74705SXin Li       .Default(nullptr);
6155*67e74705SXin Li   }
6156*67e74705SXin Li 
setCPU(const std::string & Name)6157*67e74705SXin Li   bool setCPU(const std::string &Name) override {
6158*67e74705SXin Li     if (!getHexagonCPUSuffix(Name))
6159*67e74705SXin Li       return false;
6160*67e74705SXin Li     CPU = Name;
6161*67e74705SXin Li     return true;
6162*67e74705SXin Li   }
6163*67e74705SXin Li 
getEHDataRegisterNumber(unsigned RegNo) const6164*67e74705SXin Li   int getEHDataRegisterNumber(unsigned RegNo) const override {
6165*67e74705SXin Li     return RegNo < 2 ? RegNo : -1;
6166*67e74705SXin Li   }
6167*67e74705SXin Li };
6168*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6169*67e74705SXin Li void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
6170*67e74705SXin Li                                          MacroBuilder &Builder) const {
6171*67e74705SXin Li   Builder.defineMacro("__qdsp6__", "1");
6172*67e74705SXin Li   Builder.defineMacro("__hexagon__", "1");
6173*67e74705SXin Li 
6174*67e74705SXin Li   if (CPU == "hexagonv4") {
6175*67e74705SXin Li     Builder.defineMacro("__HEXAGON_V4__");
6176*67e74705SXin Li     Builder.defineMacro("__HEXAGON_ARCH__", "4");
6177*67e74705SXin Li     if (Opts.HexagonQdsp6Compat) {
6178*67e74705SXin Li       Builder.defineMacro("__QDSP6_V4__");
6179*67e74705SXin Li       Builder.defineMacro("__QDSP6_ARCH__", "4");
6180*67e74705SXin Li     }
6181*67e74705SXin Li   } else if (CPU == "hexagonv5") {
6182*67e74705SXin Li     Builder.defineMacro("__HEXAGON_V5__");
6183*67e74705SXin Li     Builder.defineMacro("__HEXAGON_ARCH__", "5");
6184*67e74705SXin Li     if(Opts.HexagonQdsp6Compat) {
6185*67e74705SXin Li       Builder.defineMacro("__QDSP6_V5__");
6186*67e74705SXin Li       Builder.defineMacro("__QDSP6_ARCH__", "5");
6187*67e74705SXin Li     }
6188*67e74705SXin Li   } else if (CPU == "hexagonv55") {
6189*67e74705SXin Li     Builder.defineMacro("__HEXAGON_V55__");
6190*67e74705SXin Li     Builder.defineMacro("__HEXAGON_ARCH__", "55");
6191*67e74705SXin Li     Builder.defineMacro("__QDSP6_V55__");
6192*67e74705SXin Li     Builder.defineMacro("__QDSP6_ARCH__", "55");
6193*67e74705SXin Li   } else if (CPU == "hexagonv60") {
6194*67e74705SXin Li     Builder.defineMacro("__HEXAGON_V60__");
6195*67e74705SXin Li     Builder.defineMacro("__HEXAGON_ARCH__", "60");
6196*67e74705SXin Li     Builder.defineMacro("__QDSP6_V60__");
6197*67e74705SXin Li     Builder.defineMacro("__QDSP6_ARCH__", "60");
6198*67e74705SXin Li   }
6199*67e74705SXin Li 
6200*67e74705SXin Li   if (hasFeature("hvx")) {
6201*67e74705SXin Li     Builder.defineMacro("__HVX__");
6202*67e74705SXin Li     if (hasFeature("hvx-double"))
6203*67e74705SXin Li       Builder.defineMacro("__HVXDBL__");
6204*67e74705SXin Li   }
6205*67e74705SXin Li }
6206*67e74705SXin Li 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)6207*67e74705SXin Li bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
6208*67e74705SXin Li                                              DiagnosticsEngine &Diags) {
6209*67e74705SXin Li   for (auto &F : Features) {
6210*67e74705SXin Li     if (F == "+hvx")
6211*67e74705SXin Li       HasHVX = true;
6212*67e74705SXin Li     else if (F == "-hvx")
6213*67e74705SXin Li       HasHVX = HasHVXDouble = false;
6214*67e74705SXin Li     else if (F == "+hvx-double")
6215*67e74705SXin Li       HasHVX = HasHVXDouble = true;
6216*67e74705SXin Li     else if (F == "-hvx-double")
6217*67e74705SXin Li       HasHVXDouble = false;
6218*67e74705SXin Li   }
6219*67e74705SXin Li   return true;
6220*67e74705SXin Li }
6221*67e74705SXin Li 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const6222*67e74705SXin Li bool HexagonTargetInfo::initFeatureMap(llvm::StringMap<bool> &Features,
6223*67e74705SXin Li       DiagnosticsEngine &Diags, StringRef CPU,
6224*67e74705SXin Li       const std::vector<std::string> &FeaturesVec) const {
6225*67e74705SXin Li   // Default for v60: -hvx, -hvx-double.
6226*67e74705SXin Li   Features["hvx"] = false;
6227*67e74705SXin Li   Features["hvx-double"] = false;
6228*67e74705SXin Li 
6229*67e74705SXin Li   return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
6230*67e74705SXin Li }
6231*67e74705SXin Li 
6232*67e74705SXin Li 
6233*67e74705SXin Li const char *const HexagonTargetInfo::GCCRegNames[] = {
6234*67e74705SXin Li   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
6235*67e74705SXin Li   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
6236*67e74705SXin Li   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
6237*67e74705SXin Li   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
6238*67e74705SXin Li   "p0", "p1", "p2", "p3",
6239*67e74705SXin Li   "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
6240*67e74705SXin Li };
6241*67e74705SXin Li 
getGCCRegNames() const6242*67e74705SXin Li ArrayRef<const char*> HexagonTargetInfo::getGCCRegNames() const {
6243*67e74705SXin Li   return llvm::makeArrayRef(GCCRegNames);
6244*67e74705SXin Li }
6245*67e74705SXin Li 
6246*67e74705SXin Li const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
6247*67e74705SXin Li   { { "sp" }, "r29" },
6248*67e74705SXin Li   { { "fp" }, "r30" },
6249*67e74705SXin Li   { { "lr" }, "r31" },
6250*67e74705SXin Li };
6251*67e74705SXin Li 
getGCCRegAliases() const6252*67e74705SXin Li ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
6253*67e74705SXin Li   return llvm::makeArrayRef(GCCRegAliases);
6254*67e74705SXin Li }
6255*67e74705SXin Li 
6256*67e74705SXin Li 
6257*67e74705SXin Li const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
6258*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS) \
6259*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
6260*67e74705SXin Li #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
6261*67e74705SXin Li   { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
6262*67e74705SXin Li #include "clang/Basic/BuiltinsHexagon.def"
6263*67e74705SXin Li };
6264*67e74705SXin Li 
6265*67e74705SXin Li class LanaiTargetInfo : public TargetInfo {
6266*67e74705SXin Li   // Class for Lanai (32-bit).
6267*67e74705SXin Li   // The CPU profiles supported by the Lanai backend
6268*67e74705SXin Li   enum CPUKind {
6269*67e74705SXin Li     CK_NONE,
6270*67e74705SXin Li     CK_V11,
6271*67e74705SXin Li   } CPU;
6272*67e74705SXin Li 
6273*67e74705SXin Li   static const TargetInfo::GCCRegAlias GCCRegAliases[];
6274*67e74705SXin Li   static const char *const GCCRegNames[];
6275*67e74705SXin Li 
6276*67e74705SXin Li public:
LanaiTargetInfo(const llvm::Triple & Triple,const TargetOptions &)6277*67e74705SXin Li   LanaiTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
6278*67e74705SXin Li       : TargetInfo(Triple) {
6279*67e74705SXin Li     // Description string has to be kept in sync with backend.
6280*67e74705SXin Li     resetDataLayout("E"        // Big endian
6281*67e74705SXin Li                     "-m:e"     // ELF name manging
6282*67e74705SXin Li                     "-p:32:32" // 32 bit pointers, 32 bit aligned
6283*67e74705SXin Li                     "-i64:64"  // 64 bit integers, 64 bit aligned
6284*67e74705SXin Li                     "-a:0:32"  // 32 bit alignment of objects of aggregate type
6285*67e74705SXin Li                     "-n32"     // 32 bit native integer width
6286*67e74705SXin Li                     "-S64"     // 64 bit natural stack alignment
6287*67e74705SXin Li                     );
6288*67e74705SXin Li 
6289*67e74705SXin Li     // Setting RegParmMax equal to what mregparm was set to in the old
6290*67e74705SXin Li     // toolchain
6291*67e74705SXin Li     RegParmMax = 4;
6292*67e74705SXin Li 
6293*67e74705SXin Li     // Set the default CPU to V11
6294*67e74705SXin Li     CPU = CK_V11;
6295*67e74705SXin Li 
6296*67e74705SXin Li     // Temporary approach to make everything at least word-aligned and allow for
6297*67e74705SXin Li     // safely casting between pointers with different alignment requirements.
6298*67e74705SXin Li     // TODO: Remove this when there are no more cast align warnings on the
6299*67e74705SXin Li     // firmware.
6300*67e74705SXin Li     MinGlobalAlign = 32;
6301*67e74705SXin Li   }
6302*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6303*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
6304*67e74705SXin Li                         MacroBuilder &Builder) const override {
6305*67e74705SXin Li     // Define __lanai__ when building for target lanai.
6306*67e74705SXin Li     Builder.defineMacro("__lanai__");
6307*67e74705SXin Li 
6308*67e74705SXin Li     // Set define for the CPU specified.
6309*67e74705SXin Li     switch (CPU) {
6310*67e74705SXin Li     case CK_V11:
6311*67e74705SXin Li       Builder.defineMacro("__LANAI_V11__");
6312*67e74705SXin Li       break;
6313*67e74705SXin Li     case CK_NONE:
6314*67e74705SXin Li       llvm_unreachable("Unhandled target CPU");
6315*67e74705SXin Li     }
6316*67e74705SXin Li   }
6317*67e74705SXin Li 
setCPU(const std::string & Name)6318*67e74705SXin Li   bool setCPU(const std::string &Name) override {
6319*67e74705SXin Li     CPU = llvm::StringSwitch<CPUKind>(Name)
6320*67e74705SXin Li               .Case("v11", CK_V11)
6321*67e74705SXin Li               .Default(CK_NONE);
6322*67e74705SXin Li 
6323*67e74705SXin Li     return CPU != CK_NONE;
6324*67e74705SXin Li   }
6325*67e74705SXin Li 
hasFeature(StringRef Feature) const6326*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
6327*67e74705SXin Li     return llvm::StringSwitch<bool>(Feature).Case("lanai", true).Default(false);
6328*67e74705SXin Li   }
6329*67e74705SXin Li 
6330*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
6331*67e74705SXin Li 
6332*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
6333*67e74705SXin Li 
getBuiltinVaListKind() const6334*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
6335*67e74705SXin Li     return TargetInfo::VoidPtrBuiltinVaList;
6336*67e74705SXin Li   }
6337*67e74705SXin Li 
getTargetBuiltins() const6338*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
6339*67e74705SXin Li 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const6340*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
6341*67e74705SXin Li                              TargetInfo::ConstraintInfo &info) const override {
6342*67e74705SXin Li     return false;
6343*67e74705SXin Li   }
6344*67e74705SXin Li 
getClobbers() const6345*67e74705SXin Li   const char *getClobbers() const override { return ""; }
6346*67e74705SXin Li };
6347*67e74705SXin Li 
6348*67e74705SXin Li const char *const LanaiTargetInfo::GCCRegNames[] = {
6349*67e74705SXin Li     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9",  "r10",
6350*67e74705SXin Li     "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
6351*67e74705SXin Li     "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"};
6352*67e74705SXin Li 
getGCCRegNames() const6353*67e74705SXin Li ArrayRef<const char *> LanaiTargetInfo::getGCCRegNames() const {
6354*67e74705SXin Li   return llvm::makeArrayRef(GCCRegNames);
6355*67e74705SXin Li }
6356*67e74705SXin Li 
6357*67e74705SXin Li const TargetInfo::GCCRegAlias LanaiTargetInfo::GCCRegAliases[] = {
6358*67e74705SXin Li     {{"pc"}, "r2"},
6359*67e74705SXin Li     {{"sp"}, "r4"},
6360*67e74705SXin Li     {{"fp"}, "r5"},
6361*67e74705SXin Li     {{"rv"}, "r8"},
6362*67e74705SXin Li     {{"rr1"}, "r10"},
6363*67e74705SXin Li     {{"rr2"}, "r11"},
6364*67e74705SXin Li     {{"rca"}, "r15"},
6365*67e74705SXin Li };
6366*67e74705SXin Li 
getGCCRegAliases() const6367*67e74705SXin Li ArrayRef<TargetInfo::GCCRegAlias> LanaiTargetInfo::getGCCRegAliases() const {
6368*67e74705SXin Li   return llvm::makeArrayRef(GCCRegAliases);
6369*67e74705SXin Li }
6370*67e74705SXin Li 
6371*67e74705SXin Li // Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit).
6372*67e74705SXin Li class SparcTargetInfo : public TargetInfo {
6373*67e74705SXin Li   static const TargetInfo::GCCRegAlias GCCRegAliases[];
6374*67e74705SXin Li   static const char * const GCCRegNames[];
6375*67e74705SXin Li   bool SoftFloat;
6376*67e74705SXin Li public:
SparcTargetInfo(const llvm::Triple & Triple,const TargetOptions &)6377*67e74705SXin Li   SparcTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
6378*67e74705SXin Li       : TargetInfo(Triple), SoftFloat(false) {}
6379*67e74705SXin Li 
getEHDataRegisterNumber(unsigned RegNo) const6380*67e74705SXin Li   int getEHDataRegisterNumber(unsigned RegNo) const override {
6381*67e74705SXin Li     if (RegNo == 0) return 24;
6382*67e74705SXin Li     if (RegNo == 1) return 25;
6383*67e74705SXin Li     return -1;
6384*67e74705SXin Li   }
6385*67e74705SXin Li 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)6386*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
6387*67e74705SXin Li                             DiagnosticsEngine &Diags) override {
6388*67e74705SXin Li     // Check if software floating point is enabled
6389*67e74705SXin Li     auto Feature = std::find(Features.begin(), Features.end(), "+soft-float");
6390*67e74705SXin Li     if (Feature != Features.end()) {
6391*67e74705SXin Li       SoftFloat = true;
6392*67e74705SXin Li     }
6393*67e74705SXin Li     return true;
6394*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6395*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
6396*67e74705SXin Li                         MacroBuilder &Builder) const override {
6397*67e74705SXin Li     DefineStd(Builder, "sparc", Opts);
6398*67e74705SXin Li     Builder.defineMacro("__REGISTER_PREFIX__", "");
6399*67e74705SXin Li 
6400*67e74705SXin Li     if (SoftFloat)
6401*67e74705SXin Li       Builder.defineMacro("SOFT_FLOAT", "1");
6402*67e74705SXin Li   }
6403*67e74705SXin Li 
hasFeature(StringRef Feature) const6404*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
6405*67e74705SXin Li     return llvm::StringSwitch<bool>(Feature)
6406*67e74705SXin Li              .Case("softfloat", SoftFloat)
6407*67e74705SXin Li              .Case("sparc", true)
6408*67e74705SXin Li              .Default(false);
6409*67e74705SXin Li   }
6410*67e74705SXin Li 
hasSjLjLowering() const6411*67e74705SXin Li   bool hasSjLjLowering() const override {
6412*67e74705SXin Li     return true;
6413*67e74705SXin Li   }
6414*67e74705SXin Li 
getTargetBuiltins() const6415*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
6416*67e74705SXin Li     // FIXME: Implement!
6417*67e74705SXin Li     return None;
6418*67e74705SXin Li   }
getBuiltinVaListKind() const6419*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
6420*67e74705SXin Li     return TargetInfo::VoidPtrBuiltinVaList;
6421*67e74705SXin Li   }
6422*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
6423*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const6424*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
6425*67e74705SXin Li                              TargetInfo::ConstraintInfo &info) const override {
6426*67e74705SXin Li     // FIXME: Implement!
6427*67e74705SXin Li     switch (*Name) {
6428*67e74705SXin Li     case 'I': // Signed 13-bit constant
6429*67e74705SXin Li     case 'J': // Zero
6430*67e74705SXin Li     case 'K': // 32-bit constant with the low 12 bits clear
6431*67e74705SXin Li     case 'L': // A constant in the range supported by movcc (11-bit signed imm)
6432*67e74705SXin Li     case 'M': // A constant in the range supported by movrcc (19-bit signed imm)
6433*67e74705SXin Li     case 'N': // Same as 'K' but zext (required for SIMode)
6434*67e74705SXin Li     case 'O': // The constant 4096
6435*67e74705SXin Li       return true;
6436*67e74705SXin Li     }
6437*67e74705SXin Li     return false;
6438*67e74705SXin Li   }
getClobbers() const6439*67e74705SXin Li   const char *getClobbers() const override {
6440*67e74705SXin Li     // FIXME: Implement!
6441*67e74705SXin Li     return "";
6442*67e74705SXin Li   }
6443*67e74705SXin Li 
6444*67e74705SXin Li   // No Sparc V7 for now, the backend doesn't support it anyway.
6445*67e74705SXin Li   enum CPUKind {
6446*67e74705SXin Li     CK_GENERIC,
6447*67e74705SXin Li     CK_V8,
6448*67e74705SXin Li     CK_SUPERSPARC,
6449*67e74705SXin Li     CK_SPARCLITE,
6450*67e74705SXin Li     CK_F934,
6451*67e74705SXin Li     CK_HYPERSPARC,
6452*67e74705SXin Li     CK_SPARCLITE86X,
6453*67e74705SXin Li     CK_SPARCLET,
6454*67e74705SXin Li     CK_TSC701,
6455*67e74705SXin Li     CK_V9,
6456*67e74705SXin Li     CK_ULTRASPARC,
6457*67e74705SXin Li     CK_ULTRASPARC3,
6458*67e74705SXin Li     CK_NIAGARA,
6459*67e74705SXin Li     CK_NIAGARA2,
6460*67e74705SXin Li     CK_NIAGARA3,
6461*67e74705SXin Li     CK_NIAGARA4,
6462*67e74705SXin Li     CK_MYRIAD2_1,
6463*67e74705SXin Li     CK_MYRIAD2_2,
6464*67e74705SXin Li     CK_LEON2,
6465*67e74705SXin Li     CK_LEON2_AT697E,
6466*67e74705SXin Li     CK_LEON2_AT697F,
6467*67e74705SXin Li     CK_LEON3,
6468*67e74705SXin Li     CK_LEON3_UT699,
6469*67e74705SXin Li     CK_LEON3_GR712RC,
6470*67e74705SXin Li     CK_LEON4,
6471*67e74705SXin Li     CK_LEON4_GR740
6472*67e74705SXin Li   } CPU = CK_GENERIC;
6473*67e74705SXin Li 
6474*67e74705SXin Li   enum CPUGeneration {
6475*67e74705SXin Li     CG_V8,
6476*67e74705SXin Li     CG_V9,
6477*67e74705SXin Li   };
6478*67e74705SXin Li 
getCPUGeneration(CPUKind Kind) const6479*67e74705SXin Li   CPUGeneration getCPUGeneration(CPUKind Kind) const {
6480*67e74705SXin Li     switch (Kind) {
6481*67e74705SXin Li     case CK_GENERIC:
6482*67e74705SXin Li     case CK_V8:
6483*67e74705SXin Li     case CK_SUPERSPARC:
6484*67e74705SXin Li     case CK_SPARCLITE:
6485*67e74705SXin Li     case CK_F934:
6486*67e74705SXin Li     case CK_HYPERSPARC:
6487*67e74705SXin Li     case CK_SPARCLITE86X:
6488*67e74705SXin Li     case CK_SPARCLET:
6489*67e74705SXin Li     case CK_TSC701:
6490*67e74705SXin Li     case CK_MYRIAD2_1:
6491*67e74705SXin Li     case CK_MYRIAD2_2:
6492*67e74705SXin Li     case CK_LEON2:
6493*67e74705SXin Li     case CK_LEON2_AT697E:
6494*67e74705SXin Li     case CK_LEON2_AT697F:
6495*67e74705SXin Li     case CK_LEON3:
6496*67e74705SXin Li     case CK_LEON3_UT699:
6497*67e74705SXin Li     case CK_LEON3_GR712RC:
6498*67e74705SXin Li     case CK_LEON4:
6499*67e74705SXin Li     case CK_LEON4_GR740:
6500*67e74705SXin Li       return CG_V8;
6501*67e74705SXin Li     case CK_V9:
6502*67e74705SXin Li     case CK_ULTRASPARC:
6503*67e74705SXin Li     case CK_ULTRASPARC3:
6504*67e74705SXin Li     case CK_NIAGARA:
6505*67e74705SXin Li     case CK_NIAGARA2:
6506*67e74705SXin Li     case CK_NIAGARA3:
6507*67e74705SXin Li     case CK_NIAGARA4:
6508*67e74705SXin Li       return CG_V9;
6509*67e74705SXin Li     }
6510*67e74705SXin Li     llvm_unreachable("Unexpected CPU kind");
6511*67e74705SXin Li   }
6512*67e74705SXin Li 
getCPUKind(StringRef Name) const6513*67e74705SXin Li   CPUKind getCPUKind(StringRef Name) const {
6514*67e74705SXin Li     return llvm::StringSwitch<CPUKind>(Name)
6515*67e74705SXin Li         .Case("v8", CK_V8)
6516*67e74705SXin Li         .Case("supersparc", CK_SUPERSPARC)
6517*67e74705SXin Li         .Case("sparclite", CK_SPARCLITE)
6518*67e74705SXin Li         .Case("f934", CK_F934)
6519*67e74705SXin Li         .Case("hypersparc", CK_HYPERSPARC)
6520*67e74705SXin Li         .Case("sparclite86x", CK_SPARCLITE86X)
6521*67e74705SXin Li         .Case("sparclet", CK_SPARCLET)
6522*67e74705SXin Li         .Case("tsc701", CK_TSC701)
6523*67e74705SXin Li         .Case("v9", CK_V9)
6524*67e74705SXin Li         .Case("ultrasparc", CK_ULTRASPARC)
6525*67e74705SXin Li         .Case("ultrasparc3", CK_ULTRASPARC3)
6526*67e74705SXin Li         .Case("niagara", CK_NIAGARA)
6527*67e74705SXin Li         .Case("niagara2", CK_NIAGARA2)
6528*67e74705SXin Li         .Case("niagara3", CK_NIAGARA3)
6529*67e74705SXin Li         .Case("niagara4", CK_NIAGARA4)
6530*67e74705SXin Li         .Case("myriad2", CK_MYRIAD2_1)
6531*67e74705SXin Li         .Case("myriad2.1", CK_MYRIAD2_1)
6532*67e74705SXin Li         .Case("myriad2.2", CK_MYRIAD2_2)
6533*67e74705SXin Li         .Case("leon2", CK_LEON2)
6534*67e74705SXin Li         .Case("at697e", CK_LEON2_AT697E)
6535*67e74705SXin Li         .Case("at697f", CK_LEON2_AT697F)
6536*67e74705SXin Li         .Case("leon3", CK_LEON3)
6537*67e74705SXin Li         .Case("ut699", CK_LEON3_UT699)
6538*67e74705SXin Li         .Case("gr712rc", CK_LEON3_GR712RC)
6539*67e74705SXin Li         .Case("leon4", CK_LEON4)
6540*67e74705SXin Li         .Case("gr740", CK_LEON4_GR740)
6541*67e74705SXin Li         .Default(CK_GENERIC);
6542*67e74705SXin Li   }
6543*67e74705SXin Li 
setCPU(const std::string & Name)6544*67e74705SXin Li   bool setCPU(const std::string &Name) override {
6545*67e74705SXin Li     CPU = getCPUKind(Name);
6546*67e74705SXin Li     return CPU != CK_GENERIC;
6547*67e74705SXin Li   }
6548*67e74705SXin Li };
6549*67e74705SXin Li 
6550*67e74705SXin Li const char * const SparcTargetInfo::GCCRegNames[] = {
6551*67e74705SXin Li   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
6552*67e74705SXin Li   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
6553*67e74705SXin Li   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
6554*67e74705SXin Li   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
6555*67e74705SXin Li };
6556*67e74705SXin Li 
getGCCRegNames() const6557*67e74705SXin Li ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
6558*67e74705SXin Li   return llvm::makeArrayRef(GCCRegNames);
6559*67e74705SXin Li }
6560*67e74705SXin Li 
6561*67e74705SXin Li const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
6562*67e74705SXin Li   { { "g0" }, "r0" },
6563*67e74705SXin Li   { { "g1" }, "r1" },
6564*67e74705SXin Li   { { "g2" }, "r2" },
6565*67e74705SXin Li   { { "g3" }, "r3" },
6566*67e74705SXin Li   { { "g4" }, "r4" },
6567*67e74705SXin Li   { { "g5" }, "r5" },
6568*67e74705SXin Li   { { "g6" }, "r6" },
6569*67e74705SXin Li   { { "g7" }, "r7" },
6570*67e74705SXin Li   { { "o0" }, "r8" },
6571*67e74705SXin Li   { { "o1" }, "r9" },
6572*67e74705SXin Li   { { "o2" }, "r10" },
6573*67e74705SXin Li   { { "o3" }, "r11" },
6574*67e74705SXin Li   { { "o4" }, "r12" },
6575*67e74705SXin Li   { { "o5" }, "r13" },
6576*67e74705SXin Li   { { "o6", "sp" }, "r14" },
6577*67e74705SXin Li   { { "o7" }, "r15" },
6578*67e74705SXin Li   { { "l0" }, "r16" },
6579*67e74705SXin Li   { { "l1" }, "r17" },
6580*67e74705SXin Li   { { "l2" }, "r18" },
6581*67e74705SXin Li   { { "l3" }, "r19" },
6582*67e74705SXin Li   { { "l4" }, "r20" },
6583*67e74705SXin Li   { { "l5" }, "r21" },
6584*67e74705SXin Li   { { "l6" }, "r22" },
6585*67e74705SXin Li   { { "l7" }, "r23" },
6586*67e74705SXin Li   { { "i0" }, "r24" },
6587*67e74705SXin Li   { { "i1" }, "r25" },
6588*67e74705SXin Li   { { "i2" }, "r26" },
6589*67e74705SXin Li   { { "i3" }, "r27" },
6590*67e74705SXin Li   { { "i4" }, "r28" },
6591*67e74705SXin Li   { { "i5" }, "r29" },
6592*67e74705SXin Li   { { "i6", "fp" }, "r30" },
6593*67e74705SXin Li   { { "i7" }, "r31" },
6594*67e74705SXin Li };
6595*67e74705SXin Li 
getGCCRegAliases() const6596*67e74705SXin Li ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
6597*67e74705SXin Li   return llvm::makeArrayRef(GCCRegAliases);
6598*67e74705SXin Li }
6599*67e74705SXin Li 
6600*67e74705SXin Li // SPARC v8 is the 32-bit mode selected by Triple::sparc.
6601*67e74705SXin Li class SparcV8TargetInfo : public SparcTargetInfo {
6602*67e74705SXin Li public:
SparcV8TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6603*67e74705SXin Li   SparcV8TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6604*67e74705SXin Li       : SparcTargetInfo(Triple, Opts) {
6605*67e74705SXin Li     resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64");
6606*67e74705SXin Li     // NetBSD / OpenBSD use long (same as llvm default); everyone else uses int.
6607*67e74705SXin Li     switch (getTriple().getOS()) {
6608*67e74705SXin Li     default:
6609*67e74705SXin Li       SizeType = UnsignedInt;
6610*67e74705SXin Li       IntPtrType = SignedInt;
6611*67e74705SXin Li       PtrDiffType = SignedInt;
6612*67e74705SXin Li       break;
6613*67e74705SXin Li     case llvm::Triple::NetBSD:
6614*67e74705SXin Li     case llvm::Triple::OpenBSD:
6615*67e74705SXin Li       SizeType = UnsignedLong;
6616*67e74705SXin Li       IntPtrType = SignedLong;
6617*67e74705SXin Li       PtrDiffType = SignedLong;
6618*67e74705SXin Li       break;
6619*67e74705SXin Li     }
6620*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
6621*67e74705SXin Li   }
6622*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6623*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
6624*67e74705SXin Li                         MacroBuilder &Builder) const override {
6625*67e74705SXin Li     SparcTargetInfo::getTargetDefines(Opts, Builder);
6626*67e74705SXin Li     switch (getCPUGeneration(CPU)) {
6627*67e74705SXin Li     case CG_V8:
6628*67e74705SXin Li       Builder.defineMacro("__sparcv8");
6629*67e74705SXin Li       if (getTriple().getOS() != llvm::Triple::Solaris)
6630*67e74705SXin Li         Builder.defineMacro("__sparcv8__");
6631*67e74705SXin Li       break;
6632*67e74705SXin Li     case CG_V9:
6633*67e74705SXin Li       Builder.defineMacro("__sparcv9");
6634*67e74705SXin Li       if (getTriple().getOS() != llvm::Triple::Solaris) {
6635*67e74705SXin Li         Builder.defineMacro("__sparcv9__");
6636*67e74705SXin Li         Builder.defineMacro("__sparc_v9__");
6637*67e74705SXin Li       }
6638*67e74705SXin Li       break;
6639*67e74705SXin Li     }
6640*67e74705SXin Li     if (getTriple().getVendor() == llvm::Triple::Myriad) {
6641*67e74705SXin Li       switch (CPU) {
6642*67e74705SXin Li       case CK_MYRIAD2_1:
6643*67e74705SXin Li         Builder.defineMacro("__myriad2", "1");
6644*67e74705SXin Li         Builder.defineMacro("__myriad2__", "1");
6645*67e74705SXin Li         break;
6646*67e74705SXin Li       case CK_MYRIAD2_2:
6647*67e74705SXin Li         Builder.defineMacro("__myriad2", "2");
6648*67e74705SXin Li         Builder.defineMacro("__myriad2__", "2");
6649*67e74705SXin Li         break;
6650*67e74705SXin Li       default:
6651*67e74705SXin Li         break;
6652*67e74705SXin Li       }
6653*67e74705SXin Li     }
6654*67e74705SXin Li   }
6655*67e74705SXin Li 
hasSjLjLowering() const6656*67e74705SXin Li   bool hasSjLjLowering() const override {
6657*67e74705SXin Li     return true;
6658*67e74705SXin Li   }
6659*67e74705SXin Li };
6660*67e74705SXin Li 
6661*67e74705SXin Li // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
6662*67e74705SXin Li class SparcV8elTargetInfo : public SparcV8TargetInfo {
6663*67e74705SXin Li  public:
SparcV8elTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6664*67e74705SXin Li    SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6665*67e74705SXin Li        : SparcV8TargetInfo(Triple, Opts) {
6666*67e74705SXin Li      resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
6667*67e74705SXin Li      BigEndian = false;
6668*67e74705SXin Li   }
6669*67e74705SXin Li };
6670*67e74705SXin Li 
6671*67e74705SXin Li // SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
6672*67e74705SXin Li class SparcV9TargetInfo : public SparcTargetInfo {
6673*67e74705SXin Li public:
SparcV9TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6674*67e74705SXin Li   SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
6675*67e74705SXin Li       : SparcTargetInfo(Triple, Opts) {
6676*67e74705SXin Li     // FIXME: Support Sparc quad-precision long double?
6677*67e74705SXin Li     resetDataLayout("E-m:e-i64:64-n32:64-S128");
6678*67e74705SXin Li     // This is an LP64 platform.
6679*67e74705SXin Li     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
6680*67e74705SXin Li 
6681*67e74705SXin Li     // OpenBSD uses long long for int64_t and intmax_t.
6682*67e74705SXin Li     if (getTriple().getOS() == llvm::Triple::OpenBSD)
6683*67e74705SXin Li       IntMaxType = SignedLongLong;
6684*67e74705SXin Li     else
6685*67e74705SXin Li       IntMaxType = SignedLong;
6686*67e74705SXin Li     Int64Type = IntMaxType;
6687*67e74705SXin Li 
6688*67e74705SXin Li     // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
6689*67e74705SXin Li     // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
6690*67e74705SXin Li     LongDoubleWidth = 128;
6691*67e74705SXin Li     LongDoubleAlign = 128;
6692*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEquad;
6693*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
6694*67e74705SXin Li   }
6695*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6696*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
6697*67e74705SXin Li                         MacroBuilder &Builder) const override {
6698*67e74705SXin Li     SparcTargetInfo::getTargetDefines(Opts, Builder);
6699*67e74705SXin Li     Builder.defineMacro("__sparcv9");
6700*67e74705SXin Li     Builder.defineMacro("__arch64__");
6701*67e74705SXin Li     // Solaris doesn't need these variants, but the BSDs do.
6702*67e74705SXin Li     if (getTriple().getOS() != llvm::Triple::Solaris) {
6703*67e74705SXin Li       Builder.defineMacro("__sparc64__");
6704*67e74705SXin Li       Builder.defineMacro("__sparc_v9__");
6705*67e74705SXin Li       Builder.defineMacro("__sparcv9__");
6706*67e74705SXin Li     }
6707*67e74705SXin Li   }
6708*67e74705SXin Li 
setCPU(const std::string & Name)6709*67e74705SXin Li   bool setCPU(const std::string &Name) override {
6710*67e74705SXin Li     if (!SparcTargetInfo::setCPU(Name))
6711*67e74705SXin Li       return false;
6712*67e74705SXin Li     return getCPUGeneration(CPU) == CG_V9;
6713*67e74705SXin Li   }
6714*67e74705SXin Li };
6715*67e74705SXin Li 
6716*67e74705SXin Li class SystemZTargetInfo : public TargetInfo {
6717*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
6718*67e74705SXin Li   static const char *const GCCRegNames[];
6719*67e74705SXin Li   std::string CPU;
6720*67e74705SXin Li   bool HasTransactionalExecution;
6721*67e74705SXin Li   bool HasVector;
6722*67e74705SXin Li 
6723*67e74705SXin Li public:
SystemZTargetInfo(const llvm::Triple & Triple,const TargetOptions &)6724*67e74705SXin Li   SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
6725*67e74705SXin Li       : TargetInfo(Triple), CPU("z10"), HasTransactionalExecution(false),
6726*67e74705SXin Li         HasVector(false) {
6727*67e74705SXin Li     IntMaxType = SignedLong;
6728*67e74705SXin Li     Int64Type = SignedLong;
6729*67e74705SXin Li     TLSSupported = true;
6730*67e74705SXin Li     IntWidth = IntAlign = 32;
6731*67e74705SXin Li     LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
6732*67e74705SXin Li     PointerWidth = PointerAlign = 64;
6733*67e74705SXin Li     LongDoubleWidth = 128;
6734*67e74705SXin Li     LongDoubleAlign = 64;
6735*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEquad;
6736*67e74705SXin Li     DefaultAlignForAttributeAligned = 64;
6737*67e74705SXin Li     MinGlobalAlign = 16;
6738*67e74705SXin Li     resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64");
6739*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
6740*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6741*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
6742*67e74705SXin Li                         MacroBuilder &Builder) const override {
6743*67e74705SXin Li     Builder.defineMacro("__s390__");
6744*67e74705SXin Li     Builder.defineMacro("__s390x__");
6745*67e74705SXin Li     Builder.defineMacro("__zarch__");
6746*67e74705SXin Li     Builder.defineMacro("__LONG_DOUBLE_128__");
6747*67e74705SXin Li 
6748*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
6749*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
6750*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
6751*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
6752*67e74705SXin Li 
6753*67e74705SXin Li     if (HasTransactionalExecution)
6754*67e74705SXin Li       Builder.defineMacro("__HTM__");
6755*67e74705SXin Li     if (Opts.ZVector)
6756*67e74705SXin Li       Builder.defineMacro("__VEC__", "10301");
6757*67e74705SXin Li   }
getTargetBuiltins() const6758*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
6759*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
6760*67e74705SXin Li                          clang::SystemZ::LastTSBuiltin-Builtin::FirstTSBuiltin);
6761*67e74705SXin Li   }
6762*67e74705SXin Li 
6763*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
getGCCRegAliases() const6764*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
6765*67e74705SXin Li     // No aliases.
6766*67e74705SXin Li     return None;
6767*67e74705SXin Li   }
6768*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
6769*67e74705SXin Li                              TargetInfo::ConstraintInfo &info) const override;
getClobbers() const6770*67e74705SXin Li   const char *getClobbers() const override {
6771*67e74705SXin Li     // FIXME: Is this really right?
6772*67e74705SXin Li     return "";
6773*67e74705SXin Li   }
getBuiltinVaListKind() const6774*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
6775*67e74705SXin Li     return TargetInfo::SystemZBuiltinVaList;
6776*67e74705SXin Li   }
setCPU(const std::string & Name)6777*67e74705SXin Li   bool setCPU(const std::string &Name) override {
6778*67e74705SXin Li     CPU = Name;
6779*67e74705SXin Li     bool CPUKnown = llvm::StringSwitch<bool>(Name)
6780*67e74705SXin Li       .Case("z10", true)
6781*67e74705SXin Li       .Case("z196", true)
6782*67e74705SXin Li       .Case("zEC12", true)
6783*67e74705SXin Li       .Case("z13", true)
6784*67e74705SXin Li       .Default(false);
6785*67e74705SXin Li 
6786*67e74705SXin Li     return CPUKnown;
6787*67e74705SXin Li   }
6788*67e74705SXin Li   bool
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const6789*67e74705SXin Li   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
6790*67e74705SXin Li                  StringRef CPU,
6791*67e74705SXin Li                  const std::vector<std::string> &FeaturesVec) const override {
6792*67e74705SXin Li     if (CPU == "zEC12")
6793*67e74705SXin Li       Features["transactional-execution"] = true;
6794*67e74705SXin Li     if (CPU == "z13") {
6795*67e74705SXin Li       Features["transactional-execution"] = true;
6796*67e74705SXin Li       Features["vector"] = true;
6797*67e74705SXin Li     }
6798*67e74705SXin Li     return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
6799*67e74705SXin Li   }
6800*67e74705SXin Li 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)6801*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
6802*67e74705SXin Li                             DiagnosticsEngine &Diags) override {
6803*67e74705SXin Li     HasTransactionalExecution = false;
6804*67e74705SXin Li     for (const auto &Feature : Features) {
6805*67e74705SXin Li       if (Feature == "+transactional-execution")
6806*67e74705SXin Li         HasTransactionalExecution = true;
6807*67e74705SXin Li       else if (Feature == "+vector")
6808*67e74705SXin Li         HasVector = true;
6809*67e74705SXin Li     }
6810*67e74705SXin Li     // If we use the vector ABI, vector types are 64-bit aligned.
6811*67e74705SXin Li     if (HasVector) {
6812*67e74705SXin Li       MaxVectorAlign = 64;
6813*67e74705SXin Li       resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64"
6814*67e74705SXin Li                       "-v128:64-a:8:16-n32:64");
6815*67e74705SXin Li     }
6816*67e74705SXin Li     return true;
6817*67e74705SXin Li   }
6818*67e74705SXin Li 
hasFeature(StringRef Feature) const6819*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
6820*67e74705SXin Li     return llvm::StringSwitch<bool>(Feature)
6821*67e74705SXin Li         .Case("systemz", true)
6822*67e74705SXin Li         .Case("htm", HasTransactionalExecution)
6823*67e74705SXin Li         .Case("vx", HasVector)
6824*67e74705SXin Li         .Default(false);
6825*67e74705SXin Li   }
6826*67e74705SXin Li 
checkCallingConvention(CallingConv CC) const6827*67e74705SXin Li   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
6828*67e74705SXin Li     switch (CC) {
6829*67e74705SXin Li     case CC_C:
6830*67e74705SXin Li     case CC_Swift:
6831*67e74705SXin Li       return CCCR_OK;
6832*67e74705SXin Li     default:
6833*67e74705SXin Li       return CCCR_Warning;
6834*67e74705SXin Li     }
6835*67e74705SXin Li   }
6836*67e74705SXin Li 
getABI() const6837*67e74705SXin Li   StringRef getABI() const override {
6838*67e74705SXin Li     if (HasVector)
6839*67e74705SXin Li       return "vector";
6840*67e74705SXin Li     return "";
6841*67e74705SXin Li   }
6842*67e74705SXin Li 
useFloat128ManglingForLongDouble() const6843*67e74705SXin Li   bool useFloat128ManglingForLongDouble() const override {
6844*67e74705SXin Li     return true;
6845*67e74705SXin Li   }
6846*67e74705SXin Li };
6847*67e74705SXin Li 
6848*67e74705SXin Li const Builtin::Info SystemZTargetInfo::BuiltinInfo[] = {
6849*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS)                                               \
6850*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
6851*67e74705SXin Li #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
6852*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE },
6853*67e74705SXin Li #include "clang/Basic/BuiltinsSystemZ.def"
6854*67e74705SXin Li };
6855*67e74705SXin Li 
6856*67e74705SXin Li const char *const SystemZTargetInfo::GCCRegNames[] = {
6857*67e74705SXin Li   "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
6858*67e74705SXin Li   "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
6859*67e74705SXin Li   "f0",  "f2",  "f4",  "f6",  "f1",  "f3",  "f5",  "f7",
6860*67e74705SXin Li   "f8",  "f10", "f12", "f14", "f9",  "f11", "f13", "f15"
6861*67e74705SXin Li };
6862*67e74705SXin Li 
getGCCRegNames() const6863*67e74705SXin Li ArrayRef<const char *> SystemZTargetInfo::getGCCRegNames() const {
6864*67e74705SXin Li   return llvm::makeArrayRef(GCCRegNames);
6865*67e74705SXin Li }
6866*67e74705SXin Li 
6867*67e74705SXin Li bool SystemZTargetInfo::
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const6868*67e74705SXin Li validateAsmConstraint(const char *&Name,
6869*67e74705SXin Li                       TargetInfo::ConstraintInfo &Info) const {
6870*67e74705SXin Li   switch (*Name) {
6871*67e74705SXin Li   default:
6872*67e74705SXin Li     return false;
6873*67e74705SXin Li 
6874*67e74705SXin Li   case 'a': // Address register
6875*67e74705SXin Li   case 'd': // Data register (equivalent to 'r')
6876*67e74705SXin Li   case 'f': // Floating-point register
6877*67e74705SXin Li     Info.setAllowsRegister();
6878*67e74705SXin Li     return true;
6879*67e74705SXin Li 
6880*67e74705SXin Li   case 'I': // Unsigned 8-bit constant
6881*67e74705SXin Li   case 'J': // Unsigned 12-bit constant
6882*67e74705SXin Li   case 'K': // Signed 16-bit constant
6883*67e74705SXin Li   case 'L': // Signed 20-bit displacement (on all targets we support)
6884*67e74705SXin Li   case 'M': // 0x7fffffff
6885*67e74705SXin Li     return true;
6886*67e74705SXin Li 
6887*67e74705SXin Li   case 'Q': // Memory with base and unsigned 12-bit displacement
6888*67e74705SXin Li   case 'R': // Likewise, plus an index
6889*67e74705SXin Li   case 'S': // Memory with base and signed 20-bit displacement
6890*67e74705SXin Li   case 'T': // Likewise, plus an index
6891*67e74705SXin Li     Info.setAllowsMemory();
6892*67e74705SXin Li     return true;
6893*67e74705SXin Li   }
6894*67e74705SXin Li }
6895*67e74705SXin Li 
6896*67e74705SXin Li class MSP430TargetInfo : public TargetInfo {
6897*67e74705SXin Li   static const char *const GCCRegNames[];
6898*67e74705SXin Li 
6899*67e74705SXin Li public:
MSP430TargetInfo(const llvm::Triple & Triple,const TargetOptions &)6900*67e74705SXin Li   MSP430TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
6901*67e74705SXin Li       : TargetInfo(Triple) {
6902*67e74705SXin Li     BigEndian = false;
6903*67e74705SXin Li     TLSSupported = false;
6904*67e74705SXin Li     IntWidth = 16;
6905*67e74705SXin Li     IntAlign = 16;
6906*67e74705SXin Li     LongWidth = 32;
6907*67e74705SXin Li     LongLongWidth = 64;
6908*67e74705SXin Li     LongAlign = LongLongAlign = 16;
6909*67e74705SXin Li     PointerWidth = 16;
6910*67e74705SXin Li     PointerAlign = 16;
6911*67e74705SXin Li     SuitableAlign = 16;
6912*67e74705SXin Li     SizeType = UnsignedInt;
6913*67e74705SXin Li     IntMaxType = SignedLongLong;
6914*67e74705SXin Li     IntPtrType = SignedInt;
6915*67e74705SXin Li     PtrDiffType = SignedInt;
6916*67e74705SXin Li     SigAtomicType = SignedLong;
6917*67e74705SXin Li     resetDataLayout("e-m:e-p:16:16-i32:16:32-a:16-n8:16");
6918*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const6919*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
6920*67e74705SXin Li                         MacroBuilder &Builder) const override {
6921*67e74705SXin Li     Builder.defineMacro("MSP430");
6922*67e74705SXin Li     Builder.defineMacro("__MSP430__");
6923*67e74705SXin Li     // FIXME: defines for different 'flavours' of MCU
6924*67e74705SXin Li   }
getTargetBuiltins() const6925*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
6926*67e74705SXin Li     // FIXME: Implement.
6927*67e74705SXin Li     return None;
6928*67e74705SXin Li   }
hasFeature(StringRef Feature) const6929*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
6930*67e74705SXin Li     return Feature == "msp430";
6931*67e74705SXin Li   }
6932*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
getGCCRegAliases() const6933*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
6934*67e74705SXin Li     // No aliases.
6935*67e74705SXin Li     return None;
6936*67e74705SXin Li   }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const6937*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
6938*67e74705SXin Li                              TargetInfo::ConstraintInfo &info) const override {
6939*67e74705SXin Li     // FIXME: implement
6940*67e74705SXin Li     switch (*Name) {
6941*67e74705SXin Li     case 'K': // the constant 1
6942*67e74705SXin Li     case 'L': // constant -1^20 .. 1^19
6943*67e74705SXin Li     case 'M': // constant 1-4:
6944*67e74705SXin Li       return true;
6945*67e74705SXin Li     }
6946*67e74705SXin Li     // No target constraints for now.
6947*67e74705SXin Li     return false;
6948*67e74705SXin Li   }
getClobbers() const6949*67e74705SXin Li   const char *getClobbers() const override {
6950*67e74705SXin Li     // FIXME: Is this really right?
6951*67e74705SXin Li     return "";
6952*67e74705SXin Li   }
getBuiltinVaListKind() const6953*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
6954*67e74705SXin Li     // FIXME: implement
6955*67e74705SXin Li     return TargetInfo::CharPtrBuiltinVaList;
6956*67e74705SXin Li   }
6957*67e74705SXin Li };
6958*67e74705SXin Li 
6959*67e74705SXin Li const char *const MSP430TargetInfo::GCCRegNames[] = {
6960*67e74705SXin Li     "r0", "r1", "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
6961*67e74705SXin Li     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"};
6962*67e74705SXin Li 
getGCCRegNames() const6963*67e74705SXin Li ArrayRef<const char *> MSP430TargetInfo::getGCCRegNames() const {
6964*67e74705SXin Li   return llvm::makeArrayRef(GCCRegNames);
6965*67e74705SXin Li }
6966*67e74705SXin Li 
6967*67e74705SXin Li // LLVM and Clang cannot be used directly to output native binaries for
6968*67e74705SXin Li // target, but is used to compile C code to llvm bitcode with correct
6969*67e74705SXin Li // type and alignment information.
6970*67e74705SXin Li //
6971*67e74705SXin Li // TCE uses the llvm bitcode as input and uses it for generating customized
6972*67e74705SXin Li // target processor and program binary. TCE co-design environment is
6973*67e74705SXin Li // publicly available in http://tce.cs.tut.fi
6974*67e74705SXin Li 
6975*67e74705SXin Li static const unsigned TCEOpenCLAddrSpaceMap[] = {
6976*67e74705SXin Li     3, // opencl_global
6977*67e74705SXin Li     4, // opencl_local
6978*67e74705SXin Li     5, // opencl_constant
6979*67e74705SXin Li     // FIXME: generic has to be added to the target
6980*67e74705SXin Li     0, // opencl_generic
6981*67e74705SXin Li     0, // cuda_device
6982*67e74705SXin Li     0, // cuda_constant
6983*67e74705SXin Li     0  // cuda_shared
6984*67e74705SXin Li };
6985*67e74705SXin Li 
6986*67e74705SXin Li class TCETargetInfo : public TargetInfo {
6987*67e74705SXin Li public:
TCETargetInfo(const llvm::Triple & Triple,const TargetOptions &)6988*67e74705SXin Li   TCETargetInfo(const llvm::Triple &Triple, const TargetOptions &)
6989*67e74705SXin Li       : TargetInfo(Triple) {
6990*67e74705SXin Li     TLSSupported = false;
6991*67e74705SXin Li     IntWidth = 32;
6992*67e74705SXin Li     LongWidth = LongLongWidth = 32;
6993*67e74705SXin Li     PointerWidth = 32;
6994*67e74705SXin Li     IntAlign = 32;
6995*67e74705SXin Li     LongAlign = LongLongAlign = 32;
6996*67e74705SXin Li     PointerAlign = 32;
6997*67e74705SXin Li     SuitableAlign = 32;
6998*67e74705SXin Li     SizeType = UnsignedInt;
6999*67e74705SXin Li     IntMaxType = SignedLong;
7000*67e74705SXin Li     IntPtrType = SignedInt;
7001*67e74705SXin Li     PtrDiffType = SignedInt;
7002*67e74705SXin Li     FloatWidth = 32;
7003*67e74705SXin Li     FloatAlign = 32;
7004*67e74705SXin Li     DoubleWidth = 32;
7005*67e74705SXin Li     DoubleAlign = 32;
7006*67e74705SXin Li     LongDoubleWidth = 32;
7007*67e74705SXin Li     LongDoubleAlign = 32;
7008*67e74705SXin Li     FloatFormat = &llvm::APFloat::IEEEsingle;
7009*67e74705SXin Li     DoubleFormat = &llvm::APFloat::IEEEsingle;
7010*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEsingle;
7011*67e74705SXin Li     resetDataLayout("E-p:32:32-i8:8:32-i16:16:32-i64:32"
7012*67e74705SXin Li                     "-f64:32-v64:32-v128:32-a:0:32-n32");
7013*67e74705SXin Li     AddrSpaceMap = &TCEOpenCLAddrSpaceMap;
7014*67e74705SXin Li     UseAddrSpaceMapMangling = true;
7015*67e74705SXin Li   }
7016*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7017*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7018*67e74705SXin Li                         MacroBuilder &Builder) const override {
7019*67e74705SXin Li     DefineStd(Builder, "tce", Opts);
7020*67e74705SXin Li     Builder.defineMacro("__TCE__");
7021*67e74705SXin Li     Builder.defineMacro("__TCE_V1__");
7022*67e74705SXin Li   }
hasFeature(StringRef Feature) const7023*67e74705SXin Li   bool hasFeature(StringRef Feature) const override { return Feature == "tce"; }
7024*67e74705SXin Li 
getTargetBuiltins() const7025*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
getClobbers() const7026*67e74705SXin Li   const char *getClobbers() const override { return ""; }
getBuiltinVaListKind() const7027*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
7028*67e74705SXin Li     return TargetInfo::VoidPtrBuiltinVaList;
7029*67e74705SXin Li   }
getGCCRegNames() const7030*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override { return None; }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const7031*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
7032*67e74705SXin Li                              TargetInfo::ConstraintInfo &info) const override {
7033*67e74705SXin Li     return true;
7034*67e74705SXin Li   }
getGCCRegAliases() const7035*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
7036*67e74705SXin Li     return None;
7037*67e74705SXin Li   }
7038*67e74705SXin Li };
7039*67e74705SXin Li 
7040*67e74705SXin Li class BPFTargetInfo : public TargetInfo {
7041*67e74705SXin Li public:
BPFTargetInfo(const llvm::Triple & Triple,const TargetOptions &)7042*67e74705SXin Li   BPFTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
7043*67e74705SXin Li       : TargetInfo(Triple) {
7044*67e74705SXin Li     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
7045*67e74705SXin Li     SizeType    = UnsignedLong;
7046*67e74705SXin Li     PtrDiffType = SignedLong;
7047*67e74705SXin Li     IntPtrType  = SignedLong;
7048*67e74705SXin Li     IntMaxType  = SignedLong;
7049*67e74705SXin Li     Int64Type   = SignedLong;
7050*67e74705SXin Li     RegParmMax = 5;
7051*67e74705SXin Li     if (Triple.getArch() == llvm::Triple::bpfeb) {
7052*67e74705SXin Li       BigEndian = true;
7053*67e74705SXin Li       resetDataLayout("E-m:e-p:64:64-i64:64-n32:64-S128");
7054*67e74705SXin Li     } else {
7055*67e74705SXin Li       BigEndian = false;
7056*67e74705SXin Li       resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128");
7057*67e74705SXin Li     }
7058*67e74705SXin Li     MaxAtomicPromoteWidth = 64;
7059*67e74705SXin Li     MaxAtomicInlineWidth = 64;
7060*67e74705SXin Li     TLSSupported = false;
7061*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7062*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7063*67e74705SXin Li                         MacroBuilder &Builder) const override {
7064*67e74705SXin Li     DefineStd(Builder, "bpf", Opts);
7065*67e74705SXin Li     Builder.defineMacro("__BPF__");
7066*67e74705SXin Li   }
hasFeature(StringRef Feature) const7067*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
7068*67e74705SXin Li     return Feature == "bpf";
7069*67e74705SXin Li   }
7070*67e74705SXin Li 
getTargetBuiltins() const7071*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
getClobbers() const7072*67e74705SXin Li   const char *getClobbers() const override {
7073*67e74705SXin Li     return "";
7074*67e74705SXin Li   }
getBuiltinVaListKind() const7075*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
7076*67e74705SXin Li     return TargetInfo::VoidPtrBuiltinVaList;
7077*67e74705SXin Li   }
getGCCRegNames() const7078*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override {
7079*67e74705SXin Li     return None;
7080*67e74705SXin Li   }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const7081*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
7082*67e74705SXin Li                              TargetInfo::ConstraintInfo &info) const override {
7083*67e74705SXin Li     return true;
7084*67e74705SXin Li   }
getGCCRegAliases() const7085*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
7086*67e74705SXin Li     return None;
7087*67e74705SXin Li   }
7088*67e74705SXin Li };
7089*67e74705SXin Li 
7090*67e74705SXin Li class MipsTargetInfo : public TargetInfo {
setDataLayout()7091*67e74705SXin Li   void setDataLayout() {
7092*67e74705SXin Li     StringRef Layout;
7093*67e74705SXin Li 
7094*67e74705SXin Li     if (ABI == "o32")
7095*67e74705SXin Li       Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
7096*67e74705SXin Li     else if (ABI == "n32")
7097*67e74705SXin Li       Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
7098*67e74705SXin Li     else if (ABI == "n64")
7099*67e74705SXin Li       Layout = "m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128";
7100*67e74705SXin Li     else
7101*67e74705SXin Li       llvm_unreachable("Invalid ABI");
7102*67e74705SXin Li 
7103*67e74705SXin Li     if (BigEndian)
7104*67e74705SXin Li       resetDataLayout(("E-" + Layout).str());
7105*67e74705SXin Li     else
7106*67e74705SXin Li       resetDataLayout(("e-" + Layout).str());
7107*67e74705SXin Li   }
7108*67e74705SXin Li 
7109*67e74705SXin Li 
7110*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
7111*67e74705SXin Li   std::string CPU;
7112*67e74705SXin Li   bool IsMips16;
7113*67e74705SXin Li   bool IsMicromips;
7114*67e74705SXin Li   bool IsNan2008;
7115*67e74705SXin Li   bool IsSingleFloat;
7116*67e74705SXin Li   enum MipsFloatABI {
7117*67e74705SXin Li     HardFloat, SoftFloat
7118*67e74705SXin Li   } FloatABI;
7119*67e74705SXin Li   enum DspRevEnum {
7120*67e74705SXin Li     NoDSP, DSP1, DSP2
7121*67e74705SXin Li   } DspRev;
7122*67e74705SXin Li   bool HasMSA;
7123*67e74705SXin Li 
7124*67e74705SXin Li protected:
7125*67e74705SXin Li   bool HasFP64;
7126*67e74705SXin Li   std::string ABI;
7127*67e74705SXin Li 
7128*67e74705SXin Li public:
MipsTargetInfo(const llvm::Triple & Triple,const TargetOptions &)7129*67e74705SXin Li   MipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
7130*67e74705SXin Li       : TargetInfo(Triple), IsMips16(false), IsMicromips(false),
7131*67e74705SXin Li         IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat),
7132*67e74705SXin Li         DspRev(NoDSP), HasMSA(false), HasFP64(false) {
7133*67e74705SXin Li     TheCXXABI.set(TargetCXXABI::GenericMIPS);
7134*67e74705SXin Li     BigEndian = getTriple().getArch() == llvm::Triple::mips ||
7135*67e74705SXin Li                 getTriple().getArch() == llvm::Triple::mips64;
7136*67e74705SXin Li 
7137*67e74705SXin Li     setABI((getTriple().getArch() == llvm::Triple::mips ||
7138*67e74705SXin Li             getTriple().getArch() == llvm::Triple::mipsel)
7139*67e74705SXin Li                ? "o32"
7140*67e74705SXin Li                : "n64");
7141*67e74705SXin Li 
7142*67e74705SXin Li     CPU = ABI == "o32" ? "mips32r2" : "mips64r2";
7143*67e74705SXin Li   }
7144*67e74705SXin Li 
isNaN2008Default() const7145*67e74705SXin Li   bool isNaN2008Default() const {
7146*67e74705SXin Li     return CPU == "mips32r6" || CPU == "mips64r6";
7147*67e74705SXin Li   }
7148*67e74705SXin Li 
isFP64Default() const7149*67e74705SXin Li   bool isFP64Default() const {
7150*67e74705SXin Li     return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64";
7151*67e74705SXin Li   }
7152*67e74705SXin Li 
isNan2008() const7153*67e74705SXin Li   bool isNan2008() const override {
7154*67e74705SXin Li     return IsNan2008;
7155*67e74705SXin Li   }
7156*67e74705SXin Li 
processorSupportsGPR64() const7157*67e74705SXin Li   bool processorSupportsGPR64() const {
7158*67e74705SXin Li     return llvm::StringSwitch<bool>(CPU)
7159*67e74705SXin Li         .Case("mips3", true)
7160*67e74705SXin Li         .Case("mips4", true)
7161*67e74705SXin Li         .Case("mips5", true)
7162*67e74705SXin Li         .Case("mips64", true)
7163*67e74705SXin Li         .Case("mips64r2", true)
7164*67e74705SXin Li         .Case("mips64r3", true)
7165*67e74705SXin Li         .Case("mips64r5", true)
7166*67e74705SXin Li         .Case("mips64r6", true)
7167*67e74705SXin Li         .Case("octeon", true)
7168*67e74705SXin Li         .Default(false);
7169*67e74705SXin Li     return false;
7170*67e74705SXin Li   }
7171*67e74705SXin Li 
getABI() const7172*67e74705SXin Li   StringRef getABI() const override { return ABI; }
setABI(const std::string & Name)7173*67e74705SXin Li   bool setABI(const std::string &Name) override {
7174*67e74705SXin Li     if (Name == "o32") {
7175*67e74705SXin Li       setO32ABITypes();
7176*67e74705SXin Li       ABI = Name;
7177*67e74705SXin Li       return true;
7178*67e74705SXin Li     }
7179*67e74705SXin Li 
7180*67e74705SXin Li     if (Name == "n32") {
7181*67e74705SXin Li       setN32ABITypes();
7182*67e74705SXin Li       ABI = Name;
7183*67e74705SXin Li       return true;
7184*67e74705SXin Li     }
7185*67e74705SXin Li     if (Name == "n64") {
7186*67e74705SXin Li       setN64ABITypes();
7187*67e74705SXin Li       ABI = Name;
7188*67e74705SXin Li       return true;
7189*67e74705SXin Li     }
7190*67e74705SXin Li     return false;
7191*67e74705SXin Li   }
7192*67e74705SXin Li 
setO32ABITypes()7193*67e74705SXin Li   void setO32ABITypes() {
7194*67e74705SXin Li     Int64Type = SignedLongLong;
7195*67e74705SXin Li     IntMaxType = Int64Type;
7196*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
7197*67e74705SXin Li     LongDoubleWidth = LongDoubleAlign = 64;
7198*67e74705SXin Li     LongWidth = LongAlign = 32;
7199*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
7200*67e74705SXin Li     PointerWidth = PointerAlign = 32;
7201*67e74705SXin Li     PtrDiffType = SignedInt;
7202*67e74705SXin Li     SizeType = UnsignedInt;
7203*67e74705SXin Li     SuitableAlign = 64;
7204*67e74705SXin Li   }
7205*67e74705SXin Li 
setN32N64ABITypes()7206*67e74705SXin Li   void setN32N64ABITypes() {
7207*67e74705SXin Li     LongDoubleWidth = LongDoubleAlign = 128;
7208*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEquad;
7209*67e74705SXin Li     if (getTriple().getOS() == llvm::Triple::FreeBSD) {
7210*67e74705SXin Li       LongDoubleWidth = LongDoubleAlign = 64;
7211*67e74705SXin Li       LongDoubleFormat = &llvm::APFloat::IEEEdouble;
7212*67e74705SXin Li     }
7213*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
7214*67e74705SXin Li     SuitableAlign = 128;
7215*67e74705SXin Li   }
7216*67e74705SXin Li 
setN64ABITypes()7217*67e74705SXin Li   void setN64ABITypes() {
7218*67e74705SXin Li     setN32N64ABITypes();
7219*67e74705SXin Li     Int64Type = SignedLong;
7220*67e74705SXin Li     IntMaxType = Int64Type;
7221*67e74705SXin Li     LongWidth = LongAlign = 64;
7222*67e74705SXin Li     PointerWidth = PointerAlign = 64;
7223*67e74705SXin Li     PtrDiffType = SignedLong;
7224*67e74705SXin Li     SizeType = UnsignedLong;
7225*67e74705SXin Li   }
7226*67e74705SXin Li 
setN32ABITypes()7227*67e74705SXin Li   void setN32ABITypes() {
7228*67e74705SXin Li     setN32N64ABITypes();
7229*67e74705SXin Li     Int64Type = SignedLongLong;
7230*67e74705SXin Li     IntMaxType = Int64Type;
7231*67e74705SXin Li     LongWidth = LongAlign = 32;
7232*67e74705SXin Li     PointerWidth = PointerAlign = 32;
7233*67e74705SXin Li     PtrDiffType = SignedInt;
7234*67e74705SXin Li     SizeType = UnsignedInt;
7235*67e74705SXin Li   }
7236*67e74705SXin Li 
setCPU(const std::string & Name)7237*67e74705SXin Li   bool setCPU(const std::string &Name) override {
7238*67e74705SXin Li     CPU = Name;
7239*67e74705SXin Li     return llvm::StringSwitch<bool>(Name)
7240*67e74705SXin Li         .Case("mips1", true)
7241*67e74705SXin Li         .Case("mips2", true)
7242*67e74705SXin Li         .Case("mips3", true)
7243*67e74705SXin Li         .Case("mips4", true)
7244*67e74705SXin Li         .Case("mips5", true)
7245*67e74705SXin Li         .Case("mips32", true)
7246*67e74705SXin Li         .Case("mips32r2", true)
7247*67e74705SXin Li         .Case("mips32r3", true)
7248*67e74705SXin Li         .Case("mips32r5", true)
7249*67e74705SXin Li         .Case("mips32r6", true)
7250*67e74705SXin Li         .Case("mips64", true)
7251*67e74705SXin Li         .Case("mips64r2", true)
7252*67e74705SXin Li         .Case("mips64r3", true)
7253*67e74705SXin Li         .Case("mips64r5", true)
7254*67e74705SXin Li         .Case("mips64r6", true)
7255*67e74705SXin Li         .Case("octeon", true)
7256*67e74705SXin Li         .Case("p5600", true)
7257*67e74705SXin Li         .Default(false);
7258*67e74705SXin Li   }
getCPU() const7259*67e74705SXin Li   const std::string& getCPU() const { return CPU; }
7260*67e74705SXin Li   bool
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const7261*67e74705SXin Li   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
7262*67e74705SXin Li                  StringRef CPU,
7263*67e74705SXin Li                  const std::vector<std::string> &FeaturesVec) const override {
7264*67e74705SXin Li     if (CPU.empty())
7265*67e74705SXin Li       CPU = getCPU();
7266*67e74705SXin Li     if (CPU == "octeon")
7267*67e74705SXin Li       Features["mips64r2"] = Features["cnmips"] = true;
7268*67e74705SXin Li     else
7269*67e74705SXin Li       Features[CPU] = true;
7270*67e74705SXin Li     return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
7271*67e74705SXin Li   }
7272*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7273*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7274*67e74705SXin Li                         MacroBuilder &Builder) const override {
7275*67e74705SXin Li     if (BigEndian) {
7276*67e74705SXin Li       DefineStd(Builder, "MIPSEB", Opts);
7277*67e74705SXin Li       Builder.defineMacro("_MIPSEB");
7278*67e74705SXin Li     } else {
7279*67e74705SXin Li       DefineStd(Builder, "MIPSEL", Opts);
7280*67e74705SXin Li       Builder.defineMacro("_MIPSEL");
7281*67e74705SXin Li     }
7282*67e74705SXin Li 
7283*67e74705SXin Li     Builder.defineMacro("__mips__");
7284*67e74705SXin Li     Builder.defineMacro("_mips");
7285*67e74705SXin Li     if (Opts.GNUMode)
7286*67e74705SXin Li       Builder.defineMacro("mips");
7287*67e74705SXin Li 
7288*67e74705SXin Li     if (ABI == "o32") {
7289*67e74705SXin Li       Builder.defineMacro("__mips", "32");
7290*67e74705SXin Li       Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");
7291*67e74705SXin Li     } else {
7292*67e74705SXin Li       Builder.defineMacro("__mips", "64");
7293*67e74705SXin Li       Builder.defineMacro("__mips64");
7294*67e74705SXin Li       Builder.defineMacro("__mips64__");
7295*67e74705SXin Li       Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");
7296*67e74705SXin Li     }
7297*67e74705SXin Li 
7298*67e74705SXin Li     const std::string ISARev = llvm::StringSwitch<std::string>(getCPU())
7299*67e74705SXin Li                                    .Cases("mips32", "mips64", "1")
7300*67e74705SXin Li                                    .Cases("mips32r2", "mips64r2", "2")
7301*67e74705SXin Li                                    .Cases("mips32r3", "mips64r3", "3")
7302*67e74705SXin Li                                    .Cases("mips32r5", "mips64r5", "5")
7303*67e74705SXin Li                                    .Cases("mips32r6", "mips64r6", "6")
7304*67e74705SXin Li                                    .Default("");
7305*67e74705SXin Li     if (!ISARev.empty())
7306*67e74705SXin Li       Builder.defineMacro("__mips_isa_rev", ISARev);
7307*67e74705SXin Li 
7308*67e74705SXin Li     if (ABI == "o32") {
7309*67e74705SXin Li       Builder.defineMacro("__mips_o32");
7310*67e74705SXin Li       Builder.defineMacro("_ABIO32", "1");
7311*67e74705SXin Li       Builder.defineMacro("_MIPS_SIM", "_ABIO32");
7312*67e74705SXin Li     } else if (ABI == "n32") {
7313*67e74705SXin Li       Builder.defineMacro("__mips_n32");
7314*67e74705SXin Li       Builder.defineMacro("_ABIN32", "2");
7315*67e74705SXin Li       Builder.defineMacro("_MIPS_SIM", "_ABIN32");
7316*67e74705SXin Li     } else if (ABI == "n64") {
7317*67e74705SXin Li       Builder.defineMacro("__mips_n64");
7318*67e74705SXin Li       Builder.defineMacro("_ABI64", "3");
7319*67e74705SXin Li       Builder.defineMacro("_MIPS_SIM", "_ABI64");
7320*67e74705SXin Li     } else
7321*67e74705SXin Li       llvm_unreachable("Invalid ABI.");
7322*67e74705SXin Li 
7323*67e74705SXin Li     Builder.defineMacro("__REGISTER_PREFIX__", "");
7324*67e74705SXin Li 
7325*67e74705SXin Li     switch (FloatABI) {
7326*67e74705SXin Li     case HardFloat:
7327*67e74705SXin Li       Builder.defineMacro("__mips_hard_float", Twine(1));
7328*67e74705SXin Li       break;
7329*67e74705SXin Li     case SoftFloat:
7330*67e74705SXin Li       Builder.defineMacro("__mips_soft_float", Twine(1));
7331*67e74705SXin Li       break;
7332*67e74705SXin Li     }
7333*67e74705SXin Li 
7334*67e74705SXin Li     if (IsSingleFloat)
7335*67e74705SXin Li       Builder.defineMacro("__mips_single_float", Twine(1));
7336*67e74705SXin Li 
7337*67e74705SXin Li     Builder.defineMacro("__mips_fpr", HasFP64 ? Twine(64) : Twine(32));
7338*67e74705SXin Li     Builder.defineMacro("_MIPS_FPSET",
7339*67e74705SXin Li                         Twine(32 / (HasFP64 || IsSingleFloat ? 1 : 2)));
7340*67e74705SXin Li 
7341*67e74705SXin Li     if (IsMips16)
7342*67e74705SXin Li       Builder.defineMacro("__mips16", Twine(1));
7343*67e74705SXin Li 
7344*67e74705SXin Li     if (IsMicromips)
7345*67e74705SXin Li       Builder.defineMacro("__mips_micromips", Twine(1));
7346*67e74705SXin Li 
7347*67e74705SXin Li     if (IsNan2008)
7348*67e74705SXin Li       Builder.defineMacro("__mips_nan2008", Twine(1));
7349*67e74705SXin Li 
7350*67e74705SXin Li     switch (DspRev) {
7351*67e74705SXin Li     default:
7352*67e74705SXin Li       break;
7353*67e74705SXin Li     case DSP1:
7354*67e74705SXin Li       Builder.defineMacro("__mips_dsp_rev", Twine(1));
7355*67e74705SXin Li       Builder.defineMacro("__mips_dsp", Twine(1));
7356*67e74705SXin Li       break;
7357*67e74705SXin Li     case DSP2:
7358*67e74705SXin Li       Builder.defineMacro("__mips_dsp_rev", Twine(2));
7359*67e74705SXin Li       Builder.defineMacro("__mips_dspr2", Twine(1));
7360*67e74705SXin Li       Builder.defineMacro("__mips_dsp", Twine(1));
7361*67e74705SXin Li       break;
7362*67e74705SXin Li     }
7363*67e74705SXin Li 
7364*67e74705SXin Li     if (HasMSA)
7365*67e74705SXin Li       Builder.defineMacro("__mips_msa", Twine(1));
7366*67e74705SXin Li 
7367*67e74705SXin Li     Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
7368*67e74705SXin Li     Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
7369*67e74705SXin Li     Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
7370*67e74705SXin Li 
7371*67e74705SXin Li     Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");
7372*67e74705SXin Li     Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
7373*67e74705SXin Li 
7374*67e74705SXin Li     // These shouldn't be defined for MIPS-I but there's no need to check
7375*67e74705SXin Li     // for that since MIPS-I isn't supported.
7376*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
7377*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
7378*67e74705SXin Li     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
7379*67e74705SXin Li 
7380*67e74705SXin Li     // 32-bit MIPS processors don't have the necessary lld/scd instructions
7381*67e74705SXin Li     // found in 64-bit processors. In the case of O32 on a 64-bit processor,
7382*67e74705SXin Li     // the instructions exist but using them violates the ABI since they
7383*67e74705SXin Li     // require 64-bit GPRs and O32 only supports 32-bit GPRs.
7384*67e74705SXin Li     if (ABI == "n32" || ABI == "n64")
7385*67e74705SXin Li       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
7386*67e74705SXin Li   }
7387*67e74705SXin Li 
getTargetBuiltins() const7388*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
7389*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
7390*67e74705SXin Li                           clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin);
7391*67e74705SXin Li   }
hasFeature(StringRef Feature) const7392*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
7393*67e74705SXin Li     return llvm::StringSwitch<bool>(Feature)
7394*67e74705SXin Li       .Case("mips", true)
7395*67e74705SXin Li       .Case("fp64", HasFP64)
7396*67e74705SXin Li       .Default(false);
7397*67e74705SXin Li   }
getBuiltinVaListKind() const7398*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
7399*67e74705SXin Li     return TargetInfo::VoidPtrBuiltinVaList;
7400*67e74705SXin Li   }
getGCCRegNames() const7401*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override {
7402*67e74705SXin Li     static const char *const GCCRegNames[] = {
7403*67e74705SXin Li       // CPU register names
7404*67e74705SXin Li       // Must match second column of GCCRegAliases
7405*67e74705SXin Li       "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
7406*67e74705SXin Li       "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
7407*67e74705SXin Li       "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
7408*67e74705SXin Li       "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31",
7409*67e74705SXin Li       // Floating point register names
7410*67e74705SXin Li       "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
7411*67e74705SXin Li       "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
7412*67e74705SXin Li       "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
7413*67e74705SXin Li       "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
7414*67e74705SXin Li       // Hi/lo and condition register names
7415*67e74705SXin Li       "hi",   "lo",   "",     "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
7416*67e74705SXin Li       "$fcc5","$fcc6","$fcc7","$ac1hi","$ac1lo","$ac2hi","$ac2lo",
7417*67e74705SXin Li       "$ac3hi","$ac3lo",
7418*67e74705SXin Li       // MSA register names
7419*67e74705SXin Li       "$w0",  "$w1",  "$w2",  "$w3",  "$w4",  "$w5",  "$w6",  "$w7",
7420*67e74705SXin Li       "$w8",  "$w9",  "$w10", "$w11", "$w12", "$w13", "$w14", "$w15",
7421*67e74705SXin Li       "$w16", "$w17", "$w18", "$w19", "$w20", "$w21", "$w22", "$w23",
7422*67e74705SXin Li       "$w24", "$w25", "$w26", "$w27", "$w28", "$w29", "$w30", "$w31",
7423*67e74705SXin Li       // MSA control register names
7424*67e74705SXin Li       "$msair",      "$msacsr", "$msaaccess", "$msasave", "$msamodify",
7425*67e74705SXin Li       "$msarequest", "$msamap", "$msaunmap"
7426*67e74705SXin Li     };
7427*67e74705SXin Li     return llvm::makeArrayRef(GCCRegNames);
7428*67e74705SXin Li   }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const7429*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
7430*67e74705SXin Li                              TargetInfo::ConstraintInfo &Info) const override {
7431*67e74705SXin Li     switch (*Name) {
7432*67e74705SXin Li     default:
7433*67e74705SXin Li       return false;
7434*67e74705SXin Li     case 'r': // CPU registers.
7435*67e74705SXin Li     case 'd': // Equivalent to "r" unless generating MIPS16 code.
7436*67e74705SXin Li     case 'y': // Equivalent to "r", backward compatibility only.
7437*67e74705SXin Li     case 'f': // floating-point registers.
7438*67e74705SXin Li     case 'c': // $25 for indirect jumps
7439*67e74705SXin Li     case 'l': // lo register
7440*67e74705SXin Li     case 'x': // hilo register pair
7441*67e74705SXin Li       Info.setAllowsRegister();
7442*67e74705SXin Li       return true;
7443*67e74705SXin Li     case 'I': // Signed 16-bit constant
7444*67e74705SXin Li     case 'J': // Integer 0
7445*67e74705SXin Li     case 'K': // Unsigned 16-bit constant
7446*67e74705SXin Li     case 'L': // Signed 32-bit constant, lower 16-bit zeros (for lui)
7447*67e74705SXin Li     case 'M': // Constants not loadable via lui, addiu, or ori
7448*67e74705SXin Li     case 'N': // Constant -1 to -65535
7449*67e74705SXin Li     case 'O': // A signed 15-bit constant
7450*67e74705SXin Li     case 'P': // A constant between 1 go 65535
7451*67e74705SXin Li       return true;
7452*67e74705SXin Li     case 'R': // An address that can be used in a non-macro load or store
7453*67e74705SXin Li       Info.setAllowsMemory();
7454*67e74705SXin Li       return true;
7455*67e74705SXin Li     case 'Z':
7456*67e74705SXin Li       if (Name[1] == 'C') { // An address usable by ll, and sc.
7457*67e74705SXin Li         Info.setAllowsMemory();
7458*67e74705SXin Li         Name++; // Skip over 'Z'.
7459*67e74705SXin Li         return true;
7460*67e74705SXin Li       }
7461*67e74705SXin Li       return false;
7462*67e74705SXin Li     }
7463*67e74705SXin Li   }
7464*67e74705SXin Li 
convertConstraint(const char * & Constraint) const7465*67e74705SXin Li   std::string convertConstraint(const char *&Constraint) const override {
7466*67e74705SXin Li     std::string R;
7467*67e74705SXin Li     switch (*Constraint) {
7468*67e74705SXin Li     case 'Z': // Two-character constraint; add "^" hint for later parsing.
7469*67e74705SXin Li       if (Constraint[1] == 'C') {
7470*67e74705SXin Li         R = std::string("^") + std::string(Constraint, 2);
7471*67e74705SXin Li         Constraint++;
7472*67e74705SXin Li         return R;
7473*67e74705SXin Li       }
7474*67e74705SXin Li       break;
7475*67e74705SXin Li     }
7476*67e74705SXin Li     return TargetInfo::convertConstraint(Constraint);
7477*67e74705SXin Li   }
7478*67e74705SXin Li 
getClobbers() const7479*67e74705SXin Li   const char *getClobbers() const override {
7480*67e74705SXin Li     // In GCC, $1 is not widely used in generated code (it's used only in a few
7481*67e74705SXin Li     // specific situations), so there is no real need for users to add it to
7482*67e74705SXin Li     // the clobbers list if they want to use it in their inline assembly code.
7483*67e74705SXin Li     //
7484*67e74705SXin Li     // In LLVM, $1 is treated as a normal GPR and is always allocatable during
7485*67e74705SXin Li     // code generation, so using it in inline assembly without adding it to the
7486*67e74705SXin Li     // clobbers list can cause conflicts between the inline assembly code and
7487*67e74705SXin Li     // the surrounding generated code.
7488*67e74705SXin Li     //
7489*67e74705SXin Li     // Another problem is that LLVM is allowed to choose $1 for inline assembly
7490*67e74705SXin Li     // operands, which will conflict with the ".set at" assembler option (which
7491*67e74705SXin Li     // we use only for inline assembly, in order to maintain compatibility with
7492*67e74705SXin Li     // GCC) and will also conflict with the user's usage of $1.
7493*67e74705SXin Li     //
7494*67e74705SXin Li     // The easiest way to avoid these conflicts and keep $1 as an allocatable
7495*67e74705SXin Li     // register for generated code is to automatically clobber $1 for all inline
7496*67e74705SXin Li     // assembly code.
7497*67e74705SXin Li     //
7498*67e74705SXin Li     // FIXME: We should automatically clobber $1 only for inline assembly code
7499*67e74705SXin Li     // which actually uses it. This would allow LLVM to use $1 for inline
7500*67e74705SXin Li     // assembly operands if the user's assembly code doesn't use it.
7501*67e74705SXin Li     return "~{$1}";
7502*67e74705SXin Li   }
7503*67e74705SXin Li 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)7504*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
7505*67e74705SXin Li                             DiagnosticsEngine &Diags) override {
7506*67e74705SXin Li     IsMips16 = false;
7507*67e74705SXin Li     IsMicromips = false;
7508*67e74705SXin Li     IsNan2008 = isNaN2008Default();
7509*67e74705SXin Li     IsSingleFloat = false;
7510*67e74705SXin Li     FloatABI = HardFloat;
7511*67e74705SXin Li     DspRev = NoDSP;
7512*67e74705SXin Li     HasFP64 = isFP64Default();
7513*67e74705SXin Li 
7514*67e74705SXin Li     for (const auto &Feature : Features) {
7515*67e74705SXin Li       if (Feature == "+single-float")
7516*67e74705SXin Li         IsSingleFloat = true;
7517*67e74705SXin Li       else if (Feature == "+soft-float")
7518*67e74705SXin Li         FloatABI = SoftFloat;
7519*67e74705SXin Li       else if (Feature == "+mips16")
7520*67e74705SXin Li         IsMips16 = true;
7521*67e74705SXin Li       else if (Feature == "+micromips")
7522*67e74705SXin Li         IsMicromips = true;
7523*67e74705SXin Li       else if (Feature == "+dsp")
7524*67e74705SXin Li         DspRev = std::max(DspRev, DSP1);
7525*67e74705SXin Li       else if (Feature == "+dspr2")
7526*67e74705SXin Li         DspRev = std::max(DspRev, DSP2);
7527*67e74705SXin Li       else if (Feature == "+msa")
7528*67e74705SXin Li         HasMSA = true;
7529*67e74705SXin Li       else if (Feature == "+fp64")
7530*67e74705SXin Li         HasFP64 = true;
7531*67e74705SXin Li       else if (Feature == "-fp64")
7532*67e74705SXin Li         HasFP64 = false;
7533*67e74705SXin Li       else if (Feature == "+nan2008")
7534*67e74705SXin Li         IsNan2008 = true;
7535*67e74705SXin Li       else if (Feature == "-nan2008")
7536*67e74705SXin Li         IsNan2008 = false;
7537*67e74705SXin Li     }
7538*67e74705SXin Li 
7539*67e74705SXin Li     setDataLayout();
7540*67e74705SXin Li 
7541*67e74705SXin Li     return true;
7542*67e74705SXin Li   }
7543*67e74705SXin Li 
getEHDataRegisterNumber(unsigned RegNo) const7544*67e74705SXin Li   int getEHDataRegisterNumber(unsigned RegNo) const override {
7545*67e74705SXin Li     if (RegNo == 0) return 4;
7546*67e74705SXin Li     if (RegNo == 1) return 5;
7547*67e74705SXin Li     return -1;
7548*67e74705SXin Li   }
7549*67e74705SXin Li 
isCLZForZeroUndef() const7550*67e74705SXin Li   bool isCLZForZeroUndef() const override { return false; }
7551*67e74705SXin Li 
getGCCRegAliases() const7552*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
7553*67e74705SXin Li     static const TargetInfo::GCCRegAlias O32RegAliases[] = {
7554*67e74705SXin Li         {{"at"}, "$1"},  {{"v0"}, "$2"},         {{"v1"}, "$3"},
7555*67e74705SXin Li         {{"a0"}, "$4"},  {{"a1"}, "$5"},         {{"a2"}, "$6"},
7556*67e74705SXin Li         {{"a3"}, "$7"},  {{"t0"}, "$8"},         {{"t1"}, "$9"},
7557*67e74705SXin Li         {{"t2"}, "$10"}, {{"t3"}, "$11"},        {{"t4"}, "$12"},
7558*67e74705SXin Li         {{"t5"}, "$13"}, {{"t6"}, "$14"},        {{"t7"}, "$15"},
7559*67e74705SXin Li         {{"s0"}, "$16"}, {{"s1"}, "$17"},        {{"s2"}, "$18"},
7560*67e74705SXin Li         {{"s3"}, "$19"}, {{"s4"}, "$20"},        {{"s5"}, "$21"},
7561*67e74705SXin Li         {{"s6"}, "$22"}, {{"s7"}, "$23"},        {{"t8"}, "$24"},
7562*67e74705SXin Li         {{"t9"}, "$25"}, {{"k0"}, "$26"},        {{"k1"}, "$27"},
7563*67e74705SXin Li         {{"gp"}, "$28"}, {{"sp", "$sp"}, "$29"}, {{"fp", "$fp"}, "$30"},
7564*67e74705SXin Li         {{"ra"}, "$31"}};
7565*67e74705SXin Li     static const TargetInfo::GCCRegAlias NewABIRegAliases[] = {
7566*67e74705SXin Li         {{"at"}, "$1"},  {{"v0"}, "$2"},         {{"v1"}, "$3"},
7567*67e74705SXin Li         {{"a0"}, "$4"},  {{"a1"}, "$5"},         {{"a2"}, "$6"},
7568*67e74705SXin Li         {{"a3"}, "$7"},  {{"a4"}, "$8"},         {{"a5"}, "$9"},
7569*67e74705SXin Li         {{"a6"}, "$10"}, {{"a7"}, "$11"},        {{"t0"}, "$12"},
7570*67e74705SXin Li         {{"t1"}, "$13"}, {{"t2"}, "$14"},        {{"t3"}, "$15"},
7571*67e74705SXin Li         {{"s0"}, "$16"}, {{"s1"}, "$17"},        {{"s2"}, "$18"},
7572*67e74705SXin Li         {{"s3"}, "$19"}, {{"s4"}, "$20"},        {{"s5"}, "$21"},
7573*67e74705SXin Li         {{"s6"}, "$22"}, {{"s7"}, "$23"},        {{"t8"}, "$24"},
7574*67e74705SXin Li         {{"t9"}, "$25"}, {{"k0"}, "$26"},        {{"k1"}, "$27"},
7575*67e74705SXin Li         {{"gp"}, "$28"}, {{"sp", "$sp"}, "$29"}, {{"fp", "$fp"}, "$30"},
7576*67e74705SXin Li         {{"ra"}, "$31"}};
7577*67e74705SXin Li     if (ABI == "o32")
7578*67e74705SXin Li       return llvm::makeArrayRef(O32RegAliases);
7579*67e74705SXin Li     return llvm::makeArrayRef(NewABIRegAliases);
7580*67e74705SXin Li   }
7581*67e74705SXin Li 
hasInt128Type() const7582*67e74705SXin Li   bool hasInt128Type() const override {
7583*67e74705SXin Li     return ABI == "n32" || ABI == "n64";
7584*67e74705SXin Li   }
7585*67e74705SXin Li 
validateTarget(DiagnosticsEngine & Diags) const7586*67e74705SXin Li   bool validateTarget(DiagnosticsEngine &Diags) const override {
7587*67e74705SXin Li     // FIXME: It's valid to use O32 on a 64-bit CPU but the backend can't handle
7588*67e74705SXin Li     //        this yet. It's better to fail here than on the backend assertion.
7589*67e74705SXin Li     if (processorSupportsGPR64() && ABI == "o32") {
7590*67e74705SXin Li       Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU;
7591*67e74705SXin Li       return false;
7592*67e74705SXin Li     }
7593*67e74705SXin Li 
7594*67e74705SXin Li     // 64-bit ABI's require 64-bit CPU's.
7595*67e74705SXin Li     if (!processorSupportsGPR64() && (ABI == "n32" || ABI == "n64")) {
7596*67e74705SXin Li       Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU;
7597*67e74705SXin Li       return false;
7598*67e74705SXin Li     }
7599*67e74705SXin Li 
7600*67e74705SXin Li     // FIXME: It's valid to use O32 on a mips64/mips64el triple but the backend
7601*67e74705SXin Li     //        can't handle this yet. It's better to fail here than on the
7602*67e74705SXin Li     //        backend assertion.
7603*67e74705SXin Li     if ((getTriple().getArch() == llvm::Triple::mips64 ||
7604*67e74705SXin Li          getTriple().getArch() == llvm::Triple::mips64el) &&
7605*67e74705SXin Li         ABI == "o32") {
7606*67e74705SXin Li       Diags.Report(diag::err_target_unsupported_abi_for_triple)
7607*67e74705SXin Li           << ABI << getTriple().str();
7608*67e74705SXin Li       return false;
7609*67e74705SXin Li     }
7610*67e74705SXin Li 
7611*67e74705SXin Li     // FIXME: It's valid to use N32/N64 on a mips/mipsel triple but the backend
7612*67e74705SXin Li     //        can't handle this yet. It's better to fail here than on the
7613*67e74705SXin Li     //        backend assertion.
7614*67e74705SXin Li     if ((getTriple().getArch() == llvm::Triple::mips ||
7615*67e74705SXin Li          getTriple().getArch() == llvm::Triple::mipsel) &&
7616*67e74705SXin Li         (ABI == "n32" || ABI == "n64")) {
7617*67e74705SXin Li       Diags.Report(diag::err_target_unsupported_abi_for_triple)
7618*67e74705SXin Li           << ABI << getTriple().str();
7619*67e74705SXin Li       return false;
7620*67e74705SXin Li     }
7621*67e74705SXin Li 
7622*67e74705SXin Li     return true;
7623*67e74705SXin Li   }
7624*67e74705SXin Li };
7625*67e74705SXin Li 
7626*67e74705SXin Li const Builtin::Info MipsTargetInfo::BuiltinInfo[] = {
7627*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS) \
7628*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
7629*67e74705SXin Li #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
7630*67e74705SXin Li   { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
7631*67e74705SXin Li #include "clang/Basic/BuiltinsMips.def"
7632*67e74705SXin Li };
7633*67e74705SXin Li 
7634*67e74705SXin Li class PNaClTargetInfo : public TargetInfo {
7635*67e74705SXin Li public:
PNaClTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)7636*67e74705SXin Li   PNaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
7637*67e74705SXin Li       : TargetInfo(Triple) {
7638*67e74705SXin Li     BigEndian = false;
7639*67e74705SXin Li     this->LongAlign = 32;
7640*67e74705SXin Li     this->LongWidth = 32;
7641*67e74705SXin Li     this->PointerAlign = 32;
7642*67e74705SXin Li     this->PointerWidth = 32;
7643*67e74705SXin Li     this->IntMaxType = TargetInfo::SignedLongLong;
7644*67e74705SXin Li     this->Int64Type = TargetInfo::SignedLongLong;
7645*67e74705SXin Li     this->DoubleAlign = 64;
7646*67e74705SXin Li     this->LongDoubleWidth = 64;
7647*67e74705SXin Li     this->LongDoubleAlign = 64;
7648*67e74705SXin Li     this->SizeType = TargetInfo::UnsignedInt;
7649*67e74705SXin Li     this->PtrDiffType = TargetInfo::SignedInt;
7650*67e74705SXin Li     this->IntPtrType = TargetInfo::SignedInt;
7651*67e74705SXin Li     this->RegParmMax = 0; // Disallow regparm
7652*67e74705SXin Li   }
7653*67e74705SXin Li 
getArchDefines(const LangOptions & Opts,MacroBuilder & Builder) const7654*67e74705SXin Li   void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const {
7655*67e74705SXin Li     Builder.defineMacro("__le32__");
7656*67e74705SXin Li     Builder.defineMacro("__pnacl__");
7657*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7658*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7659*67e74705SXin Li                         MacroBuilder &Builder) const override {
7660*67e74705SXin Li     getArchDefines(Opts, Builder);
7661*67e74705SXin Li   }
hasFeature(StringRef Feature) const7662*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
7663*67e74705SXin Li     return Feature == "pnacl";
7664*67e74705SXin Li   }
getTargetBuiltins() const7665*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
getBuiltinVaListKind() const7666*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
7667*67e74705SXin Li     return TargetInfo::PNaClABIBuiltinVaList;
7668*67e74705SXin Li   }
7669*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override;
7670*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const7671*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
7672*67e74705SXin Li                              TargetInfo::ConstraintInfo &Info) const override {
7673*67e74705SXin Li     return false;
7674*67e74705SXin Li   }
7675*67e74705SXin Li 
getClobbers() const7676*67e74705SXin Li   const char *getClobbers() const override {
7677*67e74705SXin Li     return "";
7678*67e74705SXin Li   }
7679*67e74705SXin Li };
7680*67e74705SXin Li 
getGCCRegNames() const7681*67e74705SXin Li ArrayRef<const char *> PNaClTargetInfo::getGCCRegNames() const {
7682*67e74705SXin Li   return None;
7683*67e74705SXin Li }
7684*67e74705SXin Li 
getGCCRegAliases() const7685*67e74705SXin Li ArrayRef<TargetInfo::GCCRegAlias> PNaClTargetInfo::getGCCRegAliases() const {
7686*67e74705SXin Li   return None;
7687*67e74705SXin Li }
7688*67e74705SXin Li 
7689*67e74705SXin Li // We attempt to use PNaCl (le32) frontend and Mips32EL backend.
7690*67e74705SXin Li class NaClMips32TargetInfo : public MipsTargetInfo {
7691*67e74705SXin Li public:
NaClMips32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)7692*67e74705SXin Li   NaClMips32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
7693*67e74705SXin Li       : MipsTargetInfo(Triple, Opts) {}
7694*67e74705SXin Li 
getBuiltinVaListKind() const7695*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
7696*67e74705SXin Li     return TargetInfo::PNaClABIBuiltinVaList;
7697*67e74705SXin Li   }
7698*67e74705SXin Li };
7699*67e74705SXin Li 
7700*67e74705SXin Li class Le64TargetInfo : public TargetInfo {
7701*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
7702*67e74705SXin Li 
7703*67e74705SXin Li public:
Le64TargetInfo(const llvm::Triple & Triple,const TargetOptions &)7704*67e74705SXin Li   Le64TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
7705*67e74705SXin Li       : TargetInfo(Triple) {
7706*67e74705SXin Li     BigEndian = false;
7707*67e74705SXin Li     NoAsmVariants = true;
7708*67e74705SXin Li     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
7709*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
7710*67e74705SXin Li     resetDataLayout("e-m:e-v128:32-v16:16-v32:32-v96:32-n8:16:32:64-S128");
7711*67e74705SXin Li   }
7712*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7713*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7714*67e74705SXin Li                         MacroBuilder &Builder) const override {
7715*67e74705SXin Li     DefineStd(Builder, "unix", Opts);
7716*67e74705SXin Li     defineCPUMacros(Builder, "le64", /*Tuning=*/false);
7717*67e74705SXin Li     Builder.defineMacro("__ELF__");
7718*67e74705SXin Li   }
getTargetBuiltins() const7719*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
7720*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
7721*67e74705SXin Li                           clang::Le64::LastTSBuiltin - Builtin::FirstTSBuiltin);
7722*67e74705SXin Li   }
getBuiltinVaListKind() const7723*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
7724*67e74705SXin Li     return TargetInfo::PNaClABIBuiltinVaList;
7725*67e74705SXin Li   }
getClobbers() const7726*67e74705SXin Li   const char *getClobbers() const override { return ""; }
getGCCRegNames() const7727*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override {
7728*67e74705SXin Li     return None;
7729*67e74705SXin Li   }
getGCCRegAliases() const7730*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
7731*67e74705SXin Li     return None;
7732*67e74705SXin Li   }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const7733*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
7734*67e74705SXin Li                              TargetInfo::ConstraintInfo &Info) const override {
7735*67e74705SXin Li     return false;
7736*67e74705SXin Li   }
7737*67e74705SXin Li 
hasProtectedVisibility() const7738*67e74705SXin Li   bool hasProtectedVisibility() const override { return false; }
7739*67e74705SXin Li };
7740*67e74705SXin Li 
7741*67e74705SXin Li class WebAssemblyTargetInfo : public TargetInfo {
7742*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
7743*67e74705SXin Li 
7744*67e74705SXin Li   enum SIMDEnum {
7745*67e74705SXin Li     NoSIMD,
7746*67e74705SXin Li     SIMD128,
7747*67e74705SXin Li   } SIMDLevel;
7748*67e74705SXin Li 
7749*67e74705SXin Li public:
WebAssemblyTargetInfo(const llvm::Triple & T,const TargetOptions &)7750*67e74705SXin Li   explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
7751*67e74705SXin Li       : TargetInfo(T), SIMDLevel(NoSIMD) {
7752*67e74705SXin Li     BigEndian = false;
7753*67e74705SXin Li     NoAsmVariants = true;
7754*67e74705SXin Li     SuitableAlign = 128;
7755*67e74705SXin Li     LargeArrayMinWidth = 128;
7756*67e74705SXin Li     LargeArrayAlign = 128;
7757*67e74705SXin Li     SimdDefaultAlign = 128;
7758*67e74705SXin Li     SigAtomicType = SignedLong;
7759*67e74705SXin Li     LongDoubleWidth = LongDoubleAlign = 128;
7760*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEquad;
7761*67e74705SXin Li   }
7762*67e74705SXin Li 
7763*67e74705SXin Li protected:
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7764*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7765*67e74705SXin Li                         MacroBuilder &Builder) const override {
7766*67e74705SXin Li     defineCPUMacros(Builder, "wasm", /*Tuning=*/false);
7767*67e74705SXin Li     if (SIMDLevel >= SIMD128)
7768*67e74705SXin Li       Builder.defineMacro("__wasm_simd128__");
7769*67e74705SXin Li   }
7770*67e74705SXin Li 
7771*67e74705SXin Li private:
7772*67e74705SXin Li   bool
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const7773*67e74705SXin Li   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
7774*67e74705SXin Li                  StringRef CPU,
7775*67e74705SXin Li                  const std::vector<std::string> &FeaturesVec) const override {
7776*67e74705SXin Li     if (CPU == "bleeding-edge")
7777*67e74705SXin Li       Features["simd128"] = true;
7778*67e74705SXin Li     return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
7779*67e74705SXin Li   }
hasFeature(StringRef Feature) const7780*67e74705SXin Li   bool hasFeature(StringRef Feature) const final {
7781*67e74705SXin Li     return llvm::StringSwitch<bool>(Feature)
7782*67e74705SXin Li         .Case("simd128", SIMDLevel >= SIMD128)
7783*67e74705SXin Li         .Default(false);
7784*67e74705SXin Li   }
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)7785*67e74705SXin Li   bool handleTargetFeatures(std::vector<std::string> &Features,
7786*67e74705SXin Li                             DiagnosticsEngine &Diags) final {
7787*67e74705SXin Li     for (const auto &Feature : Features) {
7788*67e74705SXin Li       if (Feature == "+simd128") {
7789*67e74705SXin Li         SIMDLevel = std::max(SIMDLevel, SIMD128);
7790*67e74705SXin Li         continue;
7791*67e74705SXin Li       }
7792*67e74705SXin Li       if (Feature == "-simd128") {
7793*67e74705SXin Li         SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1));
7794*67e74705SXin Li         continue;
7795*67e74705SXin Li       }
7796*67e74705SXin Li 
7797*67e74705SXin Li       Diags.Report(diag::err_opt_not_valid_with_opt) << Feature
7798*67e74705SXin Li                                                      << "-target-feature";
7799*67e74705SXin Li       return false;
7800*67e74705SXin Li     }
7801*67e74705SXin Li     return true;
7802*67e74705SXin Li   }
setCPU(const std::string & Name)7803*67e74705SXin Li   bool setCPU(const std::string &Name) final {
7804*67e74705SXin Li     return llvm::StringSwitch<bool>(Name)
7805*67e74705SXin Li               .Case("mvp",           true)
7806*67e74705SXin Li               .Case("bleeding-edge", true)
7807*67e74705SXin Li               .Case("generic",       true)
7808*67e74705SXin Li               .Default(false);
7809*67e74705SXin Li   }
getTargetBuiltins() const7810*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const final {
7811*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
7812*67e74705SXin Li                    clang::WebAssembly::LastTSBuiltin - Builtin::FirstTSBuiltin);
7813*67e74705SXin Li   }
getBuiltinVaListKind() const7814*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const final {
7815*67e74705SXin Li     return VoidPtrBuiltinVaList;
7816*67e74705SXin Li   }
getGCCRegNames() const7817*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const final {
7818*67e74705SXin Li     return None;
7819*67e74705SXin Li   }
getGCCRegAliases() const7820*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
7821*67e74705SXin Li     return None;
7822*67e74705SXin Li   }
7823*67e74705SXin Li   bool
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const7824*67e74705SXin Li   validateAsmConstraint(const char *&Name,
7825*67e74705SXin Li                         TargetInfo::ConstraintInfo &Info) const final {
7826*67e74705SXin Li     return false;
7827*67e74705SXin Li   }
getClobbers() const7828*67e74705SXin Li   const char *getClobbers() const final { return ""; }
isCLZForZeroUndef() const7829*67e74705SXin Li   bool isCLZForZeroUndef() const final { return false; }
hasInt128Type() const7830*67e74705SXin Li   bool hasInt128Type() const final { return true; }
getIntTypeByWidth(unsigned BitWidth,bool IsSigned) const7831*67e74705SXin Li   IntType getIntTypeByWidth(unsigned BitWidth,
7832*67e74705SXin Li                             bool IsSigned) const final {
7833*67e74705SXin Li     // WebAssembly prefers long long for explicitly 64-bit integers.
7834*67e74705SXin Li     return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
7835*67e74705SXin Li                           : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
7836*67e74705SXin Li   }
getLeastIntTypeByWidth(unsigned BitWidth,bool IsSigned) const7837*67e74705SXin Li   IntType getLeastIntTypeByWidth(unsigned BitWidth,
7838*67e74705SXin Li                                  bool IsSigned) const final {
7839*67e74705SXin Li     // WebAssembly uses long long for int_least64_t and int_fast64_t.
7840*67e74705SXin Li     return BitWidth == 64
7841*67e74705SXin Li                ? (IsSigned ? SignedLongLong : UnsignedLongLong)
7842*67e74705SXin Li                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
7843*67e74705SXin Li   }
7844*67e74705SXin Li };
7845*67e74705SXin Li 
7846*67e74705SXin Li const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = {
7847*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS) \
7848*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
7849*67e74705SXin Li #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
7850*67e74705SXin Li   { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
7851*67e74705SXin Li #include "clang/Basic/BuiltinsWebAssembly.def"
7852*67e74705SXin Li };
7853*67e74705SXin Li 
7854*67e74705SXin Li class WebAssembly32TargetInfo : public WebAssemblyTargetInfo {
7855*67e74705SXin Li public:
WebAssembly32TargetInfo(const llvm::Triple & T,const TargetOptions & Opts)7856*67e74705SXin Li   explicit WebAssembly32TargetInfo(const llvm::Triple &T,
7857*67e74705SXin Li                                    const TargetOptions &Opts)
7858*67e74705SXin Li       : WebAssemblyTargetInfo(T, Opts) {
7859*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
7860*67e74705SXin Li     resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128");
7861*67e74705SXin Li   }
7862*67e74705SXin Li 
7863*67e74705SXin Li protected:
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7864*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7865*67e74705SXin Li                         MacroBuilder &Builder) const override {
7866*67e74705SXin Li     WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
7867*67e74705SXin Li     defineCPUMacros(Builder, "wasm32", /*Tuning=*/false);
7868*67e74705SXin Li   }
7869*67e74705SXin Li };
7870*67e74705SXin Li 
7871*67e74705SXin Li class WebAssembly64TargetInfo : public WebAssemblyTargetInfo {
7872*67e74705SXin Li public:
WebAssembly64TargetInfo(const llvm::Triple & T,const TargetOptions & Opts)7873*67e74705SXin Li   explicit WebAssembly64TargetInfo(const llvm::Triple &T,
7874*67e74705SXin Li                                    const TargetOptions &Opts)
7875*67e74705SXin Li       : WebAssemblyTargetInfo(T, Opts) {
7876*67e74705SXin Li     LongAlign = LongWidth = 64;
7877*67e74705SXin Li     PointerAlign = PointerWidth = 64;
7878*67e74705SXin Li     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
7879*67e74705SXin Li     resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128");
7880*67e74705SXin Li   }
7881*67e74705SXin Li 
7882*67e74705SXin Li protected:
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7883*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7884*67e74705SXin Li                         MacroBuilder &Builder) const override {
7885*67e74705SXin Li     WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
7886*67e74705SXin Li     defineCPUMacros(Builder, "wasm64", /*Tuning=*/false);
7887*67e74705SXin Li   }
7888*67e74705SXin Li };
7889*67e74705SXin Li 
7890*67e74705SXin Li const Builtin::Info Le64TargetInfo::BuiltinInfo[] = {
7891*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS)                                               \
7892*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
7893*67e74705SXin Li #include "clang/Basic/BuiltinsLe64.def"
7894*67e74705SXin Li };
7895*67e74705SXin Li 
7896*67e74705SXin Li static const unsigned SPIRAddrSpaceMap[] = {
7897*67e74705SXin Li     1, // opencl_global
7898*67e74705SXin Li     3, // opencl_local
7899*67e74705SXin Li     2, // opencl_constant
7900*67e74705SXin Li     4, // opencl_generic
7901*67e74705SXin Li     0, // cuda_device
7902*67e74705SXin Li     0, // cuda_constant
7903*67e74705SXin Li     0  // cuda_shared
7904*67e74705SXin Li };
7905*67e74705SXin Li class SPIRTargetInfo : public TargetInfo {
7906*67e74705SXin Li public:
SPIRTargetInfo(const llvm::Triple & Triple,const TargetOptions &)7907*67e74705SXin Li   SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
7908*67e74705SXin Li       : TargetInfo(Triple) {
7909*67e74705SXin Li     assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
7910*67e74705SXin Li            "SPIR target must use unknown OS");
7911*67e74705SXin Li     assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
7912*67e74705SXin Li            "SPIR target must use unknown environment type");
7913*67e74705SXin Li     BigEndian = false;
7914*67e74705SXin Li     TLSSupported = false;
7915*67e74705SXin Li     LongWidth = LongAlign = 64;
7916*67e74705SXin Li     AddrSpaceMap = &SPIRAddrSpaceMap;
7917*67e74705SXin Li     UseAddrSpaceMapMangling = true;
7918*67e74705SXin Li     // Define available target features
7919*67e74705SXin Li     // These must be defined in sorted order!
7920*67e74705SXin Li     NoAsmVariants = true;
7921*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7922*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7923*67e74705SXin Li                         MacroBuilder &Builder) const override {
7924*67e74705SXin Li     DefineStd(Builder, "SPIR", Opts);
7925*67e74705SXin Li   }
hasFeature(StringRef Feature) const7926*67e74705SXin Li   bool hasFeature(StringRef Feature) const override {
7927*67e74705SXin Li     return Feature == "spir";
7928*67e74705SXin Li   }
7929*67e74705SXin Li 
getTargetBuiltins() const7930*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
getClobbers() const7931*67e74705SXin Li   const char *getClobbers() const override { return ""; }
getGCCRegNames() const7932*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override { return None; }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const7933*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
7934*67e74705SXin Li                              TargetInfo::ConstraintInfo &info) const override {
7935*67e74705SXin Li     return true;
7936*67e74705SXin Li   }
getGCCRegAliases() const7937*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
7938*67e74705SXin Li     return None;
7939*67e74705SXin Li   }
getBuiltinVaListKind() const7940*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
7941*67e74705SXin Li     return TargetInfo::VoidPtrBuiltinVaList;
7942*67e74705SXin Li   }
7943*67e74705SXin Li 
checkCallingConvention(CallingConv CC) const7944*67e74705SXin Li   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
7945*67e74705SXin Li     return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
7946*67e74705SXin Li                                                             : CCCR_Warning;
7947*67e74705SXin Li   }
7948*67e74705SXin Li 
getDefaultCallingConv(CallingConvMethodType MT) const7949*67e74705SXin Li   CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
7950*67e74705SXin Li     return CC_SpirFunction;
7951*67e74705SXin Li   }
7952*67e74705SXin Li 
setSupportedOpenCLOpts()7953*67e74705SXin Li   void setSupportedOpenCLOpts() override {
7954*67e74705SXin Li     // Assume all OpenCL extensions and optional core features are supported
7955*67e74705SXin Li     // for SPIR since it is a generic target.
7956*67e74705SXin Li     getSupportedOpenCLOpts().setAll();
7957*67e74705SXin Li   }
7958*67e74705SXin Li };
7959*67e74705SXin Li 
7960*67e74705SXin Li class SPIR32TargetInfo : public SPIRTargetInfo {
7961*67e74705SXin Li public:
SPIR32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)7962*67e74705SXin Li   SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
7963*67e74705SXin Li       : SPIRTargetInfo(Triple, Opts) {
7964*67e74705SXin Li     PointerWidth = PointerAlign = 32;
7965*67e74705SXin Li     SizeType = TargetInfo::UnsignedInt;
7966*67e74705SXin Li     PtrDiffType = IntPtrType = TargetInfo::SignedInt;
7967*67e74705SXin Li     resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
7968*67e74705SXin Li                     "v96:128-v192:256-v256:256-v512:512-v1024:1024");
7969*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7970*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7971*67e74705SXin Li                         MacroBuilder &Builder) const override {
7972*67e74705SXin Li     DefineStd(Builder, "SPIR32", Opts);
7973*67e74705SXin Li   }
7974*67e74705SXin Li };
7975*67e74705SXin Li 
7976*67e74705SXin Li class SPIR64TargetInfo : public SPIRTargetInfo {
7977*67e74705SXin Li public:
SPIR64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)7978*67e74705SXin Li   SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
7979*67e74705SXin Li       : SPIRTargetInfo(Triple, Opts) {
7980*67e74705SXin Li     PointerWidth = PointerAlign = 64;
7981*67e74705SXin Li     SizeType = TargetInfo::UnsignedLong;
7982*67e74705SXin Li     PtrDiffType = IntPtrType = TargetInfo::SignedLong;
7983*67e74705SXin Li     resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
7984*67e74705SXin Li                     "v96:128-v192:256-v256:256-v512:512-v1024:1024");
7985*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const7986*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
7987*67e74705SXin Li                         MacroBuilder &Builder) const override {
7988*67e74705SXin Li     DefineStd(Builder, "SPIR64", Opts);
7989*67e74705SXin Li   }
7990*67e74705SXin Li };
7991*67e74705SXin Li 
7992*67e74705SXin Li class XCoreTargetInfo : public TargetInfo {
7993*67e74705SXin Li   static const Builtin::Info BuiltinInfo[];
7994*67e74705SXin Li public:
XCoreTargetInfo(const llvm::Triple & Triple,const TargetOptions &)7995*67e74705SXin Li   XCoreTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
7996*67e74705SXin Li       : TargetInfo(Triple) {
7997*67e74705SXin Li     BigEndian = false;
7998*67e74705SXin Li     NoAsmVariants = true;
7999*67e74705SXin Li     LongLongAlign = 32;
8000*67e74705SXin Li     SuitableAlign = 32;
8001*67e74705SXin Li     DoubleAlign = LongDoubleAlign = 32;
8002*67e74705SXin Li     SizeType = UnsignedInt;
8003*67e74705SXin Li     PtrDiffType = SignedInt;
8004*67e74705SXin Li     IntPtrType = SignedInt;
8005*67e74705SXin Li     WCharType = UnsignedChar;
8006*67e74705SXin Li     WIntType = UnsignedInt;
8007*67e74705SXin Li     UseZeroLengthBitfieldAlignment = true;
8008*67e74705SXin Li     resetDataLayout("e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32"
8009*67e74705SXin Li                     "-f64:32-a:0:32-n32");
8010*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const8011*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
8012*67e74705SXin Li                         MacroBuilder &Builder) const override {
8013*67e74705SXin Li     Builder.defineMacro("__XS1B__");
8014*67e74705SXin Li   }
getTargetBuiltins() const8015*67e74705SXin Li   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
8016*67e74705SXin Li     return llvm::makeArrayRef(BuiltinInfo,
8017*67e74705SXin Li                            clang::XCore::LastTSBuiltin-Builtin::FirstTSBuiltin);
8018*67e74705SXin Li   }
getBuiltinVaListKind() const8019*67e74705SXin Li   BuiltinVaListKind getBuiltinVaListKind() const override {
8020*67e74705SXin Li     return TargetInfo::VoidPtrBuiltinVaList;
8021*67e74705SXin Li   }
getClobbers() const8022*67e74705SXin Li   const char *getClobbers() const override {
8023*67e74705SXin Li     return "";
8024*67e74705SXin Li   }
getGCCRegNames() const8025*67e74705SXin Li   ArrayRef<const char *> getGCCRegNames() const override {
8026*67e74705SXin Li     static const char * const GCCRegNames[] = {
8027*67e74705SXin Li       "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",
8028*67e74705SXin Li       "r8",   "r9",   "r10",  "r11",  "cp",   "dp",   "sp",   "lr"
8029*67e74705SXin Li     };
8030*67e74705SXin Li     return llvm::makeArrayRef(GCCRegNames);
8031*67e74705SXin Li   }
getGCCRegAliases() const8032*67e74705SXin Li   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
8033*67e74705SXin Li     return None;
8034*67e74705SXin Li   }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const8035*67e74705SXin Li   bool validateAsmConstraint(const char *&Name,
8036*67e74705SXin Li                              TargetInfo::ConstraintInfo &Info) const override {
8037*67e74705SXin Li     return false;
8038*67e74705SXin Li   }
getEHDataRegisterNumber(unsigned RegNo) const8039*67e74705SXin Li   int getEHDataRegisterNumber(unsigned RegNo) const override {
8040*67e74705SXin Li     // R0=ExceptionPointerRegister R1=ExceptionSelectorRegister
8041*67e74705SXin Li     return (RegNo < 2)? RegNo : -1;
8042*67e74705SXin Li   }
allowsLargerPreferedTypeAlignment() const8043*67e74705SXin Li   bool allowsLargerPreferedTypeAlignment() const override {
8044*67e74705SXin Li     return false;
8045*67e74705SXin Li   }
8046*67e74705SXin Li };
8047*67e74705SXin Li 
8048*67e74705SXin Li const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = {
8049*67e74705SXin Li #define BUILTIN(ID, TYPE, ATTRS) \
8050*67e74705SXin Li   { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
8051*67e74705SXin Li #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
8052*67e74705SXin Li   { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
8053*67e74705SXin Li #include "clang/Basic/BuiltinsXCore.def"
8054*67e74705SXin Li };
8055*67e74705SXin Li 
8056*67e74705SXin Li // x86_32 Android target
8057*67e74705SXin Li class AndroidX86_32TargetInfo : public LinuxTargetInfo<X86_32TargetInfo> {
8058*67e74705SXin Li public:
AndroidX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8059*67e74705SXin Li   AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
8060*67e74705SXin Li       : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) {
8061*67e74705SXin Li     SuitableAlign = 32;
8062*67e74705SXin Li     LongDoubleWidth = 64;
8063*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
8064*67e74705SXin Li   }
8065*67e74705SXin Li };
8066*67e74705SXin Li 
8067*67e74705SXin Li // x86_64 Android target
8068*67e74705SXin Li class AndroidX86_64TargetInfo : public LinuxTargetInfo<X86_64TargetInfo> {
8069*67e74705SXin Li public:
AndroidX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8070*67e74705SXin Li   AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
8071*67e74705SXin Li       : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) {
8072*67e74705SXin Li     LongDoubleFormat = &llvm::APFloat::IEEEquad;
8073*67e74705SXin Li   }
8074*67e74705SXin Li 
useFloat128ManglingForLongDouble() const8075*67e74705SXin Li   bool useFloat128ManglingForLongDouble() const override {
8076*67e74705SXin Li     return true;
8077*67e74705SXin Li   }
8078*67e74705SXin Li };
8079*67e74705SXin Li 
8080*67e74705SXin Li // 32-bit RenderScript is armv7 with width and align of 'long' set to 8-bytes
8081*67e74705SXin Li class RenderScript32TargetInfo : public ARMleTargetInfo {
8082*67e74705SXin Li public:
RenderScript32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8083*67e74705SXin Li   RenderScript32TargetInfo(const llvm::Triple &Triple,
8084*67e74705SXin Li                            const TargetOptions &Opts)
8085*67e74705SXin Li       : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
8086*67e74705SXin Li                                      Triple.getOSName(),
8087*67e74705SXin Li                                      Triple.getEnvironmentName()),
8088*67e74705SXin Li                         Opts) {
8089*67e74705SXin Li     IsRenderScriptTarget = true;
8090*67e74705SXin Li     LongWidth = LongAlign = 64;
8091*67e74705SXin Li   }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const8092*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
8093*67e74705SXin Li                         MacroBuilder &Builder) const override {
8094*67e74705SXin Li     Builder.defineMacro("__RENDERSCRIPT__");
8095*67e74705SXin Li     ARMleTargetInfo::getTargetDefines(Opts, Builder);
8096*67e74705SXin Li   }
8097*67e74705SXin Li };
8098*67e74705SXin Li 
8099*67e74705SXin Li // 64-bit RenderScript is aarch64
8100*67e74705SXin Li class RenderScript64TargetInfo : public AArch64leTargetInfo {
8101*67e74705SXin Li public:
RenderScript64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8102*67e74705SXin Li   RenderScript64TargetInfo(const llvm::Triple &Triple,
8103*67e74705SXin Li                            const TargetOptions &Opts)
8104*67e74705SXin Li       : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
8105*67e74705SXin Li                                          Triple.getOSName(),
8106*67e74705SXin Li                                          Triple.getEnvironmentName()),
8107*67e74705SXin Li                             Opts) {
8108*67e74705SXin Li     IsRenderScriptTarget = true;
8109*67e74705SXin Li   }
8110*67e74705SXin Li 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const8111*67e74705SXin Li   void getTargetDefines(const LangOptions &Opts,
8112*67e74705SXin Li                         MacroBuilder &Builder) const override {
8113*67e74705SXin Li     Builder.defineMacro("__RENDERSCRIPT__");
8114*67e74705SXin Li     AArch64leTargetInfo::getTargetDefines(Opts, Builder);
8115*67e74705SXin Li   }
8116*67e74705SXin Li };
8117*67e74705SXin Li 
8118*67e74705SXin Li } // end anonymous namespace
8119*67e74705SXin Li 
8120*67e74705SXin Li //===----------------------------------------------------------------------===//
8121*67e74705SXin Li // Driver code
8122*67e74705SXin Li //===----------------------------------------------------------------------===//
8123*67e74705SXin Li 
AllocateTarget(const llvm::Triple & Triple,const TargetOptions & Opts)8124*67e74705SXin Li static TargetInfo *AllocateTarget(const llvm::Triple &Triple,
8125*67e74705SXin Li                                   const TargetOptions &Opts) {
8126*67e74705SXin Li   llvm::Triple::OSType os = Triple.getOS();
8127*67e74705SXin Li 
8128*67e74705SXin Li   switch (Triple.getArch()) {
8129*67e74705SXin Li   default:
8130*67e74705SXin Li     return nullptr;
8131*67e74705SXin Li 
8132*67e74705SXin Li   case llvm::Triple::xcore:
8133*67e74705SXin Li     return new XCoreTargetInfo(Triple, Opts);
8134*67e74705SXin Li 
8135*67e74705SXin Li   case llvm::Triple::hexagon:
8136*67e74705SXin Li     return new HexagonTargetInfo(Triple, Opts);
8137*67e74705SXin Li 
8138*67e74705SXin Li   case llvm::Triple::lanai:
8139*67e74705SXin Li     return new LanaiTargetInfo(Triple, Opts);
8140*67e74705SXin Li 
8141*67e74705SXin Li   case llvm::Triple::aarch64:
8142*67e74705SXin Li     if (Triple.isOSDarwin())
8143*67e74705SXin Li       return new DarwinAArch64TargetInfo(Triple, Opts);
8144*67e74705SXin Li 
8145*67e74705SXin Li     switch (os) {
8146*67e74705SXin Li     case llvm::Triple::CloudABI:
8147*67e74705SXin Li       return new CloudABITargetInfo<AArch64leTargetInfo>(Triple, Opts);
8148*67e74705SXin Li     case llvm::Triple::FreeBSD:
8149*67e74705SXin Li       return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
8150*67e74705SXin Li     case llvm::Triple::Linux:
8151*67e74705SXin Li       return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts);
8152*67e74705SXin Li     case llvm::Triple::NetBSD:
8153*67e74705SXin Li       return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
8154*67e74705SXin Li     default:
8155*67e74705SXin Li       return new AArch64leTargetInfo(Triple, Opts);
8156*67e74705SXin Li     }
8157*67e74705SXin Li 
8158*67e74705SXin Li   case llvm::Triple::aarch64_be:
8159*67e74705SXin Li     switch (os) {
8160*67e74705SXin Li     case llvm::Triple::FreeBSD:
8161*67e74705SXin Li       return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts);
8162*67e74705SXin Li     case llvm::Triple::Linux:
8163*67e74705SXin Li       return new LinuxTargetInfo<AArch64beTargetInfo>(Triple, Opts);
8164*67e74705SXin Li     case llvm::Triple::NetBSD:
8165*67e74705SXin Li       return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts);
8166*67e74705SXin Li     default:
8167*67e74705SXin Li       return new AArch64beTargetInfo(Triple, Opts);
8168*67e74705SXin Li     }
8169*67e74705SXin Li 
8170*67e74705SXin Li   case llvm::Triple::arm:
8171*67e74705SXin Li   case llvm::Triple::thumb:
8172*67e74705SXin Li     if (Triple.isOSBinFormatMachO())
8173*67e74705SXin Li       return new DarwinARMTargetInfo(Triple, Opts);
8174*67e74705SXin Li 
8175*67e74705SXin Li     switch (os) {
8176*67e74705SXin Li     case llvm::Triple::Linux:
8177*67e74705SXin Li       return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts);
8178*67e74705SXin Li     case llvm::Triple::FreeBSD:
8179*67e74705SXin Li       return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
8180*67e74705SXin Li     case llvm::Triple::NetBSD:
8181*67e74705SXin Li       return new NetBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
8182*67e74705SXin Li     case llvm::Triple::OpenBSD:
8183*67e74705SXin Li       return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
8184*67e74705SXin Li     case llvm::Triple::Bitrig:
8185*67e74705SXin Li       return new BitrigTargetInfo<ARMleTargetInfo>(Triple, Opts);
8186*67e74705SXin Li     case llvm::Triple::RTEMS:
8187*67e74705SXin Li       return new RTEMSTargetInfo<ARMleTargetInfo>(Triple, Opts);
8188*67e74705SXin Li     case llvm::Triple::NaCl:
8189*67e74705SXin Li       return new NaClTargetInfo<ARMleTargetInfo>(Triple, Opts);
8190*67e74705SXin Li     case llvm::Triple::Win32:
8191*67e74705SXin Li       switch (Triple.getEnvironment()) {
8192*67e74705SXin Li       case llvm::Triple::Cygnus:
8193*67e74705SXin Li         return new CygwinARMTargetInfo(Triple, Opts);
8194*67e74705SXin Li       case llvm::Triple::GNU:
8195*67e74705SXin Li         return new MinGWARMTargetInfo(Triple, Opts);
8196*67e74705SXin Li       case llvm::Triple::Itanium:
8197*67e74705SXin Li         return new ItaniumWindowsARMleTargetInfo(Triple, Opts);
8198*67e74705SXin Li       case llvm::Triple::MSVC:
8199*67e74705SXin Li       default: // Assume MSVC for unknown environments
8200*67e74705SXin Li         return new MicrosoftARMleTargetInfo(Triple, Opts);
8201*67e74705SXin Li       }
8202*67e74705SXin Li     default:
8203*67e74705SXin Li       return new ARMleTargetInfo(Triple, Opts);
8204*67e74705SXin Li     }
8205*67e74705SXin Li 
8206*67e74705SXin Li   case llvm::Triple::armeb:
8207*67e74705SXin Li   case llvm::Triple::thumbeb:
8208*67e74705SXin Li     if (Triple.isOSDarwin())
8209*67e74705SXin Li       return new DarwinARMTargetInfo(Triple, Opts);
8210*67e74705SXin Li 
8211*67e74705SXin Li     switch (os) {
8212*67e74705SXin Li     case llvm::Triple::Linux:
8213*67e74705SXin Li       return new LinuxTargetInfo<ARMbeTargetInfo>(Triple, Opts);
8214*67e74705SXin Li     case llvm::Triple::FreeBSD:
8215*67e74705SXin Li       return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
8216*67e74705SXin Li     case llvm::Triple::NetBSD:
8217*67e74705SXin Li       return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
8218*67e74705SXin Li     case llvm::Triple::OpenBSD:
8219*67e74705SXin Li       return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
8220*67e74705SXin Li     case llvm::Triple::Bitrig:
8221*67e74705SXin Li       return new BitrigTargetInfo<ARMbeTargetInfo>(Triple, Opts);
8222*67e74705SXin Li     case llvm::Triple::RTEMS:
8223*67e74705SXin Li       return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple, Opts);
8224*67e74705SXin Li     case llvm::Triple::NaCl:
8225*67e74705SXin Li       return new NaClTargetInfo<ARMbeTargetInfo>(Triple, Opts);
8226*67e74705SXin Li     default:
8227*67e74705SXin Li       return new ARMbeTargetInfo(Triple, Opts);
8228*67e74705SXin Li     }
8229*67e74705SXin Li 
8230*67e74705SXin Li   case llvm::Triple::bpfeb:
8231*67e74705SXin Li   case llvm::Triple::bpfel:
8232*67e74705SXin Li     return new BPFTargetInfo(Triple, Opts);
8233*67e74705SXin Li 
8234*67e74705SXin Li   case llvm::Triple::msp430:
8235*67e74705SXin Li     return new MSP430TargetInfo(Triple, Opts);
8236*67e74705SXin Li 
8237*67e74705SXin Li   case llvm::Triple::mips:
8238*67e74705SXin Li     switch (os) {
8239*67e74705SXin Li     case llvm::Triple::Linux:
8240*67e74705SXin Li       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
8241*67e74705SXin Li     case llvm::Triple::RTEMS:
8242*67e74705SXin Li       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
8243*67e74705SXin Li     case llvm::Triple::FreeBSD:
8244*67e74705SXin Li       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
8245*67e74705SXin Li     case llvm::Triple::NetBSD:
8246*67e74705SXin Li       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
8247*67e74705SXin Li     default:
8248*67e74705SXin Li       return new MipsTargetInfo(Triple, Opts);
8249*67e74705SXin Li     }
8250*67e74705SXin Li 
8251*67e74705SXin Li   case llvm::Triple::mipsel:
8252*67e74705SXin Li     switch (os) {
8253*67e74705SXin Li     case llvm::Triple::Linux:
8254*67e74705SXin Li       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
8255*67e74705SXin Li     case llvm::Triple::RTEMS:
8256*67e74705SXin Li       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
8257*67e74705SXin Li     case llvm::Triple::FreeBSD:
8258*67e74705SXin Li       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
8259*67e74705SXin Li     case llvm::Triple::NetBSD:
8260*67e74705SXin Li       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
8261*67e74705SXin Li     case llvm::Triple::NaCl:
8262*67e74705SXin Li       return new NaClTargetInfo<NaClMips32TargetInfo>(Triple, Opts);
8263*67e74705SXin Li     default:
8264*67e74705SXin Li       return new MipsTargetInfo(Triple, Opts);
8265*67e74705SXin Li     }
8266*67e74705SXin Li 
8267*67e74705SXin Li   case llvm::Triple::mips64:
8268*67e74705SXin Li     switch (os) {
8269*67e74705SXin Li     case llvm::Triple::Linux:
8270*67e74705SXin Li       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
8271*67e74705SXin Li     case llvm::Triple::RTEMS:
8272*67e74705SXin Li       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
8273*67e74705SXin Li     case llvm::Triple::FreeBSD:
8274*67e74705SXin Li       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
8275*67e74705SXin Li     case llvm::Triple::NetBSD:
8276*67e74705SXin Li       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
8277*67e74705SXin Li     case llvm::Triple::OpenBSD:
8278*67e74705SXin Li       return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
8279*67e74705SXin Li     default:
8280*67e74705SXin Li       return new MipsTargetInfo(Triple, Opts);
8281*67e74705SXin Li     }
8282*67e74705SXin Li 
8283*67e74705SXin Li   case llvm::Triple::mips64el:
8284*67e74705SXin Li     switch (os) {
8285*67e74705SXin Li     case llvm::Triple::Linux:
8286*67e74705SXin Li       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
8287*67e74705SXin Li     case llvm::Triple::RTEMS:
8288*67e74705SXin Li       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
8289*67e74705SXin Li     case llvm::Triple::FreeBSD:
8290*67e74705SXin Li       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
8291*67e74705SXin Li     case llvm::Triple::NetBSD:
8292*67e74705SXin Li       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
8293*67e74705SXin Li     case llvm::Triple::OpenBSD:
8294*67e74705SXin Li       return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
8295*67e74705SXin Li     default:
8296*67e74705SXin Li       return new MipsTargetInfo(Triple, Opts);
8297*67e74705SXin Li     }
8298*67e74705SXin Li 
8299*67e74705SXin Li   case llvm::Triple::le32:
8300*67e74705SXin Li     switch (os) {
8301*67e74705SXin Li     case llvm::Triple::NaCl:
8302*67e74705SXin Li       return new NaClTargetInfo<PNaClTargetInfo>(Triple, Opts);
8303*67e74705SXin Li     default:
8304*67e74705SXin Li       return nullptr;
8305*67e74705SXin Li     }
8306*67e74705SXin Li 
8307*67e74705SXin Li   case llvm::Triple::le64:
8308*67e74705SXin Li     return new Le64TargetInfo(Triple, Opts);
8309*67e74705SXin Li 
8310*67e74705SXin Li   case llvm::Triple::ppc:
8311*67e74705SXin Li     if (Triple.isOSDarwin())
8312*67e74705SXin Li       return new DarwinPPC32TargetInfo(Triple, Opts);
8313*67e74705SXin Li     switch (os) {
8314*67e74705SXin Li     case llvm::Triple::Linux:
8315*67e74705SXin Li       return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts);
8316*67e74705SXin Li     case llvm::Triple::FreeBSD:
8317*67e74705SXin Li       return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
8318*67e74705SXin Li     case llvm::Triple::NetBSD:
8319*67e74705SXin Li       return new NetBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
8320*67e74705SXin Li     case llvm::Triple::OpenBSD:
8321*67e74705SXin Li       return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
8322*67e74705SXin Li     case llvm::Triple::RTEMS:
8323*67e74705SXin Li       return new RTEMSTargetInfo<PPC32TargetInfo>(Triple, Opts);
8324*67e74705SXin Li     default:
8325*67e74705SXin Li       return new PPC32TargetInfo(Triple, Opts);
8326*67e74705SXin Li     }
8327*67e74705SXin Li 
8328*67e74705SXin Li   case llvm::Triple::ppc64:
8329*67e74705SXin Li     if (Triple.isOSDarwin())
8330*67e74705SXin Li       return new DarwinPPC64TargetInfo(Triple, Opts);
8331*67e74705SXin Li     switch (os) {
8332*67e74705SXin Li     case llvm::Triple::Linux:
8333*67e74705SXin Li       return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts);
8334*67e74705SXin Li     case llvm::Triple::Lv2:
8335*67e74705SXin Li       return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple, Opts);
8336*67e74705SXin Li     case llvm::Triple::FreeBSD:
8337*67e74705SXin Li       return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
8338*67e74705SXin Li     case llvm::Triple::NetBSD:
8339*67e74705SXin Li       return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
8340*67e74705SXin Li     default:
8341*67e74705SXin Li       return new PPC64TargetInfo(Triple, Opts);
8342*67e74705SXin Li     }
8343*67e74705SXin Li 
8344*67e74705SXin Li   case llvm::Triple::ppc64le:
8345*67e74705SXin Li     switch (os) {
8346*67e74705SXin Li     case llvm::Triple::Linux:
8347*67e74705SXin Li       return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts);
8348*67e74705SXin Li     case llvm::Triple::NetBSD:
8349*67e74705SXin Li       return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
8350*67e74705SXin Li     default:
8351*67e74705SXin Li       return new PPC64TargetInfo(Triple, Opts);
8352*67e74705SXin Li     }
8353*67e74705SXin Li 
8354*67e74705SXin Li   case llvm::Triple::nvptx:
8355*67e74705SXin Li     return new NVPTX32TargetInfo(Triple, Opts);
8356*67e74705SXin Li   case llvm::Triple::nvptx64:
8357*67e74705SXin Li     return new NVPTX64TargetInfo(Triple, Opts);
8358*67e74705SXin Li 
8359*67e74705SXin Li   case llvm::Triple::amdgcn:
8360*67e74705SXin Li   case llvm::Triple::r600:
8361*67e74705SXin Li     return new AMDGPUTargetInfo(Triple, Opts);
8362*67e74705SXin Li 
8363*67e74705SXin Li   case llvm::Triple::sparc:
8364*67e74705SXin Li     switch (os) {
8365*67e74705SXin Li     case llvm::Triple::Linux:
8366*67e74705SXin Li       return new LinuxTargetInfo<SparcV8TargetInfo>(Triple, Opts);
8367*67e74705SXin Li     case llvm::Triple::Solaris:
8368*67e74705SXin Li       return new SolarisTargetInfo<SparcV8TargetInfo>(Triple, Opts);
8369*67e74705SXin Li     case llvm::Triple::NetBSD:
8370*67e74705SXin Li       return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts);
8371*67e74705SXin Li     case llvm::Triple::OpenBSD:
8372*67e74705SXin Li       return new OpenBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts);
8373*67e74705SXin Li     case llvm::Triple::RTEMS:
8374*67e74705SXin Li       return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple, Opts);
8375*67e74705SXin Li     default:
8376*67e74705SXin Li       return new SparcV8TargetInfo(Triple, Opts);
8377*67e74705SXin Li     }
8378*67e74705SXin Li 
8379*67e74705SXin Li   // The 'sparcel' architecture copies all the above cases except for Solaris.
8380*67e74705SXin Li   case llvm::Triple::sparcel:
8381*67e74705SXin Li     switch (os) {
8382*67e74705SXin Li     case llvm::Triple::Linux:
8383*67e74705SXin Li       return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
8384*67e74705SXin Li     case llvm::Triple::NetBSD:
8385*67e74705SXin Li       return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
8386*67e74705SXin Li     case llvm::Triple::OpenBSD:
8387*67e74705SXin Li       return new OpenBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
8388*67e74705SXin Li     case llvm::Triple::RTEMS:
8389*67e74705SXin Li       return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
8390*67e74705SXin Li     default:
8391*67e74705SXin Li       return new SparcV8elTargetInfo(Triple, Opts);
8392*67e74705SXin Li     }
8393*67e74705SXin Li 
8394*67e74705SXin Li   case llvm::Triple::sparcv9:
8395*67e74705SXin Li     switch (os) {
8396*67e74705SXin Li     case llvm::Triple::Linux:
8397*67e74705SXin Li       return new LinuxTargetInfo<SparcV9TargetInfo>(Triple, Opts);
8398*67e74705SXin Li     case llvm::Triple::Solaris:
8399*67e74705SXin Li       return new SolarisTargetInfo<SparcV9TargetInfo>(Triple, Opts);
8400*67e74705SXin Li     case llvm::Triple::NetBSD:
8401*67e74705SXin Li       return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
8402*67e74705SXin Li     case llvm::Triple::OpenBSD:
8403*67e74705SXin Li       return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
8404*67e74705SXin Li     case llvm::Triple::FreeBSD:
8405*67e74705SXin Li       return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
8406*67e74705SXin Li     default:
8407*67e74705SXin Li       return new SparcV9TargetInfo(Triple, Opts);
8408*67e74705SXin Li     }
8409*67e74705SXin Li 
8410*67e74705SXin Li   case llvm::Triple::systemz:
8411*67e74705SXin Li     switch (os) {
8412*67e74705SXin Li     case llvm::Triple::Linux:
8413*67e74705SXin Li       return new LinuxTargetInfo<SystemZTargetInfo>(Triple, Opts);
8414*67e74705SXin Li     default:
8415*67e74705SXin Li       return new SystemZTargetInfo(Triple, Opts);
8416*67e74705SXin Li     }
8417*67e74705SXin Li 
8418*67e74705SXin Li   case llvm::Triple::tce:
8419*67e74705SXin Li     return new TCETargetInfo(Triple, Opts);
8420*67e74705SXin Li 
8421*67e74705SXin Li   case llvm::Triple::x86:
8422*67e74705SXin Li     if (Triple.isOSDarwin())
8423*67e74705SXin Li       return new DarwinI386TargetInfo(Triple, Opts);
8424*67e74705SXin Li 
8425*67e74705SXin Li     switch (os) {
8426*67e74705SXin Li     case llvm::Triple::CloudABI:
8427*67e74705SXin Li       return new CloudABITargetInfo<X86_32TargetInfo>(Triple, Opts);
8428*67e74705SXin Li     case llvm::Triple::Linux: {
8429*67e74705SXin Li       switch (Triple.getEnvironment()) {
8430*67e74705SXin Li       default:
8431*67e74705SXin Li         return new LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts);
8432*67e74705SXin Li       case llvm::Triple::Android:
8433*67e74705SXin Li         return new AndroidX86_32TargetInfo(Triple, Opts);
8434*67e74705SXin Li       }
8435*67e74705SXin Li     }
8436*67e74705SXin Li     case llvm::Triple::DragonFly:
8437*67e74705SXin Li       return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
8438*67e74705SXin Li     case llvm::Triple::NetBSD:
8439*67e74705SXin Li       return new NetBSDI386TargetInfo(Triple, Opts);
8440*67e74705SXin Li     case llvm::Triple::OpenBSD:
8441*67e74705SXin Li       return new OpenBSDI386TargetInfo(Triple, Opts);
8442*67e74705SXin Li     case llvm::Triple::Bitrig:
8443*67e74705SXin Li       return new BitrigI386TargetInfo(Triple, Opts);
8444*67e74705SXin Li     case llvm::Triple::FreeBSD:
8445*67e74705SXin Li       return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
8446*67e74705SXin Li     case llvm::Triple::KFreeBSD:
8447*67e74705SXin Li       return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
8448*67e74705SXin Li     case llvm::Triple::Minix:
8449*67e74705SXin Li       return new MinixTargetInfo<X86_32TargetInfo>(Triple, Opts);
8450*67e74705SXin Li     case llvm::Triple::Solaris:
8451*67e74705SXin Li       return new SolarisTargetInfo<X86_32TargetInfo>(Triple, Opts);
8452*67e74705SXin Li     case llvm::Triple::Win32: {
8453*67e74705SXin Li       switch (Triple.getEnvironment()) {
8454*67e74705SXin Li       case llvm::Triple::Cygnus:
8455*67e74705SXin Li         return new CygwinX86_32TargetInfo(Triple, Opts);
8456*67e74705SXin Li       case llvm::Triple::GNU:
8457*67e74705SXin Li         return new MinGWX86_32TargetInfo(Triple, Opts);
8458*67e74705SXin Li       case llvm::Triple::Itanium:
8459*67e74705SXin Li       case llvm::Triple::MSVC:
8460*67e74705SXin Li       default: // Assume MSVC for unknown environments
8461*67e74705SXin Li         return new MicrosoftX86_32TargetInfo(Triple, Opts);
8462*67e74705SXin Li       }
8463*67e74705SXin Li     }
8464*67e74705SXin Li     case llvm::Triple::Haiku:
8465*67e74705SXin Li       return new HaikuX86_32TargetInfo(Triple, Opts);
8466*67e74705SXin Li     case llvm::Triple::RTEMS:
8467*67e74705SXin Li       return new RTEMSX86_32TargetInfo(Triple, Opts);
8468*67e74705SXin Li     case llvm::Triple::NaCl:
8469*67e74705SXin Li       return new NaClTargetInfo<X86_32TargetInfo>(Triple, Opts);
8470*67e74705SXin Li     case llvm::Triple::ELFIAMCU:
8471*67e74705SXin Li       return new MCUX86_32TargetInfo(Triple, Opts);
8472*67e74705SXin Li     default:
8473*67e74705SXin Li       return new X86_32TargetInfo(Triple, Opts);
8474*67e74705SXin Li     }
8475*67e74705SXin Li 
8476*67e74705SXin Li   case llvm::Triple::x86_64:
8477*67e74705SXin Li     if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO())
8478*67e74705SXin Li       return new DarwinX86_64TargetInfo(Triple, Opts);
8479*67e74705SXin Li 
8480*67e74705SXin Li     switch (os) {
8481*67e74705SXin Li     case llvm::Triple::CloudABI:
8482*67e74705SXin Li       return new CloudABITargetInfo<X86_64TargetInfo>(Triple, Opts);
8483*67e74705SXin Li     case llvm::Triple::Linux: {
8484*67e74705SXin Li       switch (Triple.getEnvironment()) {
8485*67e74705SXin Li       default:
8486*67e74705SXin Li         return new LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts);
8487*67e74705SXin Li       case llvm::Triple::Android:
8488*67e74705SXin Li         return new AndroidX86_64TargetInfo(Triple, Opts);
8489*67e74705SXin Li       }
8490*67e74705SXin Li     }
8491*67e74705SXin Li     case llvm::Triple::DragonFly:
8492*67e74705SXin Li       return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
8493*67e74705SXin Li     case llvm::Triple::NetBSD:
8494*67e74705SXin Li       return new NetBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
8495*67e74705SXin Li     case llvm::Triple::OpenBSD:
8496*67e74705SXin Li       return new OpenBSDX86_64TargetInfo(Triple, Opts);
8497*67e74705SXin Li     case llvm::Triple::Bitrig:
8498*67e74705SXin Li       return new BitrigX86_64TargetInfo(Triple, Opts);
8499*67e74705SXin Li     case llvm::Triple::FreeBSD:
8500*67e74705SXin Li       return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
8501*67e74705SXin Li     case llvm::Triple::KFreeBSD:
8502*67e74705SXin Li       return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
8503*67e74705SXin Li     case llvm::Triple::Solaris:
8504*67e74705SXin Li       return new SolarisTargetInfo<X86_64TargetInfo>(Triple, Opts);
8505*67e74705SXin Li     case llvm::Triple::Win32: {
8506*67e74705SXin Li       switch (Triple.getEnvironment()) {
8507*67e74705SXin Li       case llvm::Triple::Cygnus:
8508*67e74705SXin Li         return new CygwinX86_64TargetInfo(Triple, Opts);
8509*67e74705SXin Li       case llvm::Triple::GNU:
8510*67e74705SXin Li         return new MinGWX86_64TargetInfo(Triple, Opts);
8511*67e74705SXin Li       case llvm::Triple::MSVC:
8512*67e74705SXin Li       default: // Assume MSVC for unknown environments
8513*67e74705SXin Li         return new MicrosoftX86_64TargetInfo(Triple, Opts);
8514*67e74705SXin Li       }
8515*67e74705SXin Li     }
8516*67e74705SXin Li     case llvm::Triple::Haiku:
8517*67e74705SXin Li       return new HaikuTargetInfo<X86_64TargetInfo>(Triple, Opts);
8518*67e74705SXin Li     case llvm::Triple::NaCl:
8519*67e74705SXin Li       return new NaClTargetInfo<X86_64TargetInfo>(Triple, Opts);
8520*67e74705SXin Li     case llvm::Triple::PS4:
8521*67e74705SXin Li       return new PS4OSTargetInfo<X86_64TargetInfo>(Triple, Opts);
8522*67e74705SXin Li     default:
8523*67e74705SXin Li       return new X86_64TargetInfo(Triple, Opts);
8524*67e74705SXin Li     }
8525*67e74705SXin Li 
8526*67e74705SXin Li   case llvm::Triple::spir: {
8527*67e74705SXin Li     if (Triple.getOS() != llvm::Triple::UnknownOS ||
8528*67e74705SXin Li         Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
8529*67e74705SXin Li       return nullptr;
8530*67e74705SXin Li     return new SPIR32TargetInfo(Triple, Opts);
8531*67e74705SXin Li   }
8532*67e74705SXin Li   case llvm::Triple::spir64: {
8533*67e74705SXin Li     if (Triple.getOS() != llvm::Triple::UnknownOS ||
8534*67e74705SXin Li         Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
8535*67e74705SXin Li       return nullptr;
8536*67e74705SXin Li     return new SPIR64TargetInfo(Triple, Opts);
8537*67e74705SXin Li   }
8538*67e74705SXin Li   case llvm::Triple::wasm32:
8539*67e74705SXin Li     if (!(Triple == llvm::Triple("wasm32-unknown-unknown")))
8540*67e74705SXin Li       return nullptr;
8541*67e74705SXin Li     return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
8542*67e74705SXin Li   case llvm::Triple::wasm64:
8543*67e74705SXin Li     if (!(Triple == llvm::Triple("wasm64-unknown-unknown")))
8544*67e74705SXin Li       return nullptr;
8545*67e74705SXin Li     return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
8546*67e74705SXin Li 
8547*67e74705SXin Li   case llvm::Triple::renderscript32:
8548*67e74705SXin Li     return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts);
8549*67e74705SXin Li   case llvm::Triple::renderscript64:
8550*67e74705SXin Li     return new LinuxTargetInfo<RenderScript64TargetInfo>(Triple, Opts);
8551*67e74705SXin Li   }
8552*67e74705SXin Li }
8553*67e74705SXin Li 
8554*67e74705SXin Li /// CreateTargetInfo - Return the target info object for the specified target
8555*67e74705SXin Li /// options.
8556*67e74705SXin Li TargetInfo *
CreateTargetInfo(DiagnosticsEngine & Diags,const std::shared_ptr<TargetOptions> & Opts)8557*67e74705SXin Li TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
8558*67e74705SXin Li                              const std::shared_ptr<TargetOptions> &Opts) {
8559*67e74705SXin Li   llvm::Triple Triple(Opts->Triple);
8560*67e74705SXin Li 
8561*67e74705SXin Li   // Construct the target
8562*67e74705SXin Li   std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple, *Opts));
8563*67e74705SXin Li   if (!Target) {
8564*67e74705SXin Li     Diags.Report(diag::err_target_unknown_triple) << Triple.str();
8565*67e74705SXin Li     return nullptr;
8566*67e74705SXin Li   }
8567*67e74705SXin Li   Target->TargetOpts = Opts;
8568*67e74705SXin Li 
8569*67e74705SXin Li   // Set the target CPU if specified.
8570*67e74705SXin Li   if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
8571*67e74705SXin Li     Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU;
8572*67e74705SXin Li     return nullptr;
8573*67e74705SXin Li   }
8574*67e74705SXin Li 
8575*67e74705SXin Li   // Set the target ABI if specified.
8576*67e74705SXin Li   if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) {
8577*67e74705SXin Li     Diags.Report(diag::err_target_unknown_abi) << Opts->ABI;
8578*67e74705SXin Li     return nullptr;
8579*67e74705SXin Li   }
8580*67e74705SXin Li 
8581*67e74705SXin Li   // Set the fp math unit.
8582*67e74705SXin Li   if (!Opts->FPMath.empty() && !Target->setFPMath(Opts->FPMath)) {
8583*67e74705SXin Li     Diags.Report(diag::err_target_unknown_fpmath) << Opts->FPMath;
8584*67e74705SXin Li     return nullptr;
8585*67e74705SXin Li   }
8586*67e74705SXin Li 
8587*67e74705SXin Li   // Compute the default target features, we need the target to handle this
8588*67e74705SXin Li   // because features may have dependencies on one another.
8589*67e74705SXin Li   llvm::StringMap<bool> Features;
8590*67e74705SXin Li   if (!Target->initFeatureMap(Features, Diags, Opts->CPU,
8591*67e74705SXin Li                               Opts->FeaturesAsWritten))
8592*67e74705SXin Li       return nullptr;
8593*67e74705SXin Li 
8594*67e74705SXin Li   // Add the features to the compile options.
8595*67e74705SXin Li   Opts->Features.clear();
8596*67e74705SXin Li   for (const auto &F : Features)
8597*67e74705SXin Li     Opts->Features.push_back((F.getValue() ? "+" : "-") + F.getKey().str());
8598*67e74705SXin Li 
8599*67e74705SXin Li   if (!Target->handleTargetFeatures(Opts->Features, Diags))
8600*67e74705SXin Li     return nullptr;
8601*67e74705SXin Li 
8602*67e74705SXin Li   Target->setSupportedOpenCLOpts();
8603*67e74705SXin Li 
8604*67e74705SXin Li   if (!Target->validateTarget(Diags))
8605*67e74705SXin Li     return nullptr;
8606*67e74705SXin Li 
8607*67e74705SXin Li   return Target.release();
8608*67e74705SXin Li }
8609