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