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