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