Targets.cpp revision bd00eb855a6080ff39b720d33bbb2db7ac08f58c
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 'Q': // Any register accessible as [r]h: a, b, c, and d.
441  case 'Z': // 32-bit integer constant for use with zero-extending x86_64
442            // instructions.
443  case 'N': // unsigned 8-bit integer constant for use with in and out
444            // instructions.
445    info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
446    return true;
447  }
448}
449
450std::string
451X86TargetInfo::convertConstraint(const char Constraint) const {
452  switch (Constraint) {
453  case 'a': return std::string("{ax}");
454  case 'b': return std::string("{bx}");
455  case 'c': return std::string("{cx}");
456  case 'd': return std::string("{dx}");
457  case 'S': return std::string("{si}");
458  case 'D': return std::string("{di}");
459  case 't': // top of floating point stack.
460    return std::string("{st}");
461  case 'u': // second from top of floating point stack.
462    return std::string("{st(1)}"); // second from top of floating point stack.
463  default:
464    return std::string(1, Constraint);
465  }
466}
467} // end anonymous namespace
468
469namespace {
470// X86-32 generic target
471class X86_32TargetInfo : public X86TargetInfo {
472public:
473  X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
474    DoubleAlign = LongLongAlign = 32;
475    LongDoubleWidth = 96;
476    LongDoubleAlign = 32;
477    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
478                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
479                        "a0:0:64-f80:32:32";
480  }
481  virtual const char *getVAListDeclaration() const {
482    return "typedef char* __builtin_va_list;";
483  }
484  virtual void getTargetDefines(std::vector<char> &Defines) const {
485    getX86Defines(Defines, false);
486  }
487};
488} // end anonymous namespace
489
490namespace {
491// x86-32 Darwin (OS X) target
492class DarwinI386TargetInfo : public X86_32TargetInfo {
493public:
494  DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
495    LongDoubleWidth = 128;
496    LongDoubleAlign = 128;
497    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
498                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
499                        "a0:0:64-f80:128:128";
500  }
501  virtual void getTargetDefines(std::vector<char> &Defines) const {
502    X86_32TargetInfo::getTargetDefines(Defines);
503    getDarwinDefines(Defines, getTargetTriple());
504  }
505  virtual bool useNeXTRuntimeAsDefault() const { return true; }
506};
507} // end anonymous namespace
508
509namespace {
510// x86-32 DragonFly target
511class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
512public:
513  DragonFlyX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
514  }
515  virtual void getTargetDefines(std::vector<char> &Defines) const {
516    X86_32TargetInfo::getTargetDefines(Defines);
517    getDragonFlyDefines(Defines);
518  }
519};
520} // end anonymous namespace
521
522namespace {
523// x86-32 Linux target
524class LinuxX86_32TargetInfo : public X86_32TargetInfo {
525public:
526  LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
527    UserLabelPrefix = "";
528  }
529  virtual void getTargetDefines(std::vector<char> &Defines) const {
530    X86_32TargetInfo::getTargetDefines(Defines);
531    getLinuxDefines(Defines);
532  }
533};
534} // end anonymous namespace
535
536namespace {
537// x86-32 Windows target
538class WindowsX86_32TargetInfo : public X86_32TargetInfo {
539public:
540  WindowsX86_32TargetInfo(const std::string& triple)
541    : X86_32TargetInfo(triple) {
542    // FIXME: Fix wchar_t.
543    // FIXME: We should probably enable -fms-extensions by default for
544    // this target.
545  }
546  virtual void getTargetDefines(std::vector<char> &Defines) const {
547    X86_32TargetInfo::getTargetDefines(Defines);
548    // This list is based off of the the list of things MingW defines
549    Define(Defines, "__WIN32__");
550    Define(Defines, "__WIN32");
551    Define(Defines, "_WIN32");
552    Define(Defines, "WIN32");
553    Define(Defines, "__WINNT__");
554    Define(Defines, "__WINNT");
555    Define(Defines, "WINNT");
556    Define(Defines, "_X86_");
557    Define(Defines, "__MSVCRT__");
558  }
559};
560} // end anonymous namespace
561
562namespace {
563// x86-64 generic target
564class X86_64TargetInfo : public X86TargetInfo {
565public:
566  X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
567    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
568    LongDoubleWidth = 128;
569    LongDoubleAlign = 128;
570    DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
571                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
572                        "a0:0:64-f80:128:128";
573  }
574  virtual const char *getVAListDeclaration() const {
575    return "typedef struct __va_list_tag {"
576           "  unsigned gp_offset;"
577           "  unsigned fp_offset;"
578           "  void* overflow_arg_area;"
579           "  void* reg_save_area;"
580           "} __builtin_va_list[1];";
581  }
582  virtual void getTargetDefines(std::vector<char> &Defines) const {
583    getX86Defines(Defines, true);
584  }
585};
586} // end anonymous namespace
587
588namespace {
589// x86-64 Linux target
590class LinuxX86_64TargetInfo : public X86_64TargetInfo {
591public:
592  LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
593    UserLabelPrefix = "";
594  }
595  virtual void getTargetDefines(std::vector<char> &Defines) const {
596    X86_64TargetInfo::getTargetDefines(Defines);
597    getLinuxDefines(Defines);
598  }
599};
600} // end anonymous namespace
601
602namespace {
603// x86-64 Darwin (OS X) target
604class DarwinX86_64TargetInfo : public X86_64TargetInfo {
605public:
606  DarwinX86_64TargetInfo(const std::string& triple) :
607    X86_64TargetInfo(triple) {}
608
609  virtual void getTargetDefines(std::vector<char> &Defines) const {
610    X86_64TargetInfo::getTargetDefines(Defines);
611    getDarwinDefines(Defines, getTargetTriple());
612  }
613
614  virtual bool useNeXTRuntimeAsDefault() const { return true; }
615};
616} // end anonymous namespace.
617
618namespace {
619class ARMTargetInfo : public TargetInfo {
620public:
621  ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
622    // FIXME: Are the defaults correct for ARM?
623    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
624                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
625  }
626  virtual void getTargetDefines(std::vector<char> &Defines) const {
627    getARMDefines(Defines);
628  }
629  virtual void getTargetBuiltins(const Builtin::Info *&Records,
630                                 unsigned &NumRecords) const {
631    // FIXME: Implement.
632    Records = 0;
633    NumRecords = 0;
634  }
635  virtual const char *getVAListDeclaration() const {
636    return "typedef char* __builtin_va_list;";
637  }
638  virtual const char *getTargetPrefix() const {
639    return "arm";
640  }
641  virtual void getGCCRegNames(const char * const *&Names,
642                              unsigned &NumNames) const {
643    // FIXME: Implement.
644    Names = 0;
645    NumNames = 0;
646  }
647  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
648                                unsigned &NumAliases) const {
649    // FIXME: Implement.
650    Aliases = 0;
651    NumAliases = 0;
652  }
653  virtual bool validateAsmConstraint(char c,
654                                     TargetInfo::ConstraintInfo &info) const {
655    // FIXME: Check if this is complete
656    switch (c) {
657    default:
658    case 'l': // r0-r7
659    case 'h': // r8-r15
660    case 'w': // VFP Floating point register single precision
661    case 'P': // VFP Floating point register double precision
662      info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
663      return true;
664    }
665    return false;
666  }
667  virtual const char *getClobbers() const {
668    // FIXME: Is this really right?
669    return "";
670  }
671};
672} // end anonymous namespace.
673
674
675namespace {
676class DarwinARMTargetInfo : public ARMTargetInfo {
677public:
678  DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
679
680  virtual void getTargetDefines(std::vector<char> &Defines) const {
681    ARMTargetInfo::getTargetDefines(Defines);
682    getDarwinDefines(Defines, getTargetTriple());
683  }
684};
685} // end anonymous namespace.
686
687namespace {
688class SparcV8TargetInfo : public TargetInfo {
689public:
690  SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
691    // FIXME: Support Sparc quad-precision long double?
692    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
693                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
694  }
695  virtual void getTargetDefines(std::vector<char> &Defines) const {
696    // FIXME: This is missing a lot of important defines; some of the
697    // missing stuff is likely to break system headers.
698    Define(Defines, "__sparc");
699    Define(Defines, "__sparc__");
700    Define(Defines, "__sparcv8");
701  }
702  virtual void getTargetBuiltins(const Builtin::Info *&Records,
703                                 unsigned &NumRecords) const {
704    // FIXME: Implement!
705  }
706  virtual const char *getVAListDeclaration() const {
707    return "typedef void* __builtin_va_list;";
708  }
709  virtual const char *getTargetPrefix() const {
710    return "sparc";
711  }
712  virtual void getGCCRegNames(const char * const *&Names,
713                              unsigned &NumNames) const {
714    // FIXME: Implement!
715    Names = 0;
716    NumNames = 0;
717  }
718  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
719                                unsigned &NumAliases) const {
720    // FIXME: Implement!
721    Aliases = 0;
722    NumAliases = 0;
723  }
724  virtual bool validateAsmConstraint(char c,
725                                     TargetInfo::ConstraintInfo &info) const {
726    // FIXME: Implement!
727    return false;
728  }
729  virtual const char *getClobbers() const {
730    // FIXME: Implement!
731    return "";
732  }
733};
734
735} // end anonymous namespace.
736
737namespace {
738class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
739public:
740  SolarisSparcV8TargetInfo(const std::string& triple) :
741    SparcV8TargetInfo(triple) {}
742
743  virtual void getTargetDefines(std::vector<char> &Defines) const {
744    SparcV8TargetInfo::getTargetDefines(Defines);
745    getSolarisDefines(Defines);
746  }
747};
748} // end anonymous namespace.
749
750namespace {
751  class PIC16TargetInfo : public TargetInfo{
752  public:
753    PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
754      // FIXME: Is IntAlign really supposed to be 16?  There seems
755      // little point on a platform with 8-bit loads.
756      IntWidth = IntAlign = LongAlign = LongLongAlign = PointerWidth = 16;
757      LongWidth = 16;
758      PointerAlign = 8;
759      DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
760    }
761    virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
762    virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
763    virtual void getTargetDefines(std::vector<char> &Defines) const {
764      Define(Defines, "__pic16");
765    }
766    virtual void getTargetBuiltins(const Builtin::Info *&Records,
767                                   unsigned &NumRecords) const {}
768    virtual const char *getVAListDeclaration() const { return "";}
769    virtual const char *getClobbers() const {return "";}
770    virtual const char *getTargetPrefix() const {return "";}
771    virtual void getGCCRegNames(const char * const *&Names,
772                                unsigned &NumNames) const {}
773    virtual bool validateAsmConstraint(char c,
774                                       TargetInfo::ConstraintInfo &info) const {
775      return true;
776    }
777    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
778                                  unsigned &NumAliases) const {}
779    virtual bool useGlobalsForAutomaticVariables() const {return true;}
780  };
781}
782
783//===----------------------------------------------------------------------===//
784// Driver code
785//===----------------------------------------------------------------------===//
786
787static inline bool IsX86(const std::string& TT) {
788  return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
789          TT[4] == '-' && TT[1] - '3' < 6);
790}
791
792/// CreateTargetInfo - Return the target info object for the specified target
793/// triple.
794TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
795  // OS detection; this isn't really anywhere near complete.
796  // Additions and corrections are welcome.
797  bool isDarwin = T.find("-darwin") != std::string::npos;
798  bool isDragonFly = T.find("-dragonfly") != std::string::npos;
799  bool isSolaris = T.find("-solaris") != std::string::npos;
800  bool isLinux = T.find("-linux") != std::string::npos;
801  bool isWindows = T.find("-windows") != std::string::npos ||
802                   T.find("-win32") != std::string::npos ||
803                   T.find("-mingw") != std::string::npos;
804
805  if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
806    if (isDarwin)
807      return new DarwinPPCTargetInfo(T);
808    return new PPC32TargetInfo(T);
809  }
810
811  if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
812    if (isDarwin)
813      return new DarwinPPC64TargetInfo(T);
814    return new PPC64TargetInfo(T);
815  }
816
817  if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
818    if (isDarwin)
819      return new DarwinARMTargetInfo(T);
820    return new ARMTargetInfo(T);
821  }
822
823  if (T.find("sparc-") == 0) {
824    if (isSolaris)
825      return new SolarisSparcV8TargetInfo(T);
826    return new SparcV8TargetInfo(T);
827  }
828
829  if (T.find("x86_64-") == 0) {
830    if (isDarwin)
831      return new DarwinX86_64TargetInfo(T);
832    if (isLinux)
833      return new LinuxX86_64TargetInfo(T);
834    return new X86_64TargetInfo(T);
835  }
836
837  if (T.find("pic16-") == 0)
838    return new PIC16TargetInfo(T);
839
840  if (IsX86(T)) {
841    if (isDarwin)
842      return new DarwinI386TargetInfo(T);
843    if (isLinux)
844      return new LinuxX86_32TargetInfo(T);
845    if (isDragonFly)
846      return new DragonFlyX86_32TargetInfo(T);
847    if (isWindows)
848      return new WindowsX86_32TargetInfo(T);
849    return new X86_32TargetInfo(T);
850  }
851
852  return NULL;
853}
854
855