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