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