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