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