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