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