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