Targets.cpp revision fce0934560b0e3cc55e95e54883c0f540c98cdb6
1//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements construction of a TargetInfo object from a
11// target triple.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/AST/Builtins.h"
16#include "clang/AST/TargetBuiltins.h"
17#include "clang/Basic/TargetInfo.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/APFloat.h"
20using namespace clang;
21
22//===----------------------------------------------------------------------===//
23//  Common code shared among targets.
24//===----------------------------------------------------------------------===//
25
26static void Define(std::vector<char> &Buf, const char *Macro,
27                   const char *Val = "1") {
28  const char *Def = "#define ";
29  Buf.insert(Buf.end(), Def, Def+strlen(Def));
30  Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
31  Buf.push_back(' ');
32  Buf.insert(Buf.end(), Val, Val+strlen(Val));
33  Buf.push_back('\n');
34}
35
36//===----------------------------------------------------------------------===//
37// Defines specific to certain operating systems.
38//===----------------------------------------------------------------------===//
39
40static void getSolarisDefines(std::vector<char> &Defs) {
41  Define(Defs, "__SUN__");
42  Define(Defs, "__SOLARIS__");
43}
44
45static void getDragonFlyDefines(std::vector<char> &Defs) {
46  // DragonFly defines; list based off of gcc output
47  Define(Defs, "__DragonFly__");
48  Define(Defs, "__DragonFly_cc_version", "100001");
49  Define(Defs, "__ELF__");
50  Define(Defs, "__KPRINTF_ATTRIBUTE__");
51  Define(Defs, "__tune_i386__");
52  Define(Defs, "unix");
53  Define(Defs, "__unix");
54  Define(Defs, "__unix__");
55}
56
57static void getLinuxDefines(std::vector<char> &Defs) {
58  // Linux defines; list based off of gcc output
59  Define(Defs, "__unix__");
60  Define(Defs, "__unix");
61  Define(Defs, "unix");
62  Define(Defs, "__linux__");
63  Define(Defs, "__linux");
64  Define(Defs, "linux");
65  Define(Defs, "__gnu_linux__");
66}
67
68static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
69  Define(Defs, "__APPLE__");
70  Define(Defs, "__MACH__");
71
72  // Figure out which "darwin number" the target triple is.  "darwin9" -> 10.5.
73  const char *Darwin = strstr(Triple, "-darwin");
74  if (Darwin) {
75    char DarwinStr[] = "1000";
76    Darwin += strlen("-darwin");
77    if (Darwin[0] >= '0' && Darwin[0] <= '9') {
78      unsigned DarwinNo = Darwin[0]-'0';
79      ++Darwin;
80
81      // Handle "darwin11".
82      if (DarwinNo == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
83        DarwinNo = 10+Darwin[0]-'0';
84        ++Darwin;
85      }
86
87      if (DarwinNo >= 4 && DarwinNo <= 13) { // 10.0-10.9
88        // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
89        DarwinStr[2] = '0' + DarwinNo-4;
90      }
91
92      // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
93      if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' &&
94          Darwin[2] == '\0')
95        DarwinStr[3] = Darwin[1];
96
97    }
98    Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
99  }
100}
101
102//===----------------------------------------------------------------------===//
103// Defines specific to certain architectures.
104//===----------------------------------------------------------------------===//
105
106/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
107/// not tied to a specific subtarget.
108static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
109  // Target identification.
110  Define(Defs, "__ppc__");
111  Define(Defs, "_ARCH_PPC");
112  Define(Defs, "__POWERPC__");
113  if (is64Bit) {
114    Define(Defs, "_ARCH_PPC64");
115    Define(Defs, "_LP64");
116    Define(Defs, "__LP64__");
117    Define(Defs, "__ppc64__");
118  } else {
119    Define(Defs, "__ppc__");
120  }
121
122  // Target properties.
123  Define(Defs, "_BIG_ENDIAN");
124  Define(Defs, "__BIG_ENDIAN__");
125
126  // Subtarget options.
127  Define(Defs, "__NATURAL_ALIGNMENT__");
128  Define(Defs, "__REGISTER_PREFIX__", "");
129
130  // FIXME: Should be controlled by command line option.
131  Define(Defs, "__LONG_DOUBLE_128__");
132}
133
134/// getX86Defines - Return a set of the X86-specific #defines that are
135/// not tied to a specific subtarget.
136static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
137  // Target identification.
138  if (is64Bit) {
139    Define(Defs, "_LP64");
140    Define(Defs, "__LP64__");
141    Define(Defs, "__amd64__");
142    Define(Defs, "__amd64");
143    Define(Defs, "__x86_64");
144    Define(Defs, "__x86_64__");
145  } else {
146    Define(Defs, "__i386__");
147    Define(Defs, "__i386");
148    Define(Defs, "i386");
149  }
150
151  // Target properties.
152  Define(Defs, "__LITTLE_ENDIAN__");
153
154  // Subtarget options.
155  Define(Defs, "__nocona");
156  Define(Defs, "__nocona__");
157  Define(Defs, "__tune_nocona__");
158  Define(Defs, "__SSE2_MATH__");
159  Define(Defs, "__SSE2__");
160  Define(Defs, "__SSE_MATH__");
161  Define(Defs, "__SSE__");
162  Define(Defs, "__MMX__");
163  Define(Defs, "__REGISTER_PREFIX__", "");
164}
165
166/// getARMDefines - Return a set of the ARM-specific #defines that are
167/// not tied to a specific subtarget.
168static void getARMDefines(std::vector<char> &Defs) {
169  // Target identification.
170  Define(Defs, "__arm");
171  Define(Defs, "__arm__");
172
173  // Target properties.
174  Define(Defs, "__LITTLE_ENDIAN__");
175
176  // Subtarget options.  [hard coded to v6 for now]
177  Define(Defs, "__ARM_ARCH_6K__");
178  Define(Defs, "__ARMEL__");
179  Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
180}
181
182//===----------------------------------------------------------------------===//
183// Specific target implementations.
184//===----------------------------------------------------------------------===//
185
186namespace {
187// PPC abstract base class
188class PPCTargetInfo : public TargetInfo {
189  static const Builtin::Info BuiltinInfo[];
190  static const char * const GCCRegNames[];
191  static const TargetInfo::GCCRegAlias GCCRegAliases[];
192
193public:
194  PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
195    CharIsSigned = false;
196  }
197  virtual void getTargetBuiltins(const Builtin::Info *&Records,
198                                 unsigned &NumRecords) const {
199    Records = BuiltinInfo;
200    NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
201  }
202  virtual const char *getVAListDeclaration() const {
203    return "typedef struct __va_list_tag {"
204           "  unsigned char gpr;"
205           "  unsigned char fpr;"
206           "  unsigned short reserved;"
207           "  void* overflow_arg_area;"
208           "  void* reg_save_area;"
209           "} __builtin_va_list[1];";
210  }
211  virtual const char *getTargetPrefix() const {
212    return "ppc";
213  }
214  virtual void getGCCRegNames(const char * const *&Names,
215                              unsigned &NumNames) const;
216  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
217                                unsigned &NumAliases) const;
218  virtual bool validateAsmConstraint(char c,
219                                     TargetInfo::ConstraintInfo &info) const {
220    switch (c) {
221    default: return false;
222    case 'O': // Zero
223      return true;
224    case 'b': // Base register
225    case 'f': // Floating point register
226      info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
227      return true;
228    }
229  }
230  virtual const char *getClobbers() const {
231    return "";
232  }
233};
234
235const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
236#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
237#include "clang/AST/PPCBuiltins.def"
238};
239
240const char * const PPCTargetInfo::GCCRegNames[] = {
241  "0", "1", "2", "3", "4", "5", "6", "7",
242  "8", "9", "10", "11", "12", "13", "14", "15",
243  "16", "17", "18", "19", "20", "21", "22", "23",
244  "24", "25", "26", "27", "28", "29", "30", "31",
245  "0", "1", "2", "3", "4", "5", "6", "7",
246  "8", "9", "10", "11", "12", "13", "14", "15",
247  "16", "17", "18", "19", "20", "21", "22", "23",
248  "24", "25", "26", "27", "28", "29", "30", "31",
249  "mq", "lr", "ctr", "ap",
250  "0", "1", "2", "3", "4", "5", "6", "7",
251  "xer",
252  "0", "1", "2", "3", "4", "5", "6", "7",
253  "8", "9", "10", "11", "12", "13", "14", "15",
254  "16", "17", "18", "19", "20", "21", "22", "23",
255  "24", "25", "26", "27", "28", "29", "30", "31",
256  "vrsave", "vscr",
257  "spe_acc", "spefscr",
258  "sfp"
259};
260
261void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
262                                   unsigned &NumNames) const {
263  Names = GCCRegNames;
264  NumNames = llvm::array_lengthof(GCCRegNames);
265}
266
267const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
268  // While some of these aliases do map to different registers
269  // they still share the same register name.
270  { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
271  { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
272  { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
273  { { "cr3", "fr3", "r3", "v3"}, "3" },
274  { { "cr4", "fr4", "r4", "v4"}, "4" },
275  { { "cr5", "fr5", "r5", "v5"}, "5" },
276  { { "cr6", "fr6", "r6", "v6"}, "6" },
277  { { "cr7", "fr7", "r7", "v7"}, "7" },
278  { { "fr8", "r8", "v8"}, "8" },
279  { { "fr9", "r9", "v9"}, "9" },
280  { { "fr10", "r10", "v10"}, "10" },
281  { { "fr11", "r11", "v11"}, "11" },
282  { { "fr12", "r12", "v12"}, "12" },
283  { { "fr13", "r13", "v13"}, "13" },
284  { { "fr14", "r14", "v14"}, "14" },
285  { { "fr15", "r15", "v15"}, "15" },
286  { { "fr16", "r16", "v16"}, "16" },
287  { { "fr17", "r17", "v17"}, "17" },
288  { { "fr18", "r18", "v18"}, "18" },
289  { { "fr19", "r19", "v19"}, "19" },
290  { { "fr20", "r20", "v20"}, "20" },
291  { { "fr21", "r21", "v21"}, "21" },
292  { { "fr22", "r22", "v22"}, "22" },
293  { { "fr23", "r23", "v23"}, "23" },
294  { { "fr24", "r24", "v24"}, "24" },
295  { { "fr25", "r25", "v25"}, "25" },
296  { { "fr26", "r26", "v26"}, "26" },
297  { { "fr27", "r27", "v27"}, "27" },
298  { { "fr28", "r28", "v28"}, "28" },
299  { { "fr29", "r29", "v29"}, "29" },
300  { { "fr30", "r30", "v30"}, "30" },
301  { { "fr31", "r31", "v31"}, "31" },
302};
303
304void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
305                                     unsigned &NumAliases) const {
306  Aliases = GCCRegAliases;
307  NumAliases = llvm::array_lengthof(GCCRegAliases);
308}
309} // end anonymous namespace.
310
311namespace {
312class PPC32TargetInfo : public PPCTargetInfo {
313public:
314  PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
315    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
316                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
317  }
318  virtual void getTargetDefines(std::vector<char> &Defines) const {
319    getPowerPCDefines(Defines, false);
320  }
321};
322} // end anonymous namespace.
323
324namespace {
325class PPC64TargetInfo : public PPCTargetInfo {
326public:
327  PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
328    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
329    DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
330                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
331  }
332  virtual void getTargetDefines(std::vector<char> &Defines) const {
333    getPowerPCDefines(Defines, true);
334  }
335};
336} // end anonymous namespace.
337
338namespace {
339class DarwinPPCTargetInfo : public PPC32TargetInfo {
340public:
341  DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
342  virtual void getTargetDefines(std::vector<char> &Defines) const {
343    PPC32TargetInfo::getTargetDefines(Defines);
344    getDarwinDefines(Defines, getTargetTriple());
345  }
346
347  virtual bool useNeXTRuntimeAsDefault() const { return true; }
348};
349} // end anonymous namespace.
350
351namespace {
352class DarwinPPC64TargetInfo : public PPC64TargetInfo {
353public:
354  DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
355  virtual void getTargetDefines(std::vector<char> &Defines) const {
356    PPC64TargetInfo::getTargetDefines(Defines);
357    getDarwinDefines(Defines, getTargetTriple());
358  }
359
360  virtual bool useNeXTRuntimeAsDefault() const { return true; }
361};
362} // end anonymous namespace.
363
364namespace {
365// Namespace for x86 abstract base class
366const Builtin::Info BuiltinInfo[] = {
367#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
368#include "clang/AST/X86Builtins.def"
369};
370
371const char *GCCRegNames[] = {
372  "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
373  "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
374  "argp", "flags", "fspr", "dirflag", "frame",
375  "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
376  "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
377  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
378  "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
379};
380
381const TargetInfo::GCCRegAlias GCCRegAliases[] = {
382  { { "al", "ah", "eax", "rax" }, "ax" },
383  { { "bl", "bh", "ebx", "rbx" }, "bx" },
384  { { "cl", "ch", "ecx", "rcx" }, "cx" },
385  { { "dl", "dh", "edx", "rdx" }, "dx" },
386  { { "esi", "rsi" }, "si" },
387  { { "edi", "rdi" }, "di" },
388  { { "esp", "rsp" }, "sp" },
389  { { "ebp", "rbp" }, "bp" },
390};
391
392// X86 target abstract base class; x86-32 and x86-64 are very close, so
393// most of the implementation can be shared.
394class X86TargetInfo : public TargetInfo {
395public:
396  X86TargetInfo(const std::string& triple) : TargetInfo(triple) {
397    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
398  }
399  virtual void getTargetBuiltins(const Builtin::Info *&Records,
400                                 unsigned &NumRecords) const {
401    Records = BuiltinInfo;
402    NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
403  }
404  virtual const char *getTargetPrefix() const {
405    return "x86";
406  }
407  virtual void getGCCRegNames(const char * const *&Names,
408                              unsigned &NumNames) const {
409    Names = GCCRegNames;
410    NumNames = llvm::array_lengthof(GCCRegNames);
411  }
412  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
413                                unsigned &NumAliases) const {
414    Aliases = GCCRegAliases;
415    NumAliases = llvm::array_lengthof(GCCRegAliases);
416  }
417  virtual bool validateAsmConstraint(char c,
418                                     TargetInfo::ConstraintInfo &info) const;
419  virtual std::string convertConstraint(const char Constraint) const;
420  virtual const char *getClobbers() const {
421    return "~{dirflag},~{fpsr},~{flags}";
422  }
423};
424
425bool
426X86TargetInfo::validateAsmConstraint(char c,
427                                     TargetInfo::ConstraintInfo &info) const {
428  switch (c) {
429  default: return false;
430  case 'a': // eax.
431  case 'b': // ebx.
432  case 'c': // ecx.
433  case 'd': // edx.
434  case 'S': // esi.
435  case 'D': // edi.
436  case 'A': // edx:eax.
437  case 't': // top of floating point stack.
438  case 'u': // second from top of floating point stack.
439  case 'q': // Any register accessible as [r]l: a, b, c, and d.
440  case 'y': // Any MMX register.
441  case 'Q': // Any register accessible as [r]h: a, b, c, and d.
442  case 'Z': // 32-bit integer constant for use with zero-extending x86_64
443            // instructions.
444  case 'N': // unsigned 8-bit integer constant for use with in and out
445            // instructions.
446    info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
447    return true;
448  }
449}
450
451std::string
452X86TargetInfo::convertConstraint(const char Constraint) const {
453  switch (Constraint) {
454  case 'a': return std::string("{ax}");
455  case 'b': return std::string("{bx}");
456  case 'c': return std::string("{cx}");
457  case 'd': return std::string("{dx}");
458  case 'S': return std::string("{si}");
459  case 'D': return std::string("{di}");
460  case 't': // top of floating point stack.
461    return std::string("{st}");
462  case 'u': // second from top of floating point stack.
463    return std::string("{st(1)}"); // second from top of floating point stack.
464  default:
465    return std::string(1, Constraint);
466  }
467}
468} // end anonymous namespace
469
470namespace {
471// X86-32 generic target
472class X86_32TargetInfo : public X86TargetInfo {
473public:
474  X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
475    DoubleAlign = LongLongAlign = 32;
476    LongDoubleWidth = 96;
477    LongDoubleAlign = 32;
478    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
479                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
480                        "a0:0:64-f80:32:32";
481  }
482  virtual const char *getVAListDeclaration() const {
483    return "typedef char* __builtin_va_list;";
484  }
485  virtual void getTargetDefines(std::vector<char> &Defines) const {
486    getX86Defines(Defines, false);
487  }
488};
489} // end anonymous namespace
490
491namespace {
492// x86-32 Darwin (OS X) target
493class DarwinI386TargetInfo : public X86_32TargetInfo {
494public:
495  DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
496    LongDoubleWidth = 128;
497    LongDoubleAlign = 128;
498    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
499                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
500                        "a0:0:64-f80:128:128";
501  }
502  virtual void getTargetDefines(std::vector<char> &Defines) const {
503    X86_32TargetInfo::getTargetDefines(Defines);
504    getDarwinDefines(Defines, getTargetTriple());
505  }
506  virtual bool useNeXTRuntimeAsDefault() const { return true; }
507};
508} // end anonymous namespace
509
510namespace {
511// x86-32 DragonFly target
512class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
513public:
514  DragonFlyX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
515  }
516  virtual void getTargetDefines(std::vector<char> &Defines) const {
517    X86_32TargetInfo::getTargetDefines(Defines);
518    getDragonFlyDefines(Defines);
519  }
520};
521} // end anonymous namespace
522
523namespace {
524// x86-32 Linux target
525class LinuxX86_32TargetInfo : public X86_32TargetInfo {
526public:
527  LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
528    UserLabelPrefix = "";
529  }
530  virtual void getTargetDefines(std::vector<char> &Defines) const {
531    X86_32TargetInfo::getTargetDefines(Defines);
532    getLinuxDefines(Defines);
533  }
534};
535} // end anonymous namespace
536
537namespace {
538// x86-32 Windows target
539class WindowsX86_32TargetInfo : public X86_32TargetInfo {
540public:
541  WindowsX86_32TargetInfo(const std::string& triple)
542    : X86_32TargetInfo(triple) {
543    // FIXME: Fix wchar_t.
544    // FIXME: We should probably enable -fms-extensions by default for
545    // this target.
546  }
547  virtual void getTargetDefines(std::vector<char> &Defines) const {
548    X86_32TargetInfo::getTargetDefines(Defines);
549    // This list is based off of the the list of things MingW defines
550    Define(Defines, "__WIN32__");
551    Define(Defines, "__WIN32");
552    Define(Defines, "_WIN32");
553    Define(Defines, "WIN32");
554    Define(Defines, "__WINNT__");
555    Define(Defines, "__WINNT");
556    Define(Defines, "WINNT");
557    Define(Defines, "_X86_");
558    Define(Defines, "__MSVCRT__");
559  }
560};
561} // end anonymous namespace
562
563namespace {
564// x86-64 generic target
565class X86_64TargetInfo : public X86TargetInfo {
566public:
567  X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
568    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
569    LongDoubleWidth = 128;
570    LongDoubleAlign = 128;
571    DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
572                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
573                        "a0:0:64-f80:128:128";
574  }
575  virtual const char *getVAListDeclaration() const {
576    return "typedef struct __va_list_tag {"
577           "  unsigned gp_offset;"
578           "  unsigned fp_offset;"
579           "  void* overflow_arg_area;"
580           "  void* reg_save_area;"
581           "} __builtin_va_list[1];";
582  }
583  virtual void getTargetDefines(std::vector<char> &Defines) const {
584    getX86Defines(Defines, true);
585  }
586};
587} // end anonymous namespace
588
589namespace {
590// x86-64 Linux target
591class LinuxX86_64TargetInfo : public X86_64TargetInfo {
592public:
593  LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
594    UserLabelPrefix = "";
595  }
596  virtual void getTargetDefines(std::vector<char> &Defines) const {
597    X86_64TargetInfo::getTargetDefines(Defines);
598    getLinuxDefines(Defines);
599  }
600};
601} // end anonymous namespace
602
603namespace {
604// x86-64 Darwin (OS X) target
605class DarwinX86_64TargetInfo : public X86_64TargetInfo {
606public:
607  DarwinX86_64TargetInfo(const std::string& triple) :
608    X86_64TargetInfo(triple) {}
609
610  virtual void getTargetDefines(std::vector<char> &Defines) const {
611    X86_64TargetInfo::getTargetDefines(Defines);
612    getDarwinDefines(Defines, getTargetTriple());
613  }
614
615  virtual bool useNeXTRuntimeAsDefault() const { return true; }
616};
617} // end anonymous namespace.
618
619namespace {
620class ARMTargetInfo : public TargetInfo {
621public:
622  ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
623    // FIXME: Are the defaults correct for ARM?
624    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
625                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
626  }
627  virtual void getTargetDefines(std::vector<char> &Defines) const {
628    getARMDefines(Defines);
629  }
630  virtual void getTargetBuiltins(const Builtin::Info *&Records,
631                                 unsigned &NumRecords) const {
632    // FIXME: Implement.
633    Records = 0;
634    NumRecords = 0;
635  }
636  virtual const char *getVAListDeclaration() const {
637    return "typedef char* __builtin_va_list;";
638  }
639  virtual const char *getTargetPrefix() const {
640    return "arm";
641  }
642  virtual void getGCCRegNames(const char * const *&Names,
643                              unsigned &NumNames) const {
644    // FIXME: Implement.
645    Names = 0;
646    NumNames = 0;
647  }
648  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
649                                unsigned &NumAliases) const {
650    // FIXME: Implement.
651    Aliases = 0;
652    NumAliases = 0;
653  }
654  virtual bool validateAsmConstraint(char c,
655                                     TargetInfo::ConstraintInfo &info) const {
656    // FIXME: Check if this is complete
657    switch (c) {
658    default:
659    case 'l': // r0-r7
660    case 'h': // r8-r15
661    case 'w': // VFP Floating point register single precision
662    case 'P': // VFP Floating point register double precision
663      info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
664      return true;
665    }
666    return false;
667  }
668  virtual const char *getClobbers() const {
669    // FIXME: Is this really right?
670    return "";
671  }
672};
673} // end anonymous namespace.
674
675
676namespace {
677class DarwinARMTargetInfo : public ARMTargetInfo {
678public:
679  DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
680
681  virtual void getTargetDefines(std::vector<char> &Defines) const {
682    ARMTargetInfo::getTargetDefines(Defines);
683    getDarwinDefines(Defines, getTargetTriple());
684  }
685};
686} // end anonymous namespace.
687
688namespace {
689class SparcV8TargetInfo : public TargetInfo {
690public:
691  SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
692    // FIXME: Support Sparc quad-precision long double?
693    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
694                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
695  }
696  virtual void getTargetDefines(std::vector<char> &Defines) const {
697    // FIXME: This is missing a lot of important defines; some of the
698    // missing stuff is likely to break system headers.
699    Define(Defines, "__sparc");
700    Define(Defines, "__sparc__");
701    Define(Defines, "__sparcv8");
702  }
703  virtual void getTargetBuiltins(const Builtin::Info *&Records,
704                                 unsigned &NumRecords) const {
705    // FIXME: Implement!
706  }
707  virtual const char *getVAListDeclaration() const {
708    return "typedef void* __builtin_va_list;";
709  }
710  virtual const char *getTargetPrefix() const {
711    return "sparc";
712  }
713  virtual void getGCCRegNames(const char * const *&Names,
714                              unsigned &NumNames) const {
715    // FIXME: Implement!
716    Names = 0;
717    NumNames = 0;
718  }
719  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
720                                unsigned &NumAliases) const {
721    // FIXME: Implement!
722    Aliases = 0;
723    NumAliases = 0;
724  }
725  virtual bool validateAsmConstraint(char c,
726                                     TargetInfo::ConstraintInfo &info) const {
727    // FIXME: Implement!
728    return false;
729  }
730  virtual const char *getClobbers() const {
731    // FIXME: Implement!
732    return "";
733  }
734};
735
736} // end anonymous namespace.
737
738namespace {
739class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
740public:
741  SolarisSparcV8TargetInfo(const std::string& triple) :
742    SparcV8TargetInfo(triple) {}
743
744  virtual void getTargetDefines(std::vector<char> &Defines) const {
745    SparcV8TargetInfo::getTargetDefines(Defines);
746    getSolarisDefines(Defines);
747  }
748};
749} // end anonymous namespace.
750
751namespace {
752  class PIC16TargetInfo : public TargetInfo{
753  public:
754    PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
755      // FIXME: Is IntAlign really supposed to be 16?  There seems
756      // little point on a platform with 8-bit loads.
757      IntWidth = IntAlign = LongAlign = LongLongAlign = PointerWidth = 16;
758      LongWidth = 16;
759      PointerAlign = 8;
760      DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
761    }
762    virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
763    virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
764    virtual void getTargetDefines(std::vector<char> &Defines) const {
765      Define(Defines, "__pic16");
766    }
767    virtual void getTargetBuiltins(const Builtin::Info *&Records,
768                                   unsigned &NumRecords) const {}
769    virtual const char *getVAListDeclaration() const { return "";}
770    virtual const char *getClobbers() const {return "";}
771    virtual const char *getTargetPrefix() const {return "";}
772    virtual void getGCCRegNames(const char * const *&Names,
773                                unsigned &NumNames) const {}
774    virtual bool validateAsmConstraint(char c,
775                                       TargetInfo::ConstraintInfo &info) const {
776      return true;
777    }
778    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
779                                  unsigned &NumAliases) const {}
780    virtual bool useGlobalsForAutomaticVariables() const {return true;}
781  };
782}
783
784//===----------------------------------------------------------------------===//
785// Driver code
786//===----------------------------------------------------------------------===//
787
788static inline bool IsX86(const std::string& TT) {
789  return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
790          TT[4] == '-' && TT[1] - '3' < 6);
791}
792
793/// CreateTargetInfo - Return the target info object for the specified target
794/// triple.
795TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
796  // OS detection; this isn't really anywhere near complete.
797  // Additions and corrections are welcome.
798  bool isDarwin = T.find("-darwin") != std::string::npos;
799  bool isDragonFly = T.find("-dragonfly") != std::string::npos;
800  bool isSolaris = T.find("-solaris") != std::string::npos;
801  bool isLinux = T.find("-linux") != std::string::npos;
802  bool isWindows = T.find("-windows") != std::string::npos ||
803                   T.find("-win32") != std::string::npos ||
804                   T.find("-mingw") != std::string::npos;
805
806  if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
807    if (isDarwin)
808      return new DarwinPPCTargetInfo(T);
809    return new PPC32TargetInfo(T);
810  }
811
812  if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
813    if (isDarwin)
814      return new DarwinPPC64TargetInfo(T);
815    return new PPC64TargetInfo(T);
816  }
817
818  if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
819    if (isDarwin)
820      return new DarwinARMTargetInfo(T);
821    return new ARMTargetInfo(T);
822  }
823
824  if (T.find("sparc-") == 0) {
825    if (isSolaris)
826      return new SolarisSparcV8TargetInfo(T);
827    return new SparcV8TargetInfo(T);
828  }
829
830  if (T.find("x86_64-") == 0) {
831    if (isDarwin)
832      return new DarwinX86_64TargetInfo(T);
833    if (isLinux)
834      return new LinuxX86_64TargetInfo(T);
835    return new X86_64TargetInfo(T);
836  }
837
838  if (T.find("pic16-") == 0)
839    return new PIC16TargetInfo(T);
840
841  if (IsX86(T)) {
842    if (isDarwin)
843      return new DarwinI386TargetInfo(T);
844    if (isLinux)
845      return new LinuxX86_32TargetInfo(T);
846    if (isDragonFly)
847      return new DragonFlyX86_32TargetInfo(T);
848    if (isWindows)
849      return new WindowsX86_32TargetInfo(T);
850    return new X86_32TargetInfo(T);
851  }
852
853  return NULL;
854}
855
856