Targets.cpp revision 89e887fd73dd87c1118e13ebddf11aed9e25b763
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/Basic/Builtins.h"
16#include "clang/Basic/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"
21#include "llvm/ADT/SmallString.h"
22using namespace clang;
23
24//===----------------------------------------------------------------------===//
25//  Common code shared among targets.
26//===----------------------------------------------------------------------===//
27
28static void Define(std::vector<char> &Buf, const char *Macro,
29                   const char *Val = "1") {
30  const char *Def = "#define ";
31  Buf.insert(Buf.end(), Def, Def+strlen(Def));
32  Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
33  Buf.push_back(' ');
34  Buf.insert(Buf.end(), Val, Val+strlen(Val));
35  Buf.push_back('\n');
36}
37
38/// DefineStd - Define a macro name and standard variants.  For example if
39/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
40/// when in GNU mode.
41static void DefineStd(std::vector<char> &Buf, const char *MacroName,
42                      const LangOptions &Opts) {
43  assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
44
45  // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
46  // in the user's namespace.
47  if (Opts.GNUMode)
48    Define(Buf, MacroName);
49
50  // Define __unix.
51  llvm::SmallString<20> TmpStr;
52  TmpStr = "__";
53  TmpStr += MacroName;
54  Define(Buf, TmpStr.c_str());
55
56  // Define __unix__.
57  TmpStr += "__";
58  Define(Buf, TmpStr.c_str());
59}
60
61//===----------------------------------------------------------------------===//
62// Defines specific to certain operating systems.
63//===----------------------------------------------------------------------===//
64namespace {
65template<typename TgtInfo>
66class OSTargetInfo : public TgtInfo {
67protected:
68  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
69                            std::vector<char> &Defines) const=0;
70public:
71  OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
72  virtual void getTargetDefines(const LangOptions &Opts,
73                                std::vector<char> &Defines) const {
74    TgtInfo::getTargetDefines(Opts, Defines);
75    getOSDefines(Opts, TgtInfo::getTargetTriple(), Defines);
76  }
77
78};
79}
80
81namespace {
82/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
83/// triple.  For example, if we have darwin8.5 return 8,5,0.  If any entry is
84/// not defined, return 0's.  Return true if we have -darwin in the string or
85/// false otherwise.
86static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min, unsigned &Revision) {
87  Maj = Min = Revision = 0;
88  const char *Darwin = strstr(Triple, "-darwin");
89  if (Darwin == 0) return false;
90
91  Darwin += strlen("-darwin");
92  if (Darwin[0] < '0' || Darwin[0] > '9')
93    return true;
94
95  Maj = Darwin[0]-'0';
96  ++Darwin;
97
98  // Handle "darwin11".
99  if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
100    Maj = Maj*10 + (Darwin[0] - '0');
101    ++Darwin;
102  }
103
104  // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
105  if (Darwin[0] != '.')
106    return true;
107
108  ++Darwin;
109  if (Darwin[0] < '0' || Darwin[0] > '9')
110    return true;
111
112  Min = Darwin[0]-'0';
113  ++Darwin;
114
115  // Handle 10.4.11 -> darwin8.11
116  if (Min == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
117    Min = Min*10 + (Darwin[0] - '0');
118    ++Darwin;
119  }
120
121  // Handle revision darwin8.9.1
122  if (Darwin[0] != '.')
123    return true;
124
125  ++Darwin;
126  if (Darwin[0] < '0' || Darwin[0] > '9')
127    return true;
128
129  Revision = Darwin[0]-'0';
130  ++Darwin;
131
132  if (Revision == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
133    Revision = Revision*10 + (Darwin[0] - '0');
134    ++Darwin;
135  }
136
137  return true;
138}
139
140static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) {
141  Define(Defs, "__APPLE_CC__", "5621");
142  Define(Defs, "__APPLE__");
143  Define(Defs, "__MACH__");
144  Define(Defs, "OBJC_NEW_PROPERTIES");
145
146  // __weak is always defined, for use in blocks and with objc pointers.
147  Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
148
149  // Darwin defines __strong even in C mode (just to nothing).
150  if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
151    Define(Defs, "__strong", "");
152  else
153    Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
154
155  if (Opts.Static)
156    Define(Defs, "__STATIC__");
157  else
158    Define(Defs, "__DYNAMIC__");
159}
160
161static void getDarwinOSXDefines(std::vector<char> &Defs, const char *Triple) {
162  // Figure out which "darwin number" the target triple is.  "darwin9" -> 10.5.
163  unsigned Maj, Min, Rev;
164  if (getDarwinNumber(Triple, Maj, Min, Rev)) {
165    char MacOSXStr[] = "1000";
166    if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
167      // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
168      MacOSXStr[2] = '0' + Maj-4;
169    }
170
171    // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
172    // Cap 10.4.11 -> darwin8.11 -> "1049"
173    MacOSXStr[3] = std::min(Min, 9U)+'0';
174    Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr);
175  }
176}
177
178static void getDarwinIPhoneOSDefines(std::vector<char> &Defs,
179                                     const char *Triple) {
180  // Figure out which "darwin number" the target triple is.  "darwin9" -> 10.5.
181  unsigned Maj, Min, Rev;
182  if (getDarwinNumber(Triple, Maj, Min, Rev)) {
183    // When targetting iPhone OS, interpret the minor version and
184    // revision as the iPhone OS version
185    char iPhoneOSStr[] = "10000";
186    if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0
187      // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc.
188      iPhoneOSStr[0] = '0' + Min;
189    }
190
191    // Handle minor version: 2.2 -> darwin9.2.2 -> 20200
192    iPhoneOSStr[2] = std::min(Rev, 9U)+'0';
193    Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
194           iPhoneOSStr);
195  }
196}
197
198/// GetDarwinLanguageOptions - Set the default language options for darwin.
199static void GetDarwinLanguageOptions(LangOptions &Opts,
200                                     const char *Triple) {
201  Opts.NeXTRuntime = true;
202
203  unsigned Maj, Min, Rev;
204  if (!getDarwinNumber(Triple, Maj, Min, Rev))
205    return;
206
207  // Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
208  if (Maj > 9) {
209    Opts.Blocks = 1;
210    Opts.setStackProtectorMode(LangOptions::SSPOn);
211  }
212
213  // Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and
214  // beyond.
215  if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
216    Opts.ObjCNonFragileABI = 1;
217}
218
219template<typename Target>
220class DarwinTargetInfo : public OSTargetInfo<Target> {
221protected:
222  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
223                    std::vector<char> &Defines) const {
224    getDarwinDefines(Defines, Opts);
225    getDarwinOSXDefines(Defines, Triple);
226  }
227
228  /// getDefaultLangOptions - Allow the target to specify default settings for
229  /// various language options.  These may be overridden by command line
230  /// options.
231  virtual void getDefaultLangOptions(LangOptions &Opts) {
232    TargetInfo::getDefaultLangOptions(Opts);
233    GetDarwinLanguageOptions(Opts, TargetInfo::getTargetTriple());
234  }
235public:
236  DarwinTargetInfo(const std::string& triple) :
237    OSTargetInfo<Target>(triple) {
238      this->TLSSupported = false;
239    }
240
241  virtual const char *getUnicodeStringSymbolPrefix() const {
242    return "__utf16_string_";
243  }
244
245  virtual const char *getUnicodeStringSection() const {
246    return "__TEXT,__ustring";
247  }
248};
249
250// DragonFlyBSD Target
251template<typename Target>
252class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
253protected:
254  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
255                    std::vector<char> &Defs) const {
256    // DragonFly defines; list based off of gcc output
257    Define(Defs, "__DragonFly__");
258    Define(Defs, "__DragonFly_cc_version", "100001");
259    Define(Defs, "__ELF__");
260    Define(Defs, "__KPRINTF_ATTRIBUTE__");
261    Define(Defs, "__tune_i386__");
262    DefineStd(Defs, "unix", Opts);
263  }
264public:
265  DragonFlyBSDTargetInfo(const std::string &triple)
266    : OSTargetInfo<Target>(triple) {}
267};
268
269// FreeBSD Target
270template<typename Target>
271class FreeBSDTargetInfo : public OSTargetInfo<Target> {
272protected:
273  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
274                    std::vector<char> &Defs) const {
275    // FreeBSD defines; list based off of gcc output
276
277    const char *FreeBSD = strstr(Triple, "-freebsd");
278    FreeBSD += strlen("-freebsd");
279    char release[] = "X";
280    release[0] = FreeBSD[0];
281    char version[] = "X00001";
282    version[0] = FreeBSD[0];
283
284    Define(Defs, "__FreeBSD__", release);
285    Define(Defs, "__FreeBSD_cc_version", version);
286    Define(Defs, "__KPRINTF_ATTRIBUTE__");
287    DefineStd(Defs, "unix", Opts);
288    Define(Defs, "__ELF__", "1");
289  }
290public:
291  FreeBSDTargetInfo(const std::string &triple)
292    : OSTargetInfo<Target>(triple) {
293      this->UserLabelPrefix = "";
294    }
295};
296
297// Linux target
298template<typename Target>
299class LinuxTargetInfo : public OSTargetInfo<Target> {
300protected:
301  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
302                           std::vector<char> &Defs) const {
303    // Linux defines; list based off of gcc output
304    DefineStd(Defs, "unix", Opts);
305    DefineStd(Defs, "linux", Opts);
306    Define(Defs, "__gnu_linux__");
307    Define(Defs, "__ELF__", "1");
308  }
309public:
310  LinuxTargetInfo(const std::string& triple)
311    : OSTargetInfo<Target>(triple) {
312    this->UserLabelPrefix = "";
313  }
314};
315
316// NetBSD Target
317template<typename Target>
318class NetBSDTargetInfo : public OSTargetInfo<Target> {
319protected:
320  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
321                    std::vector<char> &Defs) const {
322    // NetBSD defines; list based off of gcc output
323    Define(Defs, "__NetBSD__", "1");
324    Define(Defs, "__unix__", "1");
325    Define(Defs, "__ELF__", "1");
326  }
327public:
328  NetBSDTargetInfo(const std::string &triple)
329    : OSTargetInfo<Target>(triple) {
330      this->UserLabelPrefix = "";
331    }
332};
333
334// OpenBSD Target
335template<typename Target>
336class OpenBSDTargetInfo : public OSTargetInfo<Target> {
337protected:
338  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
339                    std::vector<char> &Defs) const {
340    // OpenBSD defines; list based off of gcc output
341
342    Define(Defs, "__OpenBSD__", "1");
343    DefineStd(Defs, "unix", Opts);
344    Define(Defs, "__ELF__", "1");
345  }
346public:
347  OpenBSDTargetInfo(const std::string &triple)
348    : OSTargetInfo<Target>(triple) {}
349};
350
351// Solaris target
352template<typename Target>
353class SolarisTargetInfo : public OSTargetInfo<Target> {
354protected:
355  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
356                                std::vector<char> &Defs) const {
357    DefineStd(Defs, "sun", Opts);
358    DefineStd(Defs, "unix", Opts);
359    Define(Defs, "__ELF__");
360    Define(Defs, "__svr4__");
361    Define(Defs, "__SVR4");
362  }
363public:
364  SolarisTargetInfo(const std::string& triple)
365    : OSTargetInfo<Target>(triple) {
366    this->UserLabelPrefix = "";
367    this->WCharType = this->SignedLong;
368    // FIXME: WIntType should be SignedLong
369  }
370};
371} // end anonymous namespace.
372
373/// GetWindowsLanguageOptions - Set the default language options for Windows.
374static void GetWindowsLanguageOptions(LangOptions &Opts,
375                                     const char *Triple) {
376  Opts.Microsoft = true;
377}
378
379//===----------------------------------------------------------------------===//
380// Specific target implementations.
381//===----------------------------------------------------------------------===//
382
383namespace {
384// PPC abstract base class
385class PPCTargetInfo : public TargetInfo {
386  static const Builtin::Info BuiltinInfo[];
387  static const char * const GCCRegNames[];
388  static const TargetInfo::GCCRegAlias GCCRegAliases[];
389
390public:
391  PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
392
393  virtual void getTargetBuiltins(const Builtin::Info *&Records,
394                                 unsigned &NumRecords) const {
395    Records = BuiltinInfo;
396    NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
397  }
398
399  virtual void getTargetDefines(const LangOptions &Opts,
400                                std::vector<char> &Defines) const;
401
402  virtual const char *getVAListDeclaration() const {
403    return "typedef char* __builtin_va_list;";
404    // This is the right definition for ABI/V4: System V.4/eabi.
405    /*return "typedef struct __va_list_tag {"
406           "  unsigned char gpr;"
407           "  unsigned char fpr;"
408           "  unsigned short reserved;"
409           "  void* overflow_arg_area;"
410           "  void* reg_save_area;"
411           "} __builtin_va_list[1];";*/
412  }
413  virtual const char *getTargetPrefix() const {
414    return "ppc";
415  }
416  virtual void getGCCRegNames(const char * const *&Names,
417                              unsigned &NumNames) const;
418  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
419                                unsigned &NumAliases) const;
420  virtual bool validateAsmConstraint(const char *&Name,
421                                     TargetInfo::ConstraintInfo &Info) const {
422    switch (*Name) {
423    default: return false;
424    case 'O': // Zero
425      return true;
426    case 'b': // Base register
427    case 'f': // Floating point register
428      Info.setAllowsRegister();
429      return true;
430    }
431  }
432  virtual void getDefaultLangOptions(LangOptions &Opts) {
433    TargetInfo::getDefaultLangOptions(Opts);
434    Opts.CharIsSigned = false;
435  }
436  virtual const char *getClobbers() const {
437    return "";
438  }
439};
440
441const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
442#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
443#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
444#include "clang/Basic/BuiltinsPPC.def"
445};
446
447
448/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
449/// #defines that are not tied to a specific subtarget.
450void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
451                                     std::vector<char> &Defs) const {
452  // Target identification.
453  Define(Defs, "__ppc__");
454  Define(Defs, "_ARCH_PPC");
455  Define(Defs, "__POWERPC__");
456  if (PointerWidth == 64) {
457    Define(Defs, "_ARCH_PPC64");
458    Define(Defs, "_LP64");
459    Define(Defs, "__LP64__");
460    Define(Defs, "__ppc64__");
461  } else {
462    Define(Defs, "__ppc__");
463  }
464
465  // Target properties.
466  Define(Defs, "_BIG_ENDIAN");
467  Define(Defs, "__BIG_ENDIAN__");
468
469  // Subtarget options.
470  Define(Defs, "__NATURAL_ALIGNMENT__");
471  Define(Defs, "__REGISTER_PREFIX__", "");
472
473  // FIXME: Should be controlled by command line option.
474  Define(Defs, "__LONG_DOUBLE_128__");
475}
476
477
478const char * const PPCTargetInfo::GCCRegNames[] = {
479  "0", "1", "2", "3", "4", "5", "6", "7",
480  "8", "9", "10", "11", "12", "13", "14", "15",
481  "16", "17", "18", "19", "20", "21", "22", "23",
482  "24", "25", "26", "27", "28", "29", "30", "31",
483  "0", "1", "2", "3", "4", "5", "6", "7",
484  "8", "9", "10", "11", "12", "13", "14", "15",
485  "16", "17", "18", "19", "20", "21", "22", "23",
486  "24", "25", "26", "27", "28", "29", "30", "31",
487  "mq", "lr", "ctr", "ap",
488  "0", "1", "2", "3", "4", "5", "6", "7",
489  "xer",
490  "0", "1", "2", "3", "4", "5", "6", "7",
491  "8", "9", "10", "11", "12", "13", "14", "15",
492  "16", "17", "18", "19", "20", "21", "22", "23",
493  "24", "25", "26", "27", "28", "29", "30", "31",
494  "vrsave", "vscr",
495  "spe_acc", "spefscr",
496  "sfp"
497};
498
499void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
500                                   unsigned &NumNames) const {
501  Names = GCCRegNames;
502  NumNames = llvm::array_lengthof(GCCRegNames);
503}
504
505const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
506  // While some of these aliases do map to different registers
507  // they still share the same register name.
508  { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
509  { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
510  { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
511  { { "cr3", "fr3", "r3", "v3"}, "3" },
512  { { "cr4", "fr4", "r4", "v4"}, "4" },
513  { { "cr5", "fr5", "r5", "v5"}, "5" },
514  { { "cr6", "fr6", "r6", "v6"}, "6" },
515  { { "cr7", "fr7", "r7", "v7"}, "7" },
516  { { "fr8", "r8", "v8"}, "8" },
517  { { "fr9", "r9", "v9"}, "9" },
518  { { "fr10", "r10", "v10"}, "10" },
519  { { "fr11", "r11", "v11"}, "11" },
520  { { "fr12", "r12", "v12"}, "12" },
521  { { "fr13", "r13", "v13"}, "13" },
522  { { "fr14", "r14", "v14"}, "14" },
523  { { "fr15", "r15", "v15"}, "15" },
524  { { "fr16", "r16", "v16"}, "16" },
525  { { "fr17", "r17", "v17"}, "17" },
526  { { "fr18", "r18", "v18"}, "18" },
527  { { "fr19", "r19", "v19"}, "19" },
528  { { "fr20", "r20", "v20"}, "20" },
529  { { "fr21", "r21", "v21"}, "21" },
530  { { "fr22", "r22", "v22"}, "22" },
531  { { "fr23", "r23", "v23"}, "23" },
532  { { "fr24", "r24", "v24"}, "24" },
533  { { "fr25", "r25", "v25"}, "25" },
534  { { "fr26", "r26", "v26"}, "26" },
535  { { "fr27", "r27", "v27"}, "27" },
536  { { "fr28", "r28", "v28"}, "28" },
537  { { "fr29", "r29", "v29"}, "29" },
538  { { "fr30", "r30", "v30"}, "30" },
539  { { "fr31", "r31", "v31"}, "31" },
540};
541
542void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
543                                     unsigned &NumAliases) const {
544  Aliases = GCCRegAliases;
545  NumAliases = llvm::array_lengthof(GCCRegAliases);
546}
547} // end anonymous namespace.
548
549namespace {
550class PPC32TargetInfo : public PPCTargetInfo {
551public:
552  PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
553    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
554                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
555  }
556};
557} // end anonymous namespace.
558
559namespace {
560class PPC64TargetInfo : public PPCTargetInfo {
561public:
562  PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
563    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
564    IntMaxType = SignedLong;
565    UIntMaxType = UnsignedLong;
566    Int64Type = SignedLong;
567    DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
568                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
569  }
570};
571} // end anonymous namespace.
572
573namespace {
574// Namespace for x86 abstract base class
575const Builtin::Info BuiltinInfo[] = {
576#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
577#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
578#include "clang/Basic/BuiltinsX86.def"
579};
580
581const char *GCCRegNames[] = {
582  "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
583  "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
584  "argp", "flags", "fspr", "dirflag", "frame",
585  "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
586  "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
587  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
588  "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
589};
590
591const TargetInfo::GCCRegAlias GCCRegAliases[] = {
592  { { "al", "ah", "eax", "rax" }, "ax" },
593  { { "bl", "bh", "ebx", "rbx" }, "bx" },
594  { { "cl", "ch", "ecx", "rcx" }, "cx" },
595  { { "dl", "dh", "edx", "rdx" }, "dx" },
596  { { "esi", "rsi" }, "si" },
597  { { "edi", "rdi" }, "di" },
598  { { "esp", "rsp" }, "sp" },
599  { { "ebp", "rbp" }, "bp" },
600};
601
602// X86 target abstract base class; x86-32 and x86-64 are very close, so
603// most of the implementation can be shared.
604class X86TargetInfo : public TargetInfo {
605  enum X86SSEEnum {
606    NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
607  } SSELevel;
608public:
609  X86TargetInfo(const std::string& triple)
610    : TargetInfo(triple), SSELevel(NoMMXSSE) {
611    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
612  }
613  virtual void getTargetBuiltins(const Builtin::Info *&Records,
614                                 unsigned &NumRecords) const {
615    Records = BuiltinInfo;
616    NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
617  }
618  virtual const char *getTargetPrefix() const {
619    return "x86";
620  }
621  virtual void getGCCRegNames(const char * const *&Names,
622                              unsigned &NumNames) const {
623    Names = GCCRegNames;
624    NumNames = llvm::array_lengthof(GCCRegNames);
625  }
626  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
627                                unsigned &NumAliases) const {
628    Aliases = GCCRegAliases;
629    NumAliases = llvm::array_lengthof(GCCRegAliases);
630  }
631  virtual bool validateAsmConstraint(const char *&Name,
632                                     TargetInfo::ConstraintInfo &info) const;
633  virtual std::string convertConstraint(const char Constraint) const;
634  virtual const char *getClobbers() const {
635    return "~{dirflag},~{fpsr},~{flags}";
636  }
637  virtual void getTargetDefines(const LangOptions &Opts,
638                                std::vector<char> &Defines) const;
639  virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
640                                 const std::string &Name,
641                                 bool Enabled) const;
642  virtual void getDefaultFeatures(const std::string &CPU,
643                                  llvm::StringMap<bool> &Features) const;
644  virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
645};
646
647void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
648                                       llvm::StringMap<bool> &Features) const {
649  // FIXME: This should not be here.
650  Features["3dnow"] = false;
651  Features["3dnowa"] = false;
652  Features["mmx"] = false;
653  Features["sse"] = false;
654  Features["sse2"] = false;
655  Features["sse3"] = false;
656  Features["ssse3"] = false;
657  Features["sse41"] = false;
658  Features["sse42"] = false;
659
660  // LLVM does not currently recognize this.
661  // Features["sse4a"] = false;
662
663  // FIXME: This *really* should not be here.
664
665  // X86_64 always has SSE2.
666  if (PointerWidth == 64)
667    Features["sse2"] = Features["sse"] = Features["mmx"] = true;
668
669  if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
670      CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
671    ;
672  else if (CPU == "pentium-mmx" || CPU == "pentium2")
673    setFeatureEnabled(Features, "mmx", true);
674  else if (CPU == "pentium3")
675    setFeatureEnabled(Features, "sse", true);
676  else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
677    setFeatureEnabled(Features, "sse2", true);
678  else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
679    setFeatureEnabled(Features, "sse3", true);
680  else if (CPU == "core2")
681    setFeatureEnabled(Features, "ssse3", true);
682  else if (CPU == "penryn") {
683    setFeatureEnabled(Features, "sse4", true);
684    Features["sse42"] = false;
685  } else if (CPU == "atom")
686    setFeatureEnabled(Features, "sse3", true);
687  else if (CPU == "corei7")
688    setFeatureEnabled(Features, "sse4", true);
689  else if (CPU == "k6" || CPU == "winchip-c6")
690    setFeatureEnabled(Features, "mmx", true);
691  else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
692           CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
693    setFeatureEnabled(Features, "mmx", true);
694    setFeatureEnabled(Features, "3dnow", true);
695  } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
696    setFeatureEnabled(Features, "sse", true);
697    setFeatureEnabled(Features, "3dnowa", true);
698  } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
699           CPU == "athlon-fx") {
700    setFeatureEnabled(Features, "sse2", true);
701    setFeatureEnabled(Features, "3dnowa", true);
702  } else if (CPU == "c3-2")
703    setFeatureEnabled(Features, "sse", true);
704}
705
706bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
707                                      const std::string &Name,
708                                      bool Enabled) const {
709  // FIXME: This *really* should not be here.
710  if (!Features.count(Name) && Name != "sse4")
711    return false;
712
713  if (Enabled) {
714    if (Name == "mmx")
715      Features["mmx"] = true;
716    else if (Name == "sse")
717      Features["mmx"] = Features["sse"] = true;
718    else if (Name == "sse2")
719      Features["mmx"] = Features["sse"] = Features["sse2"] = true;
720    else if (Name == "sse3")
721      Features["mmx"] = Features["sse"] = Features["sse2"] =
722        Features["sse3"] = true;
723    else if (Name == "ssse3")
724      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
725        Features["ssse3"] = true;
726    else if (Name == "sse4")
727      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
728        Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
729    else if (Name == "3dnow")
730      Features["3dnowa"] = true;
731    else if (Name == "3dnowa")
732      Features["3dnow"] = Features["3dnowa"] = true;
733  } else {
734    if (Name == "mmx")
735      Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
736        Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
737    else if (Name == "sse")
738      Features["sse"] = Features["sse2"] = Features["sse3"] =
739        Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
740    else if (Name == "sse2")
741      Features["sse2"] = Features["sse3"] = Features["ssse3"] =
742        Features["sse41"] = Features["sse42"] = false;
743    else if (Name == "sse3")
744      Features["sse3"] = Features["ssse3"] = Features["sse41"] =
745        Features["sse42"] = false;
746    else if (Name == "ssse3")
747      Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
748    else if (Name == "sse4")
749      Features["sse41"] = Features["sse42"] = false;
750    else if (Name == "3dnow")
751      Features["3dnow"] = Features["3dnowa"] = false;
752    else if (Name == "3dnowa")
753      Features["3dnowa"] = false;
754  }
755
756  return true;
757}
758
759/// HandleTargetOptions - Perform initialization based on the user
760/// configured set of features.
761void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) {
762  if (Features.lookup("sse42"))
763    SSELevel = SSE42;
764  else if (Features.lookup("sse41"))
765    SSELevel = SSE41;
766  else if (Features.lookup("ssse3"))
767    SSELevel = SSSE3;
768  else if (Features.lookup("sse3"))
769    SSELevel = SSE3;
770  else if (Features.lookup("sse2"))
771    SSELevel = SSE2;
772  else if (Features.lookup("sse"))
773    SSELevel = SSE1;
774  else if (Features.lookup("mmx"))
775    SSELevel = MMX;
776}
777
778/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
779/// that are not tied to a specific subtarget.
780void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
781                                     std::vector<char> &Defs) const {
782  // Target identification.
783  if (PointerWidth == 64) {
784    Define(Defs, "_LP64");
785    Define(Defs, "__LP64__");
786    Define(Defs, "__amd64__");
787    Define(Defs, "__amd64");
788    Define(Defs, "__x86_64");
789    Define(Defs, "__x86_64__");
790  } else {
791    DefineStd(Defs, "i386", Opts);
792  }
793
794  // Target properties.
795  Define(Defs, "__LITTLE_ENDIAN__");
796
797  // Subtarget options.
798  Define(Defs, "__nocona");
799  Define(Defs, "__nocona__");
800  Define(Defs, "__tune_nocona__");
801  Define(Defs, "__REGISTER_PREFIX__", "");
802
803  // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
804  // functions in glibc header files that use FP Stack inline asm which the
805  // backend can't deal with (PR879).
806  Define(Defs, "__NO_MATH_INLINES");
807
808  // Each case falls through to the previous one here.
809  switch (SSELevel) {
810  case SSE42:
811    Define(Defs, "__SSE4_2__");
812  case SSE41:
813    Define(Defs, "__SSE4_1__");
814  case SSSE3:
815    Define(Defs, "__SSSE3__");
816  case SSE3:
817    Define(Defs, "__SSE3__");
818  case SSE2:
819    Define(Defs, "__SSE2__");
820    Define(Defs, "__SSE2_MATH__");  // -mfp-math=sse always implied.
821  case SSE1:
822    Define(Defs, "__SSE__");
823    Define(Defs, "__SSE_MATH__");   // -mfp-math=sse always implied.
824  case MMX:
825    Define(Defs, "__MMX__");
826  case NoMMXSSE:
827    break;
828  }
829}
830
831
832bool
833X86TargetInfo::validateAsmConstraint(const char *&Name,
834                                     TargetInfo::ConstraintInfo &Info) const {
835  switch (*Name) {
836  default: return false;
837  case 'a': // eax.
838  case 'b': // ebx.
839  case 'c': // ecx.
840  case 'd': // edx.
841  case 'S': // esi.
842  case 'D': // edi.
843  case 'A': // edx:eax.
844  case 't': // top of floating point stack.
845  case 'u': // second from top of floating point stack.
846  case 'q': // Any register accessible as [r]l: a, b, c, and d.
847  case 'y': // Any MMX register.
848  case 'x': // Any SSE register.
849  case 'Q': // Any register accessible as [r]h: a, b, c, and d.
850  case 'e': // 32-bit signed integer constant for use with zero-extending
851            // x86_64 instructions.
852  case 'Z': // 32-bit unsigned integer constant for use with zero-extending
853            // x86_64 instructions.
854  case 'N': // unsigned 8-bit integer constant for use with in and out
855            // instructions.
856  case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
857    Info.setAllowsRegister();
858    return true;
859  }
860}
861
862std::string
863X86TargetInfo::convertConstraint(const char Constraint) const {
864  switch (Constraint) {
865  case 'a': return std::string("{ax}");
866  case 'b': return std::string("{bx}");
867  case 'c': return std::string("{cx}");
868  case 'd': return std::string("{dx}");
869  case 'S': return std::string("{si}");
870  case 'D': return std::string("{di}");
871  case 't': // top of floating point stack.
872    return std::string("{st}");
873  case 'u': // second from top of floating point stack.
874    return std::string("{st(1)}"); // second from top of floating point stack.
875  default:
876    return std::string(1, Constraint);
877  }
878}
879} // end anonymous namespace
880
881namespace {
882// X86-32 generic target
883class X86_32TargetInfo : public X86TargetInfo {
884public:
885  X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
886    DoubleAlign = LongLongAlign = 32;
887    LongDoubleWidth = 96;
888    LongDoubleAlign = 32;
889    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
890                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
891                        "a0:0:64-f80:32:32";
892    SizeType = UnsignedInt;
893    PtrDiffType = SignedInt;
894    IntPtrType = SignedInt;
895    RegParmMax = 3;
896  }
897  virtual const char *getVAListDeclaration() const {
898    return "typedef char* __builtin_va_list;";
899  }
900};
901} // end anonymous namespace
902
903namespace {
904class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
905public:
906  OpenBSDI386TargetInfo(const std::string& triple) :
907    OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
908    SizeType = UnsignedLong;
909    IntPtrType = SignedLong;
910    PtrDiffType = SignedLong;
911  }
912};
913} // end anonymous namespace
914
915namespace {
916class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
917public:
918  DarwinI386TargetInfo(const std::string& triple) :
919    DarwinTargetInfo<X86_32TargetInfo>(triple) {
920    LongDoubleWidth = 128;
921    LongDoubleAlign = 128;
922    SizeType = UnsignedLong;
923    IntPtrType = SignedLong;
924    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
925                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
926                        "a0:0:64-f80:128:128";
927  }
928
929};
930} // end anonymous namespace
931
932namespace {
933// x86-32 Windows target
934class WindowsX86_32TargetInfo : public X86_32TargetInfo {
935public:
936  WindowsX86_32TargetInfo(const std::string& triple)
937    : X86_32TargetInfo(triple) {
938    TLSSupported = false;
939    WCharType = UnsignedShort;
940    WCharWidth = WCharAlign = 16;
941    DoubleAlign = LongLongAlign = 64;
942    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
943                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
944                        "a0:0:64-f80:32:32";
945  }
946  virtual void getTargetDefines(const LangOptions &Opts,
947                                std::vector<char> &Defines) const {
948    X86_32TargetInfo::getTargetDefines(Opts, Defines);
949    // This list is based off of the the list of things MingW defines
950    Define(Defines, "_WIN32");
951    DefineStd(Defines, "WIN32", Opts);
952    DefineStd(Defines, "WINNT", Opts);
953    Define(Defines, "_X86_");
954    Define(Defines, "__MSVCRT__");
955  }
956
957  virtual void getDefaultLangOptions(LangOptions &Opts) {
958    X86_32TargetInfo::getDefaultLangOptions(Opts);
959    GetWindowsLanguageOptions(Opts, getTargetTriple());
960  }
961};
962} // end anonymous namespace
963
964namespace {
965// x86-64 generic target
966class X86_64TargetInfo : public X86TargetInfo {
967public:
968  X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
969    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
970    LongDoubleWidth = 128;
971    LongDoubleAlign = 128;
972    IntMaxType = SignedLong;
973    UIntMaxType = UnsignedLong;
974    Int64Type = SignedLong;
975    RegParmMax = 6;
976
977    DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
978                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
979                        "a0:0:64-s0:64:64-f80:128:128";
980  }
981  virtual const char *getVAListDeclaration() const {
982    return "typedef struct __va_list_tag {"
983           "  unsigned gp_offset;"
984           "  unsigned fp_offset;"
985           "  void* overflow_arg_area;"
986           "  void* reg_save_area;"
987           "} __va_list_tag;"
988           "typedef __va_list_tag __builtin_va_list[1];";
989  }
990};
991} // end anonymous namespace
992
993namespace {
994class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
995public:
996  DarwinX86_64TargetInfo(const std::string& triple)
997      : DarwinTargetInfo<X86_64TargetInfo>(triple) {
998    Int64Type = SignedLongLong;
999  }
1000};
1001} // end anonymous namespace
1002
1003namespace {
1004class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1005public:
1006  OpenBSDX86_64TargetInfo(const std::string& triple)
1007      : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1008    IntMaxType = SignedLongLong;
1009    UIntMaxType = UnsignedLongLong;
1010    Int64Type = SignedLongLong;
1011  }
1012};
1013} // end anonymous namespace
1014
1015namespace {
1016class ARMTargetInfo : public TargetInfo {
1017  enum {
1018    Armv4t,
1019    Armv5,
1020    Armv6,
1021    XScale
1022  } ArmArch;
1023public:
1024  ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
1025    // FIXME: Are the defaults correct for ARM?
1026    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1027                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
1028    if (triple.find("arm-") == 0 || triple.find("armv6-") == 0)
1029      ArmArch = Armv6;
1030    else if (triple.find("armv5-") == 0)
1031      ArmArch = Armv5;
1032    else if (triple.find("armv4t-") == 0)
1033      ArmArch = Armv4t;
1034    else if (triple.find("xscale-") == 0)
1035      ArmArch = XScale;
1036    else if (triple.find("armv") == 0) {
1037      // FIXME: fuzzy match for other random weird arm triples.  This is useful
1038      // for the static analyzer and other clients, but probably should be
1039      // re-evaluated when codegen is brought up.
1040      ArmArch = Armv6;
1041    }
1042  }
1043  virtual void getTargetDefines(const LangOptions &Opts,
1044                                std::vector<char> &Defs) const {
1045    // Target identification.
1046    Define(Defs, "__arm");
1047    Define(Defs, "__arm__");
1048
1049    // Target properties.
1050    Define(Defs, "__LITTLE_ENDIAN__");
1051
1052    // Subtarget options.
1053    if (ArmArch == Armv6) {
1054      Define(Defs, "__ARM_ARCH_6K__");
1055      Define(Defs, "__THUMB_INTERWORK__");
1056    } else if (ArmArch == Armv5) {
1057      Define(Defs, "__ARM_ARCH_5TEJ__");
1058      Define(Defs, "__THUMB_INTERWORK__");
1059      Define(Defs, "__SOFTFP__");
1060    } else if (ArmArch == Armv4t) {
1061      Define(Defs, "__ARM_ARCH_4T__");
1062      Define(Defs, "__SOFTFP__");
1063    } else if (ArmArch == XScale) {
1064      Define(Defs, "__ARM_ARCH_5TE__");
1065      Define(Defs, "__XSCALE__");
1066      Define(Defs, "__SOFTFP__");
1067    }
1068    Define(Defs, "__ARMEL__");
1069    Define(Defs, "__APCS_32__");
1070    Define(Defs, "__VFP_FP__");
1071  }
1072  virtual void getTargetBuiltins(const Builtin::Info *&Records,
1073                                 unsigned &NumRecords) const {
1074    // FIXME: Implement.
1075    Records = 0;
1076    NumRecords = 0;
1077  }
1078  virtual const char *getVAListDeclaration() const {
1079    return "typedef char* __builtin_va_list;";
1080  }
1081  virtual const char *getTargetPrefix() const {
1082    return "arm";
1083  }
1084  virtual void getGCCRegNames(const char * const *&Names,
1085                              unsigned &NumNames) const {
1086    // FIXME: Implement.
1087    Names = 0;
1088    NumNames = 0;
1089  }
1090  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1091                                unsigned &NumAliases) const {
1092    // FIXME: Implement.
1093    Aliases = 0;
1094    NumAliases = 0;
1095  }
1096  virtual bool validateAsmConstraint(const char *&Name,
1097                                     TargetInfo::ConstraintInfo &Info) const {
1098    // FIXME: Check if this is complete
1099    switch (*Name) {
1100    default:
1101    case 'l': // r0-r7
1102    case 'h': // r8-r15
1103    case 'w': // VFP Floating point register single precision
1104    case 'P': // VFP Floating point register double precision
1105      Info.setAllowsRegister();
1106      return true;
1107    }
1108    return false;
1109  }
1110  virtual const char *getClobbers() const {
1111    // FIXME: Is this really right?
1112    return "";
1113  }
1114};
1115} // end anonymous namespace.
1116
1117
1118namespace {
1119class DarwinARMTargetInfo :
1120  public DarwinTargetInfo<ARMTargetInfo> {
1121protected:
1122  virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
1123                    std::vector<char> &Defines) const {
1124    getDarwinDefines(Defines, Opts);
1125    getDarwinIPhoneOSDefines(Defines, Triple);
1126  }
1127
1128public:
1129  DarwinARMTargetInfo(const std::string& triple)
1130    : DarwinTargetInfo<ARMTargetInfo>(triple) {}
1131};
1132} // end anonymous namespace.
1133
1134namespace {
1135class SparcV8TargetInfo : public TargetInfo {
1136  static const TargetInfo::GCCRegAlias GCCRegAliases[];
1137  static const char * const GCCRegNames[];
1138public:
1139  SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1140    // FIXME: Support Sparc quad-precision long double?
1141    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1142                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
1143  }
1144  virtual void getTargetDefines(const LangOptions &Opts,
1145                                std::vector<char> &Defines) const {
1146    DefineStd(Defines, "sparc", Opts);
1147    Define(Defines, "__sparcv8");
1148    Define(Defines, "__REGISTER_PREFIX__", "");
1149  }
1150  virtual void getTargetBuiltins(const Builtin::Info *&Records,
1151                                 unsigned &NumRecords) const {
1152    // FIXME: Implement!
1153  }
1154  virtual const char *getVAListDeclaration() const {
1155    return "typedef void* __builtin_va_list;";
1156  }
1157  virtual const char *getTargetPrefix() const {
1158    return "sparc";
1159  }
1160  virtual void getGCCRegNames(const char * const *&Names,
1161                              unsigned &NumNames) const;
1162  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1163                                unsigned &NumAliases) const;
1164  virtual bool validateAsmConstraint(const char *&Name,
1165                                     TargetInfo::ConstraintInfo &info) const {
1166    // FIXME: Implement!
1167    return false;
1168  }
1169  virtual const char *getClobbers() const {
1170    // FIXME: Implement!
1171    return "";
1172  }
1173};
1174
1175const char * const SparcV8TargetInfo::GCCRegNames[] = {
1176  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1177  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1178  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1179  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1180};
1181
1182void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
1183                                       unsigned &NumNames) const {
1184  Names = GCCRegNames;
1185  NumNames = llvm::array_lengthof(GCCRegNames);
1186}
1187
1188const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
1189  { { "g0" }, "r0" },
1190  { { "g1" }, "r1" },
1191  { { "g2" }, "r2" },
1192  { { "g3" }, "r3" },
1193  { { "g4" }, "r4" },
1194  { { "g5" }, "r5" },
1195  { { "g6" }, "r6" },
1196  { { "g7" }, "r7" },
1197  { { "o0" }, "r8" },
1198  { { "o1" }, "r9" },
1199  { { "o2" }, "r10" },
1200  { { "o3" }, "r11" },
1201  { { "o4" }, "r12" },
1202  { { "o5" }, "r13" },
1203  { { "o6", "sp" }, "r14" },
1204  { { "o7" }, "r15" },
1205  { { "l0" }, "r16" },
1206  { { "l1" }, "r17" },
1207  { { "l2" }, "r18" },
1208  { { "l3" }, "r19" },
1209  { { "l4" }, "r20" },
1210  { { "l5" }, "r21" },
1211  { { "l6" }, "r22" },
1212  { { "l7" }, "r23" },
1213  { { "i0" }, "r24" },
1214  { { "i1" }, "r25" },
1215  { { "i2" }, "r26" },
1216  { { "i3" }, "r27" },
1217  { { "i4" }, "r28" },
1218  { { "i5" }, "r29" },
1219  { { "i6", "fp" }, "r30" },
1220  { { "i7" }, "r31" },
1221};
1222
1223void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1224                                         unsigned &NumAliases) const {
1225  Aliases = GCCRegAliases;
1226  NumAliases = llvm::array_lengthof(GCCRegAliases);
1227}
1228} // end anonymous namespace.
1229
1230namespace {
1231class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
1232public:
1233  SolarisSparcV8TargetInfo(const std::string& triple) :
1234      SolarisTargetInfo<SparcV8TargetInfo>(triple) {
1235    SizeType = UnsignedInt;
1236    PtrDiffType = SignedInt;
1237  }
1238};
1239} // end anonymous namespace.
1240
1241namespace {
1242  class PIC16TargetInfo : public TargetInfo{
1243  public:
1244    PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
1245      TLSSupported = false;
1246      IntWidth = 16;
1247      LongWidth = LongLongWidth = 32;
1248      IntMaxTWidth = 32;
1249      PointerWidth = 16;
1250      IntAlign = 8;
1251      LongAlign = LongLongAlign = 8;
1252      PointerAlign = 8;
1253      SizeType = UnsignedInt;
1254      IntMaxType = SignedLong;
1255      UIntMaxType = UnsignedLong;
1256      IntPtrType = SignedShort;
1257      PtrDiffType = SignedInt;
1258      FloatWidth = 32;
1259      FloatAlign = 32;
1260      DoubleWidth = 32;
1261      DoubleAlign = 32;
1262      LongDoubleWidth = 32;
1263      LongDoubleAlign = 32;
1264      FloatFormat = &llvm::APFloat::IEEEsingle;
1265      DoubleFormat = &llvm::APFloat::IEEEsingle;
1266      LongDoubleFormat = &llvm::APFloat::IEEEsingle;
1267      DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32";
1268
1269    }
1270    virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1271    virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
1272    virtual void getTargetDefines(const LangOptions &Opts,
1273                                  std::vector<char> &Defines) const {
1274      Define(Defines, "__pic16");
1275      Define(Defines, "rom", "__attribute__((address_space(1)))");
1276      Define(Defines, "ram", "__attribute__((address_space(0)))");
1277      Define(Defines, "_section(SectName)", "__attribute__((section(SectName)))");
1278      Define(Defines, "_address(Addr)","__attribute__((section(\"Address=\"#Addr)))");
1279      Define(Defines, "_CONFIG(conf)", "asm(\"CONFIG \"#conf)");
1280    }
1281    virtual void getTargetBuiltins(const Builtin::Info *&Records,
1282                                   unsigned &NumRecords) const {}
1283    virtual const char *getVAListDeclaration() const { return "";}
1284    virtual const char *getClobbers() const {return "";}
1285    virtual const char *getTargetPrefix() const {return "pic16";}
1286    virtual void getGCCRegNames(const char * const *&Names,
1287                                unsigned &NumNames) const {}
1288    virtual bool validateAsmConstraint(const char *&Name,
1289                                       TargetInfo::ConstraintInfo &info) const {
1290      return true;
1291    }
1292    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1293                                  unsigned &NumAliases) const {}
1294    virtual bool useGlobalsForAutomaticVariables() const {return true;}
1295  };
1296}
1297
1298namespace {
1299  class MSP430TargetInfo : public TargetInfo {
1300    static const char * const GCCRegNames[];
1301  public:
1302    MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1303      TLSSupported = false;
1304      IntWidth = 16;
1305      LongWidth = LongLongWidth = 32;
1306      IntMaxTWidth = 32;
1307      PointerWidth = 16;
1308      IntAlign = 8;
1309      LongAlign = LongLongAlign = 8;
1310      PointerAlign = 8;
1311      SizeType = UnsignedInt;
1312      IntMaxType = SignedLong;
1313      UIntMaxType = UnsignedLong;
1314      IntPtrType = SignedShort;
1315      PtrDiffType = SignedInt;
1316      DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
1317   }
1318    virtual void getTargetDefines(const LangOptions &Opts,
1319                                 std::vector<char> &Defines) const {
1320      Define(Defines, "MSP430");
1321      Define(Defines, "__MSP430__");
1322      // FIXME: defines for different 'flavours' of MCU
1323    }
1324    virtual void getTargetBuiltins(const Builtin::Info *&Records,
1325                                   unsigned &NumRecords) const {
1326     // FIXME: Implement.
1327      Records = 0;
1328      NumRecords = 0;
1329    }
1330    virtual const char *getTargetPrefix() const {
1331      return "msp430";
1332    }
1333    virtual void getGCCRegNames(const char * const *&Names,
1334                                unsigned &NumNames) const;
1335    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1336                                  unsigned &NumAliases) const {
1337      // No aliases.
1338      Aliases = 0;
1339      NumAliases = 0;
1340    }
1341    virtual bool validateAsmConstraint(const char *&Name,
1342                                       TargetInfo::ConstraintInfo &info) const {
1343      // FIXME: implement
1344      return true;
1345    }
1346    virtual const char *getClobbers() const {
1347      // FIXME: Is this really right?
1348      return "";
1349    }
1350    virtual const char *getVAListDeclaration() const {
1351      // FIXME: implement
1352      return "typedef char* __builtin_va_list;";
1353   }
1354  };
1355
1356  const char * const MSP430TargetInfo::GCCRegNames[] = {
1357    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1358    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1359  };
1360
1361  void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1362                                        unsigned &NumNames) const {
1363    Names = GCCRegNames;
1364    NumNames = llvm::array_lengthof(GCCRegNames);
1365  }
1366}
1367
1368
1369namespace {
1370  class SystemZTargetInfo : public TargetInfo {
1371    static const char * const GCCRegNames[];
1372  public:
1373    SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
1374      TLSSupported = false;
1375      IntWidth = IntAlign = 32;
1376      LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
1377      PointerWidth = PointerAlign = 64;
1378      DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16";
1379   }
1380    virtual void getTargetDefines(const LangOptions &Opts,
1381                                 std::vector<char> &Defines) const {
1382      Define(Defines, "__s390__");
1383      Define(Defines, "__s390x__");
1384    }
1385    virtual void getTargetBuiltins(const Builtin::Info *&Records,
1386                                   unsigned &NumRecords) const {
1387      // FIXME: Implement.
1388      Records = 0;
1389      NumRecords = 0;
1390    }
1391    virtual const char *getTargetPrefix() const {
1392      return "s390x";
1393    }
1394
1395    virtual void getDefaultLangOptions(LangOptions &Opts) {
1396      TargetInfo::getDefaultLangOptions(Opts);
1397      Opts.CharIsSigned = false;
1398    }
1399
1400    virtual void getGCCRegNames(const char * const *&Names,
1401                                unsigned &NumNames) const;
1402    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1403                                  unsigned &NumAliases) const {
1404      // No aliases.
1405      Aliases = 0;
1406      NumAliases = 0;
1407    }
1408    virtual bool validateAsmConstraint(const char *&Name,
1409                                       TargetInfo::ConstraintInfo &info) const {
1410      // FIXME: implement
1411      return true;
1412    }
1413    virtual const char *getClobbers() const {
1414      // FIXME: Is this really right?
1415      return "";
1416    }
1417    virtual const char *getVAListDeclaration() const {
1418      // FIXME: implement
1419      return "typedef char* __builtin_va_list;";
1420   }
1421  };
1422
1423  const char * const SystemZTargetInfo::GCCRegNames[] = {
1424    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1425    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1426  };
1427
1428  void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
1429                                         unsigned &NumNames) const {
1430    Names = GCCRegNames;
1431    NumNames = llvm::array_lengthof(GCCRegNames);
1432  }
1433}
1434
1435//===----------------------------------------------------------------------===//
1436// Driver code
1437//===----------------------------------------------------------------------===//
1438
1439static inline bool IsX86(const std::string& TT) {
1440  return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1441          TT[4] == '-' && TT[1] - '3' < 6);
1442}
1443
1444/// CreateTargetInfo - Return the target info object for the specified target
1445/// triple.
1446TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
1447  // OS detection; this isn't really anywhere near complete.
1448  // Additions and corrections are welcome.
1449  bool isDarwin = T.find("-darwin") != std::string::npos;
1450  bool isDragonFly = T.find("-dragonfly") != std::string::npos;
1451  bool isNetBSD = T.find("-netbsd") != std::string::npos;
1452  bool isOpenBSD = T.find("-openbsd") != std::string::npos;
1453  bool isFreeBSD = T.find("-freebsd") != std::string::npos;
1454  bool isSolaris = T.find("-solaris") != std::string::npos;
1455  bool isLinux = T.find("-linux") != std::string::npos;
1456  bool isWindows = T.find("-windows") != std::string::npos ||
1457                   T.find("-win32") != std::string::npos ||
1458                   T.find("-mingw") != std::string::npos;
1459
1460  if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1461    if (isDarwin)
1462      return new DarwinTargetInfo<PPCTargetInfo>(T);
1463    return new PPC32TargetInfo(T);
1464  }
1465
1466  if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1467    if (isDarwin)
1468      return new DarwinTargetInfo<PPC64TargetInfo>(T);
1469    return new PPC64TargetInfo(T);
1470  }
1471
1472  if (T.find("armv") == 0 || T.find("arm-") == 0 || T.find("xscale") == 0) {
1473    if (isDarwin)
1474      return new DarwinARMTargetInfo(T);
1475    if (isFreeBSD)
1476      return new FreeBSDTargetInfo<ARMTargetInfo>(T);
1477    return new ARMTargetInfo(T);
1478  }
1479
1480  if (T.find("sparc-") == 0) {
1481    if (isSolaris)
1482      return new SolarisSparcV8TargetInfo(T);
1483    return new SparcV8TargetInfo(T);
1484  }
1485
1486  if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
1487    if (isDarwin)
1488      return new DarwinX86_64TargetInfo(T);
1489    if (isLinux)
1490      return new LinuxTargetInfo<X86_64TargetInfo>(T);
1491    if (isNetBSD)
1492      return new NetBSDTargetInfo<X86_64TargetInfo>(T);
1493    if (isOpenBSD)
1494      return new OpenBSDX86_64TargetInfo(T);
1495    if (isFreeBSD)
1496      return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
1497    if (isSolaris)
1498      return new SolarisTargetInfo<X86_64TargetInfo>(T);
1499    return new X86_64TargetInfo(T);
1500  }
1501
1502  if (T.find("pic16-") == 0)
1503    return new PIC16TargetInfo(T);
1504
1505  if (T.find("msp430-") == 0)
1506    return new MSP430TargetInfo(T);
1507
1508  if (T.find("s390x-") == 0)
1509    return new SystemZTargetInfo(T);
1510
1511  if (IsX86(T)) {
1512    if (isDarwin)
1513      return new DarwinI386TargetInfo(T);
1514    if (isLinux)
1515      return new LinuxTargetInfo<X86_32TargetInfo>(T);
1516    if (isDragonFly)
1517      return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
1518    if (isNetBSD)
1519      return new NetBSDTargetInfo<X86_32TargetInfo>(T);
1520    if (isOpenBSD)
1521      return new OpenBSDI386TargetInfo(T);
1522    if (isFreeBSD)
1523      return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
1524    if (isSolaris)
1525      return new SolarisTargetInfo<X86_32TargetInfo>(T);
1526    if (isWindows)
1527      return new WindowsX86_32TargetInfo(T);
1528    return new X86_32TargetInfo(T);
1529  }
1530
1531  return NULL;
1532}
1533