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