1193326Sed//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This file implements construction of a TargetInfo object from a
11193326Sed// target triple.
12193326Sed//
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15199482Srdivacky#include "clang/Basic/TargetInfo.h"
16194179Sed#include "clang/Basic/Builtins.h"
17199482Srdivacky#include "clang/Basic/Diagnostic.h"
18199482Srdivacky#include "clang/Basic/LangOptions.h"
19202879Srdivacky#include "clang/Basic/MacroBuilder.h"
20194179Sed#include "clang/Basic/TargetBuiltins.h"
21199482Srdivacky#include "clang/Basic/TargetOptions.h"
22193326Sed#include "llvm/ADT/APFloat.h"
23199482Srdivacky#include "llvm/ADT/OwningPtr.h"
24199482Srdivacky#include "llvm/ADT/STLExtras.h"
25198092Srdivacky#include "llvm/ADT/StringRef.h"
26199482Srdivacky#include "llvm/ADT/StringSwitch.h"
27198092Srdivacky#include "llvm/ADT/Triple.h"
28249423Sdim#include "llvm/IR/Type.h"
29198092Srdivacky#include "llvm/MC/MCSectionMachO.h"
30226633Sdim#include "llvm/Support/ErrorHandling.h"
31202379Srdivacky#include <algorithm>
32193326Sedusing namespace clang;
33193326Sed
34193326Sed//===----------------------------------------------------------------------===//
35193326Sed//  Common code shared among targets.
36193326Sed//===----------------------------------------------------------------------===//
37193326Sed
38193326Sed/// DefineStd - Define a macro name and standard variants.  For example if
39193326Sed/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
40193326Sed/// when in GNU mode.
41226633Sdimstatic void DefineStd(MacroBuilder &Builder, StringRef MacroName,
42193326Sed                      const LangOptions &Opts) {
43193326Sed  assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
44193326Sed
45193326Sed  // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
46193326Sed  // in the user's namespace.
47193326Sed  if (Opts.GNUMode)
48202379Srdivacky    Builder.defineMacro(MacroName);
49193326Sed
50193326Sed  // Define __unix.
51202379Srdivacky  Builder.defineMacro("__" + MacroName);
52193326Sed
53193326Sed  // Define __unix__.
54202379Srdivacky  Builder.defineMacro("__" + MacroName + "__");
55193326Sed}
56193326Sed
57234353Sdimstatic void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName,
58234353Sdim                            bool Tuning = true) {
59234353Sdim  Builder.defineMacro("__" + CPUName);
60234353Sdim  Builder.defineMacro("__" + CPUName + "__");
61234353Sdim  if (Tuning)
62234353Sdim    Builder.defineMacro("__tune_" + CPUName + "__");
63234353Sdim}
64234353Sdim
65193326Sed//===----------------------------------------------------------------------===//
66193326Sed// Defines specific to certain operating systems.
67193326Sed//===----------------------------------------------------------------------===//
68198092Srdivacky
69195341Sednamespace {
70195341Sedtemplate<typename TgtInfo>
71195341Sedclass OSTargetInfo : public TgtInfo {
72195341Sedprotected:
73198092Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
74202379Srdivacky                            MacroBuilder &Builder) const=0;
75195341Sedpublic:
76195341Sed  OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
77195341Sed  virtual void getTargetDefines(const LangOptions &Opts,
78202379Srdivacky                                MacroBuilder &Builder) const {
79202379Srdivacky    TgtInfo::getTargetDefines(Opts, Builder);
80202379Srdivacky    getOSDefines(Opts, TgtInfo::getTriple(), Builder);
81193326Sed  }
82193326Sed
83195341Sed};
84198092Srdivacky} // end anonymous namespace
85193326Sed
86193326Sed
87203955Srdivackystatic void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
88221345Sdim                             const llvm::Triple &Triple,
89226633Sdim                             StringRef &PlatformName,
90221345Sdim                             VersionTuple &PlatformMinVersion) {
91202379Srdivacky  Builder.defineMacro("__APPLE_CC__", "5621");
92202379Srdivacky  Builder.defineMacro("__APPLE__");
93202379Srdivacky  Builder.defineMacro("__MACH__");
94202379Srdivacky  Builder.defineMacro("OBJC_NEW_PROPERTIES");
95243830Sdim  // AddressSanitizer doesn't play well with source fortification, which is on
96243830Sdim  // by default on Darwin.
97249423Sdim  if (Opts.Sanitize.Address) Builder.defineMacro("_FORTIFY_SOURCE", "0");
98193326Sed
99224145Sdim  if (!Opts.ObjCAutoRefCount) {
100224145Sdim    // __weak is always defined, for use in blocks and with objc pointers.
101224145Sdim    Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
102193326Sed
103224145Sdim    // Darwin defines __strong even in C mode (just to nothing).
104226633Sdim    if (Opts.getGC() != LangOptions::NonGC)
105224145Sdim      Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
106224145Sdim    else
107224145Sdim      Builder.defineMacro("__strong", "");
108193576Sed
109224145Sdim    // __unsafe_unretained is defined to nothing in non-ARC mode. We even
110224145Sdim    // allow this in C, since one might have block pointers in structs that
111224145Sdim    // are used in pure C code and in Objective-C ARC.
112224145Sdim    Builder.defineMacro("__unsafe_unretained", "");
113224145Sdim  }
114224145Sdim
115193576Sed  if (Opts.Static)
116202379Srdivacky    Builder.defineMacro("__STATIC__");
117193576Sed  else
118202379Srdivacky    Builder.defineMacro("__DYNAMIC__");
119198092Srdivacky
120198092Srdivacky  if (Opts.POSIXThreads)
121202379Srdivacky    Builder.defineMacro("_REENTRANT");
122193326Sed
123221345Sdim  // Get the platform type and version number from the triple.
124193326Sed  unsigned Maj, Min, Rev;
125234353Sdim  if (Triple.isMacOSX()) {
126234353Sdim    Triple.getMacOSXVersion(Maj, Min, Rev);
127221345Sdim    PlatformName = "macosx";
128221345Sdim  } else {
129234353Sdim    Triple.getOSVersion(Maj, Min, Rev);
130234353Sdim    PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
131221345Sdim  }
132221345Sdim
133234353Sdim  // If -target arch-pc-win32-macho option specified, we're
134226633Sdim  // generating code for Win32 ABI. No need to emit
135226633Sdim  // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.
136226633Sdim  if (PlatformName == "win32") {
137226633Sdim    PlatformMinVersion = VersionTuple(Maj, Min, Rev);
138226633Sdim    return;
139226633Sdim  }
140226633Sdim
141203955Srdivacky  // Set the appropriate OS version define.
142234353Sdim  if (Triple.getOS() == llvm::Triple::IOS) {
143221345Sdim    assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
144203955Srdivacky    char Str[6];
145203955Srdivacky    Str[0] = '0' + Maj;
146203955Srdivacky    Str[1] = '0' + (Min / 10);
147203955Srdivacky    Str[2] = '0' + (Min % 10);
148203955Srdivacky    Str[3] = '0' + (Rev / 10);
149203955Srdivacky    Str[4] = '0' + (Rev % 10);
150203955Srdivacky    Str[5] = '\0';
151203955Srdivacky    Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
152203955Srdivacky  } else {
153221345Sdim    // Note that the Driver allows versions which aren't representable in the
154221345Sdim    // define (because we only get a single digit for the minor and micro
155221345Sdim    // revision numbers). So, we limit them to the maximum representable
156221345Sdim    // version.
157203955Srdivacky    assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
158221345Sdim    assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
159203955Srdivacky    char Str[5];
160203955Srdivacky    Str[0] = '0' + (Maj / 10);
161203955Srdivacky    Str[1] = '0' + (Maj % 10);
162221345Sdim    Str[2] = '0' + std::min(Min, 9U);
163221345Sdim    Str[3] = '0' + std::min(Rev, 9U);
164203955Srdivacky    Str[4] = '\0';
165203955Srdivacky    Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
166193326Sed  }
167221345Sdim
168221345Sdim  PlatformMinVersion = VersionTuple(Maj, Min, Rev);
169193326Sed}
170193326Sed
171198092Srdivackynamespace {
172195341Sedtemplate<typename Target>
173195341Sedclass DarwinTargetInfo : public OSTargetInfo<Target> {
174195341Sedprotected:
175198092Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
176202379Srdivacky                            MacroBuilder &Builder) const {
177224145Sdim    getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
178221345Sdim                     this->PlatformMinVersion);
179195341Sed  }
180198092Srdivacky
181195341Sedpublic:
182195341Sed  DarwinTargetInfo(const std::string& triple) :
183195341Sed    OSTargetInfo<Target>(triple) {
184224145Sdim      llvm::Triple T = llvm::Triple(triple);
185224145Sdim      this->TLSSupported = T.isMacOSX() && !T.isMacOSXVersionLT(10,7);
186219077Sdim      this->MCountName = "\01mcount";
187195341Sed    }
188195341Sed
189226633Sdim  virtual std::string isValidSectionSpecifier(StringRef SR) const {
190198092Srdivacky    // Let MCSectionMachO validate this.
191226633Sdim    StringRef Segment, Section;
192198092Srdivacky    unsigned TAA, StubSize;
193221345Sdim    bool HasTAA;
194198092Srdivacky    return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
195221345Sdim                                                       TAA, HasTAA, StubSize);
196195341Sed  }
197218893Sdim
198210299Sed  virtual const char *getStaticInitSectionSpecifier() const {
199210299Sed    // FIXME: We should return 0 when building kexts.
200210299Sed    return "__TEXT,__StaticInit,regular,pure_instructions";
201210299Sed  }
202218893Sdim
203234353Sdim  /// Darwin does not support protected visibility.  Darwin's "default"
204234353Sdim  /// is very similar to ELF's "protected";  Darwin requires a "weak"
205234353Sdim  /// attribute on declarations that can be dynamically replaced.
206234353Sdim  virtual bool hasProtectedVisibility() const {
207234353Sdim    return false;
208234353Sdim  }
209198092Srdivacky};
210195341Sed
211195341Sed
212195341Sed// DragonFlyBSD Target
213195341Sedtemplate<typename Target>
214195341Sedclass DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
215195341Sedprotected:
216198092Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
217202379Srdivacky                            MacroBuilder &Builder) const {
218195341Sed    // DragonFly defines; list based off of gcc output
219202379Srdivacky    Builder.defineMacro("__DragonFly__");
220202379Srdivacky    Builder.defineMacro("__DragonFly_cc_version", "100001");
221202379Srdivacky    Builder.defineMacro("__ELF__");
222202379Srdivacky    Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
223202379Srdivacky    Builder.defineMacro("__tune_i386__");
224202379Srdivacky    DefineStd(Builder, "unix", Opts);
225195341Sed  }
226195341Sedpublic:
227198092Srdivacky  DragonFlyBSDTargetInfo(const std::string &triple)
228234353Sdim    : OSTargetInfo<Target>(triple) {
229234353Sdim      this->UserLabelPrefix = "";
230234353Sdim
231234353Sdim      llvm::Triple Triple(triple);
232234353Sdim      switch (Triple.getArch()) {
233234353Sdim        default:
234234353Sdim        case llvm::Triple::x86:
235234353Sdim        case llvm::Triple::x86_64:
236234353Sdim          this->MCountName = ".mcount";
237234353Sdim          break;
238234353Sdim      }
239234353Sdim  }
240195341Sed};
241195341Sed
242195341Sed// FreeBSD Target
243195341Sedtemplate<typename Target>
244195341Sedclass FreeBSDTargetInfo : public OSTargetInfo<Target> {
245195341Sedprotected:
246198092Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
247202379Srdivacky                            MacroBuilder &Builder) const {
248195341Sed    // FreeBSD defines; list based off of gcc output
249195341Sed
250226518Sdim    unsigned Release = Triple.getOSMajorVersion();
251226518Sdim    if (Release == 0U)
252234353Sdim      Release = 8;
253195341Sed
254226633Sdim    Builder.defineMacro("__FreeBSD__", Twine(Release));
255226633Sdim    Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U));
256202379Srdivacky    Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
257202379Srdivacky    DefineStd(Builder, "unix", Opts);
258202379Srdivacky    Builder.defineMacro("__ELF__");
259195341Sed  }
260195341Sedpublic:
261198092Srdivacky  FreeBSDTargetInfo(const std::string &triple)
262198092Srdivacky    : OSTargetInfo<Target>(triple) {
263198092Srdivacky      this->UserLabelPrefix = "";
264218893Sdim
265218893Sdim      llvm::Triple Triple(triple);
266218893Sdim      switch (Triple.getArch()) {
267218893Sdim        default:
268218893Sdim        case llvm::Triple::x86:
269218893Sdim        case llvm::Triple::x86_64:
270218893Sdim          this->MCountName = ".mcount";
271218893Sdim          break;
272218893Sdim        case llvm::Triple::mips:
273218893Sdim        case llvm::Triple::mipsel:
274218893Sdim        case llvm::Triple::ppc:
275218893Sdim        case llvm::Triple::ppc64:
276218893Sdim          this->MCountName = "_mcount";
277218893Sdim          break;
278218893Sdim        case llvm::Triple::arm:
279218893Sdim          this->MCountName = "__mcount";
280218893Sdim          break;
281218893Sdim      }
282218893Sdim
283198092Srdivacky    }
284195341Sed};
285195341Sed
286210299Sed// Minix Target
287210299Sedtemplate<typename Target>
288210299Sedclass MinixTargetInfo : public OSTargetInfo<Target> {
289210299Sedprotected:
290210299Sed  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
291210299Sed                            MacroBuilder &Builder) const {
292210299Sed    // Minix defines
293210299Sed
294210299Sed    Builder.defineMacro("__minix", "3");
295210299Sed    Builder.defineMacro("_EM_WSIZE", "4");
296210299Sed    Builder.defineMacro("_EM_PSIZE", "4");
297210299Sed    Builder.defineMacro("_EM_SSIZE", "2");
298210299Sed    Builder.defineMacro("_EM_LSIZE", "4");
299210299Sed    Builder.defineMacro("_EM_FSIZE", "4");
300210299Sed    Builder.defineMacro("_EM_DSIZE", "8");
301234353Sdim    Builder.defineMacro("__ELF__");
302210299Sed    DefineStd(Builder, "unix", Opts);
303210299Sed  }
304210299Sedpublic:
305210299Sed  MinixTargetInfo(const std::string &triple)
306210299Sed    : OSTargetInfo<Target>(triple) {
307210299Sed      this->UserLabelPrefix = "";
308210299Sed    }
309210299Sed};
310210299Sed
311195341Sed// Linux target
312195341Sedtemplate<typename Target>
313195341Sedclass LinuxTargetInfo : public OSTargetInfo<Target> {
314195341Sedprotected:
315198092Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
316202379Srdivacky                            MacroBuilder &Builder) const {
317195341Sed    // Linux defines; list based off of gcc output
318202379Srdivacky    DefineStd(Builder, "unix", Opts);
319202379Srdivacky    DefineStd(Builder, "linux", Opts);
320202379Srdivacky    Builder.defineMacro("__gnu_linux__");
321202379Srdivacky    Builder.defineMacro("__ELF__");
322243830Sdim    if (Triple.getEnvironment() == llvm::Triple::Android)
323239462Sdim      Builder.defineMacro("__ANDROID__", "1");
324198092Srdivacky    if (Opts.POSIXThreads)
325202379Srdivacky      Builder.defineMacro("_REENTRANT");
326207619Srdivacky    if (Opts.CPlusPlus)
327207619Srdivacky      Builder.defineMacro("_GNU_SOURCE");
328195341Sed  }
329195341Sedpublic:
330198092Srdivacky  LinuxTargetInfo(const std::string& triple)
331195341Sed    : OSTargetInfo<Target>(triple) {
332195341Sed    this->UserLabelPrefix = "";
333218893Sdim    this->WIntType = TargetInfo::UnsignedInt;
334195341Sed  }
335234353Sdim
336234353Sdim  virtual const char *getStaticInitSectionSpecifier() const {
337234353Sdim    return ".text.startup";
338234353Sdim  }
339195341Sed};
340195341Sed
341198092Srdivacky// NetBSD Target
342198092Srdivackytemplate<typename Target>
343198092Srdivackyclass NetBSDTargetInfo : public OSTargetInfo<Target> {
344198092Srdivackyprotected:
345198092Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
346202379Srdivacky                            MacroBuilder &Builder) const {
347198092Srdivacky    // NetBSD defines; list based off of gcc output
348202379Srdivacky    Builder.defineMacro("__NetBSD__");
349202379Srdivacky    Builder.defineMacro("__unix__");
350202379Srdivacky    Builder.defineMacro("__ELF__");
351198092Srdivacky    if (Opts.POSIXThreads)
352202379Srdivacky      Builder.defineMacro("_POSIX_THREADS");
353198092Srdivacky  }
354198092Srdivackypublic:
355198092Srdivacky  NetBSDTargetInfo(const std::string &triple)
356198092Srdivacky    : OSTargetInfo<Target>(triple) {
357198092Srdivacky      this->UserLabelPrefix = "";
358198092Srdivacky    }
359198092Srdivacky};
360198092Srdivacky
361195341Sed// OpenBSD Target
362195341Sedtemplate<typename Target>
363195341Sedclass OpenBSDTargetInfo : public OSTargetInfo<Target> {
364195341Sedprotected:
365198092Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
366202379Srdivacky                            MacroBuilder &Builder) const {
367195341Sed    // OpenBSD defines; list based off of gcc output
368195341Sed
369202379Srdivacky    Builder.defineMacro("__OpenBSD__");
370202379Srdivacky    DefineStd(Builder, "unix", Opts);
371202379Srdivacky    Builder.defineMacro("__ELF__");
372198092Srdivacky    if (Opts.POSIXThreads)
373234982Sdim      Builder.defineMacro("_REENTRANT");
374195341Sed  }
375195341Sedpublic:
376198092Srdivacky  OpenBSDTargetInfo(const std::string &triple)
377234353Sdim    : OSTargetInfo<Target>(triple) {
378234353Sdim      this->UserLabelPrefix = "";
379239462Sdim      this->TLSSupported = false;
380234353Sdim
381234353Sdim      llvm::Triple Triple(triple);
382234353Sdim      switch (Triple.getArch()) {
383234353Sdim        default:
384234353Sdim        case llvm::Triple::x86:
385234353Sdim        case llvm::Triple::x86_64:
386234353Sdim        case llvm::Triple::arm:
387249423Sdim        case llvm::Triple::sparc:
388234353Sdim          this->MCountName = "__mcount";
389234353Sdim          break;
390234353Sdim        case llvm::Triple::mips64:
391234353Sdim        case llvm::Triple::mips64el:
392234353Sdim        case llvm::Triple::ppc:
393249423Sdim        case llvm::Triple::sparcv9:
394234353Sdim          this->MCountName = "_mcount";
395234353Sdim          break;
396234353Sdim      }
397234353Sdim  }
398195341Sed};
399195341Sed
400239462Sdim// Bitrig Target
401239462Sdimtemplate<typename Target>
402239462Sdimclass BitrigTargetInfo : public OSTargetInfo<Target> {
403239462Sdimprotected:
404239462Sdim  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
405239462Sdim                            MacroBuilder &Builder) const {
406239462Sdim    // Bitrig defines; list based off of gcc output
407239462Sdim
408239462Sdim    Builder.defineMacro("__Bitrig__");
409239462Sdim    DefineStd(Builder, "unix", Opts);
410239462Sdim    Builder.defineMacro("__ELF__");
411239462Sdim    if (Opts.POSIXThreads)
412239462Sdim      Builder.defineMacro("_REENTRANT");
413239462Sdim  }
414239462Sdimpublic:
415239462Sdim  BitrigTargetInfo(const std::string &triple)
416239462Sdim    : OSTargetInfo<Target>(triple) {
417239462Sdim      this->UserLabelPrefix = "";
418239462Sdim      this->TLSSupported = false;
419239462Sdim      this->MCountName = "__mcount";
420239462Sdim  }
421239462Sdim};
422239462Sdim
423199482Srdivacky// PSP Target
424199482Srdivackytemplate<typename Target>
425199482Srdivackyclass PSPTargetInfo : public OSTargetInfo<Target> {
426199482Srdivackyprotected:
427199482Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
428202379Srdivacky                            MacroBuilder &Builder) const {
429199482Srdivacky    // PSP defines; list based on the output of the pspdev gcc toolchain.
430202379Srdivacky    Builder.defineMacro("PSP");
431202379Srdivacky    Builder.defineMacro("_PSP");
432202379Srdivacky    Builder.defineMacro("__psp__");
433202379Srdivacky    Builder.defineMacro("__ELF__");
434199482Srdivacky  }
435199482Srdivackypublic:
436199482Srdivacky  PSPTargetInfo(const std::string& triple)
437199482Srdivacky    : OSTargetInfo<Target>(triple) {
438199482Srdivacky    this->UserLabelPrefix = "";
439199482Srdivacky  }
440199482Srdivacky};
441199482Srdivacky
442199990Srdivacky// PS3 PPU Target
443199990Srdivackytemplate<typename Target>
444199990Srdivackyclass PS3PPUTargetInfo : public OSTargetInfo<Target> {
445199990Srdivackyprotected:
446199990Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
447202379Srdivacky                            MacroBuilder &Builder) const {
448199990Srdivacky    // PS3 PPU defines.
449206084Srdivacky    Builder.defineMacro("__PPC__");
450202379Srdivacky    Builder.defineMacro("__PPU__");
451202379Srdivacky    Builder.defineMacro("__CELLOS_LV2__");
452202379Srdivacky    Builder.defineMacro("__ELF__");
453202379Srdivacky    Builder.defineMacro("__LP32__");
454210299Sed    Builder.defineMacro("_ARCH_PPC64");
455210299Sed    Builder.defineMacro("__powerpc64__");
456199990Srdivacky  }
457199990Srdivackypublic:
458199990Srdivacky  PS3PPUTargetInfo(const std::string& triple)
459199990Srdivacky    : OSTargetInfo<Target>(triple) {
460199990Srdivacky    this->UserLabelPrefix = "";
461234353Sdim    this->LongWidth = this->LongAlign = 32;
462234353Sdim    this->PointerWidth = this->PointerAlign = 32;
463210299Sed    this->IntMaxType = TargetInfo::SignedLongLong;
464210299Sed    this->UIntMaxType = TargetInfo::UnsignedLongLong;
465210299Sed    this->Int64Type = TargetInfo::SignedLongLong;
466201361Srdivacky    this->SizeType = TargetInfo::UnsignedInt;
467210299Sed    this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
468234353Sdim                              "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
469199990Srdivacky  }
470199990Srdivacky};
471199990Srdivacky
472199990Srdivacky// FIXME: Need a real SPU target.
473199990Srdivacky// PS3 SPU Target
474199990Srdivackytemplate<typename Target>
475199990Srdivackyclass PS3SPUTargetInfo : public OSTargetInfo<Target> {
476199990Srdivackyprotected:
477199990Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
478202379Srdivacky                            MacroBuilder &Builder) const {
479199990Srdivacky    // PS3 PPU defines.
480202379Srdivacky    Builder.defineMacro("__SPU__");
481202379Srdivacky    Builder.defineMacro("__ELF__");
482199990Srdivacky  }
483199990Srdivackypublic:
484199990Srdivacky  PS3SPUTargetInfo(const std::string& triple)
485199990Srdivacky    : OSTargetInfo<Target>(triple) {
486199990Srdivacky    this->UserLabelPrefix = "";
487199990Srdivacky  }
488199990Srdivacky};
489199990Srdivacky
490198398Srdivacky// AuroraUX target
491198398Srdivackytemplate<typename Target>
492198398Srdivackyclass AuroraUXTargetInfo : public OSTargetInfo<Target> {
493198398Srdivackyprotected:
494198398Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
495202379Srdivacky                            MacroBuilder &Builder) const {
496202379Srdivacky    DefineStd(Builder, "sun", Opts);
497202379Srdivacky    DefineStd(Builder, "unix", Opts);
498202379Srdivacky    Builder.defineMacro("__ELF__");
499202379Srdivacky    Builder.defineMacro("__svr4__");
500202379Srdivacky    Builder.defineMacro("__SVR4");
501198398Srdivacky  }
502198398Srdivackypublic:
503198398Srdivacky  AuroraUXTargetInfo(const std::string& triple)
504198398Srdivacky    : OSTargetInfo<Target>(triple) {
505198398Srdivacky    this->UserLabelPrefix = "";
506198398Srdivacky    this->WCharType = this->SignedLong;
507198398Srdivacky    // FIXME: WIntType should be SignedLong
508198398Srdivacky  }
509198398Srdivacky};
510198398Srdivacky
511195341Sed// Solaris target
512195341Sedtemplate<typename Target>
513195341Sedclass SolarisTargetInfo : public OSTargetInfo<Target> {
514195341Sedprotected:
515198092Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
516202379Srdivacky                            MacroBuilder &Builder) const {
517202379Srdivacky    DefineStd(Builder, "sun", Opts);
518202379Srdivacky    DefineStd(Builder, "unix", Opts);
519202379Srdivacky    Builder.defineMacro("__ELF__");
520202379Srdivacky    Builder.defineMacro("__svr4__");
521202379Srdivacky    Builder.defineMacro("__SVR4");
522234353Sdim    // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
523234353Sdim    // newer, but to 500 for everything else.  feature_test.h has a check to
524234353Sdim    // ensure that you are not using C99 with an old version of X/Open or C89
525234353Sdim    // with a new version.
526234353Sdim    if (Opts.C99 || Opts.C11)
527234353Sdim      Builder.defineMacro("_XOPEN_SOURCE", "600");
528234353Sdim    else
529234353Sdim      Builder.defineMacro("_XOPEN_SOURCE", "500");
530234353Sdim    if (Opts.CPlusPlus)
531234353Sdim      Builder.defineMacro("__C99FEATURES__");
532234353Sdim    Builder.defineMacro("_LARGEFILE_SOURCE");
533234353Sdim    Builder.defineMacro("_LARGEFILE64_SOURCE");
534234353Sdim    Builder.defineMacro("__EXTENSIONS__");
535234353Sdim    Builder.defineMacro("_REENTRANT");
536195341Sed  }
537195341Sedpublic:
538198092Srdivacky  SolarisTargetInfo(const std::string& triple)
539195341Sed    : OSTargetInfo<Target>(triple) {
540195341Sed    this->UserLabelPrefix = "";
541234353Sdim    this->WCharType = this->SignedInt;
542195341Sed    // FIXME: WIntType should be SignedLong
543195341Sed  }
544195341Sed};
545218893Sdim
546218893Sdim// Windows target
547218893Sdimtemplate<typename Target>
548218893Sdimclass WindowsTargetInfo : public OSTargetInfo<Target> {
549218893Sdimprotected:
550218893Sdim  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
551218893Sdim                            MacroBuilder &Builder) const {
552218893Sdim    Builder.defineMacro("_WIN32");
553218893Sdim  }
554218893Sdim  void getVisualStudioDefines(const LangOptions &Opts,
555218893Sdim                              MacroBuilder &Builder) const {
556218893Sdim    if (Opts.CPlusPlus) {
557218893Sdim      if (Opts.RTTI)
558218893Sdim        Builder.defineMacro("_CPPRTTI");
559218893Sdim
560218893Sdim      if (Opts.Exceptions)
561218893Sdim        Builder.defineMacro("_CPPUNWIND");
562218893Sdim    }
563218893Sdim
564218893Sdim    if (!Opts.CharIsSigned)
565218893Sdim      Builder.defineMacro("_CHAR_UNSIGNED");
566218893Sdim
567218893Sdim    // FIXME: POSIXThreads isn't exactly the option this should be defined for,
568218893Sdim    //        but it works for now.
569218893Sdim    if (Opts.POSIXThreads)
570218893Sdim      Builder.defineMacro("_MT");
571218893Sdim
572218893Sdim    if (Opts.MSCVersion != 0)
573226633Sdim      Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion));
574218893Sdim
575226633Sdim    if (Opts.MicrosoftExt) {
576218893Sdim      Builder.defineMacro("_MSC_EXTENSIONS");
577218893Sdim
578249423Sdim      if (Opts.CPlusPlus11) {
579218893Sdim        Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
580218893Sdim        Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
581218893Sdim        Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
582218893Sdim      }
583218893Sdim    }
584218893Sdim
585218893Sdim    Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
586218893Sdim  }
587218893Sdim
588218893Sdimpublic:
589218893Sdim  WindowsTargetInfo(const std::string &triple)
590218893Sdim    : OSTargetInfo<Target>(triple) {}
591218893Sdim};
592218893Sdim
593243830Sdimtemplate <typename Target>
594243830Sdimclass NaClTargetInfo : public OSTargetInfo<Target> {
595243830Sdim protected:
596243830Sdim  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
597243830Sdim                            MacroBuilder &Builder) const {
598243830Sdim    if (Opts.POSIXThreads)
599243830Sdim      Builder.defineMacro("_REENTRANT");
600243830Sdim    if (Opts.CPlusPlus)
601243830Sdim      Builder.defineMacro("_GNU_SOURCE");
602243830Sdim
603243830Sdim    DefineStd(Builder, "unix", Opts);
604243830Sdim    Builder.defineMacro("__ELF__");
605243830Sdim    Builder.defineMacro("__native_client__");
606243830Sdim  }
607243830Sdim public:
608243830Sdim  NaClTargetInfo(const std::string &triple)
609243830Sdim    : OSTargetInfo<Target>(triple) {
610243830Sdim    this->UserLabelPrefix = "";
611243830Sdim    this->LongAlign = 32;
612243830Sdim    this->LongWidth = 32;
613243830Sdim    this->PointerAlign = 32;
614243830Sdim    this->PointerWidth = 32;
615243830Sdim    this->IntMaxType = TargetInfo::SignedLongLong;
616243830Sdim    this->UIntMaxType = TargetInfo::UnsignedLongLong;
617243830Sdim    this->Int64Type = TargetInfo::SignedLongLong;
618243830Sdim    this->DoubleAlign = 64;
619243830Sdim    this->LongDoubleWidth = 64;
620243830Sdim    this->LongDoubleAlign = 64;
621243830Sdim    this->SizeType = TargetInfo::UnsignedInt;
622243830Sdim    this->PtrDiffType = TargetInfo::SignedInt;
623243830Sdim    this->IntPtrType = TargetInfo::SignedInt;
624251662Sdim    // RegParmMax is inherited from the underlying architecture
625243830Sdim    this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
626243830Sdim    this->DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
627243830Sdim                              "f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
628243830Sdim  }
629243830Sdim  virtual typename Target::CallingConvCheckResult checkCallingConvention(
630243830Sdim      CallingConv CC) const {
631243830Sdim    return CC == CC_PnaclCall ? Target::CCCR_OK :
632243830Sdim        Target::checkCallingConvention(CC);
633243830Sdim  }
634243830Sdim};
635198092Srdivacky} // end anonymous namespace.
636195341Sed
637193326Sed//===----------------------------------------------------------------------===//
638193326Sed// Specific target implementations.
639193326Sed//===----------------------------------------------------------------------===//
640193326Sed
641193326Sednamespace {
642193326Sed// PPC abstract base class
643193326Sedclass PPCTargetInfo : public TargetInfo {
644193326Sed  static const Builtin::Info BuiltinInfo[];
645193326Sed  static const char * const GCCRegNames[];
646193326Sed  static const TargetInfo::GCCRegAlias GCCRegAliases[];
647239462Sdim  std::string CPU;
648193326Sedpublic:
649234353Sdim  PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
650234353Sdim    LongDoubleWidth = LongDoubleAlign = 128;
651234353Sdim    LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
652234353Sdim  }
653193576Sed
654239462Sdim  /// \brief Flags for architecture specific defines.
655239462Sdim  typedef enum {
656239462Sdim    ArchDefineNone  = 0,
657239462Sdim    ArchDefineName  = 1 << 0, // <name> is substituted for arch name.
658239462Sdim    ArchDefinePpcgr = 1 << 1,
659239462Sdim    ArchDefinePpcsq = 1 << 2,
660239462Sdim    ArchDefine440   = 1 << 3,
661239462Sdim    ArchDefine603   = 1 << 4,
662239462Sdim    ArchDefine604   = 1 << 5,
663239462Sdim    ArchDefinePwr4  = 1 << 6,
664249423Sdim    ArchDefinePwr5  = 1 << 7,
665249423Sdim    ArchDefinePwr5x = 1 << 8,
666249423Sdim    ArchDefinePwr6  = 1 << 9,
667249423Sdim    ArchDefinePwr6x = 1 << 10,
668249423Sdim    ArchDefinePwr7  = 1 << 11,
669249423Sdim    ArchDefineA2    = 1 << 12,
670249423Sdim    ArchDefineA2q   = 1 << 13
671239462Sdim  } ArchDefineTypes;
672239462Sdim
673249423Sdim  // Note: GCC recognizes the following additional cpus:
674249423Sdim  //  401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801,
675249423Sdim  //  821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell,
676249423Sdim  //  titan, rs64.
677239462Sdim  virtual bool setCPU(const std::string &Name) {
678239462Sdim    bool CPUKnown = llvm::StringSwitch<bool>(Name)
679239462Sdim      .Case("generic", true)
680239462Sdim      .Case("440", true)
681239462Sdim      .Case("450", true)
682239462Sdim      .Case("601", true)
683239462Sdim      .Case("602", true)
684239462Sdim      .Case("603", true)
685239462Sdim      .Case("603e", true)
686239462Sdim      .Case("603ev", true)
687239462Sdim      .Case("604", true)
688239462Sdim      .Case("604e", true)
689239462Sdim      .Case("620", true)
690249423Sdim      .Case("630", true)
691239462Sdim      .Case("g3", true)
692239462Sdim      .Case("7400", true)
693239462Sdim      .Case("g4", true)
694239462Sdim      .Case("7450", true)
695239462Sdim      .Case("g4+", true)
696239462Sdim      .Case("750", true)
697239462Sdim      .Case("970", true)
698239462Sdim      .Case("g5", true)
699239462Sdim      .Case("a2", true)
700249423Sdim      .Case("a2q", true)
701243830Sdim      .Case("e500mc", true)
702243830Sdim      .Case("e5500", true)
703249423Sdim      .Case("power3", true)
704249423Sdim      .Case("pwr3", true)
705249423Sdim      .Case("power4", true)
706249423Sdim      .Case("pwr4", true)
707249423Sdim      .Case("power5", true)
708249423Sdim      .Case("pwr5", true)
709249423Sdim      .Case("power5x", true)
710249423Sdim      .Case("pwr5x", true)
711249423Sdim      .Case("power6", true)
712239462Sdim      .Case("pwr6", true)
713249423Sdim      .Case("power6x", true)
714249423Sdim      .Case("pwr6x", true)
715249423Sdim      .Case("power7", true)
716239462Sdim      .Case("pwr7", true)
717249423Sdim      .Case("powerpc", true)
718239462Sdim      .Case("ppc", true)
719249423Sdim      .Case("powerpc64", true)
720239462Sdim      .Case("ppc64", true)
721239462Sdim      .Default(false);
722239462Sdim
723239462Sdim    if (CPUKnown)
724239462Sdim      CPU = Name;
725239462Sdim
726239462Sdim    return CPUKnown;
727239462Sdim  }
728239462Sdim
729193326Sed  virtual void getTargetBuiltins(const Builtin::Info *&Records,
730193326Sed                                 unsigned &NumRecords) const {
731193326Sed    Records = BuiltinInfo;
732193326Sed    NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
733193326Sed  }
734193326Sed
735234353Sdim  virtual bool isCLZForZeroUndef() const { return false; }
736234353Sdim
737193326Sed  virtual void getTargetDefines(const LangOptions &Opts,
738202379Srdivacky                                MacroBuilder &Builder) const;
739193326Sed
740249423Sdim  virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
741249423Sdim
742249423Sdim  virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
743249423Sdim                                 StringRef Name,
744249423Sdim                                 bool Enabled) const;
745249423Sdim
746234353Sdim  virtual bool hasFeature(StringRef Feature) const;
747234353Sdim
748193326Sed  virtual void getGCCRegNames(const char * const *&Names,
749193326Sed                              unsigned &NumNames) const;
750193326Sed  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
751193326Sed                                unsigned &NumAliases) const;
752193326Sed  virtual bool validateAsmConstraint(const char *&Name,
753193326Sed                                     TargetInfo::ConstraintInfo &Info) const {
754193326Sed    switch (*Name) {
755193326Sed    default: return false;
756193326Sed    case 'O': // Zero
757210299Sed      break;
758193326Sed    case 'b': // Base register
759193326Sed    case 'f': // Floating point register
760193326Sed      Info.setAllowsRegister();
761210299Sed      break;
762210299Sed    // FIXME: The following are added to allow parsing.
763210299Sed    // I just took a guess at what the actions should be.
764210299Sed    // Also, is more specific checking needed?  I.e. specific registers?
765218893Sdim    case 'd': // Floating point register (containing 64-bit value)
766210299Sed    case 'v': // Altivec vector register
767210299Sed      Info.setAllowsRegister();
768210299Sed      break;
769210299Sed    case 'w':
770210299Sed      switch (Name[1]) {
771218893Sdim        case 'd':// VSX vector register to hold vector double data
772218893Sdim        case 'f':// VSX vector register to hold vector float data
773218893Sdim        case 's':// VSX vector register to hold scalar float data
774218893Sdim        case 'a':// Any VSX register
775210299Sed          break;
776210299Sed        default:
777210299Sed          return false;
778210299Sed      }
779210299Sed      Info.setAllowsRegister();
780210299Sed      Name++; // Skip over 'w'.
781210299Sed      break;
782218893Sdim    case 'h': // `MQ', `CTR', or `LINK' register
783218893Sdim    case 'q': // `MQ' register
784218893Sdim    case 'c': // `CTR' register
785218893Sdim    case 'l': // `LINK' register
786218893Sdim    case 'x': // `CR' register (condition register) number 0
787218893Sdim    case 'y': // `CR' register (condition register)
788218893Sdim    case 'z': // `XER[CA]' carry bit (part of the XER register)
789210299Sed      Info.setAllowsRegister();
790210299Sed      break;
791218893Sdim    case 'I': // Signed 16-bit constant
792210299Sed    case 'J': // Unsigned 16-bit constant shifted left 16 bits
793218893Sdim              //  (use `L' instead for SImode constants)
794218893Sdim    case 'K': // Unsigned 16-bit constant
795218893Sdim    case 'L': // Signed 16-bit constant shifted left 16 bits
796218893Sdim    case 'M': // Constant larger than 31
797218893Sdim    case 'N': // Exact power of 2
798218893Sdim    case 'P': // Constant whose negation is a signed 16-bit constant
799210299Sed    case 'G': // Floating point constant that can be loaded into a
800218893Sdim              // register with one instruction per word
801210299Sed    case 'H': // Integer/Floating point constant that can be loaded
802218893Sdim              // into a register using three instructions
803210299Sed      break;
804210299Sed    case 'm': // Memory operand. Note that on PowerPC targets, m can
805210299Sed              // include addresses that update the base register. It
806210299Sed              // is therefore only safe to use `m' in an asm statement
807210299Sed              // if that asm statement accesses the operand exactly once.
808210299Sed              // The asm statement must also use `%U<opno>' as a
809212904Sdim              // placeholder for the "update" flag in the corresponding
810218893Sdim              // load or store instruction. For example:
811210299Sed              // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
812218893Sdim              // is correct but:
813210299Sed              // asm ("st %1,%0" : "=m" (mem) : "r" (val));
814210299Sed              // is not. Use es rather than m if you don't want the base
815218893Sdim              // register to be updated.
816218893Sdim    case 'e':
817210299Sed      if (Name[1] != 's')
818210299Sed          return false;
819212904Sdim              // es: A "stable" memory operand; that is, one which does not
820210299Sed              // include any automodification of the base register. Unlike
821210299Sed              // `m', this constraint can be used in asm statements that
822210299Sed              // might access the operand several times, or that might not
823210299Sed              // access it at all.
824210299Sed      Info.setAllowsMemory();
825210299Sed      Name++; // Skip over 'e'.
826210299Sed      break;
827210299Sed    case 'Q': // Memory operand that is an offset from a register (it is
828218893Sdim              // usually better to use `m' or `es' in asm statements)
829210299Sed    case 'Z': // Memory operand that is an indexed or indirect from a
830210299Sed              // register (it is usually better to use `m' or `es' in
831218893Sdim              // asm statements)
832210299Sed      Info.setAllowsMemory();
833210299Sed      Info.setAllowsRegister();
834210299Sed      break;
835218893Sdim    case 'R': // AIX TOC entry
836210299Sed    case 'a': // Address operand that is an indexed or indirect from a
837218893Sdim              // register (`p' is preferable for asm statements)
838218893Sdim    case 'S': // Constant suitable as a 64-bit mask operand
839218893Sdim    case 'T': // Constant suitable as a 32-bit mask operand
840218893Sdim    case 'U': // System V Release 4 small data area reference
841210299Sed    case 't': // AND masks that can be performed by two rldic{l, r}
842218893Sdim              // instructions
843218893Sdim    case 'W': // Vector constant that does not require memory
844218893Sdim    case 'j': // Vector constant that is all zeros.
845210299Sed      break;
846210299Sed    // End FIXME.
847193326Sed    }
848210299Sed    return true;
849193326Sed  }
850193326Sed  virtual const char *getClobbers() const {
851193326Sed    return "";
852193326Sed  }
853249423Sdim  int getEHDataRegisterNumber(unsigned RegNo) const {
854249423Sdim    if (RegNo == 0) return 3;
855249423Sdim    if (RegNo == 1) return 4;
856249423Sdim    return -1;
857249423Sdim  }
858193326Sed};
859193326Sed
860193326Sedconst Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
861224145Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
862218893Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
863224145Sdim                                              ALL_LANGUAGES },
864194179Sed#include "clang/Basic/BuiltinsPPC.def"
865193326Sed};
866193326Sed
867193326Sed
868193326Sed/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
869193326Sed/// #defines that are not tied to a specific subtarget.
870193326Sedvoid PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
871202379Srdivacky                                     MacroBuilder &Builder) const {
872193326Sed  // Target identification.
873202379Srdivacky  Builder.defineMacro("__ppc__");
874202379Srdivacky  Builder.defineMacro("_ARCH_PPC");
875204643Srdivacky  Builder.defineMacro("__powerpc__");
876202379Srdivacky  Builder.defineMacro("__POWERPC__");
877193326Sed  if (PointerWidth == 64) {
878202379Srdivacky    Builder.defineMacro("_ARCH_PPC64");
879204643Srdivacky    Builder.defineMacro("__powerpc64__");
880202379Srdivacky    Builder.defineMacro("__ppc64__");
881193326Sed  } else {
882202379Srdivacky    Builder.defineMacro("__ppc__");
883193326Sed  }
884193326Sed
885193326Sed  // Target properties.
886239462Sdim  if (getTriple().getOS() != llvm::Triple::NetBSD &&
887239462Sdim      getTriple().getOS() != llvm::Triple::OpenBSD)
888224145Sdim    Builder.defineMacro("_BIG_ENDIAN");
889202379Srdivacky  Builder.defineMacro("__BIG_ENDIAN__");
890193326Sed
891193326Sed  // Subtarget options.
892202379Srdivacky  Builder.defineMacro("__NATURAL_ALIGNMENT__");
893202379Srdivacky  Builder.defineMacro("__REGISTER_PREFIX__", "");
894193326Sed
895193326Sed  // FIXME: Should be controlled by command line option.
896202379Srdivacky  Builder.defineMacro("__LONG_DOUBLE_128__");
897218893Sdim
898199990Srdivacky  if (Opts.AltiVec) {
899202379Srdivacky    Builder.defineMacro("__VEC__", "10206");
900202379Srdivacky    Builder.defineMacro("__ALTIVEC__");
901199990Srdivacky  }
902239462Sdim
903239462Sdim  // CPU identification.
904239462Sdim  ArchDefineTypes defs = (ArchDefineTypes)llvm::StringSwitch<int>(CPU)
905239462Sdim    .Case("440",   ArchDefineName)
906239462Sdim    .Case("450",   ArchDefineName | ArchDefine440)
907239462Sdim    .Case("601",   ArchDefineName)
908239462Sdim    .Case("602",   ArchDefineName | ArchDefinePpcgr)
909239462Sdim    .Case("603",   ArchDefineName | ArchDefinePpcgr)
910239462Sdim    .Case("603e",  ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
911239462Sdim    .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
912239462Sdim    .Case("604",   ArchDefineName | ArchDefinePpcgr)
913239462Sdim    .Case("604e",  ArchDefineName | ArchDefine604 | ArchDefinePpcgr)
914239462Sdim    .Case("620",   ArchDefineName | ArchDefinePpcgr)
915249423Sdim    .Case("630",   ArchDefineName | ArchDefinePpcgr)
916239462Sdim    .Case("7400",  ArchDefineName | ArchDefinePpcgr)
917239462Sdim    .Case("7450",  ArchDefineName | ArchDefinePpcgr)
918239462Sdim    .Case("750",   ArchDefineName | ArchDefinePpcgr)
919239462Sdim    .Case("970",   ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
920239462Sdim                     | ArchDefinePpcsq)
921249423Sdim    .Case("a2",    ArchDefineA2)
922249423Sdim    .Case("a2q",   ArchDefineName | ArchDefineA2 | ArchDefineA2q)
923249423Sdim    .Case("pwr3",  ArchDefinePpcgr)
924249423Sdim    .Case("pwr4",  ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq)
925249423Sdim    .Case("pwr5",  ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
926239462Sdim                     | ArchDefinePpcsq)
927249423Sdim    .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4
928249423Sdim                     | ArchDefinePpcgr | ArchDefinePpcsq)
929249423Sdim    .Case("pwr6",  ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5
930249423Sdim                     | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
931249423Sdim    .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x
932249423Sdim                     | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
933249423Sdim                     | ArchDefinePpcsq)
934249423Sdim    .Case("pwr7",  ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6
935249423Sdim                     | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
936249423Sdim                     | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
937249423Sdim    .Case("power3",  ArchDefinePpcgr)
938249423Sdim    .Case("power4",  ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
939249423Sdim    .Case("power5",  ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
940249423Sdim                       | ArchDefinePpcsq)
941249423Sdim    .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
942249423Sdim                       | ArchDefinePpcgr | ArchDefinePpcsq)
943249423Sdim    .Case("power6",  ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
944249423Sdim                       | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
945249423Sdim    .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x
946249423Sdim                       | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
947249423Sdim                       | ArchDefinePpcsq)
948249423Sdim    .Case("power7",  ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6
949249423Sdim                       | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
950249423Sdim                       | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
951239462Sdim    .Default(ArchDefineNone);
952239462Sdim
953239462Sdim  if (defs & ArchDefineName)
954239462Sdim    Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
955239462Sdim  if (defs & ArchDefinePpcgr)
956239462Sdim    Builder.defineMacro("_ARCH_PPCGR");
957239462Sdim  if (defs & ArchDefinePpcsq)
958239462Sdim    Builder.defineMacro("_ARCH_PPCSQ");
959239462Sdim  if (defs & ArchDefine440)
960239462Sdim    Builder.defineMacro("_ARCH_440");
961239462Sdim  if (defs & ArchDefine603)
962239462Sdim    Builder.defineMacro("_ARCH_603");
963239462Sdim  if (defs & ArchDefine604)
964239462Sdim    Builder.defineMacro("_ARCH_604");
965249423Sdim  if (defs & ArchDefinePwr4)
966239462Sdim    Builder.defineMacro("_ARCH_PWR4");
967249423Sdim  if (defs & ArchDefinePwr5)
968239462Sdim    Builder.defineMacro("_ARCH_PWR5");
969249423Sdim  if (defs & ArchDefinePwr5x)
970249423Sdim    Builder.defineMacro("_ARCH_PWR5X");
971249423Sdim  if (defs & ArchDefinePwr6)
972239462Sdim    Builder.defineMacro("_ARCH_PWR6");
973249423Sdim  if (defs & ArchDefinePwr6x)
974249423Sdim    Builder.defineMacro("_ARCH_PWR6X");
975249423Sdim  if (defs & ArchDefinePwr7)
976249423Sdim    Builder.defineMacro("_ARCH_PWR7");
977249423Sdim  if (defs & ArchDefineA2)
978249423Sdim    Builder.defineMacro("_ARCH_A2");
979249423Sdim  if (defs & ArchDefineA2q) {
980249423Sdim    Builder.defineMacro("_ARCH_A2Q");
981249423Sdim    Builder.defineMacro("_ARCH_QP");
982239462Sdim  }
983249423Sdim
984249423Sdim  if (getTriple().getVendor() == llvm::Triple::BGQ) {
985249423Sdim    Builder.defineMacro("__bg__");
986249423Sdim    Builder.defineMacro("__THW_BLUEGENE__");
987249423Sdim    Builder.defineMacro("__bgq__");
988249423Sdim    Builder.defineMacro("__TOS_BGQ__");
989249423Sdim  }
990249423Sdim
991249423Sdim  // FIXME: The following are not yet generated here by Clang, but are
992249423Sdim  //        generated by GCC:
993249423Sdim  //
994249423Sdim  //   _SOFT_FLOAT_
995249423Sdim  //   __RECIP_PRECISION__
996249423Sdim  //   __APPLE_ALTIVEC__
997249423Sdim  //   __VSX__
998249423Sdim  //   __RECIP__
999249423Sdim  //   __RECIPF__
1000249423Sdim  //   __RSQRTE__
1001249423Sdim  //   __RSQRTEF__
1002249423Sdim  //   _SOFT_DOUBLE_
1003249423Sdim  //   __NO_LWSYNC__
1004249423Sdim  //   __HAVE_BSWAP__
1005249423Sdim  //   __LONGDOUBLE128
1006249423Sdim  //   __CMODEL_MEDIUM__
1007249423Sdim  //   __CMODEL_LARGE__
1008249423Sdim  //   _CALL_SYSV
1009249423Sdim  //   _CALL_DARWIN
1010249423Sdim  //   __NO_FPRS__
1011193326Sed}
1012193326Sed
1013249423Sdimvoid PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
1014249423Sdim  Features["altivec"] = llvm::StringSwitch<bool>(CPU)
1015249423Sdim    .Case("7400", true)
1016249423Sdim    .Case("g4", true)
1017249423Sdim    .Case("7450", true)
1018249423Sdim    .Case("g4+", true)
1019249423Sdim    .Case("970", true)
1020249423Sdim    .Case("g5", true)
1021249423Sdim    .Case("pwr6", true)
1022249423Sdim    .Case("pwr7", true)
1023249423Sdim    .Case("ppc64", true)
1024249423Sdim    .Default(false);
1025249423Sdim
1026249423Sdim  Features["qpx"] = (CPU == "a2q");
1027249423Sdim}
1028249423Sdim
1029249423Sdimbool PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
1030249423Sdim                                         StringRef Name,
1031249423Sdim                                         bool Enabled) const {
1032249423Sdim  if (Name == "altivec" || Name == "fprnd" || Name == "mfocrf" ||
1033249423Sdim      Name == "popcntd" || Name == "qpx") {
1034249423Sdim    Features[Name] = Enabled;
1035249423Sdim    return true;
1036249423Sdim  }
1037249423Sdim
1038249423Sdim  return false;
1039249423Sdim}
1040249423Sdim
1041234353Sdimbool PPCTargetInfo::hasFeature(StringRef Feature) const {
1042234353Sdim  return Feature == "powerpc";
1043234353Sdim}
1044193326Sed
1045234353Sdim
1046193326Sedconst char * const PPCTargetInfo::GCCRegNames[] = {
1047198092Srdivacky  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1048198092Srdivacky  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1049198092Srdivacky  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1050198092Srdivacky  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
1051198092Srdivacky  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1052198092Srdivacky  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1053198092Srdivacky  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1054198092Srdivacky  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1055193326Sed  "mq", "lr", "ctr", "ap",
1056198092Srdivacky  "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
1057193326Sed  "xer",
1058198092Srdivacky  "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
1059198092Srdivacky  "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
1060198092Srdivacky  "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
1061198092Srdivacky  "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
1062193326Sed  "vrsave", "vscr",
1063193326Sed  "spe_acc", "spefscr",
1064193326Sed  "sfp"
1065193326Sed};
1066193326Sed
1067193326Sedvoid PPCTargetInfo::getGCCRegNames(const char * const *&Names,
1068193326Sed                                   unsigned &NumNames) const {
1069193326Sed  Names = GCCRegNames;
1070193326Sed  NumNames = llvm::array_lengthof(GCCRegNames);
1071193326Sed}
1072193326Sed
1073193326Sedconst TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
1074193326Sed  // While some of these aliases do map to different registers
1075193326Sed  // they still share the same register name.
1076198092Srdivacky  { { "0" }, "r0" },
1077198092Srdivacky  { { "1"}, "r1" },
1078198092Srdivacky  { { "2" }, "r2" },
1079198092Srdivacky  { { "3" }, "r3" },
1080198092Srdivacky  { { "4" }, "r4" },
1081198092Srdivacky  { { "5" }, "r5" },
1082198092Srdivacky  { { "6" }, "r6" },
1083198092Srdivacky  { { "7" }, "r7" },
1084198092Srdivacky  { { "8" }, "r8" },
1085198092Srdivacky  { { "9" }, "r9" },
1086198092Srdivacky  { { "10" }, "r10" },
1087198092Srdivacky  { { "11" }, "r11" },
1088198092Srdivacky  { { "12" }, "r12" },
1089198092Srdivacky  { { "13" }, "r13" },
1090198092Srdivacky  { { "14" }, "r14" },
1091198092Srdivacky  { { "15" }, "r15" },
1092198092Srdivacky  { { "16" }, "r16" },
1093198092Srdivacky  { { "17" }, "r17" },
1094198092Srdivacky  { { "18" }, "r18" },
1095198092Srdivacky  { { "19" }, "r19" },
1096198092Srdivacky  { { "20" }, "r20" },
1097198092Srdivacky  { { "21" }, "r21" },
1098198092Srdivacky  { { "22" }, "r22" },
1099198092Srdivacky  { { "23" }, "r23" },
1100198092Srdivacky  { { "24" }, "r24" },
1101198092Srdivacky  { { "25" }, "r25" },
1102198092Srdivacky  { { "26" }, "r26" },
1103198092Srdivacky  { { "27" }, "r27" },
1104198092Srdivacky  { { "28" }, "r28" },
1105198092Srdivacky  { { "29" }, "r29" },
1106198092Srdivacky  { { "30" }, "r30" },
1107198092Srdivacky  { { "31" }, "r31" },
1108198092Srdivacky  { { "fr0" }, "f0" },
1109198092Srdivacky  { { "fr1" }, "f1" },
1110198092Srdivacky  { { "fr2" }, "f2" },
1111198092Srdivacky  { { "fr3" }, "f3" },
1112198092Srdivacky  { { "fr4" }, "f4" },
1113198092Srdivacky  { { "fr5" }, "f5" },
1114198092Srdivacky  { { "fr6" }, "f6" },
1115198092Srdivacky  { { "fr7" }, "f7" },
1116198092Srdivacky  { { "fr8" }, "f8" },
1117198092Srdivacky  { { "fr9" }, "f9" },
1118198092Srdivacky  { { "fr10" }, "f10" },
1119198092Srdivacky  { { "fr11" }, "f11" },
1120198092Srdivacky  { { "fr12" }, "f12" },
1121198092Srdivacky  { { "fr13" }, "f13" },
1122198092Srdivacky  { { "fr14" }, "f14" },
1123198092Srdivacky  { { "fr15" }, "f15" },
1124198092Srdivacky  { { "fr16" }, "f16" },
1125198092Srdivacky  { { "fr17" }, "f17" },
1126198092Srdivacky  { { "fr18" }, "f18" },
1127198092Srdivacky  { { "fr19" }, "f19" },
1128198092Srdivacky  { { "fr20" }, "f20" },
1129198092Srdivacky  { { "fr21" }, "f21" },
1130198092Srdivacky  { { "fr22" }, "f22" },
1131198092Srdivacky  { { "fr23" }, "f23" },
1132198092Srdivacky  { { "fr24" }, "f24" },
1133198092Srdivacky  { { "fr25" }, "f25" },
1134198092Srdivacky  { { "fr26" }, "f26" },
1135198092Srdivacky  { { "fr27" }, "f27" },
1136198092Srdivacky  { { "fr28" }, "f28" },
1137198092Srdivacky  { { "fr29" }, "f29" },
1138198092Srdivacky  { { "fr30" }, "f30" },
1139198092Srdivacky  { { "fr31" }, "f31" },
1140198092Srdivacky  { { "cc" }, "cr0" },
1141193326Sed};
1142193326Sed
1143193326Sedvoid PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1144193326Sed                                     unsigned &NumAliases) const {
1145193326Sed  Aliases = GCCRegAliases;
1146193326Sed  NumAliases = llvm::array_lengthof(GCCRegAliases);
1147193326Sed}
1148193326Sed} // end anonymous namespace.
1149193326Sed
1150193326Sednamespace {
1151193326Sedclass PPC32TargetInfo : public PPCTargetInfo {
1152193326Sedpublic:
1153204643Srdivacky  PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
1154193326Sed    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1155199482Srdivacky                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
1156204643Srdivacky
1157224145Sdim    switch (getTriple().getOS()) {
1158234353Sdim    case llvm::Triple::Linux:
1159224145Sdim    case llvm::Triple::FreeBSD:
1160224145Sdim    case llvm::Triple::NetBSD:
1161224145Sdim      SizeType = UnsignedInt;
1162234353Sdim      PtrDiffType = SignedInt;
1163234353Sdim      IntPtrType = SignedInt;
1164224145Sdim      break;
1165224145Sdim    default:
1166224145Sdim      break;
1167224145Sdim    }
1168234353Sdim
1169234353Sdim    if (getTriple().getOS() == llvm::Triple::FreeBSD) {
1170234353Sdim      LongDoubleWidth = LongDoubleAlign = 64;
1171234353Sdim      LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1172234353Sdim    }
1173243830Sdim
1174243830Sdim    // PPC32 supports atomics up to 4 bytes.
1175243830Sdim    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
1176193326Sed  }
1177218893Sdim
1178239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
1179218893Sdim    // This is the ELF definition, and is overridden by the Darwin sub-target
1180239462Sdim    return TargetInfo::PowerABIBuiltinVaList;
1181218893Sdim  }
1182193326Sed};
1183193326Sed} // end anonymous namespace.
1184193326Sed
1185193326Sednamespace {
1186193326Sedclass PPC64TargetInfo : public PPCTargetInfo {
1187193326Sedpublic:
1188193326Sed  PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
1189193326Sed    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
1190195341Sed    IntMaxType = SignedLong;
1191195341Sed    UIntMaxType = UnsignedLong;
1192195341Sed    Int64Type = SignedLong;
1193234353Sdim
1194234353Sdim    if (getTriple().getOS() == llvm::Triple::FreeBSD) {
1195234353Sdim      LongDoubleWidth = LongDoubleAlign = 64;
1196234353Sdim      LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1197243830Sdim      DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1198243830Sdim                          "i64:64:64-f32:32:32-f64:64:64-f128:64:64-"
1199243830Sdim                          "v128:128:128-n32:64";
1200243830Sdim    } else
1201243830Sdim      DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1202243830Sdim                          "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
1203243830Sdim                          "v128:128:128-n32:64";
1204243830Sdim
1205243830Sdim    // PPC64 supports atomics up to 8 bytes.
1206243830Sdim    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
1207193326Sed  }
1208239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
1209239462Sdim    return TargetInfo::CharPtrBuiltinVaList;
1210218893Sdim  }
1211193326Sed};
1212193326Sed} // end anonymous namespace.
1213193326Sed
1214210299Sed
1215193326Sednamespace {
1216218893Sdimclass DarwinPPC32TargetInfo :
1217218893Sdim  public DarwinTargetInfo<PPC32TargetInfo> {
1218210299Sedpublic:
1219218893Sdim  DarwinPPC32TargetInfo(const std::string& triple)
1220218893Sdim    : DarwinTargetInfo<PPC32TargetInfo>(triple) {
1221210299Sed    HasAlignMac68kSupport = true;
1222218893Sdim    BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
1223234353Sdim    LongLongAlign = 32;
1224234353Sdim    SuitableAlign = 128;
1225234353Sdim    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1226234353Sdim                        "i64:32:64-f32:32:32-f64:64:64-v128:128:128-n32";
1227210299Sed  }
1228239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
1229239462Sdim    return TargetInfo::CharPtrBuiltinVaList;
1230218893Sdim  }
1231210299Sed};
1232210299Sed
1233210299Sedclass DarwinPPC64TargetInfo :
1234210299Sed  public DarwinTargetInfo<PPC64TargetInfo> {
1235210299Sedpublic:
1236210299Sed  DarwinPPC64TargetInfo(const std::string& triple)
1237210299Sed    : DarwinTargetInfo<PPC64TargetInfo>(triple) {
1238210299Sed    HasAlignMac68kSupport = true;
1239234353Sdim    SuitableAlign = 128;
1240243830Sdim    DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1241243830Sdim                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
1242210299Sed  }
1243210299Sed};
1244210299Sed} // end anonymous namespace.
1245210299Sed
1246210299Sednamespace {
1247239462Sdim  static const unsigned NVPTXAddrSpaceMap[] = {
1248239462Sdim    1,    // opencl_global
1249239462Sdim    3,    // opencl_local
1250239462Sdim    4,    // opencl_constant
1251239462Sdim    1,    // cuda_device
1252239462Sdim    4,    // cuda_constant
1253239462Sdim    3,    // cuda_shared
1254226633Sdim  };
1255239462Sdim  class NVPTXTargetInfo : public TargetInfo {
1256221345Sdim    static const char * const GCCRegNames[];
1257221345Sdim    static const Builtin::Info BuiltinInfo[];
1258249423Sdim    std::vector<StringRef> AvailableFeatures;
1259221345Sdim  public:
1260239462Sdim    NVPTXTargetInfo(const std::string& triple) : TargetInfo(triple) {
1261234353Sdim      BigEndian = false;
1262221345Sdim      TLSSupported = false;
1263221345Sdim      LongWidth = LongAlign = 64;
1264239462Sdim      AddrSpaceMap = &NVPTXAddrSpaceMap;
1265226633Sdim      // Define available target features
1266239462Sdim      // These must be defined in sorted order!
1267239462Sdim      NoAsmVariants = true;
1268221345Sdim    }
1269221345Sdim    virtual void getTargetDefines(const LangOptions &Opts,
1270221345Sdim                                  MacroBuilder &Builder) const {
1271221345Sdim      Builder.defineMacro("__PTX__");
1272239462Sdim      Builder.defineMacro("__NVPTX__");
1273221345Sdim    }
1274221345Sdim    virtual void getTargetBuiltins(const Builtin::Info *&Records,
1275221345Sdim                                   unsigned &NumRecords) const {
1276221345Sdim      Records = BuiltinInfo;
1277239462Sdim      NumRecords = clang::NVPTX::LastTSBuiltin-Builtin::FirstTSBuiltin;
1278221345Sdim    }
1279234353Sdim    virtual bool hasFeature(StringRef Feature) const {
1280239462Sdim      return Feature == "ptx" || Feature == "nvptx";
1281234353Sdim    }
1282234353Sdim
1283221345Sdim    virtual void getGCCRegNames(const char * const *&Names,
1284221345Sdim                                unsigned &NumNames) const;
1285221345Sdim    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1286221345Sdim                                  unsigned &NumAliases) const {
1287221345Sdim      // No aliases.
1288221345Sdim      Aliases = 0;
1289221345Sdim      NumAliases = 0;
1290221345Sdim    }
1291221345Sdim    virtual bool validateAsmConstraint(const char *&Name,
1292221345Sdim                                       TargetInfo::ConstraintInfo &info) const {
1293221345Sdim      // FIXME: implement
1294221345Sdim      return true;
1295221345Sdim    }
1296221345Sdim    virtual const char *getClobbers() const {
1297221345Sdim      // FIXME: Is this really right?
1298221345Sdim      return "";
1299221345Sdim    }
1300239462Sdim    virtual BuiltinVaListKind getBuiltinVaListKind() const {
1301221345Sdim      // FIXME: implement
1302239462Sdim      return TargetInfo::CharPtrBuiltinVaList;
1303221345Sdim    }
1304239462Sdim    virtual bool setCPU(const std::string &Name) {
1305249423Sdim      bool Valid = llvm::StringSwitch<bool>(Name)
1306249423Sdim        .Case("sm_20", true)
1307249423Sdim        .Case("sm_21", true)
1308249423Sdim        .Case("sm_30", true)
1309249423Sdim        .Case("sm_35", true)
1310249423Sdim        .Default(false);
1311249423Sdim
1312249423Sdim      return Valid;
1313239462Sdim    }
1314226633Sdim    virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1315234353Sdim                                   StringRef Name,
1316226633Sdim                                   bool Enabled) const;
1317221345Sdim  };
1318221345Sdim
1319239462Sdim  const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
1320224145Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
1321221345Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1322224145Sdim                                              ALL_LANGUAGES },
1323239462Sdim#include "clang/Basic/BuiltinsNVPTX.def"
1324221345Sdim  };
1325221345Sdim
1326239462Sdim  const char * const NVPTXTargetInfo::GCCRegNames[] = {
1327221345Sdim    "r0"
1328221345Sdim  };
1329221345Sdim
1330239462Sdim  void NVPTXTargetInfo::getGCCRegNames(const char * const *&Names,
1331221345Sdim                                     unsigned &NumNames) const {
1332221345Sdim    Names = GCCRegNames;
1333221345Sdim    NumNames = llvm::array_lengthof(GCCRegNames);
1334221345Sdim  }
1335221345Sdim
1336239462Sdim  bool NVPTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
1337239462Sdim                                          StringRef Name,
1338239462Sdim                                          bool Enabled) const {
1339226633Sdim    if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(),
1340226633Sdim                          Name)) {
1341226633Sdim      Features[Name] = Enabled;
1342226633Sdim      return true;
1343226633Sdim    } else {
1344226633Sdim      return false;
1345226633Sdim    }
1346226633Sdim  }
1347221345Sdim
1348239462Sdim  class NVPTX32TargetInfo : public NVPTXTargetInfo {
1349221345Sdim  public:
1350239462Sdim    NVPTX32TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) {
1351221345Sdim      PointerWidth = PointerAlign = 32;
1352239462Sdim      SizeType     = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt;
1353221345Sdim      DescriptionString
1354239462Sdim        = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
1355239462Sdim          "f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-"
1356239462Sdim          "n16:32:64";
1357239462Sdim  }
1358221345Sdim  };
1359221345Sdim
1360239462Sdim  class NVPTX64TargetInfo : public NVPTXTargetInfo {
1361221345Sdim  public:
1362239462Sdim    NVPTX64TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) {
1363221345Sdim      PointerWidth = PointerAlign = 64;
1364239462Sdim      SizeType     = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong;
1365221345Sdim      DescriptionString
1366239462Sdim        = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
1367239462Sdim          "f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-"
1368239462Sdim          "n16:32:64";
1369239462Sdim  }
1370221345Sdim  };
1371221345Sdim}
1372221345Sdim
1373221345Sdimnamespace {
1374243830Sdim
1375243830Sdimstatic const unsigned R600AddrSpaceMap[] = {
1376243830Sdim  1,    // opencl_global
1377243830Sdim  3,    // opencl_local
1378243830Sdim  2,    // opencl_constant
1379243830Sdim  1,    // cuda_device
1380243830Sdim  2,    // cuda_constant
1381243830Sdim  3     // cuda_shared
1382243830Sdim};
1383243830Sdim
1384249423Sdimstatic const char *DescriptionStringR600 =
1385249423Sdim  "e"
1386249423Sdim  "-p:32:32:32"
1387249423Sdim  "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32"
1388249423Sdim  "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
1389249423Sdim  "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
1390249423Sdim  "-n32:64";
1391249423Sdim
1392249423Sdimstatic const char *DescriptionStringR600DoubleOps =
1393249423Sdim  "e"
1394249423Sdim  "-p:32:32:32"
1395249423Sdim  "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64"
1396249423Sdim  "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
1397249423Sdim  "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
1398249423Sdim  "-n32:64";
1399249423Sdim
1400249423Sdimstatic const char *DescriptionStringSI =
1401249423Sdim  "e"
1402249423Sdim  "-p:64:64:64"
1403249423Sdim  "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64"
1404249423Sdim  "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
1405249423Sdim  "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
1406249423Sdim  "-n32:64";
1407249423Sdim
1408243830Sdimclass R600TargetInfo : public TargetInfo {
1409249423Sdim  /// \brief The GPU profiles supported by the R600 target.
1410249423Sdim  enum GPUKind {
1411249423Sdim    GK_NONE,
1412249423Sdim    GK_R600,
1413249423Sdim    GK_R600_DOUBLE_OPS,
1414249423Sdim    GK_R700,
1415249423Sdim    GK_R700_DOUBLE_OPS,
1416249423Sdim    GK_EVERGREEN,
1417249423Sdim    GK_EVERGREEN_DOUBLE_OPS,
1418249423Sdim    GK_NORTHERN_ISLANDS,
1419249423Sdim    GK_CAYMAN,
1420249423Sdim    GK_SOUTHERN_ISLANDS
1421249423Sdim  } GPU;
1422249423Sdim
1423243830Sdimpublic:
1424249423Sdim  R600TargetInfo(const std::string& triple)
1425249423Sdim    : TargetInfo(triple),
1426249423Sdim      GPU(GK_R600) {
1427249423Sdim    DescriptionString = DescriptionStringR600;
1428243830Sdim    AddrSpaceMap = &R600AddrSpaceMap;
1429243830Sdim  }
1430243830Sdim
1431243830Sdim  virtual const char * getClobbers() const {
1432243830Sdim    return "";
1433243830Sdim  }
1434243830Sdim
1435243830Sdim  virtual void getGCCRegNames(const char * const *&Names,
1436243830Sdim                              unsigned &numNames) const  {
1437243830Sdim    Names = NULL;
1438243830Sdim    numNames = 0;
1439243830Sdim  }
1440243830Sdim
1441243830Sdim  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1442243830Sdim                                unsigned &NumAliases) const {
1443243830Sdim    Aliases = NULL;
1444243830Sdim    NumAliases = 0;
1445243830Sdim  }
1446243830Sdim
1447243830Sdim  virtual bool validateAsmConstraint(const char *&Name,
1448243830Sdim                                     TargetInfo::ConstraintInfo &info) const {
1449243830Sdim    return true;
1450243830Sdim  }
1451243830Sdim
1452243830Sdim  virtual void getTargetBuiltins(const Builtin::Info *&Records,
1453243830Sdim                                 unsigned &NumRecords) const {
1454243830Sdim    Records = NULL;
1455243830Sdim    NumRecords = 0;
1456243830Sdim  }
1457243830Sdim
1458243830Sdim
1459243830Sdim  virtual void getTargetDefines(const LangOptions &Opts,
1460243830Sdim                                MacroBuilder &Builder) const {
1461243830Sdim    Builder.defineMacro("__R600__");
1462243830Sdim  }
1463243830Sdim
1464243830Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
1465243830Sdim    return TargetInfo::CharPtrBuiltinVaList;
1466243830Sdim  }
1467243830Sdim
1468249423Sdim  virtual bool setCPU(const std::string &Name) {
1469249423Sdim    GPU = llvm::StringSwitch<GPUKind>(Name)
1470249423Sdim      .Case("r600" ,    GK_R600)
1471249423Sdim      .Case("rv610",    GK_R600)
1472249423Sdim      .Case("rv620",    GK_R600)
1473249423Sdim      .Case("rv630",    GK_R600)
1474249423Sdim      .Case("rv635",    GK_R600)
1475249423Sdim      .Case("rs780",    GK_R600)
1476249423Sdim      .Case("rs880",    GK_R600)
1477249423Sdim      .Case("rv670",    GK_R600_DOUBLE_OPS)
1478249423Sdim      .Case("rv710",    GK_R700)
1479249423Sdim      .Case("rv730",    GK_R700)
1480249423Sdim      .Case("rv740",    GK_R700_DOUBLE_OPS)
1481249423Sdim      .Case("rv770",    GK_R700_DOUBLE_OPS)
1482249423Sdim      .Case("palm",     GK_EVERGREEN)
1483249423Sdim      .Case("cedar",    GK_EVERGREEN)
1484249423Sdim      .Case("sumo",     GK_EVERGREEN)
1485249423Sdim      .Case("sumo2",    GK_EVERGREEN)
1486249423Sdim      .Case("redwood",  GK_EVERGREEN)
1487249423Sdim      .Case("juniper",  GK_EVERGREEN)
1488249423Sdim      .Case("hemlock",  GK_EVERGREEN_DOUBLE_OPS)
1489249423Sdim      .Case("cypress",  GK_EVERGREEN_DOUBLE_OPS)
1490249423Sdim      .Case("barts",    GK_NORTHERN_ISLANDS)
1491249423Sdim      .Case("turks",    GK_NORTHERN_ISLANDS)
1492249423Sdim      .Case("caicos",   GK_NORTHERN_ISLANDS)
1493249423Sdim      .Case("cayman",   GK_CAYMAN)
1494249423Sdim      .Case("aruba",    GK_CAYMAN)
1495249423Sdim      .Case("tahiti",   GK_SOUTHERN_ISLANDS)
1496249423Sdim      .Case("pitcairn", GK_SOUTHERN_ISLANDS)
1497249423Sdim      .Case("verde",    GK_SOUTHERN_ISLANDS)
1498249423Sdim      .Case("oland",    GK_SOUTHERN_ISLANDS)
1499249423Sdim      .Default(GK_NONE);
1500249423Sdim
1501249423Sdim    if (GPU == GK_NONE) {
1502249423Sdim      return false;
1503249423Sdim    }
1504249423Sdim
1505249423Sdim    // Set the correct data layout
1506249423Sdim    switch (GPU) {
1507249423Sdim    case GK_NONE:
1508249423Sdim    case GK_R600:
1509249423Sdim    case GK_R700:
1510249423Sdim    case GK_EVERGREEN:
1511249423Sdim    case GK_NORTHERN_ISLANDS:
1512249423Sdim      DescriptionString = DescriptionStringR600;
1513249423Sdim      break;
1514249423Sdim    case GK_R600_DOUBLE_OPS:
1515249423Sdim    case GK_R700_DOUBLE_OPS:
1516249423Sdim    case GK_EVERGREEN_DOUBLE_OPS:
1517249423Sdim    case GK_CAYMAN:
1518249423Sdim      DescriptionString = DescriptionStringR600DoubleOps;
1519249423Sdim      break;
1520249423Sdim    case GK_SOUTHERN_ISLANDS:
1521249423Sdim      DescriptionString = DescriptionStringSI;
1522249423Sdim      break;
1523249423Sdim    }
1524249423Sdim
1525249423Sdim    return true;
1526249423Sdim  }
1527243830Sdim};
1528243830Sdim
1529243830Sdim} // end anonymous namespace
1530243830Sdim
1531243830Sdimnamespace {
1532204962Srdivacky// MBlaze abstract base class
1533204962Srdivackyclass MBlazeTargetInfo : public TargetInfo {
1534204962Srdivacky  static const char * const GCCRegNames[];
1535204962Srdivacky  static const TargetInfo::GCCRegAlias GCCRegAliases[];
1536204962Srdivacky
1537204962Srdivackypublic:
1538204962Srdivacky  MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
1539218893Sdim    DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16";
1540204962Srdivacky  }
1541204962Srdivacky
1542204962Srdivacky  virtual void getTargetBuiltins(const Builtin::Info *&Records,
1543204962Srdivacky                                 unsigned &NumRecords) const {
1544204962Srdivacky    // FIXME: Implement.
1545204962Srdivacky    Records = 0;
1546204962Srdivacky    NumRecords = 0;
1547204962Srdivacky  }
1548204962Srdivacky
1549204962Srdivacky  virtual void getTargetDefines(const LangOptions &Opts,
1550204962Srdivacky                                MacroBuilder &Builder) const;
1551204962Srdivacky
1552234353Sdim  virtual bool hasFeature(StringRef Feature) const {
1553234353Sdim    return Feature == "mblaze";
1554234353Sdim  }
1555234353Sdim
1556239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
1557239462Sdim    return TargetInfo::CharPtrBuiltinVaList;
1558204962Srdivacky  }
1559204962Srdivacky  virtual const char *getTargetPrefix() const {
1560204962Srdivacky    return "mblaze";
1561204962Srdivacky  }
1562204962Srdivacky  virtual void getGCCRegNames(const char * const *&Names,
1563204962Srdivacky                              unsigned &NumNames) const;
1564204962Srdivacky  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1565204962Srdivacky                                unsigned &NumAliases) const;
1566204962Srdivacky  virtual bool validateAsmConstraint(const char *&Name,
1567204962Srdivacky                                     TargetInfo::ConstraintInfo &Info) const {
1568204962Srdivacky    switch (*Name) {
1569204962Srdivacky    default: return false;
1570204962Srdivacky    case 'O': // Zero
1571204962Srdivacky      return true;
1572204962Srdivacky    case 'b': // Base register
1573204962Srdivacky    case 'f': // Floating point register
1574204962Srdivacky      Info.setAllowsRegister();
1575204962Srdivacky      return true;
1576204962Srdivacky    }
1577204962Srdivacky  }
1578204962Srdivacky  virtual const char *getClobbers() const {
1579204962Srdivacky    return "";
1580204962Srdivacky  }
1581204962Srdivacky};
1582204962Srdivacky
1583204962Srdivacky/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
1584204962Srdivacky/// #defines that are not tied to a specific subtarget.
1585204962Srdivackyvoid MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
1586204962Srdivacky                                     MacroBuilder &Builder) const {
1587204962Srdivacky  // Target identification.
1588204962Srdivacky  Builder.defineMacro("__microblaze__");
1589204962Srdivacky  Builder.defineMacro("_ARCH_MICROBLAZE");
1590204962Srdivacky  Builder.defineMacro("__MICROBLAZE__");
1591204962Srdivacky
1592204962Srdivacky  // Target properties.
1593204962Srdivacky  Builder.defineMacro("_BIG_ENDIAN");
1594204962Srdivacky  Builder.defineMacro("__BIG_ENDIAN__");
1595204962Srdivacky
1596204962Srdivacky  // Subtarget options.
1597204962Srdivacky  Builder.defineMacro("__REGISTER_PREFIX__", "");
1598204962Srdivacky}
1599204962Srdivacky
1600204962Srdivacky
1601204962Srdivackyconst char * const MBlazeTargetInfo::GCCRegNames[] = {
1602204962Srdivacky  "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",
1603204962Srdivacky  "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",
1604204962Srdivacky  "r16",  "r17",  "r18",  "r19",  "r20",  "r21",  "r22",  "r23",
1605204962Srdivacky  "r24",  "r25",  "r26",  "r27",  "r28",  "r29",  "r30",  "r31",
1606204962Srdivacky  "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
1607204962Srdivacky  "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
1608204962Srdivacky  "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
1609204962Srdivacky  "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
1610204962Srdivacky  "hi",   "lo",   "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
1611204962Srdivacky  "$fcc5","$fcc6","$fcc7","$ap",  "$rap", "$frp"
1612204962Srdivacky};
1613204962Srdivacky
1614204962Srdivackyvoid MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
1615204962Srdivacky                                   unsigned &NumNames) const {
1616204962Srdivacky  Names = GCCRegNames;
1617204962Srdivacky  NumNames = llvm::array_lengthof(GCCRegNames);
1618204962Srdivacky}
1619204962Srdivacky
1620204962Srdivackyconst TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
1621204962Srdivacky  { {"f0"},  "r0" },
1622204962Srdivacky  { {"f1"},  "r1" },
1623204962Srdivacky  { {"f2"},  "r2" },
1624204962Srdivacky  { {"f3"},  "r3" },
1625204962Srdivacky  { {"f4"},  "r4" },
1626204962Srdivacky  { {"f5"},  "r5" },
1627204962Srdivacky  { {"f6"},  "r6" },
1628204962Srdivacky  { {"f7"},  "r7" },
1629204962Srdivacky  { {"f8"},  "r8" },
1630204962Srdivacky  { {"f9"},  "r9" },
1631204962Srdivacky  { {"f10"}, "r10" },
1632204962Srdivacky  { {"f11"}, "r11" },
1633204962Srdivacky  { {"f12"}, "r12" },
1634204962Srdivacky  { {"f13"}, "r13" },
1635204962Srdivacky  { {"f14"}, "r14" },
1636204962Srdivacky  { {"f15"}, "r15" },
1637204962Srdivacky  { {"f16"}, "r16" },
1638204962Srdivacky  { {"f17"}, "r17" },
1639204962Srdivacky  { {"f18"}, "r18" },
1640204962Srdivacky  { {"f19"}, "r19" },
1641204962Srdivacky  { {"f20"}, "r20" },
1642204962Srdivacky  { {"f21"}, "r21" },
1643204962Srdivacky  { {"f22"}, "r22" },
1644204962Srdivacky  { {"f23"}, "r23" },
1645204962Srdivacky  { {"f24"}, "r24" },
1646204962Srdivacky  { {"f25"}, "r25" },
1647204962Srdivacky  { {"f26"}, "r26" },
1648204962Srdivacky  { {"f27"}, "r27" },
1649204962Srdivacky  { {"f28"}, "r28" },
1650204962Srdivacky  { {"f29"}, "r29" },
1651204962Srdivacky  { {"f30"}, "r30" },
1652204962Srdivacky  { {"f31"}, "r31" },
1653204962Srdivacky};
1654204962Srdivacky
1655204962Srdivackyvoid MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1656204962Srdivacky                                     unsigned &NumAliases) const {
1657204962Srdivacky  Aliases = GCCRegAliases;
1658204962Srdivacky  NumAliases = llvm::array_lengthof(GCCRegAliases);
1659204962Srdivacky}
1660204962Srdivacky} // end anonymous namespace.
1661204962Srdivacky
1662204962Srdivackynamespace {
1663193326Sed// Namespace for x86 abstract base class
1664193326Sedconst Builtin::Info BuiltinInfo[] = {
1665224145Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
1666218893Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1667224145Sdim                                              ALL_LANGUAGES },
1668194179Sed#include "clang/Basic/BuiltinsX86.def"
1669193326Sed};
1670193326Sed
1671201361Srdivackystatic const char* const GCCRegNames[] = {
1672193326Sed  "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
1673193326Sed  "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
1674224145Sdim  "argp", "flags", "fpcr", "fpsr", "dirflag", "frame",
1675193326Sed  "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
1676193326Sed  "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
1677193326Sed  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1678224145Sdim  "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
1679234353Sdim  "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
1680234353Sdim  "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15",
1681193326Sed};
1682193326Sed
1683224145Sdimconst TargetInfo::AddlRegName AddlRegNames[] = {
1684224145Sdim  { { "al", "ah", "eax", "rax" }, 0 },
1685224145Sdim  { { "bl", "bh", "ebx", "rbx" }, 3 },
1686224145Sdim  { { "cl", "ch", "ecx", "rcx" }, 2 },
1687224145Sdim  { { "dl", "dh", "edx", "rdx" }, 1 },
1688224145Sdim  { { "esi", "rsi" }, 4 },
1689224145Sdim  { { "edi", "rdi" }, 5 },
1690224145Sdim  { { "esp", "rsp" }, 7 },
1691224145Sdim  { { "ebp", "rbp" }, 6 },
1692193326Sed};
1693193326Sed
1694193326Sed// X86 target abstract base class; x86-32 and x86-64 are very close, so
1695193326Sed// most of the implementation can be shared.
1696193326Sedclass X86TargetInfo : public TargetInfo {
1697193326Sed  enum X86SSEEnum {
1698234353Sdim    NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2
1699193326Sed  } SSELevel;
1700224145Sdim  enum MMX3DNowEnum {
1701224145Sdim    NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon
1702224145Sdim  } MMX3DNowLevel;
1703203955Srdivacky
1704206125Srdivacky  bool HasAES;
1705239462Sdim  bool HasPCLMUL;
1706234353Sdim  bool HasLZCNT;
1707239462Sdim  bool HasRDRND;
1708234353Sdim  bool HasBMI;
1709234353Sdim  bool HasBMI2;
1710234353Sdim  bool HasPOPCNT;
1711243830Sdim  bool HasRTM;
1712249423Sdim  bool HasPRFCHW;
1713249423Sdim  bool HasRDSEED;
1714239462Sdim  bool HasSSE4a;
1715234353Sdim  bool HasFMA4;
1716239462Sdim  bool HasFMA;
1717239462Sdim  bool HasXOP;
1718243830Sdim  bool HasF16C;
1719212904Sdim
1720226633Sdim  /// \brief Enumeration of all of the X86 CPUs supported by Clang.
1721226633Sdim  ///
1722226633Sdim  /// Each enumeration represents a particular CPU supported by Clang. These
1723226633Sdim  /// loosely correspond to the options passed to '-march' or '-mtune' flags.
1724226633Sdim  enum CPUKind {
1725226633Sdim    CK_Generic,
1726226633Sdim
1727226633Sdim    /// \name i386
1728226633Sdim    /// i386-generation processors.
1729226633Sdim    //@{
1730226633Sdim    CK_i386,
1731226633Sdim    //@}
1732226633Sdim
1733226633Sdim    /// \name i486
1734226633Sdim    /// i486-generation processors.
1735226633Sdim    //@{
1736226633Sdim    CK_i486,
1737226633Sdim    CK_WinChipC6,
1738226633Sdim    CK_WinChip2,
1739226633Sdim    CK_C3,
1740226633Sdim    //@}
1741226633Sdim
1742226633Sdim    /// \name i586
1743226633Sdim    /// i586-generation processors, P5 microarchitecture based.
1744226633Sdim    //@{
1745226633Sdim    CK_i586,
1746226633Sdim    CK_Pentium,
1747226633Sdim    CK_PentiumMMX,
1748226633Sdim    //@}
1749226633Sdim
1750226633Sdim    /// \name i686
1751226633Sdim    /// i686-generation processors, P6 / Pentium M microarchitecture based.
1752226633Sdim    //@{
1753226633Sdim    CK_i686,
1754226633Sdim    CK_PentiumPro,
1755226633Sdim    CK_Pentium2,
1756226633Sdim    CK_Pentium3,
1757226633Sdim    CK_Pentium3M,
1758226633Sdim    CK_PentiumM,
1759226633Sdim    CK_C3_2,
1760226633Sdim
1761226633Sdim    /// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
1762226633Sdim    /// Clang however has some logic to suport this.
1763226633Sdim    // FIXME: Warn, deprecate, and potentially remove this.
1764226633Sdim    CK_Yonah,
1765226633Sdim    //@}
1766226633Sdim
1767226633Sdim    /// \name Netburst
1768226633Sdim    /// Netburst microarchitecture based processors.
1769226633Sdim    //@{
1770226633Sdim    CK_Pentium4,
1771226633Sdim    CK_Pentium4M,
1772226633Sdim    CK_Prescott,
1773226633Sdim    CK_Nocona,
1774226633Sdim    //@}
1775226633Sdim
1776226633Sdim    /// \name Core
1777226633Sdim    /// Core microarchitecture based processors.
1778226633Sdim    //@{
1779226633Sdim    CK_Core2,
1780226633Sdim
1781226633Sdim    /// This enumerator, like \see CK_Yonah, is a bit odd. It is another
1782226633Sdim    /// codename which GCC no longer accepts as an option to -march, but Clang
1783226633Sdim    /// has some logic for recognizing it.
1784226633Sdim    // FIXME: Warn, deprecate, and potentially remove this.
1785226633Sdim    CK_Penryn,
1786226633Sdim    //@}
1787226633Sdim
1788226633Sdim    /// \name Atom
1789226633Sdim    /// Atom processors
1790226633Sdim    //@{
1791226633Sdim    CK_Atom,
1792226633Sdim    //@}
1793226633Sdim
1794226633Sdim    /// \name Nehalem
1795226633Sdim    /// Nehalem microarchitecture based processors.
1796226633Sdim    //@{
1797226633Sdim    CK_Corei7,
1798226633Sdim    CK_Corei7AVX,
1799226633Sdim    CK_CoreAVXi,
1800234353Sdim    CK_CoreAVX2,
1801226633Sdim    //@}
1802226633Sdim
1803226633Sdim    /// \name K6
1804226633Sdim    /// K6 architecture processors.
1805226633Sdim    //@{
1806226633Sdim    CK_K6,
1807226633Sdim    CK_K6_2,
1808226633Sdim    CK_K6_3,
1809226633Sdim    //@}
1810226633Sdim
1811226633Sdim    /// \name K7
1812226633Sdim    /// K7 architecture processors.
1813226633Sdim    //@{
1814226633Sdim    CK_Athlon,
1815226633Sdim    CK_AthlonThunderbird,
1816226633Sdim    CK_Athlon4,
1817226633Sdim    CK_AthlonXP,
1818226633Sdim    CK_AthlonMP,
1819226633Sdim    //@}
1820226633Sdim
1821226633Sdim    /// \name K8
1822226633Sdim    /// K8 architecture processors.
1823226633Sdim    //@{
1824226633Sdim    CK_Athlon64,
1825226633Sdim    CK_Athlon64SSE3,
1826226633Sdim    CK_AthlonFX,
1827226633Sdim    CK_K8,
1828226633Sdim    CK_K8SSE3,
1829226633Sdim    CK_Opteron,
1830226633Sdim    CK_OpteronSSE3,
1831226951Sdim    CK_AMDFAM10,
1832234353Sdim    //@}
1833226633Sdim
1834234353Sdim    /// \name Bobcat
1835234353Sdim    /// Bobcat architecture processors.
1836234353Sdim    //@{
1837234353Sdim    CK_BTVER1,
1838251662Sdim    CK_BTVER2,
1839234353Sdim    //@}
1840234353Sdim
1841234353Sdim    /// \name Bulldozer
1842234353Sdim    /// Bulldozer architecture processors.
1843234353Sdim    //@{
1844234353Sdim    CK_BDVER1,
1845234353Sdim    CK_BDVER2,
1846234353Sdim    //@}
1847234353Sdim
1848226633Sdim    /// This specification is deprecated and will be removed in the future.
1849226633Sdim    /// Users should prefer \see CK_K8.
1850226633Sdim    // FIXME: Warn on this when the CPU is set to it.
1851226633Sdim    CK_x86_64,
1852226633Sdim    //@}
1853226633Sdim
1854226633Sdim    /// \name Geode
1855226633Sdim    /// Geode processors.
1856226633Sdim    //@{
1857226633Sdim    CK_Geode
1858226633Sdim    //@}
1859226633Sdim  } CPU;
1860226633Sdim
1861193326Sedpublic:
1862193326Sed  X86TargetInfo(const std::string& triple)
1863224145Sdim    : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
1864239462Sdim      HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasRDRND(false),
1865243830Sdim      HasBMI(false), HasBMI2(false), HasPOPCNT(false), HasRTM(false),
1866249423Sdim      HasPRFCHW(false), HasRDSEED(false), HasSSE4a(false), HasFMA4(false),
1867249423Sdim      HasFMA(false), HasXOP(false), HasF16C(false), CPU(CK_Generic) {
1868234353Sdim    BigEndian = false;
1869193326Sed    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
1870193326Sed  }
1871234353Sdim  virtual unsigned getFloatEvalMethod() const {
1872234353Sdim    // X87 evaluates with 80 bits "long double" precision.
1873234353Sdim    return SSELevel == NoSSE ? 2 : 0;
1874234353Sdim  }
1875193326Sed  virtual void getTargetBuiltins(const Builtin::Info *&Records,
1876193326Sed                                 unsigned &NumRecords) const {
1877193326Sed    Records = BuiltinInfo;
1878193326Sed    NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
1879193326Sed  }
1880193326Sed  virtual void getGCCRegNames(const char * const *&Names,
1881193326Sed                              unsigned &NumNames) const {
1882193326Sed    Names = GCCRegNames;
1883193326Sed    NumNames = llvm::array_lengthof(GCCRegNames);
1884193326Sed  }
1885193326Sed  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1886193326Sed                                unsigned &NumAliases) const {
1887224145Sdim    Aliases = 0;
1888224145Sdim    NumAliases = 0;
1889193326Sed  }
1890224145Sdim  virtual void getGCCAddlRegNames(const AddlRegName *&Names,
1891249423Sdim                                  unsigned &NumNames) const {
1892224145Sdim    Names = AddlRegNames;
1893224145Sdim    NumNames = llvm::array_lengthof(AddlRegNames);
1894224145Sdim  }
1895193326Sed  virtual bool validateAsmConstraint(const char *&Name,
1896193326Sed                                     TargetInfo::ConstraintInfo &info) const;
1897223017Sdim  virtual std::string convertConstraint(const char *&Constraint) const;
1898193326Sed  virtual const char *getClobbers() const {
1899193326Sed    return "~{dirflag},~{fpsr},~{flags}";
1900193326Sed  }
1901193326Sed  virtual void getTargetDefines(const LangOptions &Opts,
1902202379Srdivacky                                MacroBuilder &Builder) const;
1903193326Sed  virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1904234353Sdim                                 StringRef Name,
1905193326Sed                                 bool Enabled) const;
1906226633Sdim  virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
1907234353Sdim  virtual bool hasFeature(StringRef Feature) const;
1908201361Srdivacky  virtual void HandleTargetFeatures(std::vector<std::string> &Features);
1909224145Sdim  virtual const char* getABI() const {
1910243830Sdim    if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
1911234353Sdim      return "avx";
1912243830Sdim    else if (getTriple().getArch() == llvm::Triple::x86 &&
1913243830Sdim             MMX3DNowLevel == NoMMX3DNow)
1914234353Sdim      return "no-mmx";
1915234353Sdim    return "";
1916224145Sdim  }
1917226633Sdim  virtual bool setCPU(const std::string &Name) {
1918226633Sdim    CPU = llvm::StringSwitch<CPUKind>(Name)
1919226633Sdim      .Case("i386", CK_i386)
1920226633Sdim      .Case("i486", CK_i486)
1921226633Sdim      .Case("winchip-c6", CK_WinChipC6)
1922226633Sdim      .Case("winchip2", CK_WinChip2)
1923226633Sdim      .Case("c3", CK_C3)
1924226633Sdim      .Case("i586", CK_i586)
1925226633Sdim      .Case("pentium", CK_Pentium)
1926226633Sdim      .Case("pentium-mmx", CK_PentiumMMX)
1927226633Sdim      .Case("i686", CK_i686)
1928226633Sdim      .Case("pentiumpro", CK_PentiumPro)
1929226633Sdim      .Case("pentium2", CK_Pentium2)
1930226633Sdim      .Case("pentium3", CK_Pentium3)
1931226633Sdim      .Case("pentium3m", CK_Pentium3M)
1932226633Sdim      .Case("pentium-m", CK_PentiumM)
1933226633Sdim      .Case("c3-2", CK_C3_2)
1934226633Sdim      .Case("yonah", CK_Yonah)
1935226633Sdim      .Case("pentium4", CK_Pentium4)
1936226633Sdim      .Case("pentium4m", CK_Pentium4M)
1937226633Sdim      .Case("prescott", CK_Prescott)
1938226633Sdim      .Case("nocona", CK_Nocona)
1939226633Sdim      .Case("core2", CK_Core2)
1940226633Sdim      .Case("penryn", CK_Penryn)
1941226633Sdim      .Case("atom", CK_Atom)
1942226633Sdim      .Case("corei7", CK_Corei7)
1943226633Sdim      .Case("corei7-avx", CK_Corei7AVX)
1944226633Sdim      .Case("core-avx-i", CK_CoreAVXi)
1945234353Sdim      .Case("core-avx2", CK_CoreAVX2)
1946226633Sdim      .Case("k6", CK_K6)
1947226633Sdim      .Case("k6-2", CK_K6_2)
1948226633Sdim      .Case("k6-3", CK_K6_3)
1949226633Sdim      .Case("athlon", CK_Athlon)
1950226633Sdim      .Case("athlon-tbird", CK_AthlonThunderbird)
1951226633Sdim      .Case("athlon-4", CK_Athlon4)
1952226633Sdim      .Case("athlon-xp", CK_AthlonXP)
1953226633Sdim      .Case("athlon-mp", CK_AthlonMP)
1954226633Sdim      .Case("athlon64", CK_Athlon64)
1955226633Sdim      .Case("athlon64-sse3", CK_Athlon64SSE3)
1956226633Sdim      .Case("athlon-fx", CK_AthlonFX)
1957226633Sdim      .Case("k8", CK_K8)
1958226633Sdim      .Case("k8-sse3", CK_K8SSE3)
1959226633Sdim      .Case("opteron", CK_Opteron)
1960226633Sdim      .Case("opteron-sse3", CK_OpteronSSE3)
1961226951Sdim      .Case("amdfam10", CK_AMDFAM10)
1962234353Sdim      .Case("btver1", CK_BTVER1)
1963251662Sdim      .Case("btver2", CK_BTVER2)
1964234353Sdim      .Case("bdver1", CK_BDVER1)
1965234353Sdim      .Case("bdver2", CK_BDVER2)
1966226633Sdim      .Case("x86-64", CK_x86_64)
1967226633Sdim      .Case("geode", CK_Geode)
1968226633Sdim      .Default(CK_Generic);
1969226633Sdim
1970226633Sdim    // Perform any per-CPU checks necessary to determine if this CPU is
1971226633Sdim    // acceptable.
1972226633Sdim    // FIXME: This results in terrible diagnostics. Clang just says the CPU is
1973226633Sdim    // invalid without explaining *why*.
1974226633Sdim    switch (CPU) {
1975226633Sdim    case CK_Generic:
1976226633Sdim      // No processor selected!
1977226633Sdim      return false;
1978226633Sdim
1979226633Sdim    case CK_i386:
1980226633Sdim    case CK_i486:
1981226633Sdim    case CK_WinChipC6:
1982226633Sdim    case CK_WinChip2:
1983226633Sdim    case CK_C3:
1984226633Sdim    case CK_i586:
1985226633Sdim    case CK_Pentium:
1986226633Sdim    case CK_PentiumMMX:
1987226633Sdim    case CK_i686:
1988226633Sdim    case CK_PentiumPro:
1989226633Sdim    case CK_Pentium2:
1990226633Sdim    case CK_Pentium3:
1991226633Sdim    case CK_Pentium3M:
1992226633Sdim    case CK_PentiumM:
1993226633Sdim    case CK_Yonah:
1994226633Sdim    case CK_C3_2:
1995226633Sdim    case CK_Pentium4:
1996226633Sdim    case CK_Pentium4M:
1997226633Sdim    case CK_Prescott:
1998226633Sdim    case CK_K6:
1999226633Sdim    case CK_K6_2:
2000226633Sdim    case CK_K6_3:
2001226633Sdim    case CK_Athlon:
2002226633Sdim    case CK_AthlonThunderbird:
2003226633Sdim    case CK_Athlon4:
2004226633Sdim    case CK_AthlonXP:
2005226633Sdim    case CK_AthlonMP:
2006226633Sdim    case CK_Geode:
2007226633Sdim      // Only accept certain architectures when compiling in 32-bit mode.
2008243830Sdim      if (getTriple().getArch() != llvm::Triple::x86)
2009226633Sdim        return false;
2010226633Sdim
2011226633Sdim      // Fallthrough
2012226633Sdim    case CK_Nocona:
2013226633Sdim    case CK_Core2:
2014226633Sdim    case CK_Penryn:
2015226633Sdim    case CK_Atom:
2016226633Sdim    case CK_Corei7:
2017226633Sdim    case CK_Corei7AVX:
2018226633Sdim    case CK_CoreAVXi:
2019234353Sdim    case CK_CoreAVX2:
2020226633Sdim    case CK_Athlon64:
2021226633Sdim    case CK_Athlon64SSE3:
2022226633Sdim    case CK_AthlonFX:
2023226633Sdim    case CK_K8:
2024226633Sdim    case CK_K8SSE3:
2025226633Sdim    case CK_Opteron:
2026226633Sdim    case CK_OpteronSSE3:
2027226951Sdim    case CK_AMDFAM10:
2028234353Sdim    case CK_BTVER1:
2029251662Sdim    case CK_BTVER2:
2030234353Sdim    case CK_BDVER1:
2031234353Sdim    case CK_BDVER2:
2032226633Sdim    case CK_x86_64:
2033226633Sdim      return true;
2034226633Sdim    }
2035226633Sdim    llvm_unreachable("Unhandled CPU kind");
2036226633Sdim  }
2037243830Sdim
2038243830Sdim  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
2039243830Sdim    // We accept all non-ARM calling conventions
2040243830Sdim    return (CC == CC_X86ThisCall ||
2041243830Sdim            CC == CC_X86FastCall ||
2042243830Sdim            CC == CC_X86StdCall ||
2043243830Sdim            CC == CC_C ||
2044249423Sdim            CC == CC_X86Pascal ||
2045249423Sdim            CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
2046243830Sdim  }
2047243830Sdim
2048249423Sdim  virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
2049249423Sdim    return MT == CCMT_Member ? CC_X86ThisCall : CC_C;
2050243830Sdim  }
2051193326Sed};
2052193326Sed
2053226633Sdimvoid X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
2054193326Sed  // FIXME: This should not be here.
2055193326Sed  Features["3dnow"] = false;
2056193326Sed  Features["3dnowa"] = false;
2057193326Sed  Features["mmx"] = false;
2058193326Sed  Features["sse"] = false;
2059193326Sed  Features["sse2"] = false;
2060193326Sed  Features["sse3"] = false;
2061193326Sed  Features["ssse3"] = false;
2062193326Sed  Features["sse41"] = false;
2063193326Sed  Features["sse42"] = false;
2064226951Sdim  Features["sse4a"] = false;
2065206125Srdivacky  Features["aes"] = false;
2066239462Sdim  Features["pclmul"] = false;
2067212904Sdim  Features["avx"] = false;
2068234353Sdim  Features["avx2"] = false;
2069234353Sdim  Features["lzcnt"] = false;
2070239462Sdim  Features["rdrand"] = false;
2071234353Sdim  Features["bmi"] = false;
2072234353Sdim  Features["bmi2"] = false;
2073234353Sdim  Features["popcnt"] = false;
2074243830Sdim  Features["rtm"] = false;
2075249423Sdim  Features["prfchw"] = false;
2076249423Sdim  Features["rdseed"] = false;
2077234353Sdim  Features["fma4"] = false;
2078239462Sdim  Features["fma"] = false;
2079239462Sdim  Features["xop"] = false;
2080243830Sdim  Features["f16c"] = false;
2081193326Sed
2082193326Sed  // FIXME: This *really* should not be here.
2083193326Sed
2084193326Sed  // X86_64 always has SSE2.
2085243830Sdim  if (getTriple().getArch() == llvm::Triple::x86_64)
2086249423Sdim    setFeatureEnabled(Features, "sse2", true);
2087193326Sed
2088226633Sdim  switch (CPU) {
2089226633Sdim  case CK_Generic:
2090226633Sdim  case CK_i386:
2091226633Sdim  case CK_i486:
2092226633Sdim  case CK_i586:
2093226633Sdim  case CK_Pentium:
2094226633Sdim  case CK_i686:
2095226633Sdim  case CK_PentiumPro:
2096226633Sdim    break;
2097226633Sdim  case CK_PentiumMMX:
2098226633Sdim  case CK_Pentium2:
2099193326Sed    setFeatureEnabled(Features, "mmx", true);
2100226633Sdim    break;
2101226633Sdim  case CK_Pentium3:
2102226633Sdim  case CK_Pentium3M:
2103193326Sed    setFeatureEnabled(Features, "sse", true);
2104226633Sdim    break;
2105226633Sdim  case CK_PentiumM:
2106226633Sdim  case CK_Pentium4:
2107226633Sdim  case CK_Pentium4M:
2108226633Sdim  case CK_x86_64:
2109193326Sed    setFeatureEnabled(Features, "sse2", true);
2110226633Sdim    break;
2111226633Sdim  case CK_Yonah:
2112226633Sdim  case CK_Prescott:
2113226633Sdim  case CK_Nocona:
2114193326Sed    setFeatureEnabled(Features, "sse3", true);
2115226633Sdim    break;
2116226633Sdim  case CK_Core2:
2117193326Sed    setFeatureEnabled(Features, "ssse3", true);
2118226633Sdim    break;
2119226633Sdim  case CK_Penryn:
2120234353Sdim    setFeatureEnabled(Features, "sse4.1", true);
2121226633Sdim    break;
2122226633Sdim  case CK_Atom:
2123226633Sdim    setFeatureEnabled(Features, "ssse3", true);
2124226633Sdim    break;
2125226633Sdim  case CK_Corei7:
2126193326Sed    setFeatureEnabled(Features, "sse4", true);
2127239462Sdim    break;
2128239462Sdim  case CK_Corei7AVX:
2129239462Sdim    setFeatureEnabled(Features, "avx", true);
2130206125Srdivacky    setFeatureEnabled(Features, "aes", true);
2131239462Sdim    setFeatureEnabled(Features, "pclmul", true);
2132226633Sdim    break;
2133226633Sdim  case CK_CoreAVXi:
2134239462Sdim    setFeatureEnabled(Features, "avx", true);
2135221345Sdim    setFeatureEnabled(Features, "aes", true);
2136239462Sdim    setFeatureEnabled(Features, "pclmul", true);
2137239462Sdim    setFeatureEnabled(Features, "rdrnd", true);
2138249423Sdim    setFeatureEnabled(Features, "f16c", true);
2139226633Sdim    break;
2140234353Sdim  case CK_CoreAVX2:
2141239462Sdim    setFeatureEnabled(Features, "avx2", true);
2142234353Sdim    setFeatureEnabled(Features, "aes", true);
2143239462Sdim    setFeatureEnabled(Features, "pclmul", true);
2144234353Sdim    setFeatureEnabled(Features, "lzcnt", true);
2145239462Sdim    setFeatureEnabled(Features, "rdrnd", true);
2146249423Sdim    setFeatureEnabled(Features, "f16c", true);
2147234353Sdim    setFeatureEnabled(Features, "bmi", true);
2148234353Sdim    setFeatureEnabled(Features, "bmi2", true);
2149243830Sdim    setFeatureEnabled(Features, "rtm", true);
2150239462Sdim    setFeatureEnabled(Features, "fma", true);
2151234353Sdim    break;
2152226633Sdim  case CK_K6:
2153226633Sdim  case CK_WinChipC6:
2154193326Sed    setFeatureEnabled(Features, "mmx", true);
2155226633Sdim    break;
2156226633Sdim  case CK_K6_2:
2157226633Sdim  case CK_K6_3:
2158226633Sdim  case CK_WinChip2:
2159226633Sdim  case CK_C3:
2160193326Sed    setFeatureEnabled(Features, "3dnow", true);
2161226633Sdim    break;
2162226633Sdim  case CK_Athlon:
2163226633Sdim  case CK_AthlonThunderbird:
2164226633Sdim  case CK_Geode:
2165226633Sdim    setFeatureEnabled(Features, "3dnowa", true);
2166226633Sdim    break;
2167226633Sdim  case CK_Athlon4:
2168226633Sdim  case CK_AthlonXP:
2169226633Sdim  case CK_AthlonMP:
2170193326Sed    setFeatureEnabled(Features, "sse", true);
2171193326Sed    setFeatureEnabled(Features, "3dnowa", true);
2172226633Sdim    break;
2173226633Sdim  case CK_K8:
2174226633Sdim  case CK_Opteron:
2175226633Sdim  case CK_Athlon64:
2176226633Sdim  case CK_AthlonFX:
2177198092Srdivacky    setFeatureEnabled(Features, "sse2", true);
2178193326Sed    setFeatureEnabled(Features, "3dnowa", true);
2179226633Sdim    break;
2180226633Sdim  case CK_K8SSE3:
2181226633Sdim  case CK_OpteronSSE3:
2182226633Sdim  case CK_Athlon64SSE3:
2183218893Sdim    setFeatureEnabled(Features, "sse3", true);
2184218893Sdim    setFeatureEnabled(Features, "3dnowa", true);
2185226633Sdim    break;
2186226951Sdim  case CK_AMDFAM10:
2187226951Sdim    setFeatureEnabled(Features, "sse3", true);
2188226951Sdim    setFeatureEnabled(Features, "sse4a", true);
2189226951Sdim    setFeatureEnabled(Features, "3dnowa", true);
2190249423Sdim    setFeatureEnabled(Features, "lzcnt", true);
2191249423Sdim    setFeatureEnabled(Features, "popcnt", true);
2192226951Sdim    break;
2193234353Sdim  case CK_BTVER1:
2194234353Sdim    setFeatureEnabled(Features, "ssse3", true);
2195234353Sdim    setFeatureEnabled(Features, "sse4a", true);
2196249423Sdim    setFeatureEnabled(Features, "lzcnt", true);
2197249423Sdim    setFeatureEnabled(Features, "popcnt", true);
2198239462Sdim    break;
2199251662Sdim  case CK_BTVER2:
2200251662Sdim    setFeatureEnabled(Features, "avx", true);
2201251662Sdim    setFeatureEnabled(Features, "sse4a", true);
2202251662Sdim    setFeatureEnabled(Features, "lzcnt", true);
2203251662Sdim    setFeatureEnabled(Features, "aes", true);
2204251662Sdim    setFeatureEnabled(Features, "pclmul", true);
2205251662Sdim    setFeatureEnabled(Features, "bmi", true);
2206251662Sdim    setFeatureEnabled(Features, "f16c", true);
2207251662Sdim    break;
2208234353Sdim  case CK_BDVER1:
2209249423Sdim    setFeatureEnabled(Features, "xop", true);
2210249423Sdim    setFeatureEnabled(Features, "lzcnt", true);
2211249423Sdim    setFeatureEnabled(Features, "aes", true);
2212249423Sdim    setFeatureEnabled(Features, "pclmul", true);
2213249423Sdim    break;
2214234353Sdim  case CK_BDVER2:
2215239462Sdim    setFeatureEnabled(Features, "xop", true);
2216249423Sdim    setFeatureEnabled(Features, "lzcnt", true);
2217234353Sdim    setFeatureEnabled(Features, "aes", true);
2218239462Sdim    setFeatureEnabled(Features, "pclmul", true);
2219249423Sdim    setFeatureEnabled(Features, "bmi", true);
2220249423Sdim    setFeatureEnabled(Features, "fma", true);
2221249423Sdim    setFeatureEnabled(Features, "f16c", true);
2222234353Sdim    break;
2223226633Sdim  case CK_C3_2:
2224193326Sed    setFeatureEnabled(Features, "sse", true);
2225226633Sdim    break;
2226224145Sdim  }
2227193326Sed}
2228193326Sed
2229193326Sedbool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
2230234353Sdim                                      StringRef Name,
2231193326Sed                                      bool Enabled) const {
2232204793Srdivacky  // FIXME: This *really* should not be here.  We need some way of translating
2233204793Srdivacky  // options into llvm subtarget features.
2234204793Srdivacky  if (!Features.count(Name) &&
2235239462Sdim      (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1" &&
2236239462Sdim       Name != "rdrnd"))
2237193326Sed    return false;
2238193326Sed
2239232894Sdim  // FIXME: this should probably use a switch with fall through.
2240232894Sdim
2241193326Sed  if (Enabled) {
2242193326Sed    if (Name == "mmx")
2243193326Sed      Features["mmx"] = true;
2244193326Sed    else if (Name == "sse")
2245232894Sdim      Features["mmx"] = Features["sse"] = true;
2246193326Sed    else if (Name == "sse2")
2247232894Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = true;
2248193326Sed    else if (Name == "sse3")
2249232894Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2250232894Sdim        true;
2251193326Sed    else if (Name == "ssse3")
2252232894Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2253193326Sed        Features["ssse3"] = true;
2254204793Srdivacky    else if (Name == "sse4" || Name == "sse4.2")
2255232894Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2256234353Sdim        Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2257234353Sdim        Features["popcnt"] = true;
2258204793Srdivacky    else if (Name == "sse4.1")
2259232894Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2260204793Srdivacky        Features["ssse3"] = Features["sse41"] = true;
2261193326Sed    else if (Name == "3dnow")
2262224145Sdim      Features["mmx"] = Features["3dnow"] = true;
2263193326Sed    else if (Name == "3dnowa")
2264224145Sdim      Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = true;
2265206125Srdivacky    else if (Name == "aes")
2266239462Sdim      Features["sse"] = Features["sse2"] = Features["aes"] = true;
2267239462Sdim    else if (Name == "pclmul")
2268239462Sdim      Features["sse"] = Features["sse2"] = Features["pclmul"] = true;
2269212904Sdim    else if (Name == "avx")
2270232894Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2271232894Sdim        Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2272234353Sdim        Features["popcnt"] = Features["avx"] = true;
2273234353Sdim    else if (Name == "avx2")
2274234353Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2275234353Sdim        Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2276234353Sdim        Features["popcnt"] = Features["avx"] = Features["avx2"] = true;
2277239462Sdim    else if (Name == "fma")
2278239462Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2279239462Sdim        Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2280239462Sdim        Features["popcnt"] = Features["avx"] = Features["fma"] = true;
2281234353Sdim    else if (Name == "fma4")
2282249423Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2283234353Sdim        Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2284239462Sdim        Features["popcnt"] = Features["avx"] = Features["sse4a"] =
2285239462Sdim        Features["fma4"] = true;
2286239462Sdim    else if (Name == "xop")
2287249423Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2288239462Sdim        Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2289239462Sdim        Features["popcnt"] = Features["avx"] = Features["sse4a"] =
2290239462Sdim        Features["fma4"] = Features["xop"] = true;
2291226951Sdim    else if (Name == "sse4a")
2292234353Sdim      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2293239462Sdim        Features["sse4a"] = true;
2294234353Sdim    else if (Name == "lzcnt")
2295234353Sdim      Features["lzcnt"] = true;
2296239462Sdim    else if (Name == "rdrnd")
2297239462Sdim      Features["rdrand"] = true;
2298234353Sdim    else if (Name == "bmi")
2299234353Sdim      Features["bmi"] = true;
2300234353Sdim    else if (Name == "bmi2")
2301234353Sdim      Features["bmi2"] = true;
2302234353Sdim    else if (Name == "popcnt")
2303234353Sdim      Features["popcnt"] = true;
2304243830Sdim    else if (Name == "f16c")
2305243830Sdim      Features["f16c"] = true;
2306243830Sdim    else if (Name == "rtm")
2307243830Sdim      Features["rtm"] = true;
2308249423Sdim    else if (Name == "prfchw")
2309249423Sdim      Features["prfchw"] = true;
2310249423Sdim    else if (Name == "rdseed")
2311249423Sdim      Features["rdseed"] = true;
2312193326Sed  } else {
2313193326Sed    if (Name == "mmx")
2314224145Sdim      Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false;
2315193326Sed    else if (Name == "sse")
2316198092Srdivacky      Features["sse"] = Features["sse2"] = Features["sse3"] =
2317234353Sdim        Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2318239462Sdim        Features["sse4a"] = Features["avx"] = Features["avx2"] =
2319239462Sdim        Features["fma"] = Features["fma4"] = Features["aes"] =
2320239462Sdim        Features["pclmul"] = Features["xop"] = false;
2321193326Sed    else if (Name == "sse2")
2322198092Srdivacky      Features["sse2"] = Features["sse3"] = Features["ssse3"] =
2323239462Sdim        Features["sse41"] = Features["sse42"] = Features["sse4a"] =
2324239462Sdim        Features["avx"] = Features["avx2"] = Features["fma"] =
2325239462Sdim        Features["fma4"] = Features["aes"] = Features["pclmul"] =
2326239462Sdim        Features["xop"] = false;
2327193326Sed    else if (Name == "sse3")
2328198092Srdivacky      Features["sse3"] = Features["ssse3"] = Features["sse41"] =
2329239462Sdim        Features["sse42"] = Features["sse4a"] = Features["avx"] =
2330239462Sdim        Features["avx2"] = Features["fma"] = Features["fma4"] =
2331239462Sdim        Features["xop"] = false;
2332193326Sed    else if (Name == "ssse3")
2333239462Sdim      Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2334239462Sdim        Features["avx"] = Features["avx2"] = Features["fma"] = false;
2335220754Sdim    else if (Name == "sse4" || Name == "sse4.1")
2336239462Sdim      Features["sse41"] = Features["sse42"] = Features["avx"] =
2337239462Sdim        Features["avx2"] = Features["fma"] = false;
2338204793Srdivacky    else if (Name == "sse4.2")
2339239462Sdim      Features["sse42"] = Features["avx"] = Features["avx2"] =
2340239462Sdim        Features["fma"] = false;
2341193326Sed    else if (Name == "3dnow")
2342193326Sed      Features["3dnow"] = Features["3dnowa"] = false;
2343193326Sed    else if (Name == "3dnowa")
2344193326Sed      Features["3dnowa"] = false;
2345206125Srdivacky    else if (Name == "aes")
2346206125Srdivacky      Features["aes"] = false;
2347239462Sdim    else if (Name == "pclmul")
2348239462Sdim      Features["pclmul"] = false;
2349212904Sdim    else if (Name == "avx")
2350239462Sdim      Features["avx"] = Features["avx2"] = Features["fma"] =
2351239462Sdim        Features["fma4"] = Features["xop"] = false;
2352234353Sdim    else if (Name == "avx2")
2353234353Sdim      Features["avx2"] = false;
2354239462Sdim    else if (Name == "fma")
2355239462Sdim      Features["fma"] = false;
2356226951Sdim    else if (Name == "sse4a")
2357239462Sdim      Features["sse4a"] = Features["fma4"] = Features["xop"] = false;
2358234353Sdim    else if (Name == "lzcnt")
2359234353Sdim      Features["lzcnt"] = false;
2360239462Sdim    else if (Name == "rdrnd")
2361239462Sdim      Features["rdrand"] = false;
2362234353Sdim    else if (Name == "bmi")
2363234353Sdim      Features["bmi"] = false;
2364234353Sdim    else if (Name == "bmi2")
2365234353Sdim      Features["bmi2"] = false;
2366234353Sdim    else if (Name == "popcnt")
2367234353Sdim      Features["popcnt"] = false;
2368234353Sdim    else if (Name == "fma4")
2369239462Sdim      Features["fma4"] = Features["xop"] = false;
2370239462Sdim    else if (Name == "xop")
2371239462Sdim      Features["xop"] = false;
2372243830Sdim    else if (Name == "f16c")
2373243830Sdim      Features["f16c"] = false;
2374243830Sdim    else if (Name == "rtm")
2375243830Sdim      Features["rtm"] = false;
2376249423Sdim    else if (Name == "prfchw")
2377249423Sdim      Features["prfchw"] = false;
2378249423Sdim    else if (Name == "rdseed")
2379249423Sdim      Features["rdseed"] = false;
2380193326Sed  }
2381193326Sed
2382193326Sed  return true;
2383193326Sed}
2384193326Sed
2385193326Sed/// HandleTargetOptions - Perform initialization based on the user
2386193326Sed/// configured set of features.
2387201361Srdivackyvoid X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
2388199482Srdivacky  // Remember the maximum enabled sselevel.
2389199482Srdivacky  for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
2390199482Srdivacky    // Ignore disabled features.
2391199482Srdivacky    if (Features[i][0] == '-')
2392199482Srdivacky      continue;
2393199482Srdivacky
2394234353Sdim    StringRef Feature = StringRef(Features[i]).substr(1);
2395234353Sdim
2396234353Sdim    if (Feature == "aes") {
2397206125Srdivacky      HasAES = true;
2398206125Srdivacky      continue;
2399206125Srdivacky    }
2400206125Srdivacky
2401239462Sdim    if (Feature == "pclmul") {
2402239462Sdim      HasPCLMUL = true;
2403239462Sdim      continue;
2404239462Sdim    }
2405239462Sdim
2406234353Sdim    if (Feature == "lzcnt") {
2407234353Sdim      HasLZCNT = true;
2408212904Sdim      continue;
2409212904Sdim    }
2410212904Sdim
2411239462Sdim    if (Feature == "rdrand") {
2412239462Sdim      HasRDRND = true;
2413239462Sdim      continue;
2414239462Sdim    }
2415239462Sdim
2416234353Sdim    if (Feature == "bmi") {
2417234353Sdim      HasBMI = true;
2418234353Sdim      continue;
2419234353Sdim    }
2420234353Sdim
2421234353Sdim    if (Feature == "bmi2") {
2422234353Sdim      HasBMI2 = true;
2423234353Sdim      continue;
2424234353Sdim    }
2425234353Sdim
2426234353Sdim    if (Feature == "popcnt") {
2427234353Sdim      HasPOPCNT = true;
2428234353Sdim      continue;
2429234353Sdim    }
2430234353Sdim
2431243830Sdim    if (Feature == "rtm") {
2432243830Sdim      HasRTM = true;
2433243830Sdim      continue;
2434243830Sdim    }
2435243830Sdim
2436249423Sdim    if (Feature == "prfchw") {
2437249423Sdim      HasPRFCHW = true;
2438249423Sdim      continue;
2439249423Sdim    }
2440249423Sdim
2441249423Sdim    if (Feature == "rdseed") {
2442249423Sdim      HasRDSEED = true;
2443249423Sdim      continue;
2444249423Sdim    }
2445249423Sdim
2446239462Sdim    if (Feature == "sse4a") {
2447239462Sdim      HasSSE4a = true;
2448239462Sdim      continue;
2449239462Sdim    }
2450239462Sdim
2451234353Sdim    if (Feature == "fma4") {
2452234353Sdim      HasFMA4 = true;
2453234353Sdim      continue;
2454234353Sdim    }
2455234353Sdim
2456239462Sdim    if (Feature == "fma") {
2457239462Sdim      HasFMA = true;
2458239462Sdim      continue;
2459239462Sdim    }
2460239462Sdim
2461239462Sdim    if (Feature == "xop") {
2462239462Sdim      HasXOP = true;
2463239462Sdim      continue;
2464239462Sdim    }
2465239462Sdim
2466243830Sdim    if (Feature == "f16c") {
2467243830Sdim      HasF16C = true;
2468243830Sdim      continue;
2469243830Sdim    }
2470243830Sdim
2471199482Srdivacky    assert(Features[i][0] == '+' && "Invalid target feature!");
2472234353Sdim    X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
2473234353Sdim      .Case("avx2", AVX2)
2474234353Sdim      .Case("avx", AVX)
2475199482Srdivacky      .Case("sse42", SSE42)
2476199482Srdivacky      .Case("sse41", SSE41)
2477199482Srdivacky      .Case("ssse3", SSSE3)
2478205219Srdivacky      .Case("sse3", SSE3)
2479199482Srdivacky      .Case("sse2", SSE2)
2480199482Srdivacky      .Case("sse", SSE1)
2481224145Sdim      .Default(NoSSE);
2482199482Srdivacky    SSELevel = std::max(SSELevel, Level);
2483218893Sdim
2484224145Sdim    MMX3DNowEnum ThreeDNowLevel =
2485234353Sdim      llvm::StringSwitch<MMX3DNowEnum>(Feature)
2486203955Srdivacky        .Case("3dnowa", AMD3DNowAthlon)
2487203955Srdivacky        .Case("3dnow", AMD3DNow)
2488224145Sdim        .Case("mmx", MMX)
2489224145Sdim        .Default(NoMMX3DNow);
2490218893Sdim
2491224145Sdim    MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
2492199482Srdivacky  }
2493224145Sdim
2494224145Sdim  // Don't tell the backend if we're turning off mmx; it will end up disabling
2495224145Sdim  // SSE, which we don't want.
2496224145Sdim  std::vector<std::string>::iterator it;
2497224145Sdim  it = std::find(Features.begin(), Features.end(), "-mmx");
2498224145Sdim  if (it != Features.end())
2499224145Sdim    Features.erase(it);
2500193326Sed}
2501193326Sed
2502226633Sdim/// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
2503226633Sdim/// definitions for this particular subtarget.
2504193326Sedvoid X86TargetInfo::getTargetDefines(const LangOptions &Opts,
2505202379Srdivacky                                     MacroBuilder &Builder) const {
2506193326Sed  // Target identification.
2507243830Sdim  if (getTriple().getArch() == llvm::Triple::x86_64) {
2508202379Srdivacky    Builder.defineMacro("__amd64__");
2509202379Srdivacky    Builder.defineMacro("__amd64");
2510202379Srdivacky    Builder.defineMacro("__x86_64");
2511202379Srdivacky    Builder.defineMacro("__x86_64__");
2512193326Sed  } else {
2513202379Srdivacky    DefineStd(Builder, "i386", Opts);
2514193326Sed  }
2515193326Sed
2516226633Sdim  // Subtarget options.
2517226633Sdim  // FIXME: We are hard-coding the tune parameters based on the CPU, but they
2518226633Sdim  // truly should be based on -mtune options.
2519226633Sdim  switch (CPU) {
2520226633Sdim  case CK_Generic:
2521226633Sdim    break;
2522226633Sdim  case CK_i386:
2523226633Sdim    // The rest are coming from the i386 define above.
2524226633Sdim    Builder.defineMacro("__tune_i386__");
2525226633Sdim    break;
2526226633Sdim  case CK_i486:
2527226633Sdim  case CK_WinChipC6:
2528226633Sdim  case CK_WinChip2:
2529226633Sdim  case CK_C3:
2530234353Sdim    defineCPUMacros(Builder, "i486");
2531226633Sdim    break;
2532226633Sdim  case CK_PentiumMMX:
2533226633Sdim    Builder.defineMacro("__pentium_mmx__");
2534226633Sdim    Builder.defineMacro("__tune_pentium_mmx__");
2535226633Sdim    // Fallthrough
2536226633Sdim  case CK_i586:
2537226633Sdim  case CK_Pentium:
2538234353Sdim    defineCPUMacros(Builder, "i586");
2539234353Sdim    defineCPUMacros(Builder, "pentium");
2540226633Sdim    break;
2541226633Sdim  case CK_Pentium3:
2542226633Sdim  case CK_Pentium3M:
2543226633Sdim  case CK_PentiumM:
2544226633Sdim    Builder.defineMacro("__tune_pentium3__");
2545226633Sdim    // Fallthrough
2546226633Sdim  case CK_Pentium2:
2547226633Sdim  case CK_C3_2:
2548226633Sdim    Builder.defineMacro("__tune_pentium2__");
2549226633Sdim    // Fallthrough
2550226633Sdim  case CK_PentiumPro:
2551226633Sdim    Builder.defineMacro("__tune_i686__");
2552226633Sdim    Builder.defineMacro("__tune_pentiumpro__");
2553226633Sdim    // Fallthrough
2554226633Sdim  case CK_i686:
2555226633Sdim    Builder.defineMacro("__i686");
2556226633Sdim    Builder.defineMacro("__i686__");
2557226633Sdim    // Strangely, __tune_i686__ isn't defined by GCC when CPU == i686.
2558226633Sdim    Builder.defineMacro("__pentiumpro");
2559226633Sdim    Builder.defineMacro("__pentiumpro__");
2560226633Sdim    break;
2561226633Sdim  case CK_Pentium4:
2562226633Sdim  case CK_Pentium4M:
2563234353Sdim    defineCPUMacros(Builder, "pentium4");
2564226633Sdim    break;
2565226633Sdim  case CK_Yonah:
2566226633Sdim  case CK_Prescott:
2567226633Sdim  case CK_Nocona:
2568234353Sdim    defineCPUMacros(Builder, "nocona");
2569226633Sdim    break;
2570226633Sdim  case CK_Core2:
2571226633Sdim  case CK_Penryn:
2572234353Sdim    defineCPUMacros(Builder, "core2");
2573226633Sdim    break;
2574226633Sdim  case CK_Atom:
2575234353Sdim    defineCPUMacros(Builder, "atom");
2576226633Sdim    break;
2577226633Sdim  case CK_Corei7:
2578226633Sdim  case CK_Corei7AVX:
2579226633Sdim  case CK_CoreAVXi:
2580234353Sdim  case CK_CoreAVX2:
2581234353Sdim    defineCPUMacros(Builder, "corei7");
2582226633Sdim    break;
2583226633Sdim  case CK_K6_2:
2584226633Sdim    Builder.defineMacro("__k6_2__");
2585226633Sdim    Builder.defineMacro("__tune_k6_2__");
2586226633Sdim    // Fallthrough
2587226633Sdim  case CK_K6_3:
2588226633Sdim    if (CPU != CK_K6_2) {  // In case of fallthrough
2589226633Sdim      // FIXME: GCC may be enabling these in cases where some other k6
2590226633Sdim      // architecture is specified but -m3dnow is explicitly provided. The
2591226633Sdim      // exact semantics need to be determined and emulated here.
2592226633Sdim      Builder.defineMacro("__k6_3__");
2593226633Sdim      Builder.defineMacro("__tune_k6_3__");
2594226633Sdim    }
2595226633Sdim    // Fallthrough
2596226633Sdim  case CK_K6:
2597234353Sdim    defineCPUMacros(Builder, "k6");
2598226633Sdim    break;
2599226633Sdim  case CK_Athlon:
2600226633Sdim  case CK_AthlonThunderbird:
2601226633Sdim  case CK_Athlon4:
2602226633Sdim  case CK_AthlonXP:
2603226633Sdim  case CK_AthlonMP:
2604234353Sdim    defineCPUMacros(Builder, "athlon");
2605226633Sdim    if (SSELevel != NoSSE) {
2606226633Sdim      Builder.defineMacro("__athlon_sse__");
2607226633Sdim      Builder.defineMacro("__tune_athlon_sse__");
2608226633Sdim    }
2609226633Sdim    break;
2610226633Sdim  case CK_K8:
2611226633Sdim  case CK_K8SSE3:
2612226633Sdim  case CK_x86_64:
2613226633Sdim  case CK_Opteron:
2614226633Sdim  case CK_OpteronSSE3:
2615226633Sdim  case CK_Athlon64:
2616226633Sdim  case CK_Athlon64SSE3:
2617226633Sdim  case CK_AthlonFX:
2618234353Sdim    defineCPUMacros(Builder, "k8");
2619226633Sdim    break;
2620226951Sdim  case CK_AMDFAM10:
2621234353Sdim    defineCPUMacros(Builder, "amdfam10");
2622226951Sdim    break;
2623234353Sdim  case CK_BTVER1:
2624234353Sdim    defineCPUMacros(Builder, "btver1");
2625234353Sdim    break;
2626251662Sdim  case CK_BTVER2:
2627251662Sdim    defineCPUMacros(Builder, "btver2");
2628251662Sdim    break;
2629234353Sdim  case CK_BDVER1:
2630234353Sdim    defineCPUMacros(Builder, "bdver1");
2631234353Sdim    break;
2632234353Sdim  case CK_BDVER2:
2633234353Sdim    defineCPUMacros(Builder, "bdver2");
2634234353Sdim    break;
2635226633Sdim  case CK_Geode:
2636234353Sdim    defineCPUMacros(Builder, "geode");
2637226633Sdim    break;
2638226633Sdim  }
2639206125Srdivacky
2640193326Sed  // Target properties.
2641202379Srdivacky  Builder.defineMacro("__LITTLE_ENDIAN__");
2642202379Srdivacky  Builder.defineMacro("__REGISTER_PREFIX__", "");
2643193326Sed
2644193326Sed  // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
2645193326Sed  // functions in glibc header files that use FP Stack inline asm which the
2646193326Sed  // backend can't deal with (PR879).
2647202379Srdivacky  Builder.defineMacro("__NO_MATH_INLINES");
2648193326Sed
2649226633Sdim  if (HasAES)
2650226633Sdim    Builder.defineMacro("__AES__");
2651226633Sdim
2652239462Sdim  if (HasPCLMUL)
2653239462Sdim    Builder.defineMacro("__PCLMUL__");
2654239462Sdim
2655234353Sdim  if (HasLZCNT)
2656234353Sdim    Builder.defineMacro("__LZCNT__");
2657226633Sdim
2658239462Sdim  if (HasRDRND)
2659239462Sdim    Builder.defineMacro("__RDRND__");
2660239462Sdim
2661234353Sdim  if (HasBMI)
2662234353Sdim    Builder.defineMacro("__BMI__");
2663234353Sdim
2664234353Sdim  if (HasBMI2)
2665234353Sdim    Builder.defineMacro("__BMI2__");
2666234353Sdim
2667234353Sdim  if (HasPOPCNT)
2668234353Sdim    Builder.defineMacro("__POPCNT__");
2669234353Sdim
2670243830Sdim  if (HasRTM)
2671243830Sdim    Builder.defineMacro("__RTM__");
2672243830Sdim
2673249423Sdim  if (HasPRFCHW)
2674249423Sdim    Builder.defineMacro("__PRFCHW__");
2675249423Sdim
2676249423Sdim  if (HasRDSEED)
2677249423Sdim    Builder.defineMacro("__RDSEED__");
2678249423Sdim
2679239462Sdim  if (HasSSE4a)
2680239462Sdim    Builder.defineMacro("__SSE4A__");
2681239462Sdim
2682234353Sdim  if (HasFMA4)
2683234353Sdim    Builder.defineMacro("__FMA4__");
2684234353Sdim
2685239462Sdim  if (HasFMA)
2686239462Sdim    Builder.defineMacro("__FMA__");
2687239462Sdim
2688239462Sdim  if (HasXOP)
2689239462Sdim    Builder.defineMacro("__XOP__");
2690239462Sdim
2691243830Sdim  if (HasF16C)
2692243830Sdim    Builder.defineMacro("__F16C__");
2693243830Sdim
2694193326Sed  // Each case falls through to the previous one here.
2695193326Sed  switch (SSELevel) {
2696234353Sdim  case AVX2:
2697234353Sdim    Builder.defineMacro("__AVX2__");
2698234353Sdim  case AVX:
2699234353Sdim    Builder.defineMacro("__AVX__");
2700193326Sed  case SSE42:
2701202379Srdivacky    Builder.defineMacro("__SSE4_2__");
2702193326Sed  case SSE41:
2703202379Srdivacky    Builder.defineMacro("__SSE4_1__");
2704193326Sed  case SSSE3:
2705202379Srdivacky    Builder.defineMacro("__SSSE3__");
2706193326Sed  case SSE3:
2707202379Srdivacky    Builder.defineMacro("__SSE3__");
2708193326Sed  case SSE2:
2709202379Srdivacky    Builder.defineMacro("__SSE2__");
2710202379Srdivacky    Builder.defineMacro("__SSE2_MATH__");  // -mfp-math=sse always implied.
2711193326Sed  case SSE1:
2712202379Srdivacky    Builder.defineMacro("__SSE__");
2713202379Srdivacky    Builder.defineMacro("__SSE_MATH__");   // -mfp-math=sse always implied.
2714224145Sdim  case NoSSE:
2715193326Sed    break;
2716193326Sed  }
2717218893Sdim
2718243830Sdim  if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
2719218893Sdim    switch (SSELevel) {
2720234353Sdim    case AVX2:
2721234353Sdim    case AVX:
2722218893Sdim    case SSE42:
2723218893Sdim    case SSE41:
2724218893Sdim    case SSSE3:
2725218893Sdim    case SSE3:
2726218893Sdim    case SSE2:
2727226633Sdim      Builder.defineMacro("_M_IX86_FP", Twine(2));
2728218893Sdim      break;
2729218893Sdim    case SSE1:
2730226633Sdim      Builder.defineMacro("_M_IX86_FP", Twine(1));
2731218893Sdim      break;
2732218893Sdim    default:
2733226633Sdim      Builder.defineMacro("_M_IX86_FP", Twine(0));
2734218893Sdim    }
2735218893Sdim  }
2736218893Sdim
2737203955Srdivacky  // Each case falls through to the previous one here.
2738224145Sdim  switch (MMX3DNowLevel) {
2739203955Srdivacky  case AMD3DNowAthlon:
2740203955Srdivacky    Builder.defineMacro("__3dNOW_A__");
2741203955Srdivacky  case AMD3DNow:
2742203955Srdivacky    Builder.defineMacro("__3dNOW__");
2743224145Sdim  case MMX:
2744224145Sdim    Builder.defineMacro("__MMX__");
2745224145Sdim  case NoMMX3DNow:
2746203955Srdivacky    break;
2747203955Srdivacky  }
2748249423Sdim
2749249423Sdim  if (CPU >= CK_i486) {
2750249423Sdim    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
2751249423Sdim    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
2752249423Sdim    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
2753249423Sdim  }
2754249423Sdim  if (CPU >= CK_i586)
2755249423Sdim    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
2756193326Sed}
2757193326Sed
2758234353Sdimbool X86TargetInfo::hasFeature(StringRef Feature) const {
2759234353Sdim  return llvm::StringSwitch<bool>(Feature)
2760234353Sdim      .Case("aes", HasAES)
2761234353Sdim      .Case("avx", SSELevel >= AVX)
2762234353Sdim      .Case("avx2", SSELevel >= AVX2)
2763234353Sdim      .Case("bmi", HasBMI)
2764234353Sdim      .Case("bmi2", HasBMI2)
2765239462Sdim      .Case("fma", HasFMA)
2766234353Sdim      .Case("fma4", HasFMA4)
2767234353Sdim      .Case("lzcnt", HasLZCNT)
2768239462Sdim      .Case("rdrnd", HasRDRND)
2769234353Sdim      .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
2770234353Sdim      .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
2771234353Sdim      .Case("mmx", MMX3DNowLevel >= MMX)
2772239462Sdim      .Case("pclmul", HasPCLMUL)
2773234353Sdim      .Case("popcnt", HasPOPCNT)
2774243830Sdim      .Case("rtm", HasRTM)
2775249423Sdim      .Case("prfchw", HasPRFCHW)
2776249423Sdim      .Case("rdseed", HasRDSEED)
2777234353Sdim      .Case("sse", SSELevel >= SSE1)
2778234353Sdim      .Case("sse2", SSELevel >= SSE2)
2779234353Sdim      .Case("sse3", SSELevel >= SSE3)
2780234353Sdim      .Case("ssse3", SSELevel >= SSSE3)
2781234353Sdim      .Case("sse41", SSELevel >= SSE41)
2782234353Sdim      .Case("sse42", SSELevel >= SSE42)
2783239462Sdim      .Case("sse4a", HasSSE4a)
2784234353Sdim      .Case("x86", true)
2785243830Sdim      .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
2786243830Sdim      .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
2787239462Sdim      .Case("xop", HasXOP)
2788243830Sdim      .Case("f16c", HasF16C)
2789234353Sdim      .Default(false);
2790234353Sdim}
2791193326Sed
2792193326Sedbool
2793193326SedX86TargetInfo::validateAsmConstraint(const char *&Name,
2794193326Sed                                     TargetInfo::ConstraintInfo &Info) const {
2795193326Sed  switch (*Name) {
2796193326Sed  default: return false;
2797212904Sdim  case 'Y': // first letter of a pair:
2798212904Sdim    switch (*(Name+1)) {
2799212904Sdim    default: return false;
2800212904Sdim    case '0':  // First SSE register.
2801212904Sdim    case 't':  // Any SSE register, when SSE2 is enabled.
2802212904Sdim    case 'i':  // Any SSE register, when SSE2 and inter-unit moves enabled.
2803212904Sdim    case 'm':  // any MMX register, when inter-unit moves enabled.
2804212904Sdim      break;   // falls through to setAllowsRegister.
2805212904Sdim  }
2806193326Sed  case 'a': // eax.
2807193326Sed  case 'b': // ebx.
2808193326Sed  case 'c': // ecx.
2809193326Sed  case 'd': // edx.
2810193326Sed  case 'S': // esi.
2811193326Sed  case 'D': // edi.
2812193326Sed  case 'A': // edx:eax.
2813212904Sdim  case 'f': // any x87 floating point stack register.
2814193326Sed  case 't': // top of floating point stack.
2815193326Sed  case 'u': // second from top of floating point stack.
2816193326Sed  case 'q': // Any register accessible as [r]l: a, b, c, and d.
2817193326Sed  case 'y': // Any MMX register.
2818193326Sed  case 'x': // Any SSE register.
2819193326Sed  case 'Q': // Any register accessible as [r]h: a, b, c, and d.
2820212904Sdim  case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
2821212904Sdim  case 'l': // "Index" registers: any general register that can be used as an
2822212904Sdim            // index in a base+index memory access.
2823212904Sdim    Info.setAllowsRegister();
2824212904Sdim    return true;
2825212904Sdim  case 'C': // SSE floating point constant.
2826212904Sdim  case 'G': // x87 floating point constant.
2827193326Sed  case 'e': // 32-bit signed integer constant for use with zero-extending
2828193326Sed            // x86_64 instructions.
2829193326Sed  case 'Z': // 32-bit unsigned integer constant for use with zero-extending
2830193326Sed            // x86_64 instructions.
2831193326Sed    return true;
2832193326Sed  }
2833193326Sed}
2834193326Sed
2835218893Sdim
2836193326Sedstd::string
2837223017SdimX86TargetInfo::convertConstraint(const char *&Constraint) const {
2838223017Sdim  switch (*Constraint) {
2839193326Sed  case 'a': return std::string("{ax}");
2840193326Sed  case 'b': return std::string("{bx}");
2841193326Sed  case 'c': return std::string("{cx}");
2842193326Sed  case 'd': return std::string("{dx}");
2843193326Sed  case 'S': return std::string("{si}");
2844193326Sed  case 'D': return std::string("{di}");
2845218893Sdim  case 'p': // address
2846218893Sdim    return std::string("im");
2847193326Sed  case 't': // top of floating point stack.
2848193326Sed    return std::string("{st}");
2849193326Sed  case 'u': // second from top of floating point stack.
2850193326Sed    return std::string("{st(1)}"); // second from top of floating point stack.
2851193326Sed  default:
2852223017Sdim    return std::string(1, *Constraint);
2853193326Sed  }
2854193326Sed}
2855193326Sed} // end anonymous namespace
2856193326Sed
2857193326Sednamespace {
2858193326Sed// X86-32 generic target
2859193326Sedclass X86_32TargetInfo : public X86TargetInfo {
2860193326Sedpublic:
2861193326Sed  X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
2862193326Sed    DoubleAlign = LongLongAlign = 32;
2863193326Sed    LongDoubleWidth = 96;
2864193326Sed    LongDoubleAlign = 32;
2865234353Sdim    SuitableAlign = 128;
2866193326Sed    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
2867193326Sed                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
2868226633Sdim                        "a0:0:64-f80:32:32-n8:16:32-S128";
2869193326Sed    SizeType = UnsignedInt;
2870193326Sed    PtrDiffType = SignedInt;
2871193326Sed    IntPtrType = SignedInt;
2872193326Sed    RegParmMax = 3;
2873210299Sed
2874210299Sed    // Use fpret for all types.
2875210299Sed    RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
2876210299Sed                             (1 << TargetInfo::Double) |
2877210299Sed                             (1 << TargetInfo::LongDouble));
2878226633Sdim
2879226633Sdim    // x86-32 has atomics up to 8 bytes
2880226633Sdim    // FIXME: Check that we actually have cmpxchg8b before setting
2881226633Sdim    // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
2882226633Sdim    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
2883193326Sed  }
2884239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
2885239462Sdim    return TargetInfo::CharPtrBuiltinVaList;
2886193326Sed  }
2887218893Sdim
2888198092Srdivacky  int getEHDataRegisterNumber(unsigned RegNo) const {
2889198092Srdivacky    if (RegNo == 0) return 0;
2890198092Srdivacky    if (RegNo == 1) return 2;
2891198092Srdivacky    return -1;
2892198092Srdivacky  }
2893249423Sdim  virtual bool validateInputSize(StringRef Constraint,
2894249423Sdim                                 unsigned Size) const {
2895249423Sdim    switch (Constraint[0]) {
2896249423Sdim    default: break;
2897249423Sdim    case 'a':
2898249423Sdim    case 'b':
2899249423Sdim    case 'c':
2900249423Sdim    case 'd':
2901249423Sdim      return Size <= 32;
2902249423Sdim    }
2903249423Sdim
2904249423Sdim    return true;
2905249423Sdim  }
2906193326Sed};
2907193326Sed} // end anonymous namespace
2908193326Sed
2909193326Sednamespace {
2910234353Sdimclass NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> {
2911234353Sdimpublic:
2912234353Sdim  NetBSDI386TargetInfo(const std::string &triple) :
2913234353Sdim    NetBSDTargetInfo<X86_32TargetInfo>(triple) {
2914234353Sdim  }
2915234353Sdim
2916234353Sdim  virtual unsigned getFloatEvalMethod() const {
2917234353Sdim    // NetBSD defaults to "double" rounding
2918234353Sdim    return 1;
2919234353Sdim  }
2920234353Sdim};
2921234353Sdim} // end anonymous namespace
2922234353Sdim
2923234353Sdimnamespace {
2924198092Srdivackyclass OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
2925198092Srdivackypublic:
2926198092Srdivacky  OpenBSDI386TargetInfo(const std::string& triple) :
2927198092Srdivacky    OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
2928198092Srdivacky    SizeType = UnsignedLong;
2929198092Srdivacky    IntPtrType = SignedLong;
2930198092Srdivacky    PtrDiffType = SignedLong;
2931198092Srdivacky  }
2932198092Srdivacky};
2933198092Srdivacky} // end anonymous namespace
2934198092Srdivacky
2935198092Srdivackynamespace {
2936239462Sdimclass BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> {
2937239462Sdimpublic:
2938239462Sdim  BitrigI386TargetInfo(const std::string& triple) :
2939239462Sdim    BitrigTargetInfo<X86_32TargetInfo>(triple) {
2940239462Sdim    SizeType = UnsignedLong;
2941239462Sdim    IntPtrType = SignedLong;
2942239462Sdim    PtrDiffType = SignedLong;
2943239462Sdim  }
2944239462Sdim};
2945239462Sdim} // end anonymous namespace
2946239462Sdim
2947239462Sdimnamespace {
2948195341Sedclass DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
2949193326Sedpublic:
2950195341Sed  DarwinI386TargetInfo(const std::string& triple) :
2951195341Sed    DarwinTargetInfo<X86_32TargetInfo>(triple) {
2952193326Sed    LongDoubleWidth = 128;
2953193326Sed    LongDoubleAlign = 128;
2954234353Sdim    SuitableAlign = 128;
2955239462Sdim    MaxVectorAlign = 256;
2956193326Sed    SizeType = UnsignedLong;
2957193326Sed    IntPtrType = SignedLong;
2958193326Sed    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
2959193326Sed                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
2960226633Sdim                        "a0:0:64-f80:128:128-n8:16:32-S128";
2961208600Srdivacky    HasAlignMac68kSupport = true;
2962193326Sed  }
2963193326Sed
2964193326Sed};
2965193326Sed} // end anonymous namespace
2966193326Sed
2967193326Sednamespace {
2968193326Sed// x86-32 Windows target
2969218893Sdimclass WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
2970193326Sedpublic:
2971193326Sed  WindowsX86_32TargetInfo(const std::string& triple)
2972218893Sdim    : WindowsTargetInfo<X86_32TargetInfo>(triple) {
2973193326Sed    TLSSupported = false;
2974195099Sed    WCharType = UnsignedShort;
2975194179Sed    DoubleAlign = LongLongAlign = 64;
2976194179Sed    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
2977201361Srdivacky                        "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
2978226633Sdim                        "v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32";
2979193326Sed  }
2980193326Sed  virtual void getTargetDefines(const LangOptions &Opts,
2981202379Srdivacky                                MacroBuilder &Builder) const {
2982218893Sdim    WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
2983193326Sed  }
2984198092Srdivacky};
2985198092Srdivacky} // end anonymous namespace
2986193725Sed
2987198092Srdivackynamespace {
2988198092Srdivacky
2989198092Srdivacky// x86-32 Windows Visual Studio target
2990198092Srdivackyclass VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
2991198092Srdivackypublic:
2992198092Srdivacky  VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
2993198092Srdivacky    : WindowsX86_32TargetInfo(triple) {
2994221345Sdim    LongDoubleWidth = LongDoubleAlign = 64;
2995218893Sdim    LongDoubleFormat = &llvm::APFloat::IEEEdouble;
2996198092Srdivacky  }
2997198092Srdivacky  virtual void getTargetDefines(const LangOptions &Opts,
2998202379Srdivacky                                MacroBuilder &Builder) const {
2999202379Srdivacky    WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
3000218893Sdim    WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
3001198092Srdivacky    // The value of the following reflects processor type.
3002198092Srdivacky    // 300=386, 400=486, 500=Pentium, 600=Blend (default)
3003198092Srdivacky    // We lost the original triple, so we use the default.
3004202379Srdivacky    Builder.defineMacro("_M_IX86", "600");
3005198092Srdivacky  }
3006193326Sed};
3007193326Sed} // end anonymous namespace
3008193326Sed
3009193326Sednamespace {
3010198092Srdivacky// x86-32 MinGW target
3011198092Srdivackyclass MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
3012198092Srdivackypublic:
3013198092Srdivacky  MinGWX86_32TargetInfo(const std::string& triple)
3014198092Srdivacky    : WindowsX86_32TargetInfo(triple) {
3015198092Srdivacky  }
3016198092Srdivacky  virtual void getTargetDefines(const LangOptions &Opts,
3017202379Srdivacky                                MacroBuilder &Builder) const {
3018202379Srdivacky    WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
3019218893Sdim    DefineStd(Builder, "WIN32", Opts);
3020218893Sdim    DefineStd(Builder, "WINNT", Opts);
3021218893Sdim    Builder.defineMacro("_X86_");
3022202379Srdivacky    Builder.defineMacro("__MSVCRT__");
3023202379Srdivacky    Builder.defineMacro("__MINGW32__");
3024221345Sdim
3025221345Sdim    // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
3026221345Sdim    // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
3027226633Sdim    if (Opts.MicrosoftExt)
3028221345Sdim      // Provide "as-is" __declspec.
3029221345Sdim      Builder.defineMacro("__declspec", "__declspec");
3030221345Sdim    else
3031221345Sdim      // Provide alias of __attribute__ like mingw32-gcc.
3032221345Sdim      Builder.defineMacro("__declspec(a)", "__attribute__((a))");
3033198092Srdivacky  }
3034198092Srdivacky};
3035198092Srdivacky} // end anonymous namespace
3036198092Srdivacky
3037198092Srdivackynamespace {
3038198092Srdivacky// x86-32 Cygwin target
3039198092Srdivackyclass CygwinX86_32TargetInfo : public X86_32TargetInfo {
3040198092Srdivackypublic:
3041198092Srdivacky  CygwinX86_32TargetInfo(const std::string& triple)
3042198092Srdivacky    : X86_32TargetInfo(triple) {
3043198092Srdivacky    TLSSupported = false;
3044198092Srdivacky    WCharType = UnsignedShort;
3045198092Srdivacky    DoubleAlign = LongLongAlign = 64;
3046198092Srdivacky    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
3047198092Srdivacky                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
3048226633Sdim                        "a0:0:64-f80:32:32-n8:16:32-S32";
3049198092Srdivacky  }
3050198092Srdivacky  virtual void getTargetDefines(const LangOptions &Opts,
3051202379Srdivacky                                MacroBuilder &Builder) const {
3052202379Srdivacky    X86_32TargetInfo::getTargetDefines(Opts, Builder);
3053249423Sdim    Builder.defineMacro("_X86_");
3054202379Srdivacky    Builder.defineMacro("__CYGWIN__");
3055202379Srdivacky    Builder.defineMacro("__CYGWIN32__");
3056202379Srdivacky    DefineStd(Builder, "unix", Opts);
3057207619Srdivacky    if (Opts.CPlusPlus)
3058207619Srdivacky      Builder.defineMacro("_GNU_SOURCE");
3059198092Srdivacky  }
3060198092Srdivacky};
3061198092Srdivacky} // end anonymous namespace
3062198092Srdivacky
3063198092Srdivackynamespace {
3064207619Srdivacky// x86-32 Haiku target
3065207619Srdivackyclass HaikuX86_32TargetInfo : public X86_32TargetInfo {
3066207619Srdivackypublic:
3067207619Srdivacky  HaikuX86_32TargetInfo(const std::string& triple)
3068207619Srdivacky    : X86_32TargetInfo(triple) {
3069207619Srdivacky    SizeType = UnsignedLong;
3070207619Srdivacky    IntPtrType = SignedLong;
3071207619Srdivacky    PtrDiffType = SignedLong;
3072243830Sdim    ProcessIDType = SignedLong;
3073218893Sdim    this->UserLabelPrefix = "";
3074243830Sdim    this->TLSSupported = false;
3075212904Sdim  }
3076207619Srdivacky  virtual void getTargetDefines(const LangOptions &Opts,
3077207619Srdivacky                                MacroBuilder &Builder) const {
3078207619Srdivacky    X86_32TargetInfo::getTargetDefines(Opts, Builder);
3079207619Srdivacky    Builder.defineMacro("__INTEL__");
3080207619Srdivacky    Builder.defineMacro("__HAIKU__");
3081207619Srdivacky  }
3082207619Srdivacky};
3083207619Srdivacky} // end anonymous namespace
3084207619Srdivacky
3085224145Sdim// RTEMS Target
3086224145Sdimtemplate<typename Target>
3087224145Sdimclass RTEMSTargetInfo : public OSTargetInfo<Target> {
3088224145Sdimprotected:
3089224145Sdim  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
3090224145Sdim                            MacroBuilder &Builder) const {
3091224145Sdim    // RTEMS defines; list based off of gcc output
3092224145Sdim
3093224145Sdim    Builder.defineMacro("__rtems__");
3094224145Sdim    Builder.defineMacro("__ELF__");
3095224145Sdim  }
3096224145Sdimpublic:
3097224145Sdim  RTEMSTargetInfo(const std::string &triple)
3098224145Sdim    : OSTargetInfo<Target>(triple) {
3099224145Sdim      this->UserLabelPrefix = "";
3100224145Sdim
3101224145Sdim      llvm::Triple Triple(triple);
3102224145Sdim      switch (Triple.getArch()) {
3103224145Sdim        default:
3104224145Sdim        case llvm::Triple::x86:
3105224145Sdim          // this->MCountName = ".mcount";
3106224145Sdim          break;
3107224145Sdim        case llvm::Triple::mips:
3108224145Sdim        case llvm::Triple::mipsel:
3109224145Sdim        case llvm::Triple::ppc:
3110224145Sdim        case llvm::Triple::ppc64:
3111224145Sdim          // this->MCountName = "_mcount";
3112224145Sdim          break;
3113224145Sdim        case llvm::Triple::arm:
3114224145Sdim          // this->MCountName = "__mcount";
3115224145Sdim          break;
3116224145Sdim      }
3117224145Sdim
3118224145Sdim    }
3119224145Sdim};
3120224145Sdim
3121207619Srdivackynamespace {
3122224145Sdim// x86-32 RTEMS target
3123224145Sdimclass RTEMSX86_32TargetInfo : public X86_32TargetInfo {
3124224145Sdimpublic:
3125224145Sdim  RTEMSX86_32TargetInfo(const std::string& triple)
3126224145Sdim    : X86_32TargetInfo(triple) {
3127224145Sdim    SizeType = UnsignedLong;
3128224145Sdim    IntPtrType = SignedLong;
3129224145Sdim    PtrDiffType = SignedLong;
3130224145Sdim    this->UserLabelPrefix = "";
3131224145Sdim  }
3132224145Sdim  virtual void getTargetDefines(const LangOptions &Opts,
3133224145Sdim                                MacroBuilder &Builder) const {
3134224145Sdim    X86_32TargetInfo::getTargetDefines(Opts, Builder);
3135224145Sdim    Builder.defineMacro("__INTEL__");
3136224145Sdim    Builder.defineMacro("__rtems__");
3137224145Sdim  }
3138224145Sdim};
3139224145Sdim} // end anonymous namespace
3140224145Sdim
3141224145Sdimnamespace {
3142193326Sed// x86-64 generic target
3143193326Sedclass X86_64TargetInfo : public X86TargetInfo {
3144193326Sedpublic:
3145193326Sed  X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
3146193326Sed    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
3147193326Sed    LongDoubleWidth = 128;
3148193326Sed    LongDoubleAlign = 128;
3149210299Sed    LargeArrayMinWidth = 128;
3150210299Sed    LargeArrayAlign = 128;
3151234353Sdim    SuitableAlign = 128;
3152193326Sed    IntMaxType = SignedLong;
3153193326Sed    UIntMaxType = UnsignedLong;
3154195341Sed    Int64Type = SignedLong;
3155193326Sed    RegParmMax = 6;
3156193326Sed
3157193326Sed    DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
3158193326Sed                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
3159226633Sdim                        "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128";
3160210299Sed
3161210299Sed    // Use fpret only for long double.
3162210299Sed    RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
3163226633Sdim
3164234353Sdim    // Use fp2ret for _Complex long double.
3165234353Sdim    ComplexLongDoubleUsesFP2Ret = true;
3166234353Sdim
3167226633Sdim    // x86-64 has atomics up to 16 bytes.
3168226633Sdim    // FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128
3169226633Sdim    // on CPUs with cmpxchg16b
3170226633Sdim    MaxAtomicPromoteWidth = 128;
3171226633Sdim    MaxAtomicInlineWidth = 64;
3172193326Sed  }
3173239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
3174239462Sdim    return TargetInfo::X86_64ABIBuiltinVaList;
3175193326Sed  }
3176218893Sdim
3177198092Srdivacky  int getEHDataRegisterNumber(unsigned RegNo) const {
3178198092Srdivacky    if (RegNo == 0) return 0;
3179198092Srdivacky    if (RegNo == 1) return 1;
3180198092Srdivacky    return -1;
3181198092Srdivacky  }
3182243830Sdim
3183243830Sdim  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
3184249423Sdim    return (CC == CC_Default ||
3185256030Sdim            CC == CC_C ||
3186256030Sdim            CC == CC_IntelOclBicc ||
3187256030Sdim            CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning;
3188243830Sdim  }
3189243830Sdim
3190249423Sdim  virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
3191249423Sdim    return CC_C;
3192243830Sdim  }
3193243830Sdim
3194193326Sed};
3195193326Sed} // end anonymous namespace
3196193326Sed
3197193326Sednamespace {
3198198092Srdivacky// x86-64 Windows target
3199218893Sdimclass WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
3200198092Srdivackypublic:
3201198092Srdivacky  WindowsX86_64TargetInfo(const std::string& triple)
3202218893Sdim    : WindowsTargetInfo<X86_64TargetInfo>(triple) {
3203198092Srdivacky    TLSSupported = false;
3204198092Srdivacky    WCharType = UnsignedShort;
3205198092Srdivacky    LongWidth = LongAlign = 32;
3206218893Sdim    DoubleAlign = LongLongAlign = 64;
3207212904Sdim    IntMaxType = SignedLongLong;
3208212904Sdim    UIntMaxType = UnsignedLongLong;
3209212904Sdim    Int64Type = SignedLongLong;
3210218893Sdim    SizeType = UnsignedLongLong;
3211218893Sdim    PtrDiffType = SignedLongLong;
3212218893Sdim    IntPtrType = SignedLongLong;
3213218893Sdim    this->UserLabelPrefix = "";
3214198092Srdivacky  }
3215198092Srdivacky  virtual void getTargetDefines(const LangOptions &Opts,
3216202379Srdivacky                                MacroBuilder &Builder) const {
3217218893Sdim    WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
3218202379Srdivacky    Builder.defineMacro("_WIN64");
3219198092Srdivacky  }
3220239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
3221239462Sdim    return TargetInfo::CharPtrBuiltinVaList;
3222218893Sdim  }
3223256030Sdim  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
3224256030Sdim    return (CC == CC_C ||
3225256030Sdim            CC == CC_IntelOclBicc ||
3226256030Sdim            CC == CC_X86_64SysV) ? CCCR_OK : CCCR_Warning;
3227256030Sdim  }
3228198092Srdivacky};
3229198092Srdivacky} // end anonymous namespace
3230198092Srdivacky
3231198092Srdivackynamespace {
3232198092Srdivacky// x86-64 Windows Visual Studio target
3233198092Srdivackyclass VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
3234198092Srdivackypublic:
3235198092Srdivacky  VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
3236198092Srdivacky    : WindowsX86_64TargetInfo(triple) {
3237221345Sdim    LongDoubleWidth = LongDoubleAlign = 64;
3238221345Sdim    LongDoubleFormat = &llvm::APFloat::IEEEdouble;
3239198092Srdivacky  }
3240198092Srdivacky  virtual void getTargetDefines(const LangOptions &Opts,
3241202379Srdivacky                                MacroBuilder &Builder) const {
3242202379Srdivacky    WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
3243218893Sdim    WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
3244202379Srdivacky    Builder.defineMacro("_M_X64");
3245218893Sdim    Builder.defineMacro("_M_AMD64");
3246198092Srdivacky  }
3247198092Srdivacky};
3248198092Srdivacky} // end anonymous namespace
3249198092Srdivacky
3250198092Srdivackynamespace {
3251198092Srdivacky// x86-64 MinGW target
3252198092Srdivackyclass MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
3253198092Srdivackypublic:
3254198092Srdivacky  MinGWX86_64TargetInfo(const std::string& triple)
3255198092Srdivacky    : WindowsX86_64TargetInfo(triple) {
3256198092Srdivacky  }
3257198092Srdivacky  virtual void getTargetDefines(const LangOptions &Opts,
3258202379Srdivacky                                MacroBuilder &Builder) const {
3259202379Srdivacky    WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
3260218893Sdim    DefineStd(Builder, "WIN64", Opts);
3261202379Srdivacky    Builder.defineMacro("__MSVCRT__");
3262221345Sdim    Builder.defineMacro("__MINGW32__");
3263202379Srdivacky    Builder.defineMacro("__MINGW64__");
3264221345Sdim
3265221345Sdim    // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
3266221345Sdim    // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
3267226633Sdim    if (Opts.MicrosoftExt)
3268221345Sdim      // Provide "as-is" __declspec.
3269221345Sdim      Builder.defineMacro("__declspec", "__declspec");
3270221345Sdim    else
3271221345Sdim      // Provide alias of __attribute__ like mingw32-gcc.
3272221345Sdim      Builder.defineMacro("__declspec(a)", "__attribute__((a))");
3273198092Srdivacky  }
3274198092Srdivacky};
3275198092Srdivacky} // end anonymous namespace
3276198092Srdivacky
3277198092Srdivackynamespace {
3278195341Sedclass DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
3279193326Sedpublic:
3280198092Srdivacky  DarwinX86_64TargetInfo(const std::string& triple)
3281195341Sed      : DarwinTargetInfo<X86_64TargetInfo>(triple) {
3282195341Sed    Int64Type = SignedLongLong;
3283239462Sdim    MaxVectorAlign = 256;
3284193326Sed  }
3285193326Sed};
3286193326Sed} // end anonymous namespace
3287193326Sed
3288193326Sednamespace {
3289198092Srdivackyclass OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
3290198092Srdivackypublic:
3291198092Srdivacky  OpenBSDX86_64TargetInfo(const std::string& triple)
3292198092Srdivacky      : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
3293198092Srdivacky    IntMaxType = SignedLongLong;
3294198092Srdivacky    UIntMaxType = UnsignedLongLong;
3295198092Srdivacky    Int64Type = SignedLongLong;
3296198092Srdivacky  }
3297198092Srdivacky};
3298198092Srdivacky} // end anonymous namespace
3299198092Srdivacky
3300198092Srdivackynamespace {
3301239462Sdimclass BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> {
3302239462Sdimpublic:
3303239462Sdim  BitrigX86_64TargetInfo(const std::string& triple)
3304239462Sdim      : BitrigTargetInfo<X86_64TargetInfo>(triple) {
3305239462Sdim     IntMaxType = SignedLongLong;
3306239462Sdim     UIntMaxType = UnsignedLongLong;
3307239462Sdim     Int64Type = SignedLongLong;
3308239462Sdim  }
3309239462Sdim};
3310249423Sdim}
3311249423Sdim
3312249423Sdimnamespace {
3313249423Sdimclass AArch64TargetInfo : public TargetInfo {
3314249423Sdim  static const char * const GCCRegNames[];
3315249423Sdim  static const TargetInfo::GCCRegAlias GCCRegAliases[];
3316251662Sdim
3317251662Sdim  static const Builtin::Info BuiltinInfo[];
3318249423Sdimpublic:
3319249423Sdim  AArch64TargetInfo(const std::string& triple) : TargetInfo(triple) {
3320249423Sdim    BigEndian = false;
3321249423Sdim    LongWidth = LongAlign = 64;
3322249423Sdim    LongDoubleWidth = LongDoubleAlign = 128;
3323249423Sdim    PointerWidth = PointerAlign = 64;
3324249423Sdim    SuitableAlign = 128;
3325249423Sdim    DescriptionString = "e-p:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
3326249423Sdim                        "i64:64:64-i128:128:128-f32:32:32-f64:64:64-"
3327249423Sdim                        "f128:128:128-n32:64-S128";
3328249423Sdim
3329249423Sdim    WCharType = UnsignedInt;
3330249423Sdim    LongDoubleFormat = &llvm::APFloat::IEEEquad;
3331249423Sdim
3332249423Sdim    // AArch64 backend supports 64-bit operations at the moment. In principle
3333249423Sdim    // 128-bit is possible if register-pairs are used.
3334249423Sdim    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
3335249423Sdim
3336249423Sdim    TheCXXABI.set(TargetCXXABI::GenericAArch64);
3337249423Sdim  }
3338249423Sdim  virtual void getTargetDefines(const LangOptions &Opts,
3339249423Sdim                                MacroBuilder &Builder) const {
3340249423Sdim    // GCC defines theses currently
3341249423Sdim    Builder.defineMacro("__aarch64__");
3342249423Sdim    Builder.defineMacro("__AARCH64EL__");
3343249423Sdim
3344249423Sdim    // ACLE predefines. Many can only have one possible value on v8 AArch64.
3345249423Sdim
3346249423Sdim    // FIXME: these were written based on an unreleased version of a 32-bit ACLE
3347249423Sdim    // which was intended to be compatible with a 64-bit implementation. They
3348249423Sdim    // will need updating when a real 64-bit ACLE exists. Particularly pressing
3349251662Sdim    // instances are: __ARM_ARCH_ISA_ARM, __ARM_ARCH_ISA_THUMB, __ARM_PCS.
3350251662Sdim    Builder.defineMacro("__ARM_ACLE",         "101");
3351251662Sdim    Builder.defineMacro("__ARM_ARCH",         "8");
3352251662Sdim    Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
3353249423Sdim
3354251662Sdim    Builder.defineMacro("__ARM_FEATURE_UNALIGNED");
3355251662Sdim    Builder.defineMacro("__ARM_FEATURE_CLZ");
3356251662Sdim    Builder.defineMacro("__ARM_FEATURE_FMA");
3357249423Sdim
3358249423Sdim    // FIXME: ACLE 1.1 reserves bit 4. Will almost certainly come to mean
3359249423Sdim    // 128-bit LDXP present, at which point this becomes 0x1f.
3360251662Sdim    Builder.defineMacro("__ARM_FEATURE_LDREX", "0xf");
3361249423Sdim
3362249423Sdim    // 0xe implies support for half, single and double precision operations.
3363251662Sdim    Builder.defineMacro("__ARM_FP", "0xe");
3364249423Sdim
3365249423Sdim    // PCS specifies this for SysV variants, which is all we support. Other ABIs
3366251662Sdim    // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
3367251662Sdim    Builder.defineMacro("__ARM_FP16_FORMAT_IEEE");
3368249423Sdim
3369249423Sdim    if (Opts.FastMath || Opts.FiniteMathOnly)
3370251662Sdim      Builder.defineMacro("__ARM_FP_FAST");
3371249423Sdim
3372249423Sdim    if ((Opts.C99 || Opts.C11) && !Opts.Freestanding)
3373251662Sdim      Builder.defineMacro("__ARM_FP_FENV_ROUNDING");
3374249423Sdim
3375251662Sdim    Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
3376249423Sdim                        Opts.ShortWChar ? "2" : "4");
3377249423Sdim
3378251662Sdim    Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
3379249423Sdim                        Opts.ShortEnums ? "1" : "4");
3380249423Sdim
3381249423Sdim    if (BigEndian)
3382251662Sdim      Builder.defineMacro("__ARM_BIG_ENDIAN");
3383249423Sdim  }
3384249423Sdim  virtual void getTargetBuiltins(const Builtin::Info *&Records,
3385249423Sdim                                 unsigned &NumRecords) const {
3386251662Sdim    Records = BuiltinInfo;
3387251662Sdim    NumRecords = clang::AArch64::LastTSBuiltin-Builtin::FirstTSBuiltin;
3388249423Sdim  }
3389249423Sdim  virtual bool hasFeature(StringRef Feature) const {
3390249423Sdim    return Feature == "aarch64";
3391249423Sdim  }
3392249423Sdim  virtual void getGCCRegNames(const char * const *&Names,
3393249423Sdim                              unsigned &NumNames) const;
3394249423Sdim  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
3395249423Sdim                                unsigned &NumAliases) const;
3396249423Sdim
3397249423Sdim  virtual bool isCLZForZeroUndef() const { return false; }
3398249423Sdim
3399249423Sdim  virtual bool validateAsmConstraint(const char *&Name,
3400249423Sdim                                     TargetInfo::ConstraintInfo &Info) const {
3401249423Sdim    switch (*Name) {
3402249423Sdim    default: return false;
3403249423Sdim    case 'w': // An FP/SIMD vector register
3404249423Sdim      Info.setAllowsRegister();
3405249423Sdim      return true;
3406249423Sdim    case 'I': // Constant that can be used with an ADD instruction
3407249423Sdim    case 'J': // Constant that can be used with a SUB instruction
3408249423Sdim    case 'K': // Constant that can be used with a 32-bit logical instruction
3409249423Sdim    case 'L': // Constant that can be used with a 64-bit logical instruction
3410249423Sdim    case 'M': // Constant that can be used as a 32-bit MOV immediate
3411249423Sdim    case 'N': // Constant that can be used as a 64-bit MOV immediate
3412249423Sdim    case 'Y': // Floating point constant zero
3413249423Sdim    case 'Z': // Integer constant zero
3414249423Sdim      return true;
3415249423Sdim    case 'Q': // A memory reference with base register and no offset
3416249423Sdim      Info.setAllowsMemory();
3417249423Sdim      return true;
3418249423Sdim    case 'S': // A symbolic address
3419249423Sdim      Info.setAllowsRegister();
3420249423Sdim      return true;
3421249423Sdim    case 'U':
3422249423Sdim      // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes, whatever they may be
3423249423Sdim      // Utf: A memory address suitable for ldp/stp in TF mode, whatever it may be
3424249423Sdim      // Usa: An absolute symbolic address
3425249423Sdim      // Ush: The high part (bits 32:12) of a pc-relative symbolic address
3426249423Sdim      llvm_unreachable("FIXME: Unimplemented support for bizarre constraints");
3427249423Sdim    }
3428249423Sdim  }
3429249423Sdim
3430249423Sdim  virtual const char *getClobbers() const {
3431249423Sdim    // There are no AArch64 clobbers shared by all asm statements.
3432249423Sdim    return "";
3433249423Sdim  }
3434249423Sdim
3435249423Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
3436249423Sdim    return TargetInfo::AArch64ABIBuiltinVaList;
3437249423Sdim  }
3438249423Sdim};
3439249423Sdim
3440249423Sdimconst char * const AArch64TargetInfo::GCCRegNames[] = {
3441249423Sdim  "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7",
3442249423Sdim  "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15",
3443249423Sdim  "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23",
3444249423Sdim  "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", "wzr",
3445249423Sdim
3446249423Sdim  "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
3447249423Sdim  "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
3448249423Sdim  "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
3449249423Sdim  "x24", "x25", "x26", "x27", "x28", "x29", "x30", "sp", "xzr",
3450249423Sdim
3451249423Sdim  "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
3452249423Sdim  "b8", "b9", "b10", "b11", "b12", "b13", "b14", "b15",
3453249423Sdim  "b16", "b17", "b18", "b19", "b20", "b21", "b22", "b23",
3454249423Sdim  "b24", "b25", "b26", "b27", "b28", "b29", "b30", "b31",
3455249423Sdim
3456249423Sdim  "h0", "h1", "h2", "h3", "h4", "h5", "h6", "h7",
3457249423Sdim  "h8", "h9", "h10", "h11", "h12", "h13", "h14", "h15",
3458249423Sdim  "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
3459249423Sdim  "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31",
3460249423Sdim
3461249423Sdim  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
3462249423Sdim  "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
3463249423Sdim  "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
3464249423Sdim  "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
3465249423Sdim
3466249423Sdim  "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
3467249423Sdim  "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
3468249423Sdim  "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
3469249423Sdim  "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
3470249423Sdim
3471249423Sdim  "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
3472249423Sdim  "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
3473249423Sdim  "q16", "q17", "q18", "q19", "q20", "q21", "q22", "q23",
3474249423Sdim  "q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31"
3475249423Sdim};
3476249423Sdim
3477249423Sdimvoid AArch64TargetInfo::getGCCRegNames(const char * const *&Names,
3478249423Sdim                                       unsigned &NumNames) const {
3479249423Sdim  Names = GCCRegNames;
3480249423Sdim  NumNames = llvm::array_lengthof(GCCRegNames);
3481249423Sdim}
3482249423Sdim
3483249423Sdimconst TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
3484249423Sdim  { { "x16" }, "ip0"},
3485249423Sdim  { { "x17" }, "ip1"},
3486249423Sdim  { { "x29" }, "fp" },
3487249423Sdim  { { "x30" }, "lr" }
3488249423Sdim};
3489249423Sdim
3490249423Sdimvoid AArch64TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
3491249423Sdim                                         unsigned &NumAliases) const {
3492249423Sdim  Aliases = GCCRegAliases;
3493249423Sdim  NumAliases = llvm::array_lengthof(GCCRegAliases);
3494249423Sdim
3495249423Sdim}
3496251662Sdim
3497251662Sdimconst Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
3498251662Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
3499251662Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
3500251662Sdim                                              ALL_LANGUAGES },
3501251662Sdim#include "clang/Basic/BuiltinsAArch64.def"
3502251662Sdim};
3503251662Sdim
3504239462Sdim} // end anonymous namespace
3505239462Sdim
3506239462Sdimnamespace {
3507193326Sedclass ARMTargetInfo : public TargetInfo {
3508201361Srdivacky  // Possible FPU choices.
3509201361Srdivacky  enum FPUMode {
3510243830Sdim    VFP2FPU = (1 << 0),
3511243830Sdim    VFP3FPU = (1 << 1),
3512243830Sdim    VFP4FPU = (1 << 2),
3513243830Sdim    NeonFPU = (1 << 3)
3514201361Srdivacky  };
3515198092Srdivacky
3516201361Srdivacky  static bool FPUModeIsVFP(FPUMode Mode) {
3517243830Sdim    return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU);
3518201361Srdivacky  }
3519198092Srdivacky
3520201361Srdivacky  static const TargetInfo::GCCRegAlias GCCRegAliases[];
3521201361Srdivacky  static const char * const GCCRegNames[];
3522198092Srdivacky
3523201361Srdivacky  std::string ABI, CPU;
3524201361Srdivacky
3525243830Sdim  unsigned FPU : 4;
3526201361Srdivacky
3527243830Sdim  unsigned IsAAPCS : 1;
3528201361Srdivacky  unsigned IsThumb : 1;
3529201361Srdivacky
3530201361Srdivacky  // Initialized via features.
3531201361Srdivacky  unsigned SoftFloat : 1;
3532201361Srdivacky  unsigned SoftFloatABI : 1;
3533201361Srdivacky
3534204793Srdivacky  static const Builtin::Info BuiltinInfo[];
3535204793Srdivacky
3536251662Sdim  static bool shouldUseInlineAtomic(const llvm::Triple &T) {
3537251662Sdim    // On linux, binaries targeting old cpus call functions in libgcc to
3538251662Sdim    // perform atomic operations. The implementation in libgcc then calls into
3539251662Sdim    // the kernel which on armv6 and newer uses ldrex and strex. The net result
3540251662Sdim    // is that if we assume the kernel is at least as recent as the hardware,
3541251662Sdim    // it is safe to use atomic instructions on armv6 and newer.
3542251785Sed    if (T.getOS() != llvm::Triple::Linux && T.getOS() != llvm::Triple::FreeBSD)
3543251785Sed      return false;
3544251662Sdim    StringRef ArchName = T.getArchName();
3545251662Sdim    if (T.getArch() == llvm::Triple::arm) {
3546251662Sdim      if (!ArchName.startswith("armv"))
3547251662Sdim        return false;
3548251662Sdim      StringRef VersionStr = ArchName.substr(4);
3549251662Sdim      unsigned Version;
3550251662Sdim      if (VersionStr.getAsInteger(10, Version))
3551251662Sdim        return false;
3552251662Sdim      return Version >= 6;
3553251662Sdim    }
3554251662Sdim    assert(T.getArch() == llvm::Triple::thumb);
3555251662Sdim    if (!ArchName.startswith("thumbv"))
3556251662Sdim      return false;
3557251662Sdim    StringRef VersionStr = ArchName.substr(6);
3558251662Sdim    unsigned Version;
3559251662Sdim    if (VersionStr.getAsInteger(10, Version))
3560251662Sdim      return false;
3561251662Sdim    return Version >= 7;
3562251662Sdim  }
3563251662Sdim
3564193326Sedpublic:
3565198092Srdivacky  ARMTargetInfo(const std::string &TripleStr)
3566243830Sdim    : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s"), IsAAPCS(true)
3567198092Srdivacky  {
3568234353Sdim    BigEndian = false;
3569198092Srdivacky    SizeType = UnsignedInt;
3570198092Srdivacky    PtrDiffType = SignedInt;
3571234353Sdim    // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
3572234353Sdim    WCharType = UnsignedInt;
3573198092Srdivacky
3574207619Srdivacky    // {} in inline assembly are neon specifiers, not assembly variant
3575207619Srdivacky    // specifiers.
3576207619Srdivacky    NoAsmVariants = true;
3577218893Sdim
3578201361Srdivacky    // FIXME: Should we just treat this as a feature?
3579201361Srdivacky    IsThumb = getTriple().getArchName().startswith("thumb");
3580198092Srdivacky    if (IsThumb) {
3581221345Sdim      // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
3582221345Sdim      // so set preferred for small types to 32.
3583198092Srdivacky      DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
3584198092Srdivacky                           "i64:64:64-f32:32:32-f64:64:64-"
3585226633Sdim                           "v64:64:64-v128:64:128-a0:0:32-n32-S64");
3586198092Srdivacky    } else {
3587198092Srdivacky      DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
3588198092Srdivacky                           "i64:64:64-f32:32:32-f64:64:64-"
3589226633Sdim                           "v64:64:64-v128:64:128-a0:0:64-n32-S64");
3590193326Sed    }
3591212904Sdim
3592212904Sdim    // ARM targets default to using the ARM C++ ABI.
3593249423Sdim    TheCXXABI.set(TargetCXXABI::GenericARM);
3594226633Sdim
3595226633Sdim    // ARM has atomics up to 8 bytes
3596226633Sdim    MaxAtomicPromoteWidth = 64;
3597251662Sdim    if (shouldUseInlineAtomic(getTriple()))
3598251662Sdim      MaxAtomicInlineWidth = 64;
3599234353Sdim
3600234353Sdim    // Do force alignment of members that follow zero length bitfields.  If
3601234353Sdim    // the alignment of the zero-length bitfield is greater than the member
3602234353Sdim    // that follows it, `bar', `bar' will be aligned as the  type of the
3603234353Sdim    // zero length bitfield.
3604234353Sdim    UseZeroLengthBitfieldAlignment = true;
3605193326Sed  }
3606198092Srdivacky  virtual const char *getABI() const { return ABI.c_str(); }
3607198092Srdivacky  virtual bool setABI(const std::string &Name) {
3608198092Srdivacky    ABI = Name;
3609198092Srdivacky
3610198092Srdivacky    // The defaults (above) are for AAPCS, check if we need to change them.
3611198092Srdivacky    //
3612198092Srdivacky    // FIXME: We need support for -meabi... we could just mangle it into the
3613198092Srdivacky    // name.
3614198092Srdivacky    if (Name == "apcs-gnu") {
3615234353Sdim      DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
3616244640Sandrew      // size_t is unsigned int on FreeBSD.
3617244640Sandrew      if (getTriple().getOS() != llvm::Triple::FreeBSD)
3618244640Sandrew        SizeType = UnsignedLong;
3619198092Srdivacky
3620234353Sdim      // Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
3621234353Sdim      WCharType = SignedInt;
3622234353Sdim
3623207619Srdivacky      // Do not respect the alignment of bit-field types when laying out
3624207619Srdivacky      // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
3625207619Srdivacky      UseBitFieldTypeAlignment = false;
3626207619Srdivacky
3627226633Sdim      /// gcc forces the alignment to 4 bytes, regardless of the type of the
3628226633Sdim      /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
3629226633Sdim      /// gcc.
3630226633Sdim      ZeroLengthBitfieldBoundary = 32;
3631226633Sdim
3632243830Sdim      IsAAPCS = false;
3633243830Sdim
3634198092Srdivacky      if (IsThumb) {
3635221345Sdim        // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
3636221345Sdim        // so set preferred for small types to 32.
3637198092Srdivacky        DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
3638224145Sdim                             "i64:32:64-f32:32:32-f64:32:64-"
3639226633Sdim                             "v64:32:64-v128:32:128-a0:0:32-n32-S32");
3640198092Srdivacky      } else {
3641198092Srdivacky        DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
3642221345Sdim                             "i64:32:64-f32:32:32-f64:32:64-"
3643226633Sdim                             "v64:32:64-v128:32:128-a0:0:32-n32-S32");
3644198092Srdivacky      }
3645198092Srdivacky
3646198092Srdivacky      // FIXME: Override "preferred align" for double and long long.
3647243830Sdim    } else if (Name == "aapcs" || Name == "aapcs-vfp") {
3648243830Sdim      IsAAPCS = true;
3649198092Srdivacky      // FIXME: Enumerated types are variable width in straight AAPCS.
3650198092Srdivacky    } else if (Name == "aapcs-linux") {
3651243830Sdim      IsAAPCS = true;
3652198092Srdivacky    } else
3653198092Srdivacky      return false;
3654198092Srdivacky
3655198092Srdivacky    return true;
3656198092Srdivacky  }
3657201361Srdivacky
3658226633Sdim  void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
3659201361Srdivacky    if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
3660201361Srdivacky      Features["vfp2"] = true;
3661243830Sdim    else if (CPU == "cortex-a8" || CPU == "cortex-a15" ||
3662243830Sdim             CPU == "cortex-a9" || CPU == "cortex-a9-mp")
3663201361Srdivacky      Features["neon"] = true;
3664249423Sdim    else if (CPU == "swift" || CPU == "cortex-a7") {
3665243830Sdim      Features["vfp4"] = true;
3666243830Sdim      Features["neon"] = true;
3667243830Sdim    }
3668201361Srdivacky  }
3669218893Sdim
3670201361Srdivacky  virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
3671234353Sdim                                 StringRef Name,
3672201361Srdivacky                                 bool Enabled) const {
3673224145Sdim    if (Name == "soft-float" || Name == "soft-float-abi" ||
3674243830Sdim        Name == "vfp2" || Name == "vfp3" || Name == "vfp4" || Name == "neon" ||
3675243830Sdim        Name == "d16" || Name == "neonfp") {
3676201361Srdivacky      Features[Name] = Enabled;
3677201361Srdivacky    } else
3678201361Srdivacky      return false;
3679201361Srdivacky
3680201361Srdivacky    return true;
3681201361Srdivacky  }
3682201361Srdivacky
3683201361Srdivacky  virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
3684243830Sdim    FPU = 0;
3685201361Srdivacky    SoftFloat = SoftFloatABI = false;
3686201361Srdivacky    for (unsigned i = 0, e = Features.size(); i != e; ++i) {
3687201361Srdivacky      if (Features[i] == "+soft-float")
3688201361Srdivacky        SoftFloat = true;
3689201361Srdivacky      else if (Features[i] == "+soft-float-abi")
3690201361Srdivacky        SoftFloatABI = true;
3691201361Srdivacky      else if (Features[i] == "+vfp2")
3692243830Sdim        FPU |= VFP2FPU;
3693201361Srdivacky      else if (Features[i] == "+vfp3")
3694243830Sdim        FPU |= VFP3FPU;
3695243830Sdim      else if (Features[i] == "+vfp4")
3696243830Sdim        FPU |= VFP4FPU;
3697201361Srdivacky      else if (Features[i] == "+neon")
3698243830Sdim        FPU |= NeonFPU;
3699201361Srdivacky    }
3700201361Srdivacky
3701201361Srdivacky    // Remove front-end specific options which the backend handles differently.
3702201361Srdivacky    std::vector<std::string>::iterator it;
3703201361Srdivacky    it = std::find(Features.begin(), Features.end(), "+soft-float");
3704201361Srdivacky    if (it != Features.end())
3705201361Srdivacky      Features.erase(it);
3706201361Srdivacky    it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
3707201361Srdivacky    if (it != Features.end())
3708201361Srdivacky      Features.erase(it);
3709201361Srdivacky  }
3710201361Srdivacky
3711234353Sdim  virtual bool hasFeature(StringRef Feature) const {
3712234353Sdim    return llvm::StringSwitch<bool>(Feature)
3713234353Sdim        .Case("arm", true)
3714234353Sdim        .Case("softfloat", SoftFloat)
3715234353Sdim        .Case("thumb", IsThumb)
3716234353Sdim        .Case("neon", FPU == NeonFPU && !SoftFloat &&
3717234353Sdim              StringRef(getCPUDefineSuffix(CPU)).startswith("7"))
3718234353Sdim        .Default(false);
3719234353Sdim  }
3720243830Sdim  // FIXME: Should we actually have some table instead of these switches?
3721226633Sdim  static const char *getCPUDefineSuffix(StringRef Name) {
3722201361Srdivacky    return llvm::StringSwitch<const char*>(Name)
3723201361Srdivacky      .Cases("arm8", "arm810", "4")
3724201361Srdivacky      .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
3725201361Srdivacky      .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
3726201361Srdivacky      .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
3727201361Srdivacky      .Case("ep9312", "4T")
3728201361Srdivacky      .Cases("arm10tdmi", "arm1020t", "5T")
3729201361Srdivacky      .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
3730201361Srdivacky      .Case("arm926ej-s", "5TEJ")
3731201361Srdivacky      .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
3732201361Srdivacky      .Cases("xscale", "iwmmxt", "5TE")
3733201361Srdivacky      .Case("arm1136j-s", "6J")
3734201361Srdivacky      .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
3735201361Srdivacky      .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
3736201361Srdivacky      .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
3737249423Sdim      .Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A")
3738249423Sdim      .Cases("cortex-a9", "cortex-a15", "7A")
3739249423Sdim      .Case("cortex-r5", "7R")
3740243830Sdim      .Case("cortex-a9-mp", "7F")
3741243830Sdim      .Case("swift", "7S")
3742243830Sdim      .Cases("cortex-m3", "cortex-m4", "7M")
3743221345Sdim      .Case("cortex-m0", "6M")
3744201361Srdivacky      .Default(0);
3745201361Srdivacky  }
3746243830Sdim  static const char *getCPUProfile(StringRef Name) {
3747243830Sdim    return llvm::StringSwitch<const char*>(Name)
3748243830Sdim      .Cases("cortex-a8", "cortex-a9", "A")
3749243830Sdim      .Cases("cortex-m3", "cortex-m4", "cortex-m0", "M")
3750249423Sdim      .Case("cortex-r5", "R")
3751243830Sdim      .Default("");
3752243830Sdim  }
3753201361Srdivacky  virtual bool setCPU(const std::string &Name) {
3754201361Srdivacky    if (!getCPUDefineSuffix(Name))
3755201361Srdivacky      return false;
3756201361Srdivacky
3757201361Srdivacky    CPU = Name;
3758201361Srdivacky    return true;
3759201361Srdivacky  }
3760193326Sed  virtual void getTargetDefines(const LangOptions &Opts,
3761202379Srdivacky                                MacroBuilder &Builder) const {
3762193326Sed    // Target identification.
3763202379Srdivacky    Builder.defineMacro("__arm");
3764202379Srdivacky    Builder.defineMacro("__arm__");
3765193326Sed
3766193326Sed    // Target properties.
3767202379Srdivacky    Builder.defineMacro("__ARMEL__");
3768202379Srdivacky    Builder.defineMacro("__LITTLE_ENDIAN__");
3769202379Srdivacky    Builder.defineMacro("__REGISTER_PREFIX__", "");
3770193326Sed
3771226633Sdim    StringRef CPUArch = getCPUDefineSuffix(CPU);
3772202379Srdivacky    Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
3773243830Sdim    Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
3774243830Sdim    StringRef CPUProfile = getCPUProfile(CPU);
3775243830Sdim    if (!CPUProfile.empty())
3776243830Sdim      Builder.defineMacro("__ARM_ARCH_PROFILE", CPUProfile);
3777243830Sdim
3778193326Sed    // Subtarget options.
3779201361Srdivacky
3780201361Srdivacky    // FIXME: It's more complicated than this and we don't really support
3781201361Srdivacky    // interworking.
3782201361Srdivacky    if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
3783202379Srdivacky      Builder.defineMacro("__THUMB_INTERWORK__");
3784201361Srdivacky
3785243830Sdim    if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
3786243830Sdim      // M-class CPUs on Darwin follow AAPCS, but not EABI.
3787243830Sdim      if (!(getTriple().isOSDarwin() && CPUProfile == "M"))
3788243830Sdim        Builder.defineMacro("__ARM_EABI__");
3789243830Sdim      Builder.defineMacro("__ARM_PCS", "1");
3790201361Srdivacky
3791243830Sdim      if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp")
3792243830Sdim        Builder.defineMacro("__ARM_PCS_VFP", "1");
3793243830Sdim    }
3794243830Sdim
3795201361Srdivacky    if (SoftFloat)
3796202379Srdivacky      Builder.defineMacro("__SOFTFP__");
3797201361Srdivacky
3798201361Srdivacky    if (CPU == "xscale")
3799202379Srdivacky      Builder.defineMacro("__XSCALE__");
3800198092Srdivacky
3801223017Sdim    bool IsARMv7 = CPUArch.startswith("7");
3802198092Srdivacky    if (IsThumb) {
3803202379Srdivacky      Builder.defineMacro("__THUMBEL__");
3804202379Srdivacky      Builder.defineMacro("__thumb__");
3805223017Sdim      if (CPUArch == "6T2" || IsARMv7)
3806202379Srdivacky        Builder.defineMacro("__thumb2__");
3807198092Srdivacky    }
3808198092Srdivacky
3809198092Srdivacky    // Note, this is always on in gcc, even though it doesn't make sense.
3810202379Srdivacky    Builder.defineMacro("__APCS_32__");
3811198092Srdivacky
3812243830Sdim    if (FPUModeIsVFP((FPUMode) FPU)) {
3813202379Srdivacky      Builder.defineMacro("__VFP_FP__");
3814243830Sdim      if (FPU & VFP2FPU)
3815243830Sdim        Builder.defineMacro("__ARM_VFPV2__");
3816243830Sdim      if (FPU & VFP3FPU)
3817243830Sdim        Builder.defineMacro("__ARM_VFPV3__");
3818243830Sdim      if (FPU & VFP4FPU)
3819243830Sdim        Builder.defineMacro("__ARM_VFPV4__");
3820243830Sdim    }
3821243830Sdim
3822201361Srdivacky    // This only gets set when Neon instructions are actually available, unlike
3823201361Srdivacky    // the VFP define, hence the soft float and arch check. This is subtly
3824201361Srdivacky    // different from gcc, we follow the intent which was that it should be set
3825201361Srdivacky    // when Neon instructions are actually available.
3826243830Sdim    if ((FPU & NeonFPU) && !SoftFloat && IsARMv7)
3827202379Srdivacky      Builder.defineMacro("__ARM_NEON__");
3828193326Sed  }
3829193326Sed  virtual void getTargetBuiltins(const Builtin::Info *&Records,
3830193326Sed                                 unsigned &NumRecords) const {
3831204793Srdivacky    Records = BuiltinInfo;
3832204793Srdivacky    NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
3833193326Sed  }
3834234353Sdim  virtual bool isCLZForZeroUndef() const { return false; }
3835239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
3836243830Sdim    return IsAAPCS ? AAPCSABIBuiltinVaList : TargetInfo::VoidPtrBuiltinVaList;
3837193326Sed  }
3838193326Sed  virtual void getGCCRegNames(const char * const *&Names,
3839198092Srdivacky                              unsigned &NumNames) const;
3840193326Sed  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
3841198092Srdivacky                                unsigned &NumAliases) const;
3842193326Sed  virtual bool validateAsmConstraint(const char *&Name,
3843193326Sed                                     TargetInfo::ConstraintInfo &Info) const {
3844193326Sed    switch (*Name) {
3845239462Sdim    default: break;
3846193326Sed    case 'l': // r0-r7
3847193326Sed    case 'h': // r8-r15
3848193326Sed    case 'w': // VFP Floating point register single precision
3849193326Sed    case 'P': // VFP Floating point register double precision
3850193326Sed      Info.setAllowsRegister();
3851193326Sed      return true;
3852226633Sdim    case 'Q': // A memory address that is a single base register.
3853226633Sdim      Info.setAllowsMemory();
3854226633Sdim      return true;
3855223017Sdim    case 'U': // a memory reference...
3856223017Sdim      switch (Name[1]) {
3857223017Sdim      case 'q': // ...ARMV4 ldrsb
3858223017Sdim      case 'v': // ...VFP load/store (reg+constant offset)
3859223017Sdim      case 'y': // ...iWMMXt load/store
3860224145Sdim      case 't': // address valid for load/store opaque types wider
3861249423Sdim                // than 128-bits
3862224145Sdim      case 'n': // valid address for Neon doubleword vector load/store
3863224145Sdim      case 'm': // valid address for Neon element and structure load/store
3864224145Sdim      case 's': // valid address for non-offset loads/stores of quad-word
3865249423Sdim                // values in four ARM registers
3866223017Sdim        Info.setAllowsMemory();
3867223017Sdim        Name++;
3868223017Sdim        return true;
3869223017Sdim      }
3870193326Sed    }
3871193326Sed    return false;
3872193326Sed  }
3873224145Sdim  virtual std::string convertConstraint(const char *&Constraint) const {
3874223017Sdim    std::string R;
3875223017Sdim    switch (*Constraint) {
3876223017Sdim    case 'U':   // Two-character constraint; add "^" hint for later parsing.
3877223017Sdim      R = std::string("^") + std::string(Constraint, 2);
3878223017Sdim      Constraint++;
3879223017Sdim      break;
3880224145Sdim    case 'p': // 'p' should be translated to 'r' by default.
3881224145Sdim      R = std::string("r");
3882224145Sdim      break;
3883223017Sdim    default:
3884223017Sdim      return std::string(1, *Constraint);
3885223017Sdim    }
3886223017Sdim    return R;
3887223017Sdim  }
3888243830Sdim  virtual bool validateConstraintModifier(StringRef Constraint,
3889243830Sdim                                          const char Modifier,
3890243830Sdim                                          unsigned Size) const {
3891249423Sdim    bool isOutput = (Constraint[0] == '=');
3892249423Sdim    bool isInOut = (Constraint[0] == '+');
3893249423Sdim
3894243830Sdim    // Strip off constraint modifiers.
3895243830Sdim    while (Constraint[0] == '=' ||
3896243830Sdim           Constraint[0] == '+' ||
3897243830Sdim           Constraint[0] == '&')
3898243830Sdim      Constraint = Constraint.substr(1);
3899243830Sdim
3900243830Sdim    switch (Constraint[0]) {
3901243830Sdim    default: break;
3902243830Sdim    case 'r': {
3903243830Sdim      switch (Modifier) {
3904243830Sdim      default:
3905249423Sdim        return isInOut || (isOutput && Size >= 32) ||
3906249423Sdim          (!isOutput && !isInOut && Size <= 32);
3907243830Sdim      case 'q':
3908243830Sdim        // A register of size 32 cannot fit a vector type.
3909243830Sdim        return false;
3910243830Sdim      }
3911243830Sdim    }
3912243830Sdim    }
3913243830Sdim
3914243830Sdim    return true;
3915243830Sdim  }
3916193326Sed  virtual const char *getClobbers() const {
3917193326Sed    // FIXME: Is this really right?
3918193326Sed    return "";
3919193326Sed  }
3920243830Sdim
3921243830Sdim  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
3922243830Sdim    return (CC == CC_AAPCS || CC == CC_AAPCS_VFP) ? CCCR_OK : CCCR_Warning;
3923243830Sdim  }
3924249423Sdim
3925249423Sdim  virtual int getEHDataRegisterNumber(unsigned RegNo) const {
3926249423Sdim    if (RegNo == 0) return 0;
3927249423Sdim    if (RegNo == 1) return 1;
3928249423Sdim    return -1;
3929249423Sdim  }
3930193326Sed};
3931198092Srdivacky
3932198092Srdivackyconst char * const ARMTargetInfo::GCCRegNames[] = {
3933212904Sdim  // Integer registers
3934198092Srdivacky  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3935212904Sdim  "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
3936212904Sdim
3937212904Sdim  // Float registers
3938212904Sdim  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
3939212904Sdim  "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
3940212904Sdim  "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
3941218893Sdim  "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
3942212904Sdim
3943218893Sdim  // Double registers
3944218893Sdim  "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
3945218893Sdim  "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
3946218893Sdim  "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
3947218893Sdim  "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
3948218893Sdim
3949218893Sdim  // Quad registers
3950218893Sdim  "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
3951218893Sdim  "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
3952198092Srdivacky};
3953198092Srdivacky
3954198092Srdivackyvoid ARMTargetInfo::getGCCRegNames(const char * const *&Names,
3955212904Sdim                                   unsigned &NumNames) const {
3956198092Srdivacky  Names = GCCRegNames;
3957198092Srdivacky  NumNames = llvm::array_lengthof(GCCRegNames);
3958198092Srdivacky}
3959198092Srdivacky
3960198092Srdivackyconst TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
3961198092Srdivacky  { { "a1" }, "r0" },
3962198092Srdivacky  { { "a2" }, "r1" },
3963198092Srdivacky  { { "a3" }, "r2" },
3964198092Srdivacky  { { "a4" }, "r3" },
3965198092Srdivacky  { { "v1" }, "r4" },
3966198092Srdivacky  { { "v2" }, "r5" },
3967198092Srdivacky  { { "v3" }, "r6" },
3968198092Srdivacky  { { "v4" }, "r7" },
3969198092Srdivacky  { { "v5" }, "r8" },
3970198092Srdivacky  { { "v6", "rfp" }, "r9" },
3971198092Srdivacky  { { "sl" }, "r10" },
3972198092Srdivacky  { { "fp" }, "r11" },
3973198092Srdivacky  { { "ip" }, "r12" },
3974212904Sdim  { { "r13" }, "sp" },
3975212904Sdim  { { "r14" }, "lr" },
3976212904Sdim  { { "r15" }, "pc" },
3977218893Sdim  // The S, D and Q registers overlap, but aren't really aliases; we
3978218893Sdim  // don't want to substitute one of these for a different-sized one.
3979198092Srdivacky};
3980198092Srdivacky
3981198092Srdivackyvoid ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
3982198092Srdivacky                                       unsigned &NumAliases) const {
3983198092Srdivacky  Aliases = GCCRegAliases;
3984198092Srdivacky  NumAliases = llvm::array_lengthof(GCCRegAliases);
3985198092Srdivacky}
3986204793Srdivacky
3987204793Srdivackyconst Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
3988224145Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
3989218893Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
3990224145Sdim                                              ALL_LANGUAGES },
3991204793Srdivacky#include "clang/Basic/BuiltinsARM.def"
3992204793Srdivacky};
3993193326Sed} // end anonymous namespace.
3994193326Sed
3995193326Sednamespace {
3996198092Srdivackyclass DarwinARMTargetInfo :
3997195341Sed  public DarwinTargetInfo<ARMTargetInfo> {
3998195341Sedprotected:
3999198092Srdivacky  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
4000202379Srdivacky                            MacroBuilder &Builder) const {
4001221345Sdim    getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
4002193326Sed  }
4003193326Sed
4004193326Sedpublic:
4005198092Srdivacky  DarwinARMTargetInfo(const std::string& triple)
4006208600Srdivacky    : DarwinTargetInfo<ARMTargetInfo>(triple) {
4007208600Srdivacky    HasAlignMac68kSupport = true;
4008226633Sdim    // iOS always has 64-bit atomic instructions.
4009226633Sdim    // FIXME: This should be based off of the target features in ARMTargetInfo.
4010226633Sdim    MaxAtomicInlineWidth = 64;
4011249423Sdim
4012249423Sdim    // Darwin on iOS uses a variant of the ARM C++ ABI.
4013249423Sdim    TheCXXABI.set(TargetCXXABI::iOS);
4014208600Srdivacky  }
4015193326Sed};
4016195341Sed} // end anonymous namespace.
4017193326Sed
4018234353Sdim
4019193326Sednamespace {
4020234353Sdim// Hexagon abstract base class
4021234353Sdimclass HexagonTargetInfo : public TargetInfo {
4022234353Sdim  static const Builtin::Info BuiltinInfo[];
4023234353Sdim  static const char * const GCCRegNames[];
4024234353Sdim  static const TargetInfo::GCCRegAlias GCCRegAliases[];
4025234353Sdim  std::string CPU;
4026234353Sdimpublic:
4027234353Sdim  HexagonTargetInfo(const std::string& triple) : TargetInfo(triple)  {
4028234353Sdim    BigEndian = false;
4029234353Sdim    DescriptionString = ("e-p:32:32:32-"
4030249423Sdim                         "i64:64:64-i32:32:32-i16:16:16-i1:32:32-"
4031239462Sdim                         "f64:64:64-f32:32:32-a0:0-n32");
4032234353Sdim
4033234353Sdim    // {} in inline assembly are packet specifiers, not assembly variant
4034234353Sdim    // specifiers.
4035234353Sdim    NoAsmVariants = true;
4036234353Sdim  }
4037234353Sdim
4038234353Sdim  virtual void getTargetBuiltins(const Builtin::Info *&Records,
4039234353Sdim                                 unsigned &NumRecords) const {
4040234353Sdim    Records = BuiltinInfo;
4041234353Sdim    NumRecords = clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin;
4042234353Sdim  }
4043234353Sdim
4044234353Sdim  virtual bool validateAsmConstraint(const char *&Name,
4045234353Sdim                                     TargetInfo::ConstraintInfo &Info) const {
4046234353Sdim    return true;
4047234353Sdim  }
4048234353Sdim
4049234353Sdim  virtual void getTargetDefines(const LangOptions &Opts,
4050234353Sdim                                MacroBuilder &Builder) const;
4051234353Sdim
4052234353Sdim  virtual bool hasFeature(StringRef Feature) const {
4053234353Sdim    return Feature == "hexagon";
4054234353Sdim  }
4055234353Sdim
4056239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
4057239462Sdim    return TargetInfo::CharPtrBuiltinVaList;
4058234353Sdim  }
4059234353Sdim  virtual void getGCCRegNames(const char * const *&Names,
4060234353Sdim                              unsigned &NumNames) const;
4061234353Sdim  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4062234353Sdim                                unsigned &NumAliases) const;
4063234353Sdim  virtual const char *getClobbers() const {
4064234353Sdim    return "";
4065234353Sdim  }
4066234353Sdim
4067234353Sdim  static const char *getHexagonCPUSuffix(StringRef Name) {
4068234353Sdim    return llvm::StringSwitch<const char*>(Name)
4069234353Sdim      .Case("hexagonv4", "4")
4070239462Sdim      .Case("hexagonv5", "5")
4071234353Sdim      .Default(0);
4072234353Sdim  }
4073234353Sdim
4074234353Sdim  virtual bool setCPU(const std::string &Name) {
4075234353Sdim    if (!getHexagonCPUSuffix(Name))
4076234353Sdim      return false;
4077234353Sdim
4078234353Sdim    CPU = Name;
4079234353Sdim    return true;
4080234353Sdim  }
4081234353Sdim};
4082234353Sdim
4083234353Sdimvoid HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
4084234353Sdim                                MacroBuilder &Builder) const {
4085234353Sdim  Builder.defineMacro("qdsp6");
4086234353Sdim  Builder.defineMacro("__qdsp6", "1");
4087234353Sdim  Builder.defineMacro("__qdsp6__", "1");
4088234353Sdim
4089234353Sdim  Builder.defineMacro("hexagon");
4090234353Sdim  Builder.defineMacro("__hexagon", "1");
4091234353Sdim  Builder.defineMacro("__hexagon__", "1");
4092234353Sdim
4093234353Sdim  if(CPU == "hexagonv1") {
4094234353Sdim    Builder.defineMacro("__HEXAGON_V1__");
4095234353Sdim    Builder.defineMacro("__HEXAGON_ARCH__", "1");
4096234353Sdim    if(Opts.HexagonQdsp6Compat) {
4097234353Sdim      Builder.defineMacro("__QDSP6_V1__");
4098234353Sdim      Builder.defineMacro("__QDSP6_ARCH__", "1");
4099234353Sdim    }
4100234353Sdim  }
4101234353Sdim  else if(CPU == "hexagonv2") {
4102234353Sdim    Builder.defineMacro("__HEXAGON_V2__");
4103234353Sdim    Builder.defineMacro("__HEXAGON_ARCH__", "2");
4104234353Sdim    if(Opts.HexagonQdsp6Compat) {
4105234353Sdim      Builder.defineMacro("__QDSP6_V2__");
4106234353Sdim      Builder.defineMacro("__QDSP6_ARCH__", "2");
4107234353Sdim    }
4108234353Sdim  }
4109234353Sdim  else if(CPU == "hexagonv3") {
4110234353Sdim    Builder.defineMacro("__HEXAGON_V3__");
4111234353Sdim    Builder.defineMacro("__HEXAGON_ARCH__", "3");
4112234353Sdim    if(Opts.HexagonQdsp6Compat) {
4113234353Sdim      Builder.defineMacro("__QDSP6_V3__");
4114234353Sdim      Builder.defineMacro("__QDSP6_ARCH__", "3");
4115234353Sdim    }
4116234353Sdim  }
4117234353Sdim  else if(CPU == "hexagonv4") {
4118234353Sdim    Builder.defineMacro("__HEXAGON_V4__");
4119234353Sdim    Builder.defineMacro("__HEXAGON_ARCH__", "4");
4120234353Sdim    if(Opts.HexagonQdsp6Compat) {
4121234353Sdim      Builder.defineMacro("__QDSP6_V4__");
4122234353Sdim      Builder.defineMacro("__QDSP6_ARCH__", "4");
4123234353Sdim    }
4124234353Sdim  }
4125239462Sdim  else if(CPU == "hexagonv5") {
4126239462Sdim    Builder.defineMacro("__HEXAGON_V5__");
4127239462Sdim    Builder.defineMacro("__HEXAGON_ARCH__", "5");
4128239462Sdim    if(Opts.HexagonQdsp6Compat) {
4129239462Sdim      Builder.defineMacro("__QDSP6_V5__");
4130239462Sdim      Builder.defineMacro("__QDSP6_ARCH__", "5");
4131239462Sdim    }
4132239462Sdim  }
4133234353Sdim}
4134234353Sdim
4135234353Sdimconst char * const HexagonTargetInfo::GCCRegNames[] = {
4136234353Sdim  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
4137234353Sdim  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
4138234353Sdim  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
4139234353Sdim  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
4140234353Sdim  "p0", "p1", "p2", "p3",
4141234353Sdim  "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
4142234353Sdim};
4143234353Sdim
4144234353Sdimvoid HexagonTargetInfo::getGCCRegNames(const char * const *&Names,
4145234353Sdim                                   unsigned &NumNames) const {
4146234353Sdim  Names = GCCRegNames;
4147234353Sdim  NumNames = llvm::array_lengthof(GCCRegNames);
4148234353Sdim}
4149234353Sdim
4150234353Sdim
4151234353Sdimconst TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
4152234353Sdim  { { "sp" }, "r29" },
4153234353Sdim  { { "fp" }, "r30" },
4154234353Sdim  { { "lr" }, "r31" },
4155234353Sdim };
4156234353Sdim
4157234353Sdimvoid HexagonTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
4158234353Sdim                                     unsigned &NumAliases) const {
4159234353Sdim  Aliases = GCCRegAliases;
4160234353Sdim  NumAliases = llvm::array_lengthof(GCCRegAliases);
4161234353Sdim}
4162234353Sdim
4163234353Sdim
4164234353Sdimconst Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
4165234353Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
4166234353Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
4167234353Sdim                                              ALL_LANGUAGES },
4168234353Sdim#include "clang/Basic/BuiltinsHexagon.def"
4169234353Sdim};
4170234353Sdim}
4171234353Sdim
4172234353Sdim
4173234353Sdimnamespace {
4174251662Sdim// Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit).
4175251662Sdimclass SparcTargetInfo : public TargetInfo {
4176193326Sed  static const TargetInfo::GCCRegAlias GCCRegAliases[];
4177193326Sed  static const char * const GCCRegNames[];
4178218893Sdim  bool SoftFloat;
4179193326Sedpublic:
4180251662Sdim  SparcTargetInfo(const std::string &triple) : TargetInfo(triple) {}
4181251662Sdim
4182218893Sdim  virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
4183234353Sdim                                 StringRef Name,
4184218893Sdim                                 bool Enabled) const {
4185218893Sdim    if (Name == "soft-float")
4186218893Sdim      Features[Name] = Enabled;
4187218893Sdim    else
4188218893Sdim      return false;
4189218893Sdim
4190218893Sdim    return true;
4191218893Sdim  }
4192218893Sdim  virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
4193218893Sdim    SoftFloat = false;
4194218893Sdim    for (unsigned i = 0, e = Features.size(); i != e; ++i)
4195218893Sdim      if (Features[i] == "+soft-float")
4196218893Sdim        SoftFloat = true;
4197218893Sdim  }
4198193326Sed  virtual void getTargetDefines(const LangOptions &Opts,
4199202379Srdivacky                                MacroBuilder &Builder) const {
4200202379Srdivacky    DefineStd(Builder, "sparc", Opts);
4201202379Srdivacky    Builder.defineMacro("__REGISTER_PREFIX__", "");
4202218893Sdim
4203218893Sdim    if (SoftFloat)
4204218893Sdim      Builder.defineMacro("SOFT_FLOAT", "1");
4205193326Sed  }
4206234353Sdim
4207234353Sdim  virtual bool hasFeature(StringRef Feature) const {
4208234353Sdim    return llvm::StringSwitch<bool>(Feature)
4209234353Sdim             .Case("softfloat", SoftFloat)
4210234353Sdim             .Case("sparc", true)
4211234353Sdim             .Default(false);
4212234353Sdim  }
4213234353Sdim
4214193326Sed  virtual void getTargetBuiltins(const Builtin::Info *&Records,
4215193326Sed                                 unsigned &NumRecords) const {
4216193326Sed    // FIXME: Implement!
4217193326Sed  }
4218239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
4219239462Sdim    return TargetInfo::VoidPtrBuiltinVaList;
4220193326Sed  }
4221193326Sed  virtual void getGCCRegNames(const char * const *&Names,
4222193326Sed                              unsigned &NumNames) const;
4223193326Sed  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4224193326Sed                                unsigned &NumAliases) const;
4225193326Sed  virtual bool validateAsmConstraint(const char *&Name,
4226193326Sed                                     TargetInfo::ConstraintInfo &info) const {
4227193326Sed    // FIXME: Implement!
4228193326Sed    return false;
4229193326Sed  }
4230193326Sed  virtual const char *getClobbers() const {
4231193326Sed    // FIXME: Implement!
4232193326Sed    return "";
4233193326Sed  }
4234193326Sed};
4235193326Sed
4236251662Sdimconst char * const SparcTargetInfo::GCCRegNames[] = {
4237193326Sed  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
4238193326Sed  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
4239193326Sed  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
4240193326Sed  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
4241193326Sed};
4242193326Sed
4243251662Sdimvoid SparcTargetInfo::getGCCRegNames(const char * const *&Names,
4244251662Sdim                                     unsigned &NumNames) const {
4245193326Sed  Names = GCCRegNames;
4246193326Sed  NumNames = llvm::array_lengthof(GCCRegNames);
4247193326Sed}
4248193326Sed
4249251662Sdimconst TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
4250193326Sed  { { "g0" }, "r0" },
4251193326Sed  { { "g1" }, "r1" },
4252193326Sed  { { "g2" }, "r2" },
4253193326Sed  { { "g3" }, "r3" },
4254193326Sed  { { "g4" }, "r4" },
4255193326Sed  { { "g5" }, "r5" },
4256193326Sed  { { "g6" }, "r6" },
4257193326Sed  { { "g7" }, "r7" },
4258193326Sed  { { "o0" }, "r8" },
4259193326Sed  { { "o1" }, "r9" },
4260193326Sed  { { "o2" }, "r10" },
4261193326Sed  { { "o3" }, "r11" },
4262193326Sed  { { "o4" }, "r12" },
4263193326Sed  { { "o5" }, "r13" },
4264193326Sed  { { "o6", "sp" }, "r14" },
4265193326Sed  { { "o7" }, "r15" },
4266193326Sed  { { "l0" }, "r16" },
4267193326Sed  { { "l1" }, "r17" },
4268193326Sed  { { "l2" }, "r18" },
4269193326Sed  { { "l3" }, "r19" },
4270193326Sed  { { "l4" }, "r20" },
4271193326Sed  { { "l5" }, "r21" },
4272193326Sed  { { "l6" }, "r22" },
4273193326Sed  { { "l7" }, "r23" },
4274193326Sed  { { "i0" }, "r24" },
4275193326Sed  { { "i1" }, "r25" },
4276193326Sed  { { "i2" }, "r26" },
4277193326Sed  { { "i3" }, "r27" },
4278193326Sed  { { "i4" }, "r28" },
4279193326Sed  { { "i5" }, "r29" },
4280193326Sed  { { "i6", "fp" }, "r30" },
4281193326Sed  { { "i7" }, "r31" },
4282193326Sed};
4283193326Sed
4284251662Sdimvoid SparcTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
4285251662Sdim                                       unsigned &NumAliases) const {
4286193326Sed  Aliases = GCCRegAliases;
4287193326Sed  NumAliases = llvm::array_lengthof(GCCRegAliases);
4288193326Sed}
4289251662Sdim
4290251662Sdim// SPARC v8 is the 32-bit mode selected by Triple::sparc.
4291251662Sdimclass SparcV8TargetInfo : public SparcTargetInfo {
4292251662Sdimpublic:
4293251662Sdim  SparcV8TargetInfo(const std::string& triple) : SparcTargetInfo(triple) {
4294251662Sdim    // FIXME: Support Sparc quad-precision long double?
4295251662Sdim    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
4296251662Sdim                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
4297251662Sdim  }
4298251662Sdim
4299251662Sdim  virtual void getTargetDefines(const LangOptions &Opts,
4300251662Sdim                                MacroBuilder &Builder) const {
4301251662Sdim    SparcTargetInfo::getTargetDefines(Opts, Builder);
4302251662Sdim    Builder.defineMacro("__sparcv8");
4303251662Sdim  }
4304251662Sdim};
4305251662Sdim
4306251662Sdim// SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
4307251662Sdimclass SparcV9TargetInfo : public SparcTargetInfo {
4308251662Sdimpublic:
4309251662Sdim  SparcV9TargetInfo(const std::string& triple) : SparcTargetInfo(triple) {
4310251662Sdim    // FIXME: Support Sparc quad-precision long double?
4311251662Sdim    DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
4312251662Sdim                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32:64-S128";
4313251662Sdim  }
4314251662Sdim
4315251662Sdim  virtual void getTargetDefines(const LangOptions &Opts,
4316251662Sdim                                MacroBuilder &Builder) const {
4317251662Sdim    SparcTargetInfo::getTargetDefines(Opts, Builder);
4318251662Sdim    Builder.defineMacro("__sparcv9");
4319251662Sdim    Builder.defineMacro("__arch64__");
4320251662Sdim    // Solaris and its derivative AuroraUX don't need these variants, but the
4321251662Sdim    // BSDs do.
4322251662Sdim    if (getTriple().getOS() != llvm::Triple::Solaris &&
4323251662Sdim        getTriple().getOS() != llvm::Triple::AuroraUX) {
4324251662Sdim      Builder.defineMacro("__sparc64__");
4325251662Sdim      Builder.defineMacro("__sparc_v9__");
4326251662Sdim      Builder.defineMacro("__sparcv9__");
4327251662Sdim    }
4328251662Sdim  }
4329251662Sdim};
4330251662Sdim
4331193326Sed} // end anonymous namespace.
4332193326Sed
4333193326Sednamespace {
4334198398Srdivackyclass AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
4335198398Srdivackypublic:
4336198398Srdivacky  AuroraUXSparcV8TargetInfo(const std::string& triple) :
4337198398Srdivacky      AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
4338198398Srdivacky    SizeType = UnsignedInt;
4339198398Srdivacky    PtrDiffType = SignedInt;
4340198398Srdivacky  }
4341198398Srdivacky};
4342195341Sedclass SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
4343193326Sedpublic:
4344193326Sed  SolarisSparcV8TargetInfo(const std::string& triple) :
4345195341Sed      SolarisTargetInfo<SparcV8TargetInfo>(triple) {
4346193326Sed    SizeType = UnsignedInt;
4347193326Sed    PtrDiffType = SignedInt;
4348193326Sed  }
4349193326Sed};
4350193326Sed} // end anonymous namespace.
4351193326Sed
4352193326Sednamespace {
4353251662Sdim  class SystemZTargetInfo : public TargetInfo {
4354251662Sdim    static const char *const GCCRegNames[];
4355251662Sdim
4356251662Sdim  public:
4357251662Sdim    SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
4358251662Sdim      TLSSupported = true;
4359251662Sdim      IntWidth = IntAlign = 32;
4360251662Sdim      LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
4361251662Sdim      PointerWidth = PointerAlign = 64;
4362251662Sdim      LongDoubleWidth = 128;
4363251662Sdim      LongDoubleAlign = 64;
4364251662Sdim      LongDoubleFormat = &llvm::APFloat::IEEEquad;
4365251662Sdim      MinGlobalAlign = 16;
4366251662Sdim      DescriptionString = "E-p:64:64:64-i1:8:16-i8:8:16-i16:16-i32:32-i64:64"
4367251662Sdim       "-f32:32-f64:64-f128:64-a0:8:16-n32:64";
4368251662Sdim      MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
4369251662Sdim    }
4370251662Sdim    virtual void getTargetDefines(const LangOptions &Opts,
4371251662Sdim                                  MacroBuilder &Builder) const {
4372251662Sdim      Builder.defineMacro("__s390__");
4373251662Sdim      Builder.defineMacro("__s390x__");
4374251662Sdim      Builder.defineMacro("__zarch__");
4375251662Sdim      Builder.defineMacro("__LONG_DOUBLE_128__");
4376251662Sdim    }
4377251662Sdim    virtual void getTargetBuiltins(const Builtin::Info *&Records,
4378251662Sdim                                   unsigned &NumRecords) const {
4379251662Sdim      // FIXME: Implement.
4380251662Sdim      Records = 0;
4381251662Sdim      NumRecords = 0;
4382251662Sdim    }
4383251662Sdim
4384251662Sdim    virtual void getGCCRegNames(const char *const *&Names,
4385251662Sdim                                unsigned &NumNames) const;
4386251662Sdim    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4387251662Sdim                                  unsigned &NumAliases) const {
4388251662Sdim      // No aliases.
4389251662Sdim      Aliases = 0;
4390251662Sdim      NumAliases = 0;
4391251662Sdim    }
4392251662Sdim    virtual bool validateAsmConstraint(const char *&Name,
4393251662Sdim                                       TargetInfo::ConstraintInfo &info) const;
4394251662Sdim    virtual const char *getClobbers() const {
4395251662Sdim      // FIXME: Is this really right?
4396251662Sdim      return "";
4397251662Sdim    }
4398251662Sdim    virtual BuiltinVaListKind getBuiltinVaListKind() const {
4399251662Sdim      return TargetInfo::SystemZBuiltinVaList;
4400251662Sdim    }
4401251662Sdim  };
4402251662Sdim
4403251662Sdim  const char *const SystemZTargetInfo::GCCRegNames[] = {
4404251662Sdim    "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
4405251662Sdim    "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
4406251662Sdim    "f0",  "f2",  "f4",  "f6",  "f1",  "f3",  "f5",  "f7",
4407251662Sdim    "f8",  "f10", "f12", "f14", "f9",  "f11", "f13", "f15"
4408251662Sdim  };
4409251662Sdim
4410251662Sdim  void SystemZTargetInfo::getGCCRegNames(const char *const *&Names,
4411251662Sdim                                         unsigned &NumNames) const {
4412251662Sdim    Names = GCCRegNames;
4413251662Sdim    NumNames = llvm::array_lengthof(GCCRegNames);
4414251662Sdim  }
4415251662Sdim
4416251662Sdim  bool SystemZTargetInfo::
4417251662Sdim  validateAsmConstraint(const char *&Name,
4418251662Sdim                        TargetInfo::ConstraintInfo &Info) const {
4419251662Sdim    switch (*Name) {
4420251662Sdim    default:
4421251662Sdim      return false;
4422251662Sdim
4423251662Sdim    case 'a': // Address register
4424251662Sdim    case 'd': // Data register (equivalent to 'r')
4425251662Sdim    case 'f': // Floating-point register
4426251662Sdim      Info.setAllowsRegister();
4427251662Sdim      return true;
4428251662Sdim
4429251662Sdim    case 'I': // Unsigned 8-bit constant
4430251662Sdim    case 'J': // Unsigned 12-bit constant
4431251662Sdim    case 'K': // Signed 16-bit constant
4432251662Sdim    case 'L': // Signed 20-bit displacement (on all targets we support)
4433251662Sdim    case 'M': // 0x7fffffff
4434251662Sdim      return true;
4435251662Sdim
4436251662Sdim    case 'Q': // Memory with base and unsigned 12-bit displacement
4437251662Sdim    case 'R': // Likewise, plus an index
4438251662Sdim    case 'S': // Memory with base and signed 20-bit displacement
4439251662Sdim    case 'T': // Likewise, plus an index
4440251662Sdim      Info.setAllowsMemory();
4441251662Sdim      return true;
4442251662Sdim    }
4443251662Sdim  }
4444251662Sdim}
4445251662Sdim
4446251662Sdimnamespace {
4447193326Sed  class MSP430TargetInfo : public TargetInfo {
4448193326Sed    static const char * const GCCRegNames[];
4449193326Sed  public:
4450193326Sed    MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
4451234353Sdim      BigEndian = false;
4452193326Sed      TLSSupported = false;
4453203955Srdivacky      IntWidth = 16; IntAlign = 16;
4454203955Srdivacky      LongWidth = 32; LongLongWidth = 64;
4455203955Srdivacky      LongAlign = LongLongAlign = 16;
4456203955Srdivacky      PointerWidth = 16; PointerAlign = 16;
4457234353Sdim      SuitableAlign = 16;
4458193326Sed      SizeType = UnsignedInt;
4459193326Sed      IntMaxType = SignedLong;
4460193326Sed      UIntMaxType = UnsignedLong;
4461193326Sed      IntPtrType = SignedShort;
4462193326Sed      PtrDiffType = SignedInt;
4463199990Srdivacky      SigAtomicType = SignedLong;
4464201361Srdivacky      DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
4465193326Sed   }
4466193326Sed    virtual void getTargetDefines(const LangOptions &Opts,
4467202379Srdivacky                                  MacroBuilder &Builder) const {
4468202379Srdivacky      Builder.defineMacro("MSP430");
4469202379Srdivacky      Builder.defineMacro("__MSP430__");
4470193326Sed      // FIXME: defines for different 'flavours' of MCU
4471193326Sed    }
4472193326Sed    virtual void getTargetBuiltins(const Builtin::Info *&Records,
4473193326Sed                                   unsigned &NumRecords) const {
4474193326Sed     // FIXME: Implement.
4475193326Sed      Records = 0;
4476193326Sed      NumRecords = 0;
4477193326Sed    }
4478234353Sdim    virtual bool hasFeature(StringRef Feature) const {
4479234353Sdim      return Feature == "msp430";
4480234353Sdim    }
4481193326Sed    virtual void getGCCRegNames(const char * const *&Names,
4482193326Sed                                unsigned &NumNames) const;
4483193326Sed    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4484193326Sed                                  unsigned &NumAliases) const {
4485193326Sed      // No aliases.
4486193326Sed      Aliases = 0;
4487193326Sed      NumAliases = 0;
4488193326Sed    }
4489193326Sed    virtual bool validateAsmConstraint(const char *&Name,
4490193326Sed                                       TargetInfo::ConstraintInfo &info) const {
4491198398Srdivacky      // No target constraints for now.
4492198398Srdivacky      return false;
4493193326Sed    }
4494193326Sed    virtual const char *getClobbers() const {
4495193326Sed      // FIXME: Is this really right?
4496193326Sed      return "";
4497193326Sed    }
4498239462Sdim    virtual BuiltinVaListKind getBuiltinVaListKind() const {
4499193326Sed      // FIXME: implement
4500239462Sdim      return TargetInfo::CharPtrBuiltinVaList;
4501193326Sed   }
4502193326Sed  };
4503193326Sed
4504193326Sed  const char * const MSP430TargetInfo::GCCRegNames[] = {
4505193326Sed    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
4506193326Sed    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
4507193326Sed  };
4508193326Sed
4509193326Sed  void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
4510193326Sed                                        unsigned &NumNames) const {
4511193326Sed    Names = GCCRegNames;
4512193326Sed    NumNames = llvm::array_lengthof(GCCRegNames);
4513193326Sed  }
4514193326Sed}
4515193326Sed
4516198092Srdivackynamespace {
4517198092Srdivacky
4518198092Srdivacky  // LLVM and Clang cannot be used directly to output native binaries for
4519198092Srdivacky  // target, but is used to compile C code to llvm bitcode with correct
4520198092Srdivacky  // type and alignment information.
4521198092Srdivacky  //
4522198092Srdivacky  // TCE uses the llvm bitcode as input and uses it for generating customized
4523198092Srdivacky  // target processor and program binary. TCE co-design environment is
4524198092Srdivacky  // publicly available in http://tce.cs.tut.fi
4525198092Srdivacky
4526226633Sdim  static const unsigned TCEOpenCLAddrSpaceMap[] = {
4527226633Sdim      3, // opencl_global
4528226633Sdim      4, // opencl_local
4529239462Sdim      5, // opencl_constant
4530239462Sdim      0, // cuda_device
4531239462Sdim      0, // cuda_constant
4532239462Sdim      0  // cuda_shared
4533226633Sdim  };
4534226633Sdim
4535198092Srdivacky  class TCETargetInfo : public TargetInfo{
4536198092Srdivacky  public:
4537198092Srdivacky    TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
4538198092Srdivacky      TLSSupported = false;
4539198092Srdivacky      IntWidth = 32;
4540198092Srdivacky      LongWidth = LongLongWidth = 32;
4541198092Srdivacky      PointerWidth = 32;
4542198092Srdivacky      IntAlign = 32;
4543198092Srdivacky      LongAlign = LongLongAlign = 32;
4544198092Srdivacky      PointerAlign = 32;
4545234353Sdim      SuitableAlign = 32;
4546198092Srdivacky      SizeType = UnsignedInt;
4547198092Srdivacky      IntMaxType = SignedLong;
4548198092Srdivacky      UIntMaxType = UnsignedLong;
4549198092Srdivacky      IntPtrType = SignedInt;
4550198092Srdivacky      PtrDiffType = SignedInt;
4551198092Srdivacky      FloatWidth = 32;
4552198092Srdivacky      FloatAlign = 32;
4553198092Srdivacky      DoubleWidth = 32;
4554198092Srdivacky      DoubleAlign = 32;
4555198092Srdivacky      LongDoubleWidth = 32;
4556198092Srdivacky      LongDoubleAlign = 32;
4557198092Srdivacky      FloatFormat = &llvm::APFloat::IEEEsingle;
4558198092Srdivacky      DoubleFormat = &llvm::APFloat::IEEEsingle;
4559198092Srdivacky      LongDoubleFormat = &llvm::APFloat::IEEEsingle;
4560204793Srdivacky      DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
4561204793Srdivacky                          "i16:16:32-i32:32:32-i64:32:32-"
4562218893Sdim                          "f32:32:32-f64:32:32-v64:32:32-"
4563218893Sdim                          "v128:32:32-a0:0:32-n32";
4564226633Sdim      AddrSpaceMap = &TCEOpenCLAddrSpaceMap;
4565198092Srdivacky    }
4566198092Srdivacky
4567198092Srdivacky    virtual void getTargetDefines(const LangOptions &Opts,
4568202379Srdivacky                                  MacroBuilder &Builder) const {
4569202379Srdivacky      DefineStd(Builder, "tce", Opts);
4570202379Srdivacky      Builder.defineMacro("__TCE__");
4571202379Srdivacky      Builder.defineMacro("__TCE_V1__");
4572198092Srdivacky    }
4573234353Sdim    virtual bool hasFeature(StringRef Feature) const {
4574234353Sdim      return Feature == "tce";
4575234353Sdim    }
4576234353Sdim
4577198092Srdivacky    virtual void getTargetBuiltins(const Builtin::Info *&Records,
4578198092Srdivacky                                   unsigned &NumRecords) const {}
4579198092Srdivacky    virtual const char *getClobbers() const {
4580198092Srdivacky      return "";
4581198092Srdivacky    }
4582239462Sdim    virtual BuiltinVaListKind getBuiltinVaListKind() const {
4583239462Sdim      return TargetInfo::VoidPtrBuiltinVaList;
4584198092Srdivacky    }
4585198092Srdivacky    virtual void getGCCRegNames(const char * const *&Names,
4586198092Srdivacky                                unsigned &NumNames) const {}
4587198092Srdivacky    virtual bool validateAsmConstraint(const char *&Name,
4588198092Srdivacky                                       TargetInfo::ConstraintInfo &info) const {
4589198092Srdivacky      return true;
4590198092Srdivacky    }
4591198092Srdivacky    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4592198092Srdivacky                                  unsigned &NumAliases) const {}
4593198092Srdivacky  };
4594198092Srdivacky}
4595198092Srdivacky
4596199482Srdivackynamespace {
4597226633Sdimclass MipsTargetInfoBase : public TargetInfo {
4598239462Sdim  static const Builtin::Info BuiltinInfo[];
4599226633Sdim  std::string CPU;
4600239462Sdim  bool IsMips16;
4601251662Sdim  bool IsMicromips;
4602251662Sdim  bool IsSingleFloat;
4603239462Sdim  enum MipsFloatABI {
4604251662Sdim    HardFloat, SoftFloat
4605239462Sdim  } FloatABI;
4606239462Sdim  enum DspRevEnum {
4607239462Sdim    NoDSP, DSP1, DSP2
4608239462Sdim  } DspRev;
4609234353Sdim
4610226633Sdimprotected:
4611226633Sdim  std::string ABI;
4612234353Sdim
4613199482Srdivackypublic:
4614234353Sdim  MipsTargetInfoBase(const std::string& triple,
4615234353Sdim                     const std::string& ABIStr,
4616234353Sdim                     const std::string& CPUStr)
4617234353Sdim    : TargetInfo(triple),
4618234353Sdim      CPU(CPUStr),
4619239462Sdim      IsMips16(false),
4620251662Sdim      IsMicromips(false),
4621251662Sdim      IsSingleFloat(false),
4622239462Sdim      FloatABI(HardFloat),
4623239462Sdim      DspRev(NoDSP),
4624234353Sdim      ABI(ABIStr)
4625234353Sdim  {}
4626234353Sdim
4627204643Srdivacky  virtual const char *getABI() const { return ABI.c_str(); }
4628226633Sdim  virtual bool setABI(const std::string &Name) = 0;
4629204643Srdivacky  virtual bool setCPU(const std::string &Name) {
4630204643Srdivacky    CPU = Name;
4631204643Srdivacky    return true;
4632204643Srdivacky  }
4633226633Sdim  void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
4634204643Srdivacky    Features[ABI] = true;
4635204643Srdivacky    Features[CPU] = true;
4636204643Srdivacky  }
4637234353Sdim
4638243830Sdim  virtual void getTargetDefines(const LangOptions &Opts,
4639243830Sdim                                MacroBuilder &Builder) const {
4640243830Sdim    DefineStd(Builder, "mips", Opts);
4641243830Sdim    Builder.defineMacro("_mips");
4642243830Sdim    Builder.defineMacro("__REGISTER_PREFIX__", "");
4643243830Sdim
4644239462Sdim    switch (FloatABI) {
4645239462Sdim    case HardFloat:
4646239462Sdim      Builder.defineMacro("__mips_hard_float", Twine(1));
4647239462Sdim      break;
4648239462Sdim    case SoftFloat:
4649234353Sdim      Builder.defineMacro("__mips_soft_float", Twine(1));
4650239462Sdim      break;
4651239462Sdim    }
4652234353Sdim
4653251662Sdim    if (IsSingleFloat)
4654251662Sdim      Builder.defineMacro("__mips_single_float", Twine(1));
4655251662Sdim
4656239462Sdim    if (IsMips16)
4657239462Sdim      Builder.defineMacro("__mips16", Twine(1));
4658239462Sdim
4659251662Sdim    if (IsMicromips)
4660251662Sdim      Builder.defineMacro("__mips_micromips", Twine(1));
4661251662Sdim
4662239462Sdim    switch (DspRev) {
4663239462Sdim    default:
4664239462Sdim      break;
4665239462Sdim    case DSP1:
4666239462Sdim      Builder.defineMacro("__mips_dsp_rev", Twine(1));
4667239462Sdim      Builder.defineMacro("__mips_dsp", Twine(1));
4668239462Sdim      break;
4669239462Sdim    case DSP2:
4670239462Sdim      Builder.defineMacro("__mips_dsp_rev", Twine(2));
4671239462Sdim      Builder.defineMacro("__mips_dspr2", Twine(1));
4672239462Sdim      Builder.defineMacro("__mips_dsp", Twine(1));
4673239462Sdim      break;
4674239462Sdim    }
4675239462Sdim
4676234353Sdim    Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
4677234353Sdim    Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
4678234353Sdim    Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
4679243830Sdim
4680243830Sdim    Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");
4681243830Sdim    Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
4682234353Sdim  }
4683234353Sdim
4684199482Srdivacky  virtual void getTargetBuiltins(const Builtin::Info *&Records,
4685199482Srdivacky                                 unsigned &NumRecords) const {
4686239462Sdim    Records = BuiltinInfo;
4687239462Sdim    NumRecords = clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin;
4688199482Srdivacky  }
4689234353Sdim  virtual bool hasFeature(StringRef Feature) const {
4690234353Sdim    return Feature == "mips";
4691234353Sdim  }
4692239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
4693239462Sdim    return TargetInfo::VoidPtrBuiltinVaList;
4694199482Srdivacky  }
4695199482Srdivacky  virtual void getGCCRegNames(const char * const *&Names,
4696226633Sdim                              unsigned &NumNames) const {
4697226633Sdim    static const char * const GCCRegNames[] = {
4698234353Sdim      // CPU register names
4699234353Sdim      // Must match second column of GCCRegAliases
4700226633Sdim      "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
4701226633Sdim      "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
4702226633Sdim      "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
4703234353Sdim      "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31",
4704234353Sdim      // Floating point register names
4705226633Sdim      "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
4706226633Sdim      "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
4707226633Sdim      "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
4708226633Sdim      "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
4709234353Sdim      // Hi/lo and condition register names
4710226633Sdim      "hi",   "lo",   "",     "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
4711226633Sdim      "$fcc5","$fcc6","$fcc7"
4712226633Sdim    };
4713226633Sdim    Names = GCCRegNames;
4714226633Sdim    NumNames = llvm::array_lengthof(GCCRegNames);
4715226633Sdim  }
4716199482Srdivacky  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4717226633Sdim                                unsigned &NumAliases) const = 0;
4718199482Srdivacky  virtual bool validateAsmConstraint(const char *&Name,
4719199482Srdivacky                                     TargetInfo::ConstraintInfo &Info) const {
4720199482Srdivacky    switch (*Name) {
4721199482Srdivacky    default:
4722234353Sdim      return false;
4723234353Sdim
4724199482Srdivacky    case 'r': // CPU registers.
4725199482Srdivacky    case 'd': // Equivalent to "r" unless generating MIPS16 code.
4726199482Srdivacky    case 'y': // Equivalent to "r", backwards compatibility only.
4727199482Srdivacky    case 'f': // floating-point registers.
4728234353Sdim    case 'c': // $25 for indirect jumps
4729234353Sdim    case 'l': // lo register
4730234353Sdim    case 'x': // hilo register pair
4731199482Srdivacky      Info.setAllowsRegister();
4732199482Srdivacky      return true;
4733249423Sdim    case 'R': // An address that can be used in a non-macro load or store
4734249423Sdim      Info.setAllowsMemory();
4735249423Sdim      return true;
4736199482Srdivacky    }
4737199482Srdivacky  }
4738199482Srdivacky
4739199482Srdivacky  virtual const char *getClobbers() const {
4740199482Srdivacky    // FIXME: Implement!
4741199482Srdivacky    return "";
4742199482Srdivacky  }
4743234353Sdim
4744234353Sdim  virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
4745234353Sdim                                 StringRef Name,
4746234353Sdim                                 bool Enabled) const {
4747234982Sdim    if (Name == "soft-float" || Name == "single-float" ||
4748234982Sdim        Name == "o32" || Name == "n32" || Name == "n64" || Name == "eabi" ||
4749234982Sdim        Name == "mips32" || Name == "mips32r2" ||
4750239462Sdim        Name == "mips64" || Name == "mips64r2" ||
4751251662Sdim        Name == "mips16" || Name == "micromips" ||
4752251662Sdim        Name == "dsp" || Name == "dspr2") {
4753234353Sdim      Features[Name] = Enabled;
4754234353Sdim      return true;
4755249423Sdim    } else if (Name == "32") {
4756249423Sdim      Features["o32"] = Enabled;
4757249423Sdim      return true;
4758249423Sdim    } else if (Name == "64") {
4759249423Sdim      Features["n64"] = Enabled;
4760249423Sdim      return true;
4761234353Sdim    }
4762234353Sdim    return false;
4763234353Sdim  }
4764234353Sdim
4765234353Sdim  virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
4766239462Sdim    IsMips16 = false;
4767251662Sdim    IsMicromips = false;
4768251662Sdim    IsSingleFloat = false;
4769239462Sdim    FloatABI = HardFloat;
4770239462Sdim    DspRev = NoDSP;
4771234353Sdim
4772234353Sdim    for (std::vector<std::string>::iterator it = Features.begin(),
4773234353Sdim         ie = Features.end(); it != ie; ++it) {
4774239462Sdim      if (*it == "+single-float")
4775251662Sdim        IsSingleFloat = true;
4776239462Sdim      else if (*it == "+soft-float")
4777239462Sdim        FloatABI = SoftFloat;
4778239462Sdim      else if (*it == "+mips16")
4779239462Sdim        IsMips16 = true;
4780251662Sdim      else if (*it == "+micromips")
4781251662Sdim        IsMicromips = true;
4782239462Sdim      else if (*it == "+dsp")
4783239462Sdim        DspRev = std::max(DspRev, DSP1);
4784239462Sdim      else if (*it == "+dspr2")
4785239462Sdim        DspRev = std::max(DspRev, DSP2);
4786239462Sdim    }
4787234353Sdim
4788239462Sdim    // Remove front-end specific option.
4789239462Sdim    std::vector<std::string>::iterator it =
4790239462Sdim      std::find(Features.begin(), Features.end(), "+soft-float");
4791239462Sdim    if (it != Features.end())
4792239462Sdim      Features.erase(it);
4793234353Sdim  }
4794249423Sdim
4795249423Sdim  virtual int getEHDataRegisterNumber(unsigned RegNo) const {
4796249423Sdim    if (RegNo == 0) return 4;
4797249423Sdim    if (RegNo == 1) return 5;
4798249423Sdim    return -1;
4799249423Sdim  }
4800199482Srdivacky};
4801199482Srdivacky
4802239462Sdimconst Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
4803239462Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
4804239462Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
4805239462Sdim                                              ALL_LANGUAGES },
4806239462Sdim#include "clang/Basic/BuiltinsMips.def"
4807239462Sdim};
4808239462Sdim
4809226633Sdimclass Mips32TargetInfoBase : public MipsTargetInfoBase {
4810226633Sdimpublic:
4811226633Sdim  Mips32TargetInfoBase(const std::string& triple) :
4812234353Sdim    MipsTargetInfoBase(triple, "o32", "mips32") {
4813234353Sdim    SizeType = UnsignedInt;
4814234353Sdim    PtrDiffType = SignedInt;
4815249423Sdim    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
4816234353Sdim  }
4817226633Sdim  virtual bool setABI(const std::string &Name) {
4818226633Sdim    if ((Name == "o32") || (Name == "eabi")) {
4819226633Sdim      ABI = Name;
4820226633Sdim      return true;
4821249423Sdim    } else if (Name == "32") {
4822249423Sdim      ABI = "o32";
4823249423Sdim      return true;
4824226633Sdim    } else
4825226633Sdim      return false;
4826226633Sdim  }
4827243830Sdim  virtual void getTargetDefines(const LangOptions &Opts,
4828243830Sdim                                MacroBuilder &Builder) const {
4829243830Sdim    MipsTargetInfoBase::getTargetDefines(Opts, Builder);
4830234353Sdim
4831226633Sdim    if (ABI == "o32") {
4832226633Sdim      Builder.defineMacro("__mips_o32");
4833226633Sdim      Builder.defineMacro("_ABIO32", "1");
4834226633Sdim      Builder.defineMacro("_MIPS_SIM", "_ABIO32");
4835226633Sdim    }
4836226633Sdim    else if (ABI == "eabi")
4837226633Sdim      Builder.defineMacro("__mips_eabi");
4838226633Sdim    else
4839226633Sdim      llvm_unreachable("Invalid ABI for Mips32.");
4840226633Sdim  }
4841226633Sdim  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4842226633Sdim                                unsigned &NumAliases) const {
4843226633Sdim    static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
4844226633Sdim      { { "at" },  "$1" },
4845226633Sdim      { { "v0" },  "$2" },
4846226633Sdim      { { "v1" },  "$3" },
4847226633Sdim      { { "a0" },  "$4" },
4848226633Sdim      { { "a1" },  "$5" },
4849226633Sdim      { { "a2" },  "$6" },
4850226633Sdim      { { "a3" },  "$7" },
4851226633Sdim      { { "t0" },  "$8" },
4852226633Sdim      { { "t1" },  "$9" },
4853226633Sdim      { { "t2" }, "$10" },
4854226633Sdim      { { "t3" }, "$11" },
4855226633Sdim      { { "t4" }, "$12" },
4856226633Sdim      { { "t5" }, "$13" },
4857226633Sdim      { { "t6" }, "$14" },
4858226633Sdim      { { "t7" }, "$15" },
4859226633Sdim      { { "s0" }, "$16" },
4860226633Sdim      { { "s1" }, "$17" },
4861226633Sdim      { { "s2" }, "$18" },
4862226633Sdim      { { "s3" }, "$19" },
4863226633Sdim      { { "s4" }, "$20" },
4864226633Sdim      { { "s5" }, "$21" },
4865226633Sdim      { { "s6" }, "$22" },
4866226633Sdim      { { "s7" }, "$23" },
4867226633Sdim      { { "t8" }, "$24" },
4868226633Sdim      { { "t9" }, "$25" },
4869226633Sdim      { { "k0" }, "$26" },
4870226633Sdim      { { "k1" }, "$27" },
4871226633Sdim      { { "gp" }, "$28" },
4872234353Sdim      { { "sp","$sp" }, "$29" },
4873234353Sdim      { { "fp","$fp" }, "$30" },
4874226633Sdim      { { "ra" }, "$31" }
4875226633Sdim    };
4876226633Sdim    Aliases = GCCRegAliases;
4877226633Sdim    NumAliases = llvm::array_lengthof(GCCRegAliases);
4878226633Sdim  }
4879199482Srdivacky};
4880199482Srdivacky
4881226633Sdimclass Mips32EBTargetInfo : public Mips32TargetInfoBase {
4882226633Sdimpublic:
4883226633Sdim  Mips32EBTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) {
4884226633Sdim    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
4885249423Sdim                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
4886226633Sdim  }
4887226633Sdim  virtual void getTargetDefines(const LangOptions &Opts,
4888226633Sdim                                MacroBuilder &Builder) const {
4889226633Sdim    DefineStd(Builder, "MIPSEB", Opts);
4890226633Sdim    Builder.defineMacro("_MIPSEB");
4891243830Sdim    Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
4892226633Sdim  }
4893226633Sdim};
4894199482Srdivacky
4895226633Sdimclass Mips32ELTargetInfo : public Mips32TargetInfoBase {
4896226633Sdimpublic:
4897226633Sdim  Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) {
4898234353Sdim    BigEndian = false;
4899226633Sdim    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
4900249423Sdim                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
4901226633Sdim  }
4902226633Sdim  virtual void getTargetDefines(const LangOptions &Opts,
4903226633Sdim                                MacroBuilder &Builder) const {
4904226633Sdim    DefineStd(Builder, "MIPSEL", Opts);
4905226633Sdim    Builder.defineMacro("_MIPSEL");
4906243830Sdim    Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
4907226633Sdim  }
4908199482Srdivacky};
4909199482Srdivacky
4910226633Sdimclass Mips64TargetInfoBase : public MipsTargetInfoBase {
4911226633Sdim  virtual void SetDescriptionString(const std::string &Name) = 0;
4912226633Sdimpublic:
4913226633Sdim  Mips64TargetInfoBase(const std::string& triple) :
4914234353Sdim    MipsTargetInfoBase(triple, "n64", "mips64") {
4915234353Sdim    LongWidth = LongAlign = 64;
4916234353Sdim    PointerWidth = PointerAlign = 64;
4917234353Sdim    LongDoubleWidth = LongDoubleAlign = 128;
4918234353Sdim    LongDoubleFormat = &llvm::APFloat::IEEEquad;
4919249423Sdim    if (getTriple().getOS() == llvm::Triple::FreeBSD) {
4920249423Sdim      LongDoubleWidth = LongDoubleAlign = 64;
4921249423Sdim      LongDoubleFormat = &llvm::APFloat::IEEEdouble;
4922249423Sdim    }
4923234353Sdim    SuitableAlign = 128;
4924249423Sdim    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
4925234353Sdim  }
4926226633Sdim  virtual bool setABI(const std::string &Name) {
4927226633Sdim    SetDescriptionString(Name);
4928234353Sdim    if (Name == "n32") {
4929234353Sdim      LongWidth = LongAlign = 32;
4930234353Sdim      PointerWidth = PointerAlign = 32;
4931249423Sdim      ABI = Name;
4932249423Sdim      return true;
4933249423Sdim    } else if (Name == "n64") {
4934249423Sdim      ABI = Name;
4935249423Sdim      return true;
4936249423Sdim    } else if (Name == "64") {
4937249423Sdim      ABI = "n64";
4938249423Sdim      return true;
4939249423Sdim    } else
4940249423Sdim      return false;
4941226633Sdim  }
4942243830Sdim  virtual void getTargetDefines(const LangOptions &Opts,
4943243830Sdim                                MacroBuilder &Builder) const {
4944243830Sdim    MipsTargetInfoBase::getTargetDefines(Opts, Builder);
4945234353Sdim
4946243830Sdim    Builder.defineMacro("__mips64");
4947243830Sdim    Builder.defineMacro("__mips64__");
4948243830Sdim
4949226633Sdim    if (ABI == "n32") {
4950226633Sdim      Builder.defineMacro("__mips_n32");
4951226633Sdim      Builder.defineMacro("_ABIN32", "2");
4952226633Sdim      Builder.defineMacro("_MIPS_SIM", "_ABIN32");
4953226633Sdim    }
4954226633Sdim    else if (ABI == "n64") {
4955226633Sdim      Builder.defineMacro("__mips_n64");
4956226633Sdim      Builder.defineMacro("_ABI64", "3");
4957226633Sdim      Builder.defineMacro("_MIPS_SIM", "_ABI64");
4958226633Sdim    }
4959226633Sdim    else
4960226633Sdim      llvm_unreachable("Invalid ABI for Mips64.");
4961226633Sdim  }
4962226633Sdim  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4963226633Sdim                                unsigned &NumAliases) const {
4964226633Sdim    static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
4965226633Sdim      { { "at" },  "$1" },
4966226633Sdim      { { "v0" },  "$2" },
4967226633Sdim      { { "v1" },  "$3" },
4968226633Sdim      { { "a0" },  "$4" },
4969226633Sdim      { { "a1" },  "$5" },
4970226633Sdim      { { "a2" },  "$6" },
4971226633Sdim      { { "a3" },  "$7" },
4972226633Sdim      { { "a4" },  "$8" },
4973226633Sdim      { { "a5" },  "$9" },
4974226633Sdim      { { "a6" }, "$10" },
4975226633Sdim      { { "a7" }, "$11" },
4976226633Sdim      { { "t0" }, "$12" },
4977226633Sdim      { { "t1" }, "$13" },
4978226633Sdim      { { "t2" }, "$14" },
4979226633Sdim      { { "t3" }, "$15" },
4980226633Sdim      { { "s0" }, "$16" },
4981226633Sdim      { { "s1" }, "$17" },
4982226633Sdim      { { "s2" }, "$18" },
4983226633Sdim      { { "s3" }, "$19" },
4984226633Sdim      { { "s4" }, "$20" },
4985226633Sdim      { { "s5" }, "$21" },
4986226633Sdim      { { "s6" }, "$22" },
4987226633Sdim      { { "s7" }, "$23" },
4988226633Sdim      { { "t8" }, "$24" },
4989226633Sdim      { { "t9" }, "$25" },
4990226633Sdim      { { "k0" }, "$26" },
4991226633Sdim      { { "k1" }, "$27" },
4992226633Sdim      { { "gp" }, "$28" },
4993234353Sdim      { { "sp","$sp" }, "$29" },
4994234353Sdim      { { "fp","$fp" }, "$30" },
4995226633Sdim      { { "ra" }, "$31" }
4996226633Sdim    };
4997226633Sdim    Aliases = GCCRegAliases;
4998226633Sdim    NumAliases = llvm::array_lengthof(GCCRegAliases);
4999226633Sdim  }
5000226633Sdim};
5001226633Sdim
5002226633Sdimclass Mips64EBTargetInfo : public Mips64TargetInfoBase {
5003226633Sdim  virtual void SetDescriptionString(const std::string &Name) {
5004226633Sdim    // Change DescriptionString only if ABI is n32.
5005226633Sdim    if (Name == "n32")
5006226633Sdim      DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
5007234353Sdim                          "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
5008249423Sdim                          "v64:64:64-n32:64-S128";
5009226633Sdim  }
5010226633Sdimpublic:
5011226633Sdim  Mips64EBTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) {
5012226633Sdim    // Default ABI is n64.
5013226633Sdim    DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
5014234353Sdim                        "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
5015249423Sdim                        "v64:64:64-n32:64-S128";
5016226633Sdim  }
5017226633Sdim  virtual void getTargetDefines(const LangOptions &Opts,
5018226633Sdim                                MacroBuilder &Builder) const {
5019226633Sdim    DefineStd(Builder, "MIPSEB", Opts);
5020226633Sdim    Builder.defineMacro("_MIPSEB");
5021243830Sdim    Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
5022226633Sdim  }
5023226633Sdim};
5024226633Sdim
5025226633Sdimclass Mips64ELTargetInfo : public Mips64TargetInfoBase {
5026226633Sdim  virtual void SetDescriptionString(const std::string &Name) {
5027226633Sdim    // Change DescriptionString only if ABI is n32.
5028226633Sdim    if (Name == "n32")
5029226633Sdim      DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
5030234353Sdim                          "i64:64:64-f32:32:32-f64:64:64-f128:128:128"
5031249423Sdim                          "-v64:64:64-n32:64-S128";
5032226633Sdim  }
5033226633Sdimpublic:
5034226633Sdim  Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) {
5035234353Sdim    // Default ABI is n64.
5036234353Sdim    BigEndian = false;
5037226633Sdim    DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
5038234353Sdim                        "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
5039249423Sdim                        "v64:64:64-n32:64-S128";
5040226633Sdim  }
5041226633Sdim  virtual void getTargetDefines(const LangOptions &Opts,
5042226633Sdim                                MacroBuilder &Builder) const {
5043226633Sdim    DefineStd(Builder, "MIPSEL", Opts);
5044226633Sdim    Builder.defineMacro("_MIPSEL");
5045243830Sdim    Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
5046226633Sdim  }
5047226633Sdim};
5048199482Srdivacky} // end anonymous namespace.
5049199482Srdivacky
5050199482Srdivackynamespace {
5051226633Sdimclass PNaClTargetInfo : public TargetInfo {
5052199482Srdivackypublic:
5053226633Sdim  PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) {
5054234353Sdim    BigEndian = false;
5055226633Sdim    this->UserLabelPrefix = "";
5056226633Sdim    this->LongAlign = 32;
5057226633Sdim    this->LongWidth = 32;
5058226633Sdim    this->PointerAlign = 32;
5059226633Sdim    this->PointerWidth = 32;
5060226633Sdim    this->IntMaxType = TargetInfo::SignedLongLong;
5061226633Sdim    this->UIntMaxType = TargetInfo::UnsignedLongLong;
5062226633Sdim    this->Int64Type = TargetInfo::SignedLongLong;
5063226633Sdim    this->DoubleAlign = 64;
5064226633Sdim    this->LongDoubleWidth = 64;
5065226633Sdim    this->LongDoubleAlign = 64;
5066226633Sdim    this->SizeType = TargetInfo::UnsignedInt;
5067226633Sdim    this->PtrDiffType = TargetInfo::SignedInt;
5068226633Sdim    this->IntPtrType = TargetInfo::SignedInt;
5069251662Sdim    this->RegParmMax = 0; // Disallow regparm
5070226633Sdim    DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
5071226633Sdim                        "f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
5072199482Srdivacky  }
5073199482Srdivacky
5074226633Sdim  void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
5075226633Sdim  }
5076226633Sdim  virtual void getArchDefines(const LangOptions &Opts,
5077226633Sdim                              MacroBuilder &Builder) const {
5078226633Sdim    Builder.defineMacro("__le32__");
5079226633Sdim    Builder.defineMacro("__pnacl__");
5080226633Sdim  }
5081199482Srdivacky  virtual void getTargetDefines(const LangOptions &Opts,
5082226633Sdim                                MacroBuilder &Builder) const {
5083234353Sdim    Builder.defineMacro("__LITTLE_ENDIAN__");
5084226633Sdim    getArchDefines(Opts, Builder);
5085226633Sdim  }
5086234353Sdim  virtual bool hasFeature(StringRef Feature) const {
5087234353Sdim    return Feature == "pnacl";
5088234353Sdim  }
5089226633Sdim  virtual void getTargetBuiltins(const Builtin::Info *&Records,
5090226633Sdim                                 unsigned &NumRecords) const {
5091226633Sdim  }
5092239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const {
5093239462Sdim    return TargetInfo::PNaClABIBuiltinVaList;
5094226633Sdim  }
5095226633Sdim  virtual void getGCCRegNames(const char * const *&Names,
5096226633Sdim                              unsigned &NumNames) const;
5097226633Sdim  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
5098226633Sdim                                unsigned &NumAliases) const;
5099226633Sdim  virtual bool validateAsmConstraint(const char *&Name,
5100226633Sdim                                     TargetInfo::ConstraintInfo &Info) const {
5101226633Sdim    return false;
5102226633Sdim  }
5103226633Sdim
5104226633Sdim  virtual const char *getClobbers() const {
5105226633Sdim    return "";
5106226633Sdim  }
5107199482Srdivacky};
5108199482Srdivacky
5109226633Sdimvoid PNaClTargetInfo::getGCCRegNames(const char * const *&Names,
5110226633Sdim                                     unsigned &NumNames) const {
5111226633Sdim  Names = NULL;
5112226633Sdim  NumNames = 0;
5113199482Srdivacky}
5114226633Sdim
5115226633Sdimvoid PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
5116226633Sdim                                       unsigned &NumAliases) const {
5117226633Sdim  Aliases = NULL;
5118226633Sdim  NumAliases = 0;
5119226633Sdim}
5120199482Srdivacky} // end anonymous namespace.
5121199482Srdivacky
5122249423Sdimnamespace {
5123249423Sdim  static const unsigned SPIRAddrSpaceMap[] = {
5124249423Sdim    1,    // opencl_global
5125249423Sdim    3,    // opencl_local
5126249423Sdim    2,    // opencl_constant
5127249423Sdim    0,    // cuda_device
5128249423Sdim    0,    // cuda_constant
5129249423Sdim    0     // cuda_shared
5130249423Sdim  };
5131249423Sdim  class SPIRTargetInfo : public TargetInfo {
5132249423Sdim    static const char * const GCCRegNames[];
5133249423Sdim    static const Builtin::Info BuiltinInfo[];
5134249423Sdim    std::vector<StringRef> AvailableFeatures;
5135249423Sdim  public:
5136249423Sdim    SPIRTargetInfo(const std::string& triple) : TargetInfo(triple) {
5137249423Sdim      assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
5138249423Sdim        "SPIR target must use unknown OS");
5139249423Sdim      assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
5140249423Sdim        "SPIR target must use unknown environment type");
5141249423Sdim      BigEndian = false;
5142249423Sdim      TLSSupported = false;
5143249423Sdim      LongWidth = LongAlign = 64;
5144249423Sdim      AddrSpaceMap = &SPIRAddrSpaceMap;
5145249423Sdim      // Define available target features
5146249423Sdim      // These must be defined in sorted order!
5147249423Sdim      NoAsmVariants = true;
5148249423Sdim    }
5149249423Sdim    virtual void getTargetDefines(const LangOptions &Opts,
5150249423Sdim                                  MacroBuilder &Builder) const {
5151249423Sdim      DefineStd(Builder, "SPIR", Opts);
5152249423Sdim    }
5153249423Sdim    virtual bool hasFeature(StringRef Feature) const {
5154249423Sdim      return Feature == "spir";
5155249423Sdim    }
5156249423Sdim
5157249423Sdim    virtual void getTargetBuiltins(const Builtin::Info *&Records,
5158249423Sdim                                   unsigned &NumRecords) const {}
5159249423Sdim    virtual const char *getClobbers() const {
5160249423Sdim      return "";
5161249423Sdim    }
5162249423Sdim    virtual void getGCCRegNames(const char * const *&Names,
5163249423Sdim                                unsigned &NumNames) const {}
5164249423Sdim    virtual bool validateAsmConstraint(const char *&Name,
5165249423Sdim                                       TargetInfo::ConstraintInfo &info) const {
5166249423Sdim      return true;
5167249423Sdim    }
5168249423Sdim    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
5169249423Sdim                                  unsigned &NumAliases) const {}
5170249423Sdim    virtual BuiltinVaListKind getBuiltinVaListKind() const {
5171249423Sdim      return TargetInfo::VoidPtrBuiltinVaList;
5172249423Sdim    }
5173249423Sdim  };
5174226633Sdim
5175249423Sdim
5176249423Sdim  class SPIR32TargetInfo : public SPIRTargetInfo {
5177249423Sdim  public:
5178249423Sdim    SPIR32TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) {
5179249423Sdim      PointerWidth = PointerAlign = 32;
5180249423Sdim      SizeType     = TargetInfo::UnsignedInt;
5181249423Sdim      PtrDiffType = IntPtrType = TargetInfo::SignedInt;
5182249423Sdim      DescriptionString
5183249423Sdim        = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
5184249423Sdim          "f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-"
5185249423Sdim          "v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-"
5186249423Sdim          "v512:512:512-v1024:1024:1024";
5187249423Sdim    }
5188249423Sdim    virtual void getTargetDefines(const LangOptions &Opts,
5189249423Sdim                                  MacroBuilder &Builder) const {
5190249423Sdim      DefineStd(Builder, "SPIR32", Opts);
5191249423Sdim    }
5192249423Sdim  };
5193249423Sdim
5194249423Sdim  class SPIR64TargetInfo : public SPIRTargetInfo {
5195249423Sdim  public:
5196249423Sdim    SPIR64TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) {
5197249423Sdim      PointerWidth = PointerAlign = 64;
5198249423Sdim      SizeType     = TargetInfo::UnsignedLong;
5199249423Sdim      PtrDiffType = IntPtrType = TargetInfo::SignedLong;
5200249423Sdim      DescriptionString
5201249423Sdim        = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
5202249423Sdim          "f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-"
5203249423Sdim          "v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-"
5204249423Sdim          "v512:512:512-v1024:1024:1024";
5205249423Sdim    }
5206249423Sdim    virtual void getTargetDefines(const LangOptions &Opts,
5207249423Sdim                                  MacroBuilder &Builder) const {
5208249423Sdim      DefineStd(Builder, "SPIR64", Opts);
5209249423Sdim    }
5210249423Sdim  };
5211249423Sdim}
5212249423Sdim
5213249423Sdim
5214193326Sed//===----------------------------------------------------------------------===//
5215193326Sed// Driver code
5216193326Sed//===----------------------------------------------------------------------===//
5217193326Sed
5218199482Srdivackystatic TargetInfo *AllocateTarget(const std::string &T) {
5219198092Srdivacky  llvm::Triple Triple(T);
5220198092Srdivacky  llvm::Triple::OSType os = Triple.getOS();
5221193326Sed
5222198092Srdivacky  switch (Triple.getArch()) {
5223198092Srdivacky  default:
5224198092Srdivacky    return NULL;
5225198092Srdivacky
5226234353Sdim  case llvm::Triple::hexagon:
5227234353Sdim    return new HexagonTargetInfo(T);
5228234353Sdim
5229249423Sdim  case llvm::Triple::aarch64:
5230249423Sdim    switch (os) {
5231249423Sdim    case llvm::Triple::Linux:
5232249423Sdim      return new LinuxTargetInfo<AArch64TargetInfo>(T);
5233249423Sdim    default:
5234249423Sdim      return new AArch64TargetInfo(T);
5235249423Sdim    }
5236249423Sdim
5237198092Srdivacky  case llvm::Triple::arm:
5238198092Srdivacky  case llvm::Triple::thumb:
5239221345Sdim    if (Triple.isOSDarwin())
5240221345Sdim      return new DarwinARMTargetInfo(T);
5241221345Sdim
5242198092Srdivacky    switch (os) {
5243210299Sed    case llvm::Triple::Linux:
5244210299Sed      return new LinuxTargetInfo<ARMTargetInfo>(T);
5245198092Srdivacky    case llvm::Triple::FreeBSD:
5246198092Srdivacky      return new FreeBSDTargetInfo<ARMTargetInfo>(T);
5247224145Sdim    case llvm::Triple::NetBSD:
5248224145Sdim      return new NetBSDTargetInfo<ARMTargetInfo>(T);
5249239462Sdim    case llvm::Triple::OpenBSD:
5250239462Sdim      return new OpenBSDTargetInfo<ARMTargetInfo>(T);
5251239462Sdim    case llvm::Triple::Bitrig:
5252239462Sdim      return new BitrigTargetInfo<ARMTargetInfo>(T);
5253224145Sdim    case llvm::Triple::RTEMS:
5254224145Sdim      return new RTEMSTargetInfo<ARMTargetInfo>(T);
5255249423Sdim    case llvm::Triple::NaCl:
5256243830Sdim      return new NaClTargetInfo<ARMTargetInfo>(T);
5257198092Srdivacky    default:
5258198092Srdivacky      return new ARMTargetInfo(T);
5259198092Srdivacky    }
5260198092Srdivacky
5261198092Srdivacky  case llvm::Triple::msp430:
5262198092Srdivacky    return new MSP430TargetInfo(T);
5263198092Srdivacky
5264199482Srdivacky  case llvm::Triple::mips:
5265224145Sdim    switch (os) {
5266224145Sdim    case llvm::Triple::Linux:
5267226633Sdim      return new LinuxTargetInfo<Mips32EBTargetInfo>(T);
5268224145Sdim    case llvm::Triple::RTEMS:
5269226633Sdim      return new RTEMSTargetInfo<Mips32EBTargetInfo>(T);
5270224145Sdim    case llvm::Triple::FreeBSD:
5271226633Sdim      return new FreeBSDTargetInfo<Mips32EBTargetInfo>(T);
5272224145Sdim    case llvm::Triple::NetBSD:
5273226633Sdim      return new NetBSDTargetInfo<Mips32EBTargetInfo>(T);
5274224145Sdim    default:
5275226633Sdim      return new Mips32EBTargetInfo(T);
5276224145Sdim    }
5277199482Srdivacky
5278199482Srdivacky  case llvm::Triple::mipsel:
5279224145Sdim    switch (os) {
5280224145Sdim    case llvm::Triple::Linux:
5281226633Sdim      return new LinuxTargetInfo<Mips32ELTargetInfo>(T);
5282224145Sdim    case llvm::Triple::RTEMS:
5283226633Sdim      return new RTEMSTargetInfo<Mips32ELTargetInfo>(T);
5284224145Sdim    case llvm::Triple::FreeBSD:
5285226633Sdim      return new FreeBSDTargetInfo<Mips32ELTargetInfo>(T);
5286224145Sdim    case llvm::Triple::NetBSD:
5287226633Sdim      return new NetBSDTargetInfo<Mips32ELTargetInfo>(T);
5288224145Sdim    default:
5289226633Sdim      return new Mips32ELTargetInfo(T);
5290224145Sdim    }
5291199482Srdivacky
5292226633Sdim  case llvm::Triple::mips64:
5293226633Sdim    switch (os) {
5294226633Sdim    case llvm::Triple::Linux:
5295226633Sdim      return new LinuxTargetInfo<Mips64EBTargetInfo>(T);
5296226633Sdim    case llvm::Triple::RTEMS:
5297226633Sdim      return new RTEMSTargetInfo<Mips64EBTargetInfo>(T);
5298226633Sdim    case llvm::Triple::FreeBSD:
5299226633Sdim      return new FreeBSDTargetInfo<Mips64EBTargetInfo>(T);
5300226633Sdim    case llvm::Triple::NetBSD:
5301226633Sdim      return new NetBSDTargetInfo<Mips64EBTargetInfo>(T);
5302239462Sdim    case llvm::Triple::OpenBSD:
5303239462Sdim      return new OpenBSDTargetInfo<Mips64EBTargetInfo>(T);
5304226633Sdim    default:
5305226633Sdim      return new Mips64EBTargetInfo(T);
5306226633Sdim    }
5307226633Sdim
5308226633Sdim  case llvm::Triple::mips64el:
5309226633Sdim    switch (os) {
5310226633Sdim    case llvm::Triple::Linux:
5311226633Sdim      return new LinuxTargetInfo<Mips64ELTargetInfo>(T);
5312226633Sdim    case llvm::Triple::RTEMS:
5313226633Sdim      return new RTEMSTargetInfo<Mips64ELTargetInfo>(T);
5314226633Sdim    case llvm::Triple::FreeBSD:
5315226633Sdim      return new FreeBSDTargetInfo<Mips64ELTargetInfo>(T);
5316226633Sdim    case llvm::Triple::NetBSD:
5317226633Sdim      return new NetBSDTargetInfo<Mips64ELTargetInfo>(T);
5318239462Sdim    case llvm::Triple::OpenBSD:
5319239462Sdim      return new OpenBSDTargetInfo<Mips64ELTargetInfo>(T);
5320226633Sdim    default:
5321226633Sdim      return new Mips64ELTargetInfo(T);
5322226633Sdim    }
5323226633Sdim
5324226633Sdim  case llvm::Triple::le32:
5325226633Sdim    switch (os) {
5326249423Sdim      case llvm::Triple::NaCl:
5327243830Sdim        return new NaClTargetInfo<PNaClTargetInfo>(T);
5328226633Sdim      default:
5329226633Sdim        return NULL;
5330226633Sdim    }
5331226633Sdim
5332198092Srdivacky  case llvm::Triple::ppc:
5333221345Sdim    if (Triple.isOSDarwin())
5334218893Sdim      return new DarwinPPC32TargetInfo(T);
5335224145Sdim    switch (os) {
5336226633Sdim    case llvm::Triple::Linux:
5337226633Sdim      return new LinuxTargetInfo<PPC32TargetInfo>(T);
5338224145Sdim    case llvm::Triple::FreeBSD:
5339204643Srdivacky      return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
5340224145Sdim    case llvm::Triple::NetBSD:
5341224145Sdim      return new NetBSDTargetInfo<PPC32TargetInfo>(T);
5342239462Sdim    case llvm::Triple::OpenBSD:
5343239462Sdim      return new OpenBSDTargetInfo<PPC32TargetInfo>(T);
5344224145Sdim    case llvm::Triple::RTEMS:
5345224145Sdim      return new RTEMSTargetInfo<PPC32TargetInfo>(T);
5346224145Sdim    default:
5347224145Sdim      return new PPC32TargetInfo(T);
5348224145Sdim    }
5349193326Sed
5350198092Srdivacky  case llvm::Triple::ppc64:
5351221345Sdim    if (Triple.isOSDarwin())
5352210299Sed      return new DarwinPPC64TargetInfo(T);
5353224145Sdim    switch (os) {
5354226633Sdim    case llvm::Triple::Linux:
5355226633Sdim      return new LinuxTargetInfo<PPC64TargetInfo>(T);
5356224145Sdim    case llvm::Triple::Lv2:
5357199990Srdivacky      return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
5358224145Sdim    case llvm::Triple::FreeBSD:
5359204643Srdivacky      return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
5360224145Sdim    case llvm::Triple::NetBSD:
5361224145Sdim      return new NetBSDTargetInfo<PPC64TargetInfo>(T);
5362224145Sdim    default:
5363224145Sdim      return new PPC64TargetInfo(T);
5364224145Sdim    }
5365193326Sed
5366239462Sdim  case llvm::Triple::nvptx:
5367239462Sdim    return new NVPTX32TargetInfo(T);
5368239462Sdim  case llvm::Triple::nvptx64:
5369239462Sdim    return new NVPTX64TargetInfo(T);
5370221345Sdim
5371204962Srdivacky  case llvm::Triple::mblaze:
5372204962Srdivacky    return new MBlazeTargetInfo(T);
5373204962Srdivacky
5374243830Sdim  case llvm::Triple::r600:
5375243830Sdim    return new R600TargetInfo(T);
5376243830Sdim
5377198092Srdivacky  case llvm::Triple::sparc:
5378224145Sdim    switch (os) {
5379226633Sdim    case llvm::Triple::Linux:
5380226633Sdim      return new LinuxTargetInfo<SparcV8TargetInfo>(T);
5381224145Sdim    case llvm::Triple::AuroraUX:
5382198398Srdivacky      return new AuroraUXSparcV8TargetInfo(T);
5383224145Sdim    case llvm::Triple::Solaris:
5384193326Sed      return new SolarisSparcV8TargetInfo(T);
5385224145Sdim    case llvm::Triple::NetBSD:
5386224145Sdim      return new NetBSDTargetInfo<SparcV8TargetInfo>(T);
5387239462Sdim    case llvm::Triple::OpenBSD:
5388239462Sdim      return new OpenBSDTargetInfo<SparcV8TargetInfo>(T);
5389224145Sdim    case llvm::Triple::RTEMS:
5390224145Sdim      return new RTEMSTargetInfo<SparcV8TargetInfo>(T);
5391224145Sdim    default:
5392224145Sdim      return new SparcV8TargetInfo(T);
5393224145Sdim    }
5394193326Sed
5395251662Sdim  case llvm::Triple::sparcv9:
5396251662Sdim    switch (os) {
5397251662Sdim    case llvm::Triple::Linux:
5398251662Sdim      return new LinuxTargetInfo<SparcV9TargetInfo>(T);
5399251662Sdim    case llvm::Triple::AuroraUX:
5400251662Sdim      return new AuroraUXTargetInfo<SparcV9TargetInfo>(T);
5401251662Sdim    case llvm::Triple::Solaris:
5402251662Sdim      return new SolarisTargetInfo<SparcV9TargetInfo>(T);
5403251662Sdim    case llvm::Triple::NetBSD:
5404251662Sdim      return new NetBSDTargetInfo<SparcV9TargetInfo>(T);
5405251662Sdim    case llvm::Triple::OpenBSD:
5406251662Sdim      return new OpenBSDTargetInfo<SparcV9TargetInfo>(T);
5407251662Sdim    case llvm::Triple::FreeBSD:
5408251662Sdim      return new FreeBSDTargetInfo<SparcV9TargetInfo>(T);
5409251662Sdim    default:
5410251662Sdim      return new SparcV9TargetInfo(T);
5411251662Sdim    }
5412251662Sdim
5413251662Sdim  case llvm::Triple::systemz:
5414251662Sdim    switch (os) {
5415251662Sdim    case llvm::Triple::Linux:
5416251662Sdim      return new LinuxTargetInfo<SystemZTargetInfo>(T);
5417251662Sdim    default:
5418251662Sdim      return new SystemZTargetInfo(T);
5419251662Sdim    }
5420251662Sdim
5421198092Srdivacky  case llvm::Triple::tce:
5422198092Srdivacky    return new TCETargetInfo(T);
5423193326Sed
5424198092Srdivacky  case llvm::Triple::x86:
5425221345Sdim    if (Triple.isOSDarwin())
5426221345Sdim      return new DarwinI386TargetInfo(T);
5427221345Sdim
5428198092Srdivacky    switch (os) {
5429198398Srdivacky    case llvm::Triple::AuroraUX:
5430198398Srdivacky      return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
5431198092Srdivacky    case llvm::Triple::Linux:
5432195341Sed      return new LinuxTargetInfo<X86_32TargetInfo>(T);
5433198092Srdivacky    case llvm::Triple::DragonFly:
5434195341Sed      return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
5435198092Srdivacky    case llvm::Triple::NetBSD:
5436234353Sdim      return new NetBSDI386TargetInfo(T);
5437198092Srdivacky    case llvm::Triple::OpenBSD:
5438198092Srdivacky      return new OpenBSDI386TargetInfo(T);
5439239462Sdim    case llvm::Triple::Bitrig:
5440239462Sdim      return new BitrigI386TargetInfo(T);
5441198092Srdivacky    case llvm::Triple::FreeBSD:
5442195341Sed      return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
5443210299Sed    case llvm::Triple::Minix:
5444210299Sed      return new MinixTargetInfo<X86_32TargetInfo>(T);
5445198092Srdivacky    case llvm::Triple::Solaris:
5446195341Sed      return new SolarisTargetInfo<X86_32TargetInfo>(T);
5447198092Srdivacky    case llvm::Triple::Cygwin:
5448198092Srdivacky      return new CygwinX86_32TargetInfo(T);
5449198092Srdivacky    case llvm::Triple::MinGW32:
5450198092Srdivacky      return new MinGWX86_32TargetInfo(T);
5451198092Srdivacky    case llvm::Triple::Win32:
5452198092Srdivacky      return new VisualStudioWindowsX86_32TargetInfo(T);
5453207619Srdivacky    case llvm::Triple::Haiku:
5454207619Srdivacky      return new HaikuX86_32TargetInfo(T);
5455224145Sdim    case llvm::Triple::RTEMS:
5456224145Sdim      return new RTEMSX86_32TargetInfo(T);
5457249423Sdim    case llvm::Triple::NaCl:
5458243830Sdim      return new NaClTargetInfo<X86_32TargetInfo>(T);
5459198092Srdivacky    default:
5460198092Srdivacky      return new X86_32TargetInfo(T);
5461198092Srdivacky    }
5462198092Srdivacky
5463198092Srdivacky  case llvm::Triple::x86_64:
5464221345Sdim    if (Triple.isOSDarwin() || Triple.getEnvironment() == llvm::Triple::MachO)
5465221345Sdim      return new DarwinX86_64TargetInfo(T);
5466221345Sdim
5467198092Srdivacky    switch (os) {
5468198398Srdivacky    case llvm::Triple::AuroraUX:
5469198398Srdivacky      return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
5470198092Srdivacky    case llvm::Triple::Linux:
5471198092Srdivacky      return new LinuxTargetInfo<X86_64TargetInfo>(T);
5472202379Srdivacky    case llvm::Triple::DragonFly:
5473202379Srdivacky      return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
5474198092Srdivacky    case llvm::Triple::NetBSD:
5475198092Srdivacky      return new NetBSDTargetInfo<X86_64TargetInfo>(T);
5476198092Srdivacky    case llvm::Triple::OpenBSD:
5477198092Srdivacky      return new OpenBSDX86_64TargetInfo(T);
5478239462Sdim    case llvm::Triple::Bitrig:
5479239462Sdim      return new BitrigX86_64TargetInfo(T);
5480198092Srdivacky    case llvm::Triple::FreeBSD:
5481198092Srdivacky      return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
5482198092Srdivacky    case llvm::Triple::Solaris:
5483198092Srdivacky      return new SolarisTargetInfo<X86_64TargetInfo>(T);
5484218893Sdim    case llvm::Triple::MinGW32:
5485198092Srdivacky      return new MinGWX86_64TargetInfo(T);
5486198092Srdivacky    case llvm::Triple::Win32:   // This is what Triple.h supports now.
5487221345Sdim      return new VisualStudioWindowsX86_64TargetInfo(T);
5488249423Sdim    case llvm::Triple::NaCl:
5489243830Sdim      return new NaClTargetInfo<X86_64TargetInfo>(T);
5490198092Srdivacky    default:
5491198092Srdivacky      return new X86_64TargetInfo(T);
5492198092Srdivacky    }
5493249423Sdim
5494249423Sdim    case llvm::Triple::spir: {
5495249423Sdim      llvm::Triple Triple(T);
5496249423Sdim      if (Triple.getOS() != llvm::Triple::UnknownOS ||
5497249423Sdim        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
5498249423Sdim        return NULL;
5499249423Sdim      return new SPIR32TargetInfo(T);
5500249423Sdim    }
5501249423Sdim    case llvm::Triple::spir64: {
5502249423Sdim      llvm::Triple Triple(T);
5503249423Sdim      if (Triple.getOS() != llvm::Triple::UnknownOS ||
5504249423Sdim        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
5505249423Sdim        return NULL;
5506249423Sdim      return new SPIR64TargetInfo(T);
5507249423Sdim    }
5508193326Sed  }
5509193326Sed}
5510199482Srdivacky
5511199482Srdivacky/// CreateTargetInfo - Return the target info object for the specified target
5512199482Srdivacky/// triple.
5513226633SdimTargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
5514249423Sdim                                         TargetOptions *Opts) {
5515249423Sdim  llvm::Triple Triple(Opts->Triple);
5516199482Srdivacky
5517199482Srdivacky  // Construct the target
5518234353Sdim  OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
5519199482Srdivacky  if (!Target) {
5520199482Srdivacky    Diags.Report(diag::err_target_unknown_triple) << Triple.str();
5521199482Srdivacky    return 0;
5522199482Srdivacky  }
5523243830Sdim  Target->setTargetOpts(Opts);
5524199482Srdivacky
5525201361Srdivacky  // Set the target CPU if specified.
5526249423Sdim  if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
5527249423Sdim    Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU;
5528201361Srdivacky    return 0;
5529201361Srdivacky  }
5530201361Srdivacky
5531199482Srdivacky  // Set the target ABI if specified.
5532249423Sdim  if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) {
5533249423Sdim    Diags.Report(diag::err_target_unknown_abi) << Opts->ABI;
5534199482Srdivacky    return 0;
5535199482Srdivacky  }
5536199482Srdivacky
5537210299Sed  // Set the target C++ ABI.
5538249423Sdim  if (!Opts->CXXABI.empty() && !Target->setCXXABI(Opts->CXXABI)) {
5539249423Sdim    Diags.Report(diag::err_target_unknown_cxxabi) << Opts->CXXABI;
5540210299Sed    return 0;
5541210299Sed  }
5542210299Sed
5543199482Srdivacky  // Compute the default target features, we need the target to handle this
5544199482Srdivacky  // because features may have dependencies on one another.
5545199482Srdivacky  llvm::StringMap<bool> Features;
5546226633Sdim  Target->getDefaultFeatures(Features);
5547199482Srdivacky
5548199482Srdivacky  // Apply the user specified deltas.
5549232894Sdim  // First the enables.
5550243830Sdim  for (std::vector<std::string>::const_iterator
5551249423Sdim         it = Opts->FeaturesAsWritten.begin(),
5552249423Sdim         ie = Opts->FeaturesAsWritten.end();
5553243830Sdim       it != ie; ++it) {
5554199482Srdivacky    const char *Name = it->c_str();
5555199482Srdivacky
5556232894Sdim    if (Name[0] != '+')
5557232894Sdim      continue;
5558232894Sdim
5559199482Srdivacky    // Apply the feature via the target.
5560232894Sdim    if (!Target->setFeatureEnabled(Features, Name + 1, true)) {
5561199482Srdivacky      Diags.Report(diag::err_target_invalid_feature) << Name;
5562199482Srdivacky      return 0;
5563199482Srdivacky    }
5564199482Srdivacky  }
5565199482Srdivacky
5566232894Sdim  // Then the disables.
5567243830Sdim  for (std::vector<std::string>::const_iterator
5568249423Sdim         it = Opts->FeaturesAsWritten.begin(),
5569249423Sdim         ie = Opts->FeaturesAsWritten.end();
5570243830Sdim       it != ie; ++it) {
5571232894Sdim    const char *Name = it->c_str();
5572232894Sdim
5573232894Sdim    if (Name[0] == '+')
5574232894Sdim      continue;
5575232894Sdim
5576232894Sdim    // Apply the feature via the target.
5577232894Sdim    if (Name[0] != '-' ||
5578232894Sdim        !Target->setFeatureEnabled(Features, Name + 1, false)) {
5579232894Sdim      Diags.Report(diag::err_target_invalid_feature) << Name;
5580232894Sdim      return 0;
5581232894Sdim    }
5582232894Sdim  }
5583232894Sdim
5584199482Srdivacky  // Add the features to the compile options.
5585199482Srdivacky  //
5586199482Srdivacky  // FIXME: If we are completely confident that we have the right set, we only
5587199482Srdivacky  // need to pass the minuses.
5588249423Sdim  Opts->Features.clear();
5589199482Srdivacky  for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
5590199482Srdivacky         ie = Features.end(); it != ie; ++it)
5591249423Sdim    Opts->Features.push_back((it->second ? "+" : "-") + it->first().str());
5592249423Sdim  Target->HandleTargetFeatures(Opts->Features);
5593199482Srdivacky
5594199482Srdivacky  return Target.take();
5595199482Srdivacky}
5596