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