Targets.cpp revision 624c1467809b409dcfa596b176ef45943442296b
1//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements construction of a TargetInfo object from a
11// target triple.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Basic/Builtins.h"
16#include "clang/Basic/TargetBuiltins.h"
17#include "clang/Basic/TargetInfo.h"
18#include "clang/Basic/LangOptions.h"
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/APFloat.h"
21#include "llvm/ADT/SmallString.h"
22using namespace clang;
23
24//===----------------------------------------------------------------------===//
25//  Common code shared among targets.
26//===----------------------------------------------------------------------===//
27
28static void Define(std::vector<char> &Buf, const char *Macro,
29                   const char *Val = "1") {
30  const char *Def = "#define ";
31  Buf.insert(Buf.end(), Def, Def+strlen(Def));
32  Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
33  Buf.push_back(' ');
34  Buf.insert(Buf.end(), Val, Val+strlen(Val));
35  Buf.push_back('\n');
36}
37
38/// DefineStd - Define a macro name and standard variants.  For example if
39/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
40/// when in GNU mode.
41static void DefineStd(std::vector<char> &Buf, const char *MacroName,
42                      const LangOptions &Opts) {
43  assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
44
45  // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
46  // in the user's namespace.
47  if (Opts.GNUMode)
48    Define(Buf, MacroName);
49
50  // Define __unix.
51  llvm::SmallString<20> TmpStr;
52  TmpStr = "__";
53  TmpStr += MacroName;
54  Define(Buf, TmpStr.c_str());
55
56  // Define __unix__.
57  TmpStr += "__";
58  Define(Buf, TmpStr.c_str());
59}
60
61//===----------------------------------------------------------------------===//
62// Defines specific to certain operating systems.
63//===----------------------------------------------------------------------===//
64namespace {
65template<typename TgtInfo>
66class OSTargetInfo : public TgtInfo {
67protected:
68  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
69                            std::vector<char> &Defines) const=0;
70public:
71  OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
72  virtual void getTargetDefines(const LangOptions &Opts,
73                                std::vector<char> &Defines) const {
74    TgtInfo::getTargetDefines(Opts, Defines);
75    getOSDefines(Opts, TgtInfo::getTargetTriple(), Defines);
76  }
77
78};
79}
80
81namespace {
82/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
83/// triple.  For example, if we have darwin8.5 return 8,5,0.  If any entry is
84/// not defined, return 0's.  Return true if we have -darwin in the string or
85/// false otherwise.
86static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min, unsigned &Revision) {
87  Maj = Min = Revision = 0;
88  const char *Darwin = strstr(Triple, "-darwin");
89  if (Darwin == 0) return false;
90
91  Darwin += strlen("-darwin");
92  if (Darwin[0] < '0' || Darwin[0] > '9')
93    return true;
94
95  Maj = Darwin[0]-'0';
96  ++Darwin;
97
98  // Handle "darwin11".
99  if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
100    Maj = Maj*10 + (Darwin[0] - '0');
101    ++Darwin;
102  }
103
104  // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
105  if (Darwin[0] != '.')
106    return true;
107
108  ++Darwin;
109  if (Darwin[0] < '0' || Darwin[0] > '9')
110    return true;
111
112  Min = Darwin[0]-'0';
113  ++Darwin;
114
115  // Handle 10.4.11 -> darwin8.11
116  if (Min == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
117    Min = Min*10 + (Darwin[0] - '0');
118    ++Darwin;
119  }
120
121  // Handle revision darwin8.9.1
122  if (Darwin[0] != '.')
123    return true;
124
125  ++Darwin;
126  if (Darwin[0] < '0' || Darwin[0] > '9')
127    return true;
128
129  Revision = Darwin[0]-'0';
130  ++Darwin;
131
132  if (Revision == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
133    Revision = Revision*10 + (Darwin[0] - '0');
134    ++Darwin;
135  }
136
137  return true;
138}
139
140static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) {
141  Define(Defs, "__APPLE_CC__", "5621");
142  Define(Defs, "__APPLE__");
143  Define(Defs, "__MACH__");
144  Define(Defs, "OBJC_NEW_PROPERTIES");
145
146  // __weak is always defined, for use in blocks and with objc pointers.
147  Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
148
149  // Darwin defines __strong even in C mode (just to nothing).
150  if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
151    Define(Defs, "__strong", "");
152  else
153    Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
154
155  if (Opts.Static)
156    Define(Defs, "__STATIC__");
157  else
158    Define(Defs, "__DYNAMIC__");
159}
160
161static void getDarwinOSXDefines(std::vector<char> &Defs, const char *Triple) {
162  // Figure out which "darwin number" the target triple is.  "darwin9" -> 10.5.
163  unsigned Maj, Min, Rev;
164  if (getDarwinNumber(Triple, Maj, Min, Rev)) {
165    char MacOSXStr[] = "1000";
166    if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
167      // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
168      MacOSXStr[2] = '0' + Maj-4;
169    }
170
171    // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
172    // Cap 10.4.11 -> darwin8.11 -> "1049"
173    MacOSXStr[3] = std::min(Min, 9U)+'0';
174    Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr);
175  }
176}
177
178static void getDarwinIPhoneOSDefines(std::vector<char> &Defs,
179                                     const char *Triple) {
180  // Figure out which "darwin number" the target triple is.  "darwin9" -> 10.5.
181  unsigned Maj, Min, Rev;
182  if (getDarwinNumber(Triple, Maj, Min, Rev)) {
183    // When targetting iPhone OS, interpret the minor version and
184    // revision as the iPhone OS version
185    char iPhoneOSStr[] = "10000";
186    if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0
187      // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc.
188      iPhoneOSStr[0] = '0' + Min;
189    }
190
191    // Handle minor version: 2.2 -> darwin9.2.2 -> 20200
192    iPhoneOSStr[2] = std::min(Rev, 9U)+'0';
193    Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
194           iPhoneOSStr);
195  }
196}
197
198/// GetDarwinLanguageOptions - Set the default language options for darwin.
199static void GetDarwinLanguageOptions(LangOptions &Opts,
200                                     const char *Triple) {
201  Opts.NeXTRuntime = true;
202
203  unsigned Maj, Min, Rev;
204  if (!getDarwinNumber(Triple, Maj, Min, Rev))
205    return;
206
207  // Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
208  if (Maj > 9) {
209    Opts.Blocks = 1;
210    Opts.setStackProtectorMode(LangOptions::SSPOn);
211  }
212
213  // Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and
214  // beyond.
215  if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
216    Opts.ObjCNonFragileABI = 1;
217}
218
219template<typename Target>
220class DarwinTargetInfo : public OSTargetInfo<Target> {
221protected:
222  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
223                    std::vector<char> &Defines) const {
224    getDarwinDefines(Defines, Opts);
225    getDarwinOSXDefines(Defines, Triple);
226  }
227
228  /// getDefaultLangOptions - Allow the target to specify default settings for
229  /// various language options.  These may be overridden by command line
230  /// options.
231  virtual void getDefaultLangOptions(LangOptions &Opts) {
232    TargetInfo::getDefaultLangOptions(Opts);
233    GetDarwinLanguageOptions(Opts, TargetInfo::getTargetTriple());
234  }
235public:
236  DarwinTargetInfo(const std::string& triple) :
237    OSTargetInfo<Target>(triple) {
238      this->TLSSupported = false;
239    }
240
241  virtual const char *getCFStringSymbolPrefix() const {
242    return "\01L_unnamed_cfstring_";
243  }
244
245  virtual const char *getStringSymbolPrefix(bool IsConstant) const {
246    return IsConstant ? "\01LC" : "\01lC";
247  }
248
249  virtual const char *getUnicodeStringSymbolPrefix() const {
250    return "__utf16_string_";
251  }
252
253  virtual const char *getUnicodeStringSection() const {
254    return "__TEXT,__ustring";
255  }
256};
257
258// DragonFlyBSD Target
259template<typename Target>
260class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
261protected:
262  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
263                    std::vector<char> &Defs) const {
264    // DragonFly defines; list based off of gcc output
265    Define(Defs, "__DragonFly__");
266    Define(Defs, "__DragonFly_cc_version", "100001");
267    Define(Defs, "__ELF__");
268    Define(Defs, "__KPRINTF_ATTRIBUTE__");
269    Define(Defs, "__tune_i386__");
270    DefineStd(Defs, "unix", Opts);
271  }
272public:
273  DragonFlyBSDTargetInfo(const std::string &triple)
274    : OSTargetInfo<Target>(triple) {}
275};
276
277// FreeBSD Target
278template<typename Target>
279class FreeBSDTargetInfo : public OSTargetInfo<Target> {
280protected:
281  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
282                    std::vector<char> &Defs) const {
283    // FreeBSD defines; list based off of gcc output
284
285    const char *FreeBSD = strstr(Triple, "-freebsd");
286    FreeBSD += strlen("-freebsd");
287    char release[] = "X";
288    release[0] = FreeBSD[0];
289    char version[] = "X00001";
290    version[0] = FreeBSD[0];
291
292    Define(Defs, "__FreeBSD__", release);
293    Define(Defs, "__FreeBSD_cc_version", version);
294    Define(Defs, "__KPRINTF_ATTRIBUTE__");
295    DefineStd(Defs, "unix", Opts);
296    Define(Defs, "__ELF__", "1");
297  }
298public:
299  FreeBSDTargetInfo(const std::string &triple)
300    : OSTargetInfo<Target>(triple) {}
301};
302
303// Linux target
304template<typename Target>
305class LinuxTargetInfo : public OSTargetInfo<Target> {
306protected:
307  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
308                           std::vector<char> &Defs) const {
309    // Linux defines; list based off of gcc output
310    DefineStd(Defs, "unix", Opts);
311    DefineStd(Defs, "linux", Opts);
312    Define(Defs, "__gnu_linux__");
313    Define(Defs, "__ELF__", "1");
314  }
315public:
316  LinuxTargetInfo(const std::string& triple)
317    : OSTargetInfo<Target>(triple) {
318    this->UserLabelPrefix = "";
319  }
320};
321
322// OpenBSD Target
323template<typename Target>
324class OpenBSDTargetInfo : public OSTargetInfo<Target> {
325protected:
326  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
327                    std::vector<char> &Defs) const {
328    // OpenBSD defines; list based off of gcc output
329
330    Define(Defs, "__OpenBSD__", "1");
331    DefineStd(Defs, "unix", Opts);
332    Define(Defs, "__ELF__", "1");
333  }
334public:
335  OpenBSDTargetInfo(const std::string &triple)
336    : OSTargetInfo<Target>(triple) {}
337};
338
339// Solaris target
340template<typename Target>
341class SolarisTargetInfo : public OSTargetInfo<Target> {
342protected:
343  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
344                                std::vector<char> &Defs) const {
345    DefineStd(Defs, "sun", Opts);
346    DefineStd(Defs, "unix", Opts);
347    Define(Defs, "__ELF__");
348    Define(Defs, "__svr4__");
349    Define(Defs, "__SVR4");
350  }
351public:
352  SolarisTargetInfo(const std::string& triple)
353    : OSTargetInfo<Target>(triple) {
354    this->UserLabelPrefix = "";
355    this->WCharType = this->SignedLong;
356    // FIXME: WIntType should be SignedLong
357  }
358};
359} // end anonymous namespace.
360
361/// GetWindowsLanguageOptions - Set the default language options for Windows.
362static void GetWindowsLanguageOptions(LangOptions &Opts,
363                                     const char *Triple) {
364  Opts.Microsoft = true;
365}
366
367//===----------------------------------------------------------------------===//
368// Specific target implementations.
369//===----------------------------------------------------------------------===//
370
371namespace {
372// PPC abstract base class
373class PPCTargetInfo : public TargetInfo {
374  static const Builtin::Info BuiltinInfo[];
375  static const char * const GCCRegNames[];
376  static const TargetInfo::GCCRegAlias GCCRegAliases[];
377
378public:
379  PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
380
381  virtual void getTargetBuiltins(const Builtin::Info *&Records,
382                                 unsigned &NumRecords) const {
383    Records = BuiltinInfo;
384    NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
385  }
386
387  virtual void getTargetDefines(const LangOptions &Opts,
388                                std::vector<char> &Defines) const;
389
390  virtual const char *getVAListDeclaration() const {
391    return "typedef char* __builtin_va_list;";
392    // This is the right definition for ABI/V4: System V.4/eabi.
393    /*return "typedef struct __va_list_tag {"
394           "  unsigned char gpr;"
395           "  unsigned char fpr;"
396           "  unsigned short reserved;"
397           "  void* overflow_arg_area;"
398           "  void* reg_save_area;"
399           "} __builtin_va_list[1];";*/
400  }
401  virtual const char *getTargetPrefix() const {
402    return "ppc";
403  }
404  virtual void getGCCRegNames(const char * const *&Names,
405                              unsigned &NumNames) const;
406  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
407                                unsigned &NumAliases) const;
408  virtual bool validateAsmConstraint(const char *&Name,
409                                     TargetInfo::ConstraintInfo &Info) const {
410    switch (*Name) {
411    default: return false;
412    case 'O': // Zero
413      return true;
414    case 'b': // Base register
415    case 'f': // Floating point register
416      Info.setAllowsRegister();
417      return true;
418    }
419  }
420  virtual void getDefaultLangOptions(LangOptions &Opts) {
421    TargetInfo::getDefaultLangOptions(Opts);
422    Opts.CharIsSigned = false;
423  }
424  virtual const char *getClobbers() const {
425    return "";
426  }
427};
428
429const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
430#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
431#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
432#include "clang/Basic/BuiltinsPPC.def"
433};
434
435
436/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
437/// #defines that are not tied to a specific subtarget.
438void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
439                                     std::vector<char> &Defs) const {
440  // Target identification.
441  Define(Defs, "__ppc__");
442  Define(Defs, "_ARCH_PPC");
443  Define(Defs, "__POWERPC__");
444  if (PointerWidth == 64) {
445    Define(Defs, "_ARCH_PPC64");
446    Define(Defs, "_LP64");
447    Define(Defs, "__LP64__");
448    Define(Defs, "__ppc64__");
449  } else {
450    Define(Defs, "__ppc__");
451  }
452
453  // Target properties.
454  Define(Defs, "_BIG_ENDIAN");
455  Define(Defs, "__BIG_ENDIAN__");
456
457  // Subtarget options.
458  Define(Defs, "__NATURAL_ALIGNMENT__");
459  Define(Defs, "__REGISTER_PREFIX__", "");
460
461  // FIXME: Should be controlled by command line option.
462  Define(Defs, "__LONG_DOUBLE_128__");
463}
464
465
466const char * const PPCTargetInfo::GCCRegNames[] = {
467  "0", "1", "2", "3", "4", "5", "6", "7",
468  "8", "9", "10", "11", "12", "13", "14", "15",
469  "16", "17", "18", "19", "20", "21", "22", "23",
470  "24", "25", "26", "27", "28", "29", "30", "31",
471  "0", "1", "2", "3", "4", "5", "6", "7",
472  "8", "9", "10", "11", "12", "13", "14", "15",
473  "16", "17", "18", "19", "20", "21", "22", "23",
474  "24", "25", "26", "27", "28", "29", "30", "31",
475  "mq", "lr", "ctr", "ap",
476  "0", "1", "2", "3", "4", "5", "6", "7",
477  "xer",
478  "0", "1", "2", "3", "4", "5", "6", "7",
479  "8", "9", "10", "11", "12", "13", "14", "15",
480  "16", "17", "18", "19", "20", "21", "22", "23",
481  "24", "25", "26", "27", "28", "29", "30", "31",
482  "vrsave", "vscr",
483  "spe_acc", "spefscr",
484  "sfp"
485};
486
487void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
488                                   unsigned &NumNames) const {
489  Names = GCCRegNames;
490  NumNames = llvm::array_lengthof(GCCRegNames);
491}
492
493const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
494  // While some of these aliases do map to different registers
495  // they still share the same register name.
496  { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
497  { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
498  { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
499  { { "cr3", "fr3", "r3", "v3"}, "3" },
500  { { "cr4", "fr4", "r4", "v4"}, "4" },
501  { { "cr5", "fr5", "r5", "v5"}, "5" },
502  { { "cr6", "fr6", "r6", "v6"}, "6" },
503  { { "cr7", "fr7", "r7", "v7"}, "7" },
504  { { "fr8", "r8", "v8"}, "8" },
505  { { "fr9", "r9", "v9"}, "9" },
506  { { "fr10", "r10", "v10"}, "10" },
507  { { "fr11", "r11", "v11"}, "11" },
508  { { "fr12", "r12", "v12"}, "12" },
509  { { "fr13", "r13", "v13"}, "13" },
510  { { "fr14", "r14", "v14"}, "14" },
511  { { "fr15", "r15", "v15"}, "15" },
512  { { "fr16", "r16", "v16"}, "16" },
513  { { "fr17", "r17", "v17"}, "17" },
514  { { "fr18", "r18", "v18"}, "18" },
515  { { "fr19", "r19", "v19"}, "19" },
516  { { "fr20", "r20", "v20"}, "20" },
517  { { "fr21", "r21", "v21"}, "21" },
518  { { "fr22", "r22", "v22"}, "22" },
519  { { "fr23", "r23", "v23"}, "23" },
520  { { "fr24", "r24", "v24"}, "24" },
521  { { "fr25", "r25", "v25"}, "25" },
522  { { "fr26", "r26", "v26"}, "26" },
523  { { "fr27", "r27", "v27"}, "27" },
524  { { "fr28", "r28", "v28"}, "28" },
525  { { "fr29", "r29", "v29"}, "29" },
526  { { "fr30", "r30", "v30"}, "30" },
527  { { "fr31", "r31", "v31"}, "31" },
528};
529
530void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
531                                     unsigned &NumAliases) const {
532  Aliases = GCCRegAliases;
533  NumAliases = llvm::array_lengthof(GCCRegAliases);
534}
535} // end anonymous namespace.
536
537namespace {
538class PPC32TargetInfo : public PPCTargetInfo {
539public:
540  PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
541    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
542                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
543  }
544};
545} // end anonymous namespace.
546
547namespace {
548class PPC64TargetInfo : public PPCTargetInfo {
549public:
550  PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
551    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
552    IntMaxType = SignedLong;
553    UIntMaxType = UnsignedLong;
554    Int64Type = SignedLong;
555    DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
556                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
557  }
558};
559} // end anonymous namespace.
560
561namespace {
562// Namespace for x86 abstract base class
563const Builtin::Info BuiltinInfo[] = {
564#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
565#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
566#include "clang/Basic/BuiltinsX86.def"
567};
568
569const char *GCCRegNames[] = {
570  "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
571  "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
572  "argp", "flags", "fspr", "dirflag", "frame",
573  "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
574  "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
575  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
576  "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
577};
578
579const TargetInfo::GCCRegAlias GCCRegAliases[] = {
580  { { "al", "ah", "eax", "rax" }, "ax" },
581  { { "bl", "bh", "ebx", "rbx" }, "bx" },
582  { { "cl", "ch", "ecx", "rcx" }, "cx" },
583  { { "dl", "dh", "edx", "rdx" }, "dx" },
584  { { "esi", "rsi" }, "si" },
585  { { "edi", "rdi" }, "di" },
586  { { "esp", "rsp" }, "sp" },
587  { { "ebp", "rbp" }, "bp" },
588};
589
590// X86 target abstract base class; x86-32 and x86-64 are very close, so
591// most of the implementation can be shared.
592class X86TargetInfo : public TargetInfo {
593  enum X86SSEEnum {
594    NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
595  } SSELevel;
596public:
597  X86TargetInfo(const std::string& triple)
598    : TargetInfo(triple), SSELevel(NoMMXSSE) {
599    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
600  }
601  virtual void getTargetBuiltins(const Builtin::Info *&Records,
602                                 unsigned &NumRecords) const {
603    Records = BuiltinInfo;
604    NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
605  }
606  virtual const char *getTargetPrefix() const {
607    return "x86";
608  }
609  virtual void getGCCRegNames(const char * const *&Names,
610                              unsigned &NumNames) const {
611    Names = GCCRegNames;
612    NumNames = llvm::array_lengthof(GCCRegNames);
613  }
614  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
615                                unsigned &NumAliases) const {
616    Aliases = GCCRegAliases;
617    NumAliases = llvm::array_lengthof(GCCRegAliases);
618  }
619  virtual bool validateAsmConstraint(const char *&Name,
620                                     TargetInfo::ConstraintInfo &info) const;
621  virtual std::string convertConstraint(const char Constraint) const;
622  virtual const char *getClobbers() const {
623    return "~{dirflag},~{fpsr},~{flags}";
624  }
625  virtual void getTargetDefines(const LangOptions &Opts,
626                                std::vector<char> &Defines) const;
627  virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
628                                 const std::string &Name,
629                                 bool Enabled) const;
630  virtual void getDefaultFeatures(const std::string &CPU,
631                                  llvm::StringMap<bool> &Features) const;
632  virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
633};
634
635void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
636                                       llvm::StringMap<bool> &Features) const {
637  // FIXME: This should not be here.
638  Features["3dnow"] = false;
639  Features["3dnowa"] = false;
640  Features["mmx"] = false;
641  Features["sse"] = false;
642  Features["sse2"] = false;
643  Features["sse3"] = false;
644  Features["ssse3"] = false;
645  Features["sse41"] = false;
646  Features["sse42"] = false;
647
648  // LLVM does not currently recognize this.
649  // Features["sse4a"] = false;
650
651  // FIXME: This *really* should not be here.
652
653  // X86_64 always has SSE2.
654  if (PointerWidth == 64)
655    Features["sse2"] = Features["sse"] = Features["mmx"] = true;
656
657  if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
658      CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
659    ;
660  else if (CPU == "pentium-mmx" || CPU == "pentium2")
661    setFeatureEnabled(Features, "mmx", true);
662  else if (CPU == "pentium3")
663    setFeatureEnabled(Features, "sse", true);
664  else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
665    setFeatureEnabled(Features, "sse2", true);
666  else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
667    setFeatureEnabled(Features, "sse3", true);
668  else if (CPU == "core2")
669    setFeatureEnabled(Features, "ssse3", true);
670  else if (CPU == "penryn") {
671    setFeatureEnabled(Features, "sse4", true);
672    Features["sse42"] = false;
673  } else if (CPU == "atom")
674    setFeatureEnabled(Features, "sse3", true);
675  else if (CPU == "corei7")
676    setFeatureEnabled(Features, "sse4", true);
677  else if (CPU == "k6" || CPU == "winchip-c6")
678    setFeatureEnabled(Features, "mmx", true);
679  else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
680           CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
681    setFeatureEnabled(Features, "mmx", true);
682    setFeatureEnabled(Features, "3dnow", true);
683  } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
684    setFeatureEnabled(Features, "sse", true);
685    setFeatureEnabled(Features, "3dnowa", true);
686  } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
687           CPU == "athlon-fx") {
688    setFeatureEnabled(Features, "sse2", true);
689    setFeatureEnabled(Features, "3dnowa", true);
690  } else if (CPU == "c3-2")
691    setFeatureEnabled(Features, "sse", true);
692}
693
694bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
695                                      const std::string &Name,
696                                      bool Enabled) const {
697  // FIXME: This *really* should not be here.
698  if (!Features.count(Name) && Name != "sse4")
699    return false;
700
701  if (Enabled) {
702    if (Name == "mmx")
703      Features["mmx"] = true;
704    else if (Name == "sse")
705      Features["mmx"] = Features["sse"] = true;
706    else if (Name == "sse2")
707      Features["mmx"] = Features["sse"] = Features["sse2"] = true;
708    else if (Name == "sse3")
709      Features["mmx"] = Features["sse"] = Features["sse2"] =
710        Features["sse3"] = true;
711    else if (Name == "ssse3")
712      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
713        Features["ssse3"] = true;
714    else if (Name == "sse4")
715      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
716        Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
717    else if (Name == "3dnow")
718      Features["3dnowa"] = true;
719    else if (Name == "3dnowa")
720      Features["3dnow"] = Features["3dnowa"] = true;
721  } else {
722    if (Name == "mmx")
723      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
724        Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
725    else if (Name == "sse")
726      Features["sse"] = Features["sse2"] = Features["sse3"] =
727        Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
728    else if (Name == "sse2")
729      Features["sse2"] = Features["sse3"] = Features["ssse3"] =
730        Features["sse41"] = Features["sse42"] = false;
731    else if (Name == "sse3")
732      Features["sse3"] = Features["ssse3"] = Features["sse41"] =
733        Features["sse42"] = false;
734    else if (Name == "ssse3")
735      Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
736    else if (Name == "sse4")
737      Features["sse41"] = Features["sse42"] = false;
738    else if (Name == "3dnow")
739      Features["3dnow"] = Features["3dnowa"] = false;
740    else if (Name == "3dnowa")
741      Features["3dnowa"] = false;
742  }
743
744  return true;
745}
746
747/// HandleTargetOptions - Perform initialization based on the user
748/// configured set of features.
749void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) {
750  if (Features.lookup("sse42"))
751    SSELevel = SSE42;
752  else if (Features.lookup("sse41"))
753    SSELevel = SSE41;
754  else if (Features.lookup("ssse3"))
755    SSELevel = SSSE3;
756  else if (Features.lookup("sse3"))
757    SSELevel = SSE3;
758  else if (Features.lookup("sse2"))
759    SSELevel = SSE2;
760  else if (Features.lookup("sse"))
761    SSELevel = SSE1;
762  else if (Features.lookup("mmx"))
763    SSELevel = MMX;
764}
765
766/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
767/// that are not tied to a specific subtarget.
768void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
769                                     std::vector<char> &Defs) const {
770  // Target identification.
771  if (PointerWidth == 64) {
772    Define(Defs, "_LP64");
773    Define(Defs, "__LP64__");
774    Define(Defs, "__amd64__");
775    Define(Defs, "__amd64");
776    Define(Defs, "__x86_64");
777    Define(Defs, "__x86_64__");
778  } else {
779    DefineStd(Defs, "i386", Opts);
780  }
781
782  // Target properties.
783  Define(Defs, "__LITTLE_ENDIAN__");
784
785  // Subtarget options.
786  Define(Defs, "__nocona");
787  Define(Defs, "__nocona__");
788  Define(Defs, "__tune_nocona__");
789  Define(Defs, "__REGISTER_PREFIX__", "");
790
791  // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
792  // functions in glibc header files that use FP Stack inline asm which the
793  // backend can't deal with (PR879).
794  Define(Defs, "__NO_MATH_INLINES");
795
796  // Each case falls through to the previous one here.
797  switch (SSELevel) {
798  case SSE42:
799    Define(Defs, "__SSE4_2__");
800  case SSE41:
801    Define(Defs, "__SSE4_1__");
802  case SSSE3:
803    Define(Defs, "__SSSE3__");
804  case SSE3:
805    Define(Defs, "__SSE3__");
806  case SSE2:
807    Define(Defs, "__SSE2__");
808    Define(Defs, "__SSE2_MATH__");  // -mfp-math=sse always implied.
809  case SSE1:
810    Define(Defs, "__SSE__");
811    Define(Defs, "__SSE_MATH__");   // -mfp-math=sse always implied.
812  case MMX:
813    Define(Defs, "__MMX__");
814  case NoMMXSSE:
815    break;
816  }
817}
818
819
820bool
821X86TargetInfo::validateAsmConstraint(const char *&Name,
822                                     TargetInfo::ConstraintInfo &Info) const {
823  switch (*Name) {
824  default: return false;
825  case 'a': // eax.
826  case 'b': // ebx.
827  case 'c': // ecx.
828  case 'd': // edx.
829  case 'S': // esi.
830  case 'D': // edi.
831  case 'A': // edx:eax.
832  case 't': // top of floating point stack.
833  case 'u': // second from top of floating point stack.
834  case 'q': // Any register accessible as [r]l: a, b, c, and d.
835  case 'y': // Any MMX register.
836  case 'x': // Any SSE register.
837  case 'Q': // Any register accessible as [r]h: a, b, c, and d.
838  case 'e': // 32-bit signed integer constant for use with zero-extending
839            // x86_64 instructions.
840  case 'Z': // 32-bit unsigned integer constant for use with zero-extending
841            // x86_64 instructions.
842  case 'N': // unsigned 8-bit integer constant for use with in and out
843            // instructions.
844  case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
845    Info.setAllowsRegister();
846    return true;
847  }
848}
849
850std::string
851X86TargetInfo::convertConstraint(const char Constraint) const {
852  switch (Constraint) {
853  case 'a': return std::string("{ax}");
854  case 'b': return std::string("{bx}");
855  case 'c': return std::string("{cx}");
856  case 'd': return std::string("{dx}");
857  case 'S': return std::string("{si}");
858  case 'D': return std::string("{di}");
859  case 't': // top of floating point stack.
860    return std::string("{st}");
861  case 'u': // second from top of floating point stack.
862    return std::string("{st(1)}"); // second from top of floating point stack.
863  default:
864    return std::string(1, Constraint);
865  }
866}
867} // end anonymous namespace
868
869namespace {
870// X86-32 generic target
871class X86_32TargetInfo : public X86TargetInfo {
872public:
873  X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
874    DoubleAlign = LongLongAlign = 32;
875    LongDoubleWidth = 96;
876    LongDoubleAlign = 32;
877    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
878                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
879                        "a0:0:64-f80:32:32";
880    SizeType = UnsignedInt;
881    PtrDiffType = SignedInt;
882    IntPtrType = SignedInt;
883    RegParmMax = 3;
884  }
885  virtual const char *getVAListDeclaration() const {
886    return "typedef char* __builtin_va_list;";
887  }
888};
889} // end anonymous namespace
890
891namespace {
892class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
893public:
894  OpenBSDI386TargetInfo(const std::string& triple) :
895    OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
896    SizeType = UnsignedLong;
897    IntPtrType = SignedLong;
898  }
899};
900} // end anonymous namespace
901
902namespace {
903class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
904public:
905  DarwinI386TargetInfo(const std::string& triple) :
906    DarwinTargetInfo<X86_32TargetInfo>(triple) {
907    LongDoubleWidth = 128;
908    LongDoubleAlign = 128;
909    SizeType = UnsignedLong;
910    IntPtrType = SignedLong;
911    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
912                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
913                        "a0:0:64-f80:128:128";
914  }
915
916};
917} // end anonymous namespace
918
919namespace {
920// x86-32 Windows target
921class WindowsX86_32TargetInfo : public X86_32TargetInfo {
922public:
923  WindowsX86_32TargetInfo(const std::string& triple)
924    : X86_32TargetInfo(triple) {
925    TLSSupported = false;
926    WCharType = UnsignedShort;
927    WCharWidth = WCharAlign = 16;
928    DoubleAlign = LongLongAlign = 64;
929    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
930                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
931                        "a0:0:64-f80:32:32";
932  }
933  virtual void getTargetDefines(const LangOptions &Opts,
934                                std::vector<char> &Defines) const {
935    X86_32TargetInfo::getTargetDefines(Opts, Defines);
936    // This list is based off of the the list of things MingW defines
937    Define(Defines, "_WIN32");
938    DefineStd(Defines, "WIN32", Opts);
939    DefineStd(Defines, "WINNT", Opts);
940    Define(Defines, "_X86_");
941    Define(Defines, "__MSVCRT__");
942  }
943
944  virtual void getDefaultLangOptions(LangOptions &Opts) {
945    X86_32TargetInfo::getDefaultLangOptions(Opts);
946    GetWindowsLanguageOptions(Opts, getTargetTriple());
947  }
948};
949} // end anonymous namespace
950
951namespace {
952// x86-64 generic target
953class X86_64TargetInfo : public X86TargetInfo {
954public:
955  X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
956    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
957    LongDoubleWidth = 128;
958    LongDoubleAlign = 128;
959    IntMaxType = SignedLong;
960    UIntMaxType = UnsignedLong;
961    Int64Type = SignedLong;
962    RegParmMax = 6;
963
964    DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
965                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
966                        "a0:0:64-s0:64:64-f80:128:128";
967  }
968  virtual const char *getVAListDeclaration() const {
969    return "typedef struct __va_list_tag {"
970           "  unsigned gp_offset;"
971           "  unsigned fp_offset;"
972           "  void* overflow_arg_area;"
973           "  void* reg_save_area;"
974           "} __va_list_tag;"
975           "typedef __va_list_tag __builtin_va_list[1];";
976  }
977};
978} // end anonymous namespace
979
980namespace {
981class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
982public:
983  DarwinX86_64TargetInfo(const std::string& triple)
984      : DarwinTargetInfo<X86_64TargetInfo>(triple) {
985    Int64Type = SignedLongLong;
986  }
987};
988} // end anonymous namespace
989
990namespace {
991class ARMTargetInfo : public TargetInfo {
992  enum {
993    Armv4t,
994    Armv5,
995    Armv6,
996    XScale
997  } ArmArch;
998public:
999  ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
1000    // FIXME: Are the defaults correct for ARM?
1001    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1002                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
1003    if (triple.find("arm-") == 0 || triple.find("armv6-") == 0)
1004      ArmArch = Armv6;
1005    else if (triple.find("armv5-") == 0)
1006      ArmArch = Armv5;
1007    else if (triple.find("armv4t-") == 0)
1008      ArmArch = Armv4t;
1009    else if (triple.find("xscale-") == 0)
1010      ArmArch = XScale;
1011    else if (triple.find("armv") == 0) {
1012      // FIXME: fuzzy match for other random weird arm triples.  This is useful
1013      // for the static analyzer and other clients, but probably should be
1014      // re-evaluated when codegen is brought up.
1015      ArmArch = Armv6;
1016    }
1017  }
1018  virtual void getTargetDefines(const LangOptions &Opts,
1019                                std::vector<char> &Defs) const {
1020    // Target identification.
1021    Define(Defs, "__arm");
1022    Define(Defs, "__arm__");
1023
1024    // Target properties.
1025    Define(Defs, "__LITTLE_ENDIAN__");
1026
1027    // Subtarget options.
1028    if (ArmArch == Armv6) {
1029      Define(Defs, "__ARM_ARCH_6K__");
1030      Define(Defs, "__THUMB_INTERWORK__");
1031    } else if (ArmArch == Armv5) {
1032      Define(Defs, "__ARM_ARCH_5TEJ__");
1033      Define(Defs, "__THUMB_INTERWORK__");
1034      Define(Defs, "__SOFTFP__");
1035    } else if (ArmArch == Armv4t) {
1036      Define(Defs, "__ARM_ARCH_4T__");
1037      Define(Defs, "__SOFTFP__");
1038    } else if (ArmArch == XScale) {
1039      Define(Defs, "__ARM_ARCH_5TE__");
1040      Define(Defs, "__XSCALE__");
1041      Define(Defs, "__SOFTFP__");
1042    }
1043    Define(Defs, "__ARMEL__");
1044    Define(Defs, "__APCS_32__");
1045    Define(Defs, "__VFP_FP__");
1046  }
1047  virtual void getTargetBuiltins(const Builtin::Info *&Records,
1048                                 unsigned &NumRecords) const {
1049    // FIXME: Implement.
1050    Records = 0;
1051    NumRecords = 0;
1052  }
1053  virtual const char *getVAListDeclaration() const {
1054    return "typedef char* __builtin_va_list;";
1055  }
1056  virtual const char *getTargetPrefix() const {
1057    return "arm";
1058  }
1059  virtual void getGCCRegNames(const char * const *&Names,
1060                              unsigned &NumNames) const {
1061    // FIXME: Implement.
1062    Names = 0;
1063    NumNames = 0;
1064  }
1065  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1066                                unsigned &NumAliases) const {
1067    // FIXME: Implement.
1068    Aliases = 0;
1069    NumAliases = 0;
1070  }
1071  virtual bool validateAsmConstraint(const char *&Name,
1072                                     TargetInfo::ConstraintInfo &Info) const {
1073    // FIXME: Check if this is complete
1074    switch (*Name) {
1075    default:
1076    case 'l': // r0-r7
1077    case 'h': // r8-r15
1078    case 'w': // VFP Floating point register single precision
1079    case 'P': // VFP Floating point register double precision
1080      Info.setAllowsRegister();
1081      return true;
1082    }
1083    return false;
1084  }
1085  virtual const char *getClobbers() const {
1086    // FIXME: Is this really right?
1087    return "";
1088  }
1089};
1090} // end anonymous namespace.
1091
1092
1093namespace {
1094class DarwinARMTargetInfo :
1095  public DarwinTargetInfo<ARMTargetInfo> {
1096protected:
1097  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
1098                    std::vector<char> &Defines) const {
1099    getDarwinDefines(Defines, Opts);
1100    getDarwinIPhoneOSDefines(Defines, Triple);
1101  }
1102
1103public:
1104  DarwinARMTargetInfo(const std::string& triple)
1105    : DarwinTargetInfo<ARMTargetInfo>(triple) {}
1106};
1107} // end anonymous namespace.
1108
1109namespace {
1110class SparcV8TargetInfo : public TargetInfo {
1111  static const TargetInfo::GCCRegAlias GCCRegAliases[];
1112  static const char * const GCCRegNames[];
1113public:
1114  SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1115    // FIXME: Support Sparc quad-precision long double?
1116    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1117                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
1118  }
1119  virtual void getTargetDefines(const LangOptions &Opts,
1120                                std::vector<char> &Defines) const {
1121    DefineStd(Defines, "sparc", Opts);
1122    Define(Defines, "__sparcv8");
1123    Define(Defines, "__REGISTER_PREFIX__", "");
1124  }
1125  virtual void getTargetBuiltins(const Builtin::Info *&Records,
1126                                 unsigned &NumRecords) const {
1127    // FIXME: Implement!
1128  }
1129  virtual const char *getVAListDeclaration() const {
1130    return "typedef void* __builtin_va_list;";
1131  }
1132  virtual const char *getTargetPrefix() const {
1133    return "sparc";
1134  }
1135  virtual void getGCCRegNames(const char * const *&Names,
1136                              unsigned &NumNames) const;
1137  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1138                                unsigned &NumAliases) const;
1139  virtual bool validateAsmConstraint(const char *&Name,
1140                                     TargetInfo::ConstraintInfo &info) const {
1141    // FIXME: Implement!
1142    return false;
1143  }
1144  virtual const char *getClobbers() const {
1145    // FIXME: Implement!
1146    return "";
1147  }
1148};
1149
1150const char * const SparcV8TargetInfo::GCCRegNames[] = {
1151  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1152  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1153  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1154  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1155};
1156
1157void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
1158                                       unsigned &NumNames) const {
1159  Names = GCCRegNames;
1160  NumNames = llvm::array_lengthof(GCCRegNames);
1161}
1162
1163const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
1164  { { "g0" }, "r0" },
1165  { { "g1" }, "r1" },
1166  { { "g2" }, "r2" },
1167  { { "g3" }, "r3" },
1168  { { "g4" }, "r4" },
1169  { { "g5" }, "r5" },
1170  { { "g6" }, "r6" },
1171  { { "g7" }, "r7" },
1172  { { "o0" }, "r8" },
1173  { { "o1" }, "r9" },
1174  { { "o2" }, "r10" },
1175  { { "o3" }, "r11" },
1176  { { "o4" }, "r12" },
1177  { { "o5" }, "r13" },
1178  { { "o6", "sp" }, "r14" },
1179  { { "o7" }, "r15" },
1180  { { "l0" }, "r16" },
1181  { { "l1" }, "r17" },
1182  { { "l2" }, "r18" },
1183  { { "l3" }, "r19" },
1184  { { "l4" }, "r20" },
1185  { { "l5" }, "r21" },
1186  { { "l6" }, "r22" },
1187  { { "l7" }, "r23" },
1188  { { "i0" }, "r24" },
1189  { { "i1" }, "r25" },
1190  { { "i2" }, "r26" },
1191  { { "i3" }, "r27" },
1192  { { "i4" }, "r28" },
1193  { { "i5" }, "r29" },
1194  { { "i6", "fp" }, "r30" },
1195  { { "i7" }, "r31" },
1196};
1197
1198void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1199                                         unsigned &NumAliases) const {
1200  Aliases = GCCRegAliases;
1201  NumAliases = llvm::array_lengthof(GCCRegAliases);
1202}
1203} // end anonymous namespace.
1204
1205namespace {
1206class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
1207public:
1208  SolarisSparcV8TargetInfo(const std::string& triple) :
1209      SolarisTargetInfo<SparcV8TargetInfo>(triple) {
1210    SizeType = UnsignedInt;
1211    PtrDiffType = SignedInt;
1212  }
1213};
1214} // end anonymous namespace.
1215
1216namespace {
1217  class PIC16TargetInfo : public TargetInfo{
1218  public:
1219    PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
1220      TLSSupported = false;
1221      IntWidth = 16;
1222      LongWidth = LongLongWidth = 32;
1223      IntMaxTWidth = 32;
1224      PointerWidth = 16;
1225      IntAlign = 8;
1226      LongAlign = LongLongAlign = 8;
1227      PointerAlign = 8;
1228      SizeType = UnsignedInt;
1229      IntMaxType = SignedLong;
1230      UIntMaxType = UnsignedLong;
1231      IntPtrType = SignedShort;
1232      PtrDiffType = SignedInt;
1233      FloatWidth = 32;
1234      FloatAlign = 32;
1235      DoubleWidth = 32;
1236      DoubleAlign = 32;
1237      LongDoubleWidth = 32;
1238      LongDoubleAlign = 32;
1239      FloatFormat = &llvm::APFloat::IEEEsingle;
1240      DoubleFormat = &llvm::APFloat::IEEEsingle;
1241      LongDoubleFormat = &llvm::APFloat::IEEEsingle;
1242      DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32";
1243
1244    }
1245    virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1246    virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
1247    virtual void getTargetDefines(const LangOptions &Opts,
1248                                  std::vector<char> &Defines) const {
1249      Define(Defines, "__pic16");
1250    }
1251    virtual void getTargetBuiltins(const Builtin::Info *&Records,
1252                                   unsigned &NumRecords) const {}
1253    virtual const char *getVAListDeclaration() const { return "";}
1254    virtual const char *getClobbers() const {return "";}
1255    virtual const char *getTargetPrefix() const {return "pic16";}
1256    virtual void getGCCRegNames(const char * const *&Names,
1257                                unsigned &NumNames) const {}
1258    virtual bool validateAsmConstraint(const char *&Name,
1259                                       TargetInfo::ConstraintInfo &info) const {
1260      return true;
1261    }
1262    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1263                                  unsigned &NumAliases) const {}
1264    virtual bool useGlobalsForAutomaticVariables() const {return true;}
1265  };
1266}
1267
1268namespace {
1269  class MSP430TargetInfo : public TargetInfo {
1270    static const char * const GCCRegNames[];
1271  public:
1272    MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1273      TLSSupported = false;
1274      IntWidth = 16;
1275      LongWidth = LongLongWidth = 32;
1276      IntMaxTWidth = 32;
1277      PointerWidth = 16;
1278      IntAlign = 8;
1279      LongAlign = LongLongAlign = 8;
1280      PointerAlign = 8;
1281      SizeType = UnsignedInt;
1282      IntMaxType = SignedLong;
1283      UIntMaxType = UnsignedLong;
1284      IntPtrType = SignedShort;
1285      PtrDiffType = SignedInt;
1286      DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
1287   }
1288    virtual void getTargetDefines(const LangOptions &Opts,
1289                                 std::vector<char> &Defines) const {
1290      Define(Defines, "MSP430");
1291      Define(Defines, "__MSP430__");
1292      // FIXME: defines for different 'flavours' of MCU
1293    }
1294    virtual void getTargetBuiltins(const Builtin::Info *&Records,
1295                                   unsigned &NumRecords) const {
1296     // FIXME: Implement.
1297      Records = 0;
1298      NumRecords = 0;
1299    }
1300    virtual const char *getTargetPrefix() const {
1301      return "msp430";
1302    }
1303    virtual void getGCCRegNames(const char * const *&Names,
1304                                unsigned &NumNames) const;
1305    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1306                                  unsigned &NumAliases) const {
1307      // No aliases.
1308      Aliases = 0;
1309      NumAliases = 0;
1310    }
1311    virtual bool validateAsmConstraint(const char *&Name,
1312                                       TargetInfo::ConstraintInfo &info) const {
1313      // FIXME: implement
1314      return true;
1315    }
1316    virtual const char *getClobbers() const {
1317      // FIXME: Is this really right?
1318      return "";
1319    }
1320    virtual const char *getVAListDeclaration() const {
1321      // FIXME: implement
1322      return "typedef char* __builtin_va_list;";
1323   }
1324  };
1325
1326  const char * const MSP430TargetInfo::GCCRegNames[] = {
1327    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1328    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1329  };
1330
1331  void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1332                                        unsigned &NumNames) const {
1333    Names = GCCRegNames;
1334    NumNames = llvm::array_lengthof(GCCRegNames);
1335  }
1336}
1337
1338
1339//===----------------------------------------------------------------------===//
1340// Driver code
1341//===----------------------------------------------------------------------===//
1342
1343static inline bool IsX86(const std::string& TT) {
1344  return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1345          TT[4] == '-' && TT[1] - '3' < 6);
1346}
1347
1348/// CreateTargetInfo - Return the target info object for the specified target
1349/// triple.
1350TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
1351  // OS detection; this isn't really anywhere near complete.
1352  // Additions and corrections are welcome.
1353  bool isDarwin = T.find("-darwin") != std::string::npos;
1354  bool isDragonFly = T.find("-dragonfly") != std::string::npos;
1355  bool isOpenBSD = T.find("-openbsd") != std::string::npos;
1356  bool isFreeBSD = T.find("-freebsd") != std::string::npos;
1357  bool isSolaris = T.find("-solaris") != std::string::npos;
1358  bool isLinux = T.find("-linux") != std::string::npos;
1359  bool isWindows = T.find("-windows") != std::string::npos ||
1360                   T.find("-win32") != std::string::npos ||
1361                   T.find("-mingw") != std::string::npos;
1362
1363  if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1364    if (isDarwin)
1365      return new DarwinTargetInfo<PPCTargetInfo>(T);
1366    return new PPC32TargetInfo(T);
1367  }
1368
1369  if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1370    if (isDarwin)
1371      return new DarwinTargetInfo<PPC64TargetInfo>(T);
1372    return new PPC64TargetInfo(T);
1373  }
1374
1375  if (T.find("armv") == 0 || T.find("arm-") == 0 || T.find("xscale") == 0) {
1376    if (isDarwin)
1377      return new DarwinARMTargetInfo(T);
1378    if (isFreeBSD)
1379      return new FreeBSDTargetInfo<ARMTargetInfo>(T);
1380    return new ARMTargetInfo(T);
1381  }
1382
1383  if (T.find("sparc-") == 0) {
1384    if (isSolaris)
1385      return new SolarisSparcV8TargetInfo(T);
1386    return new SparcV8TargetInfo(T);
1387  }
1388
1389  if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
1390    if (isDarwin)
1391      return new DarwinX86_64TargetInfo(T);
1392    if (isLinux)
1393      return new LinuxTargetInfo<X86_64TargetInfo>(T);
1394    if (isOpenBSD)
1395      return new OpenBSDTargetInfo<X86_64TargetInfo>(T);
1396    if (isFreeBSD)
1397      return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
1398    if (isSolaris)
1399      return new SolarisTargetInfo<X86_64TargetInfo>(T);
1400    return new X86_64TargetInfo(T);
1401  }
1402
1403  if (T.find("pic16-") == 0)
1404    return new PIC16TargetInfo(T);
1405
1406  if (T.find("msp430-") == 0)
1407    return new MSP430TargetInfo(T);
1408
1409  if (IsX86(T)) {
1410    if (isDarwin)
1411      return new DarwinI386TargetInfo(T);
1412    if (isLinux)
1413      return new LinuxTargetInfo<X86_32TargetInfo>(T);
1414    if (isDragonFly)
1415      return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
1416    if (isOpenBSD)
1417      return new OpenBSDI386TargetInfo(T);
1418    if (isFreeBSD)
1419      return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
1420    if (isSolaris)
1421      return new SolarisTargetInfo<X86_32TargetInfo>(T);
1422    if (isWindows)
1423      return new WindowsX86_32TargetInfo(T);
1424    return new X86_32TargetInfo(T);
1425  }
1426
1427  return NULL;
1428}
1429