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