1 //===--- Targets.cpp - Implement -arch option and targets -----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements construction of a TargetInfo object from a
13 //===----------------------------------------------------------------------===//
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 using namespace clang;
24 //===----------------------------------------------------------------------===//
25 // Common code shared among targets.
26 //===----------------------------------------------------------------------===//
28 static void Define(std::vector<char> &Buf, const char *Macro,
29 const char *Val = "1") {
30 const char *Def = "#define ";
31 Buf.insert(Buf.end(), Def, Def+strlen(Def));
32 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
34 Buf.insert(Buf.end(), Val, Val+strlen(Val));
38 /// DefineStd - Define a macro name and standard variants. For example if
39 /// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
41 static void DefineStd(std::vector<char> &Buf, const char *MacroName,
42 const LangOptions &Opts) {
43 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
45 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
46 // in the user's namespace.
48 Define(Buf, MacroName);
51 llvm::SmallString<20> TmpStr;
54 Define(Buf, TmpStr.c_str());
58 Define(Buf, TmpStr.c_str());
61 //===----------------------------------------------------------------------===//
62 // Defines specific to certain operating systems.
63 //===----------------------------------------------------------------------===//
65 static void getSolarisDefines(const LangOptions &Opts, std::vector<char> &Defs) {
66 DefineStd(Defs, "sun", Opts);
67 DefineStd(Defs, "unix", Opts);
68 Define(Defs, "__ELF__");
69 Define(Defs, "__svr4__");
70 Define(Defs, "__SVR4");
73 static void getFreeBSDDefines(const LangOptions &Opts, bool is64Bit,
74 const char *Triple, std::vector<char> &Defs) {
75 // FreeBSD defines; list based off of gcc output
77 const char *FreeBSD = strstr(Triple, "-freebsd");
78 FreeBSD += strlen("-freebsd");
80 release[0] = FreeBSD[0];
81 char version[] = "X00001";
82 version[0] = FreeBSD[0];
84 Define(Defs, "__FreeBSD__", release);
85 Define(Defs, "__FreeBSD_cc_version", version);
86 Define(Defs, "__KPRINTF_ATTRIBUTE__");
87 DefineStd(Defs, "unix", Opts);
88 Define(Defs, "__ELF__", "1");
90 Define(Defs, "__LP64__");
94 static void getDragonFlyDefines(const LangOptions &Opts,
95 std::vector<char> &Defs) {
96 // DragonFly defines; list based off of gcc output
97 Define(Defs, "__DragonFly__");
98 Define(Defs, "__DragonFly_cc_version", "100001");
99 Define(Defs, "__ELF__");
100 Define(Defs, "__KPRINTF_ATTRIBUTE__");
101 Define(Defs, "__tune_i386__");
102 DefineStd(Defs, "unix", Opts);
105 static void getLinuxDefines(const LangOptions &Opts, std::vector<char> &Defs) {
106 // Linux defines; list based off of gcc output
107 DefineStd(Defs, "unix", Opts);
108 DefineStd(Defs, "linux", Opts);
109 Define(Defs, "__gnu_linux__");
110 Define(Defs, "__ELF__", "1");
113 /// getDarwinNumber - Parse the 'darwin number' out of the specific targe
114 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
115 /// not defined, return 0's. Return true if we have -darwin in the string or
117 static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min, unsigned &Revision) {
118 Maj = Min = Revision = 0;
119 const char *Darwin = strstr(Triple, "-darwin");
120 if (Darwin == 0) return false;
122 Darwin += strlen("-darwin");
123 if (Darwin[0] < '0' || Darwin[0] > '9')
129 // Handle "darwin11".
130 if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
131 Maj = Maj*10 + (Darwin[0] - '0');
135 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
136 if (Darwin[0] != '.')
140 if (Darwin[0] < '0' || Darwin[0] > '9')
146 // Handle 10.4.11 -> darwin8.11
147 if (Min == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
148 Min = Min*10 + (Darwin[0] - '0');
152 // Handle revision darwin8.9.1
153 if (Darwin[0] != '.')
157 if (Darwin[0] < '0' || Darwin[0] > '9')
160 Revision = Darwin[0]-'0';
163 if (Revision == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
164 Revision = Revision*10 + (Darwin[0] - '0');
171 static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) {
172 Define(Defs, "__APPLE__");
173 Define(Defs, "__MACH__");
174 Define(Defs, "OBJC_NEW_PROPERTIES");
176 // __weak is always defined, for use in blocks and with objc pointers.
177 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
179 // Darwin defines __strong even in C mode (just to nothing).
180 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
181 Define(Defs, "__strong", "");
183 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
186 Define(Defs, "__STATIC__");
188 Define(Defs, "__DYNAMIC__");
191 static void getDarwinOSXDefines(std::vector<char> &Defs, const char *Triple) {
192 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
193 unsigned Maj, Min, Rev;
194 if (getDarwinNumber(Triple, Maj, Min, Rev)) {
195 char MacOSXStr[] = "1000";
196 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
197 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
198 MacOSXStr[2] = '0' + Maj-4;
201 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
202 // Cap 10.4.11 -> darwin8.11 -> "1049"
203 MacOSXStr[3] = std::min(Min, 9U)+'0';
204 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr);
208 static void getDarwinIPhoneOSDefines(std::vector<char> &Defs,
209 const char *Triple) {
210 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
211 unsigned Maj, Min, Rev;
212 if (getDarwinNumber(Triple, Maj, Min, Rev)) {
213 // When targetting iPhone OS, interpret the minor version and
214 // revision as the iPhone OS version
215 char iPhoneOSStr[] = "10000";
216 if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0
217 // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc.
218 iPhoneOSStr[0] = '0' + Min;
221 // Handle minor version: 2.2 -> darwin9.2.2 -> 20200
222 iPhoneOSStr[2] = std::min(Rev, 9U)+'0';
223 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
228 /// GetDarwinLanguageOptions - Set the default language options for darwin.
229 static void GetDarwinLanguageOptions(LangOptions &Opts,
230 const char *Triple) {
231 Opts.NeXTRuntime = true;
233 unsigned Maj, Min, Rev;
234 if (!getDarwinNumber(Triple, Maj, Min, Rev))
237 // Blocks default to on for 10.6 (darwin10) and beyond.
238 // As does nonfragile-abi for 64bit mode
242 if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
243 Opts.ObjCNonFragileABI = 1;
246 /// GetWindowsLanguageOptions - Set the default language options for Windows.
247 static void GetWindowsLanguageOptions(LangOptions &Opts,
248 const char *Triple) {
249 Opts.Microsoft = true;
252 //===----------------------------------------------------------------------===//
253 // Specific target implementations.
254 //===----------------------------------------------------------------------===//
257 // PPC abstract base class
258 class PPCTargetInfo : public TargetInfo {
259 static const Builtin::Info BuiltinInfo[];
260 static const char * const GCCRegNames[];
261 static const TargetInfo::GCCRegAlias GCCRegAliases[];
264 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
266 virtual void getTargetBuiltins(const Builtin::Info *&Records,
267 unsigned &NumRecords) const {
268 Records = BuiltinInfo;
269 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
272 virtual void getTargetDefines(const LangOptions &Opts,
273 std::vector<char> &Defines) const;
275 virtual const char *getVAListDeclaration() const {
276 return "typedef char* __builtin_va_list;";
277 // This is the right definition for ABI/V4: System V.4/eabi.
278 /*return "typedef struct __va_list_tag {"
279 " unsigned char gpr;"
280 " unsigned char fpr;"
281 " unsigned short reserved;"
282 " void* overflow_arg_area;"
283 " void* reg_save_area;"
284 "} __builtin_va_list[1];";*/
286 virtual const char *getTargetPrefix() const {
289 virtual void getGCCRegNames(const char * const *&Names,
290 unsigned &NumNames) const;
291 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
292 unsigned &NumAliases) const;
293 virtual bool validateAsmConstraint(const char *&Name,
294 TargetInfo::ConstraintInfo &Info) const {
296 default: return false;
299 case 'b': // Base register
300 case 'f': // Floating point register
301 Info.setAllowsRegister();
305 virtual void getDefaultLangOptions(LangOptions &Opts) {
306 TargetInfo::getDefaultLangOptions(Opts);
307 Opts.CharIsSigned = false;
309 virtual const char *getClobbers() const {
314 const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
315 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
316 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
317 #include "clang/Basic/BuiltinsPPC.def"
321 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
322 /// #defines that are not tied to a specific subtarget.
323 void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
324 std::vector<char> &Defs) const {
325 // Target identification.
326 Define(Defs, "__ppc__");
327 Define(Defs, "_ARCH_PPC");
328 Define(Defs, "__POWERPC__");
329 if (PointerWidth == 64) {
330 Define(Defs, "_ARCH_PPC64");
331 Define(Defs, "_LP64");
332 Define(Defs, "__LP64__");
333 Define(Defs, "__ppc64__");
335 Define(Defs, "__ppc__");
338 // Target properties.
339 Define(Defs, "_BIG_ENDIAN");
340 Define(Defs, "__BIG_ENDIAN__");
342 // Subtarget options.
343 Define(Defs, "__NATURAL_ALIGNMENT__");
344 Define(Defs, "__REGISTER_PREFIX__", "");
346 // FIXME: Should be controlled by command line option.
347 Define(Defs, "__LONG_DOUBLE_128__");
351 const char * const PPCTargetInfo::GCCRegNames[] = {
352 "0", "1", "2", "3", "4", "5", "6", "7",
353 "8", "9", "10", "11", "12", "13", "14", "15",
354 "16", "17", "18", "19", "20", "21", "22", "23",
355 "24", "25", "26", "27", "28", "29", "30", "31",
356 "0", "1", "2", "3", "4", "5", "6", "7",
357 "8", "9", "10", "11", "12", "13", "14", "15",
358 "16", "17", "18", "19", "20", "21", "22", "23",
359 "24", "25", "26", "27", "28", "29", "30", "31",
360 "mq", "lr", "ctr", "ap",
361 "0", "1", "2", "3", "4", "5", "6", "7",
363 "0", "1", "2", "3", "4", "5", "6", "7",
364 "8", "9", "10", "11", "12", "13", "14", "15",
365 "16", "17", "18", "19", "20", "21", "22", "23",
366 "24", "25", "26", "27", "28", "29", "30", "31",
368 "spe_acc", "spefscr",
372 void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
373 unsigned &NumNames) const {
375 NumNames = llvm::array_lengthof(GCCRegNames);
378 const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
379 // While some of these aliases do map to different registers
380 // they still share the same register name.
381 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
382 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
383 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
384 { { "cr3", "fr3", "r3", "v3"}, "3" },
385 { { "cr4", "fr4", "r4", "v4"}, "4" },
386 { { "cr5", "fr5", "r5", "v5"}, "5" },
387 { { "cr6", "fr6", "r6", "v6"}, "6" },
388 { { "cr7", "fr7", "r7", "v7"}, "7" },
389 { { "fr8", "r8", "v8"}, "8" },
390 { { "fr9", "r9", "v9"}, "9" },
391 { { "fr10", "r10", "v10"}, "10" },
392 { { "fr11", "r11", "v11"}, "11" },
393 { { "fr12", "r12", "v12"}, "12" },
394 { { "fr13", "r13", "v13"}, "13" },
395 { { "fr14", "r14", "v14"}, "14" },
396 { { "fr15", "r15", "v15"}, "15" },
397 { { "fr16", "r16", "v16"}, "16" },
398 { { "fr17", "r17", "v17"}, "17" },
399 { { "fr18", "r18", "v18"}, "18" },
400 { { "fr19", "r19", "v19"}, "19" },
401 { { "fr20", "r20", "v20"}, "20" },
402 { { "fr21", "r21", "v21"}, "21" },
403 { { "fr22", "r22", "v22"}, "22" },
404 { { "fr23", "r23", "v23"}, "23" },
405 { { "fr24", "r24", "v24"}, "24" },
406 { { "fr25", "r25", "v25"}, "25" },
407 { { "fr26", "r26", "v26"}, "26" },
408 { { "fr27", "r27", "v27"}, "27" },
409 { { "fr28", "r28", "v28"}, "28" },
410 { { "fr29", "r29", "v29"}, "29" },
411 { { "fr30", "r30", "v30"}, "30" },
412 { { "fr31", "r31", "v31"}, "31" },
415 void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
416 unsigned &NumAliases) const {
417 Aliases = GCCRegAliases;
418 NumAliases = llvm::array_lengthof(GCCRegAliases);
420 } // end anonymous namespace.
423 class PPC32TargetInfo : public PPCTargetInfo {
425 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
426 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
427 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
430 } // end anonymous namespace.
433 class PPC64TargetInfo : public PPCTargetInfo {
435 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
436 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
437 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
438 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
441 } // end anonymous namespace.
445 class DarwinPPCTargetInfo : public PPC32TargetInfo {
447 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
448 virtual void getTargetDefines(const LangOptions &Opts,
449 std::vector<char> &Defines) const {
450 PPC32TargetInfo::getTargetDefines(Opts, Defines);
451 getDarwinDefines(Defines, Opts);
452 getDarwinOSXDefines(Defines, getTargetTriple());
455 /// getDefaultLangOptions - Allow the target to specify default settings for
456 /// various language options. These may be overridden by command line
458 virtual void getDefaultLangOptions(LangOptions &Opts) {
459 PPC32TargetInfo::getDefaultLangOptions(Opts);
460 GetDarwinLanguageOptions(Opts, getTargetTriple());
463 } // end anonymous namespace.
466 class DarwinPPC64TargetInfo : public PPC64TargetInfo {
468 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
469 virtual void getTargetDefines(const LangOptions &Opts,
470 std::vector<char> &Defines) const {
471 PPC64TargetInfo::getTargetDefines(Opts, Defines);
472 getDarwinDefines(Defines, Opts);
473 getDarwinOSXDefines(Defines, getTargetTriple());
476 /// getDefaultLangOptions - Allow the target to specify default settings for
477 /// various language options. These may be overridden by command line
479 virtual void getDefaultLangOptions(LangOptions &Opts) {
480 PPC64TargetInfo::getDefaultLangOptions(Opts);
481 GetDarwinLanguageOptions(Opts, getTargetTriple());
484 } // end anonymous namespace.
487 // Namespace for x86 abstract base class
488 const Builtin::Info BuiltinInfo[] = {
489 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
490 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
491 #include "clang/Basic/BuiltinsX86.def"
494 const char *GCCRegNames[] = {
495 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
496 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
497 "argp", "flags", "fspr", "dirflag", "frame",
498 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
499 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
500 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
501 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
504 const TargetInfo::GCCRegAlias GCCRegAliases[] = {
505 { { "al", "ah", "eax", "rax" }, "ax" },
506 { { "bl", "bh", "ebx", "rbx" }, "bx" },
507 { { "cl", "ch", "ecx", "rcx" }, "cx" },
508 { { "dl", "dh", "edx", "rdx" }, "dx" },
509 { { "esi", "rsi" }, "si" },
510 { { "edi", "rdi" }, "di" },
511 { { "esp", "rsp" }, "sp" },
512 { { "ebp", "rbp" }, "bp" },
515 // X86 target abstract base class; x86-32 and x86-64 are very close, so
516 // most of the implementation can be shared.
517 class X86TargetInfo : public TargetInfo {
519 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
522 X86TargetInfo(const std::string& triple)
523 : TargetInfo(triple), SSELevel(NoMMXSSE) {
524 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
526 virtual void getTargetBuiltins(const Builtin::Info *&Records,
527 unsigned &NumRecords) const {
528 Records = BuiltinInfo;
529 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
531 virtual const char *getTargetPrefix() const {
534 virtual void getGCCRegNames(const char * const *&Names,
535 unsigned &NumNames) const {
537 NumNames = llvm::array_lengthof(GCCRegNames);
539 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
540 unsigned &NumAliases) const {
541 Aliases = GCCRegAliases;
542 NumAliases = llvm::array_lengthof(GCCRegAliases);
544 virtual bool validateAsmConstraint(const char *&Name,
545 TargetInfo::ConstraintInfo &info) const;
546 virtual std::string convertConstraint(const char Constraint) const;
547 virtual const char *getClobbers() const {
548 return "~{dirflag},~{fpsr},~{flags}";
550 virtual void getTargetDefines(const LangOptions &Opts,
551 std::vector<char> &Defines) const;
552 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
553 const std::string &Name,
555 virtual void getDefaultFeatures(const std::string &CPU,
556 llvm::StringMap<bool> &Features) const;
557 virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
560 void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
561 llvm::StringMap<bool> &Features) const {
562 // FIXME: This should not be here.
563 Features["3dnow"] = false;
564 Features["3dnowa"] = false;
565 Features["mmx"] = false;
566 Features["sse"] = false;
567 Features["sse2"] = false;
568 Features["sse3"] = false;
569 Features["ssse3"] = false;
570 Features["sse41"] = false;
571 Features["sse42"] = false;
573 // LLVM does not currently recognize this.
574 // Features["sse4a"] = false;
576 // FIXME: This *really* should not be here.
578 // X86_64 always has SSE2.
579 if (PointerWidth == 64)
580 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
582 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
583 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
585 else if (CPU == "pentium-mmx" || CPU == "pentium2")
586 setFeatureEnabled(Features, "mmx", true);
587 else if (CPU == "pentium3")
588 setFeatureEnabled(Features, "sse", true);
589 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
590 setFeatureEnabled(Features, "sse2", true);
591 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
592 setFeatureEnabled(Features, "sse3", true);
593 else if (CPU == "core2")
594 setFeatureEnabled(Features, "ssse3", true);
595 else if (CPU == "penryn") {
596 setFeatureEnabled(Features, "sse4", true);
597 Features["sse42"] = false;
598 } else if (CPU == "atom")
599 setFeatureEnabled(Features, "sse3", true);
600 else if (CPU == "corei7")
601 setFeatureEnabled(Features, "sse4", true);
602 else if (CPU == "k6" || CPU == "winchip-c6")
603 setFeatureEnabled(Features, "mmx", true);
604 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
605 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
606 setFeatureEnabled(Features, "mmx", true);
607 setFeatureEnabled(Features, "3dnow", true);
608 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
609 setFeatureEnabled(Features, "sse", true);
610 setFeatureEnabled(Features, "3dnowa", true);
611 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
612 CPU == "athlon-fx") {
613 setFeatureEnabled(Features, "sse2", true);
614 setFeatureEnabled(Features, "3dnowa", true);
615 } else if (CPU == "c3-2")
616 setFeatureEnabled(Features, "sse", true);
619 bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
620 const std::string &Name,
621 bool Enabled) const {
622 // FIXME: This *really* should not be here.
623 if (!Features.count(Name) && Name != "sse4")
628 Features["mmx"] = true;
629 else if (Name == "sse")
630 Features["mmx"] = Features["sse"] = true;
631 else if (Name == "sse2")
632 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
633 else if (Name == "sse3")
634 Features["mmx"] = Features["sse"] = Features["sse2"] =
635 Features["sse3"] = true;
636 else if (Name == "ssse3")
637 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
638 Features["ssse3"] = true;
639 else if (Name == "sse4")
640 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
641 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
642 else if (Name == "3dnow")
643 Features["3dnowa"] = true;
644 else if (Name == "3dnowa")
645 Features["3dnow"] = Features["3dnowa"] = true;
648 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
649 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
650 else if (Name == "sse")
651 Features["sse"] = Features["sse2"] = Features["sse3"] =
652 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
653 else if (Name == "sse2")
654 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
655 Features["sse41"] = Features["sse42"] = false;
656 else if (Name == "sse3")
657 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
658 Features["sse42"] = false;
659 else if (Name == "ssse3")
660 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
661 else if (Name == "sse4")
662 Features["sse41"] = Features["sse42"] = false;
663 else if (Name == "3dnow")
664 Features["3dnow"] = Features["3dnowa"] = false;
665 else if (Name == "3dnowa")
666 Features["3dnowa"] = false;
672 /// HandleTargetOptions - Perform initialization based on the user
673 /// configured set of features.
674 void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) {
675 if (Features.lookup("sse42"))
677 else if (Features.lookup("sse41"))
679 else if (Features.lookup("ssse3"))
681 else if (Features.lookup("sse3"))
683 else if (Features.lookup("sse2"))
685 else if (Features.lookup("sse"))
687 else if (Features.lookup("mmx"))
691 /// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
692 /// that are not tied to a specific subtarget.
693 void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
694 std::vector<char> &Defs) const {
695 // Target identification.
696 if (PointerWidth == 64) {
697 Define(Defs, "_LP64");
698 Define(Defs, "__LP64__");
699 Define(Defs, "__amd64__");
700 Define(Defs, "__amd64");
701 Define(Defs, "__x86_64");
702 Define(Defs, "__x86_64__");
704 DefineStd(Defs, "i386", Opts);
707 // Target properties.
708 Define(Defs, "__LITTLE_ENDIAN__");
710 // Subtarget options.
711 Define(Defs, "__nocona");
712 Define(Defs, "__nocona__");
713 Define(Defs, "__tune_nocona__");
714 Define(Defs, "__REGISTER_PREFIX__", "");
716 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
717 // functions in glibc header files that use FP Stack inline asm which the
718 // backend can't deal with (PR879).
719 Define(Defs, "__NO_MATH_INLINES");
721 // Each case falls through to the previous one here.
724 Define(Defs, "__SSE4_2__");
726 Define(Defs, "__SSE4_1__");
728 Define(Defs, "__SSSE3__");
730 Define(Defs, "__SSE3__");
732 Define(Defs, "__SSE2__");
733 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
735 Define(Defs, "__SSE__");
736 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
738 Define(Defs, "__MMX__");
746 X86TargetInfo::validateAsmConstraint(const char *&Name,
747 TargetInfo::ConstraintInfo &Info) const {
749 default: return false;
756 case 'A': // edx:eax.
757 case 't': // top of floating point stack.
758 case 'u': // second from top of floating point stack.
759 case 'q': // Any register accessible as [r]l: a, b, c, and d.
760 case 'y': // Any MMX register.
761 case 'x': // Any SSE register.
762 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
763 case 'e': // 32-bit signed integer constant for use with zero-extending
764 // x86_64 instructions.
765 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
766 // x86_64 instructions.
767 case 'N': // unsigned 8-bit integer constant for use with in and out
769 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
770 Info.setAllowsRegister();
776 X86TargetInfo::convertConstraint(const char Constraint) const {
777 switch (Constraint) {
778 case 'a': return std::string("{ax}");
779 case 'b': return std::string("{bx}");
780 case 'c': return std::string("{cx}");
781 case 'd': return std::string("{dx}");
782 case 'S': return std::string("{si}");
783 case 'D': return std::string("{di}");
784 case 't': // top of floating point stack.
785 return std::string("{st}");
786 case 'u': // second from top of floating point stack.
787 return std::string("{st(1)}"); // second from top of floating point stack.
789 return std::string(1, Constraint);
792 } // end anonymous namespace
795 // X86-32 generic target
796 class X86_32TargetInfo : public X86TargetInfo {
798 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
799 DoubleAlign = LongLongAlign = 32;
800 LongDoubleWidth = 96;
801 LongDoubleAlign = 32;
802 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
803 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
805 SizeType = UnsignedInt;
806 PtrDiffType = SignedInt;
807 IntPtrType = SignedInt;
810 virtual const char *getVAListDeclaration() const {
811 return "typedef char* __builtin_va_list;";
814 } // end anonymous namespace
817 // x86-32 Darwin (OS X) target
818 class DarwinI386TargetInfo : public X86_32TargetInfo {
820 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
821 LongDoubleWidth = 128;
822 LongDoubleAlign = 128;
823 SizeType = UnsignedLong;
824 IntPtrType = SignedLong;
825 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
826 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
827 "a0:0:64-f80:128:128";
828 TLSSupported = false;
831 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
832 return IsConstant ? "\01LC" : "\01lC";
835 virtual const char *getUnicodeStringSymbolPrefix() const {
836 return "__utf16_string_";
839 virtual const char *getUnicodeStringSection() const {
840 return "__TEXT,__ustring";
843 virtual const char *getCFStringSymbolPrefix() const {
847 virtual void getTargetDefines(const LangOptions &Opts,
848 std::vector<char> &Defines) const {
849 X86_32TargetInfo::getTargetDefines(Opts, Defines);
850 getDarwinDefines(Defines, Opts);
851 getDarwinOSXDefines(Defines, getTargetTriple());
854 /// getDefaultLangOptions - Allow the target to specify default settings for
855 /// various language options. These may be overridden by command line
857 virtual void getDefaultLangOptions(LangOptions &Opts) {
858 X86_32TargetInfo::getDefaultLangOptions(Opts);
859 GetDarwinLanguageOptions(Opts, getTargetTriple());
862 } // end anonymous namespace
865 // x86-32 FreeBSD target
866 class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
868 FreeBSDX86_32TargetInfo(const std::string& triple) :
869 X86_32TargetInfo(triple) { }
870 virtual void getTargetDefines(const LangOptions &Opts,
871 std::vector<char> &Defines) const {
872 X86_32TargetInfo::getTargetDefines(Opts, Defines);
873 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
876 } // end anonymous namespace
879 // x86-32 DragonFly target
880 class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
882 DragonFlyX86_32TargetInfo(const std::string& triple) :
883 X86_32TargetInfo(triple) { }
884 virtual void getTargetDefines(const LangOptions &Opts,
885 std::vector<char> &Defines) const {
886 X86_32TargetInfo::getTargetDefines(Opts, Defines);
887 getDragonFlyDefines(Opts, Defines);
890 } // end anonymous namespace
893 // x86-32 Linux target
894 class LinuxX86_32TargetInfo : public X86_32TargetInfo {
896 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
897 UserLabelPrefix = "";
899 virtual void getTargetDefines(const LangOptions &Opts,
900 std::vector<char> &Defines) const {
901 X86_32TargetInfo::getTargetDefines(Opts, Defines);
902 getLinuxDefines(Opts, Defines);
905 } // end anonymous namespace
908 // x86-32 Solaris target
909 class SolarisX86_32TargetInfo : public X86_32TargetInfo {
911 SolarisX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
912 UserLabelPrefix = "";
913 WCharType = SignedLong;
914 // FIXME: WIntType should be SignedLong
916 virtual void getTargetDefines(const LangOptions &Opts,
917 std::vector<char> &Defines) const {
918 X86_32TargetInfo::getTargetDefines(Opts, Defines);
919 getSolarisDefines(Opts, Defines);
922 } // end anonymous namespace
926 // x86-32 Windows target
927 class WindowsX86_32TargetInfo : public X86_32TargetInfo {
929 WindowsX86_32TargetInfo(const std::string& triple)
930 : X86_32TargetInfo(triple) {
931 TLSSupported = false;
932 WCharType = SignedShort;
933 WCharWidth = WCharAlign = 16;
934 DoubleAlign = LongLongAlign = 64;
935 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
936 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
939 virtual void getTargetDefines(const LangOptions &Opts,
940 std::vector<char> &Defines) const {
941 X86_32TargetInfo::getTargetDefines(Opts, Defines);
942 // This list is based off of the the list of things MingW defines
943 Define(Defines, "_WIN32");
944 DefineStd(Defines, "WIN32", Opts);
945 DefineStd(Defines, "WINNT", Opts);
946 Define(Defines, "_X86_");
947 Define(Defines, "__MSVCRT__");
950 virtual void getDefaultLangOptions(LangOptions &Opts) {
951 X86_32TargetInfo::getDefaultLangOptions(Opts);
952 GetWindowsLanguageOptions(Opts, getTargetTriple());
955 } // end anonymous namespace
958 // x86-64 generic target
959 class X86_64TargetInfo : public X86TargetInfo {
961 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
962 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
963 DoubleAlign = LongLongAlign = 64;
964 LongDoubleWidth = 128;
965 LongDoubleAlign = 128;
966 IntMaxType = SignedLong;
967 UIntMaxType = UnsignedLong;
970 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
971 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
972 "a0:0:64-s0:64:64-f80:128:128";
974 virtual const char *getVAListDeclaration() const {
975 return "typedef struct __va_list_tag {"
976 " unsigned gp_offset;"
977 " unsigned fp_offset;"
978 " void* overflow_arg_area;"
979 " void* reg_save_area;"
980 "} __builtin_va_list[1];";
983 } // end anonymous namespace
986 // x86-64 FreeBSD target
987 class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
989 FreeBSDX86_64TargetInfo(const std::string &triple)
990 : X86_64TargetInfo(triple) {}
991 virtual void getTargetDefines(const LangOptions &Opts,
992 std::vector<char> &Defines) const {
993 X86_64TargetInfo::getTargetDefines(Opts, Defines);
994 getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines);
997 } // end anonymous namespace
1000 // x86-64 Linux target
1001 class LinuxX86_64TargetInfo : public X86_64TargetInfo {
1003 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
1004 UserLabelPrefix = "";
1006 virtual void getTargetDefines(const LangOptions &Opts,
1007 std::vector<char> &Defines) const {
1008 X86_64TargetInfo::getTargetDefines(Opts, Defines);
1009 getLinuxDefines(Opts, Defines);
1012 } // end anonymous namespace
1015 // x86-64 Solaris target
1016 class SolarisX86_64TargetInfo : public X86_64TargetInfo {
1018 SolarisX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
1019 UserLabelPrefix = "";
1021 virtual void getTargetDefines(const LangOptions &Opts,
1022 std::vector<char> &Defines) const {
1023 X86_64TargetInfo::getTargetDefines(Opts, Defines);
1024 getSolarisDefines(Opts, Defines);
1027 } // end anonymous namespace
1030 // x86-64 Darwin (OS X) target
1031 class DarwinX86_64TargetInfo : public X86_64TargetInfo {
1033 DarwinX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
1034 TLSSupported = false;
1037 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
1038 return IsConstant ? "\01LC" : "\01lC";
1041 virtual const char *getUnicodeStringSymbolPrefix() const {
1042 return "__utf16_string_";
1045 virtual const char *getUnicodeStringSection() const {
1046 return "__TEXT,__ustring";
1049 virtual const char *getCFStringSymbolPrefix() const {
1050 return "\01L_unnamed_cfstring_";
1053 virtual void getTargetDefines(const LangOptions &Opts,
1054 std::vector<char> &Defines) const {
1055 X86_64TargetInfo::getTargetDefines(Opts, Defines);
1056 getDarwinDefines(Defines, Opts);
1057 getDarwinOSXDefines(Defines, getTargetTriple());
1060 /// getDefaultLangOptions - Allow the target to specify default settings for
1061 /// various language options. These may be overridden by command line
1063 virtual void getDefaultLangOptions(LangOptions &Opts) {
1064 GetDarwinLanguageOptions(Opts, getTargetTriple());
1067 } // end anonymous namespace.
1070 class ARMTargetInfo : public TargetInfo {
1078 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
1079 // FIXME: Are the defaults correct for ARM?
1080 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1081 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
1082 if (triple.find("arm-") == 0 || triple.find("armv6-") == 0)
1084 else if (triple.find("armv5-") == 0)
1086 else if (triple.find("armv4t-") == 0)
1088 else if (triple.find("xscale-") == 0)
1090 else if (triple.find("armv") == 0) {
1091 // FIXME: fuzzy match for other random weird arm triples. This is useful
1092 // for the static analyzer and other clients, but probably should be
1093 // re-evaluated when codegen is brought up.
1097 virtual void getTargetDefines(const LangOptions &Opts,
1098 std::vector<char> &Defs) const {
1099 // Target identification.
1100 Define(Defs, "__arm");
1101 Define(Defs, "__arm__");
1103 // Target properties.
1104 Define(Defs, "__LITTLE_ENDIAN__");
1106 // Subtarget options.
1107 if (ArmArch == Armv6) {
1108 Define(Defs, "__ARM_ARCH_6K__");
1109 Define(Defs, "__THUMB_INTERWORK__");
1110 } else if (ArmArch == Armv5) {
1111 Define(Defs, "__ARM_ARCH_5TEJ__");
1112 Define(Defs, "__THUMB_INTERWORK__");
1113 Define(Defs, "__SOFTFP__");
1114 } else if (ArmArch == Armv4t) {
1115 Define(Defs, "__ARM_ARCH_4T__");
1116 Define(Defs, "__SOFTFP__");
1117 } else if (ArmArch == XScale) {
1118 Define(Defs, "__ARM_ARCH_5TE__");
1119 Define(Defs, "__XSCALE__");
1120 Define(Defs, "__SOFTFP__");
1122 Define(Defs, "__ARMEL__");
1123 Define(Defs, "__APCS_32__");
1124 Define(Defs, "__VFP_FP__");
1126 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1127 unsigned &NumRecords) const {
1128 // FIXME: Implement.
1132 virtual const char *getVAListDeclaration() const {
1133 return "typedef char* __builtin_va_list;";
1135 virtual const char *getTargetPrefix() const {
1138 virtual void getGCCRegNames(const char * const *&Names,
1139 unsigned &NumNames) const {
1140 // FIXME: Implement.
1144 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1145 unsigned &NumAliases) const {
1146 // FIXME: Implement.
1150 virtual bool validateAsmConstraint(const char *&Name,
1151 TargetInfo::ConstraintInfo &Info) const {
1152 // FIXME: Check if this is complete
1157 case 'w': // VFP Floating point register single precision
1158 case 'P': // VFP Floating point register double precision
1159 Info.setAllowsRegister();
1164 virtual const char *getClobbers() const {
1165 // FIXME: Is this really right?
1169 } // end anonymous namespace.
1173 class DarwinARMTargetInfo : public ARMTargetInfo {
1175 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {
1176 TLSSupported = false;
1179 virtual void getTargetDefines(const LangOptions &Opts,
1180 std::vector<char> &Defines) const {
1181 ARMTargetInfo::getTargetDefines(Opts, Defines);
1182 getDarwinDefines(Defines, Opts);
1183 getDarwinIPhoneOSDefines(Defines, getTargetTriple());
1186 } // end anonymous namespace.
1189 // arm FreeBSD target
1190 class FreeBSDARMTargetInfo : public ARMTargetInfo {
1192 FreeBSDARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
1193 virtual void getTargetDefines(const LangOptions &Opts,
1194 std::vector<char> &Defines) const {
1195 ARMTargetInfo::getTargetDefines(Opts, Defines);
1196 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
1199 } // end anonymous namespace
1202 class SparcV8TargetInfo : public TargetInfo {
1203 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1204 static const char * const GCCRegNames[];
1206 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1207 // FIXME: Support Sparc quad-precision long double?
1208 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1209 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
1211 virtual void getTargetDefines(const LangOptions &Opts,
1212 std::vector<char> &Defines) const {
1213 DefineStd(Defines, "sparc", Opts);
1214 Define(Defines, "__sparcv8");
1215 Define(Defines, "__REGISTER_PREFIX__", "");
1217 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1218 unsigned &NumRecords) const {
1219 // FIXME: Implement!
1221 virtual const char *getVAListDeclaration() const {
1222 return "typedef void* __builtin_va_list;";
1224 virtual const char *getTargetPrefix() const {
1227 virtual void getGCCRegNames(const char * const *&Names,
1228 unsigned &NumNames) const;
1229 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1230 unsigned &NumAliases) const;
1231 virtual bool validateAsmConstraint(const char *&Name,
1232 TargetInfo::ConstraintInfo &info) const {
1233 // FIXME: Implement!
1236 virtual const char *getClobbers() const {
1237 // FIXME: Implement!
1242 const char * const SparcV8TargetInfo::GCCRegNames[] = {
1243 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1244 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1245 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1246 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1249 void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
1250 unsigned &NumNames) const {
1251 Names = GCCRegNames;
1252 NumNames = llvm::array_lengthof(GCCRegNames);
1255 const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
1266 { { "o2" }, "r10" },
1267 { { "o3" }, "r11" },
1268 { { "o4" }, "r12" },
1269 { { "o5" }, "r13" },
1270 { { "o6", "sp" }, "r14" },
1271 { { "o7" }, "r15" },
1272 { { "l0" }, "r16" },
1273 { { "l1" }, "r17" },
1274 { { "l2" }, "r18" },
1275 { { "l3" }, "r19" },
1276 { { "l4" }, "r20" },
1277 { { "l5" }, "r21" },
1278 { { "l6" }, "r22" },
1279 { { "l7" }, "r23" },
1280 { { "i0" }, "r24" },
1281 { { "i1" }, "r25" },
1282 { { "i2" }, "r26" },
1283 { { "i3" }, "r27" },
1284 { { "i4" }, "r28" },
1285 { { "i5" }, "r29" },
1286 { { "i6", "fp" }, "r30" },
1287 { { "i7" }, "r31" },
1290 void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1291 unsigned &NumAliases) const {
1292 Aliases = GCCRegAliases;
1293 NumAliases = llvm::array_lengthof(GCCRegAliases);
1295 } // end anonymous namespace.
1298 class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
1300 SolarisSparcV8TargetInfo(const std::string& triple) :
1301 SparcV8TargetInfo(triple) {
1302 SizeType = UnsignedInt;
1303 PtrDiffType = SignedInt;
1304 WCharType = SignedLong;
1305 // FIXME: WIntType should be SignedLong
1306 UserLabelPrefix = "";
1309 virtual void getTargetDefines(const LangOptions &Opts,
1310 std::vector<char> &Defines) const {
1311 SparcV8TargetInfo::getTargetDefines(Opts, Defines);
1312 getSolarisDefines(Opts, Defines);
1315 } // end anonymous namespace.
1318 class PIC16TargetInfo : public TargetInfo{
1320 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
1321 TLSSupported = false;
1323 LongWidth = LongLongWidth = 32;
1327 LongAlign = LongLongAlign = 8;
1329 SizeType = UnsignedInt;
1330 IntMaxType = SignedLong;
1331 UIntMaxType = UnsignedLong;
1332 IntPtrType = SignedShort;
1333 PtrDiffType = SignedInt;
1338 LongDoubleWidth = 32;
1339 LongDoubleAlign = 32;
1340 FloatFormat = &llvm::APFloat::IEEEsingle;
1341 DoubleFormat = &llvm::APFloat::IEEEsingle;
1342 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
1343 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32";
1346 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1347 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
1348 virtual void getTargetDefines(const LangOptions &Opts,
1349 std::vector<char> &Defines) const {
1350 Define(Defines, "__pic16");
1352 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1353 unsigned &NumRecords) const {}
1354 virtual const char *getVAListDeclaration() const { return "";}
1355 virtual const char *getClobbers() const {return "";}
1356 virtual const char *getTargetPrefix() const {return "pic16";}
1357 virtual void getGCCRegNames(const char * const *&Names,
1358 unsigned &NumNames) const {}
1359 virtual bool validateAsmConstraint(const char *&Name,
1360 TargetInfo::ConstraintInfo &info) const {
1363 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1364 unsigned &NumAliases) const {}
1365 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1370 class MSP430TargetInfo : public TargetInfo {
1371 static const char * const GCCRegNames[];
1373 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1374 TLSSupported = false;
1376 LongWidth = LongLongWidth = 32;
1380 LongAlign = LongLongAlign = 8;
1382 SizeType = UnsignedInt;
1383 IntMaxType = SignedLong;
1384 UIntMaxType = UnsignedLong;
1385 IntPtrType = SignedShort;
1386 PtrDiffType = SignedInt;
1387 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
1389 virtual void getTargetDefines(const LangOptions &Opts,
1390 std::vector<char> &Defines) const {
1391 Define(Defines, "MSP430");
1392 Define(Defines, "__MSP430__");
1393 // FIXME: defines for different 'flavours' of MCU
1395 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1396 unsigned &NumRecords) const {
1397 // FIXME: Implement.
1401 virtual const char *getTargetPrefix() const {
1404 virtual void getGCCRegNames(const char * const *&Names,
1405 unsigned &NumNames) const;
1406 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1407 unsigned &NumAliases) const {
1412 virtual bool validateAsmConstraint(const char *&Name,
1413 TargetInfo::ConstraintInfo &info) const {
1417 virtual const char *getClobbers() const {
1418 // FIXME: Is this really right?
1421 virtual const char *getVAListDeclaration() const {
1423 return "typedef char* __builtin_va_list;";
1427 const char * const MSP430TargetInfo::GCCRegNames[] = {
1428 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1429 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1432 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1433 unsigned &NumNames) const {
1434 Names = GCCRegNames;
1435 NumNames = llvm::array_lengthof(GCCRegNames);
1440 //===----------------------------------------------------------------------===//
1442 //===----------------------------------------------------------------------===//
1444 static inline bool IsX86(const std::string& TT) {
1445 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1446 TT[4] == '-' && TT[1] - '3' < 6);
1449 /// CreateTargetInfo - Return the target info object for the specified target
1451 TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
1452 // OS detection; this isn't really anywhere near complete.
1453 // Additions and corrections are welcome.
1454 bool isDarwin = T.find("-darwin") != std::string::npos;
1455 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
1456 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
1457 bool isSolaris = T.find("-solaris") != std::string::npos;
1458 bool isLinux = T.find("-linux") != std::string::npos;
1459 bool isWindows = T.find("-windows") != std::string::npos ||
1460 T.find("-win32") != std::string::npos ||
1461 T.find("-mingw") != std::string::npos;
1463 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1465 return new DarwinPPCTargetInfo(T);
1466 return new PPC32TargetInfo(T);
1469 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1471 return new DarwinPPC64TargetInfo(T);
1472 return new PPC64TargetInfo(T);
1475 if (T.find("armv") == 0 || T.find("arm-") == 0 || T.find("xscale") == 0) {
1477 return new DarwinARMTargetInfo(T);
1479 return new FreeBSDARMTargetInfo(T);
1480 return new ARMTargetInfo(T);
1483 if (T.find("sparc-") == 0) {
1485 return new SolarisSparcV8TargetInfo(T);
1486 return new SparcV8TargetInfo(T);
1489 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
1491 return new DarwinX86_64TargetInfo(T);
1493 return new LinuxX86_64TargetInfo(T);
1495 return new FreeBSDX86_64TargetInfo(T);
1497 return new SolarisX86_64TargetInfo(T);
1498 return new X86_64TargetInfo(T);
1501 if (T.find("pic16-") == 0)
1502 return new PIC16TargetInfo(T);
1504 if (T.find("msp430-") == 0)
1505 return new MSP430TargetInfo(T);
1509 return new DarwinI386TargetInfo(T);
1511 return new LinuxX86_32TargetInfo(T);
1513 return new DragonFlyX86_32TargetInfo(T);
1515 return new FreeBSDX86_32TargetInfo(T);
1517 return new SolarisX86_32TargetInfo(T);
1519 return new WindowsX86_32TargetInfo(T);
1520 return new X86_32TargetInfo(T);