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