Targets.cpp revision 3c79eeefa6374946455ccdba3f46b94394ef0c9c
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 DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> { 893public: 894 DarwinI386TargetInfo(const std::string& triple) : 895 DarwinTargetInfo<X86_32TargetInfo>(triple) { 896 LongDoubleWidth = 128; 897 LongDoubleAlign = 128; 898 SizeType = UnsignedLong; 899 IntPtrType = SignedLong; 900 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 901 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 902 "a0:0:64-f80:128:128"; 903 } 904 905}; 906} // end anonymous namespace 907 908namespace { 909// x86-32 Windows target 910class WindowsX86_32TargetInfo : public X86_32TargetInfo { 911public: 912 WindowsX86_32TargetInfo(const std::string& triple) 913 : X86_32TargetInfo(triple) { 914 TLSSupported = false; 915 WCharType = UnsignedShort; 916 WCharWidth = WCharAlign = 16; 917 DoubleAlign = LongLongAlign = 64; 918 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 919 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 920 "a0:0:64-f80:32:32"; 921 } 922 virtual void getTargetDefines(const LangOptions &Opts, 923 std::vector<char> &Defines) const { 924 X86_32TargetInfo::getTargetDefines(Opts, Defines); 925 // This list is based off of the the list of things MingW defines 926 Define(Defines, "_WIN32"); 927 DefineStd(Defines, "WIN32", Opts); 928 DefineStd(Defines, "WINNT", Opts); 929 Define(Defines, "_X86_"); 930 Define(Defines, "__MSVCRT__"); 931 } 932 933 virtual void getDefaultLangOptions(LangOptions &Opts) { 934 X86_32TargetInfo::getDefaultLangOptions(Opts); 935 GetWindowsLanguageOptions(Opts, getTargetTriple()); 936 } 937}; 938} // end anonymous namespace 939 940namespace { 941// x86-64 generic target 942class X86_64TargetInfo : public X86TargetInfo { 943public: 944 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) { 945 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 946 LongDoubleWidth = 128; 947 LongDoubleAlign = 128; 948 IntMaxType = SignedLong; 949 UIntMaxType = UnsignedLong; 950 Int64Type = SignedLong; 951 RegParmMax = 6; 952 953 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 954 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 955 "a0:0:64-s0:64:64-f80:128:128"; 956 } 957 virtual const char *getVAListDeclaration() const { 958 return "typedef struct __va_list_tag {" 959 " unsigned gp_offset;" 960 " unsigned fp_offset;" 961 " void* overflow_arg_area;" 962 " void* reg_save_area;" 963 "} __va_list_tag;" 964 "typedef __va_list_tag __builtin_va_list[1];"; 965 } 966}; 967} // end anonymous namespace 968 969namespace { 970class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> { 971public: 972 DarwinX86_64TargetInfo(const std::string& triple) 973 : DarwinTargetInfo<X86_64TargetInfo>(triple) { 974 Int64Type = SignedLongLong; 975 } 976}; 977} // end anonymous namespace 978 979namespace { 980class ARMTargetInfo : public TargetInfo { 981 enum { 982 Armv4t, 983 Armv5, 984 Armv6, 985 XScale 986 } ArmArch; 987public: 988 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) { 989 // FIXME: Are the defaults correct for ARM? 990 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 991 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64"; 992 if (triple.find("arm-") == 0 || triple.find("armv6-") == 0) 993 ArmArch = Armv6; 994 else if (triple.find("armv5-") == 0) 995 ArmArch = Armv5; 996 else if (triple.find("armv4t-") == 0) 997 ArmArch = Armv4t; 998 else if (triple.find("xscale-") == 0) 999 ArmArch = XScale; 1000 else if (triple.find("armv") == 0) { 1001 // FIXME: fuzzy match for other random weird arm triples. This is useful 1002 // for the static analyzer and other clients, but probably should be 1003 // re-evaluated when codegen is brought up. 1004 ArmArch = Armv6; 1005 } 1006 } 1007 virtual void getTargetDefines(const LangOptions &Opts, 1008 std::vector<char> &Defs) const { 1009 // Target identification. 1010 Define(Defs, "__arm"); 1011 Define(Defs, "__arm__"); 1012 1013 // Target properties. 1014 Define(Defs, "__LITTLE_ENDIAN__"); 1015 1016 // Subtarget options. 1017 if (ArmArch == Armv6) { 1018 Define(Defs, "__ARM_ARCH_6K__"); 1019 Define(Defs, "__THUMB_INTERWORK__"); 1020 } else if (ArmArch == Armv5) { 1021 Define(Defs, "__ARM_ARCH_5TEJ__"); 1022 Define(Defs, "__THUMB_INTERWORK__"); 1023 Define(Defs, "__SOFTFP__"); 1024 } else if (ArmArch == Armv4t) { 1025 Define(Defs, "__ARM_ARCH_4T__"); 1026 Define(Defs, "__SOFTFP__"); 1027 } else if (ArmArch == XScale) { 1028 Define(Defs, "__ARM_ARCH_5TE__"); 1029 Define(Defs, "__XSCALE__"); 1030 Define(Defs, "__SOFTFP__"); 1031 } 1032 Define(Defs, "__ARMEL__"); 1033 Define(Defs, "__APCS_32__"); 1034 Define(Defs, "__VFP_FP__"); 1035 } 1036 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1037 unsigned &NumRecords) const { 1038 // FIXME: Implement. 1039 Records = 0; 1040 NumRecords = 0; 1041 } 1042 virtual const char *getVAListDeclaration() const { 1043 return "typedef char* __builtin_va_list;"; 1044 } 1045 virtual const char *getTargetPrefix() const { 1046 return "arm"; 1047 } 1048 virtual void getGCCRegNames(const char * const *&Names, 1049 unsigned &NumNames) const { 1050 // FIXME: Implement. 1051 Names = 0; 1052 NumNames = 0; 1053 } 1054 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1055 unsigned &NumAliases) const { 1056 // FIXME: Implement. 1057 Aliases = 0; 1058 NumAliases = 0; 1059 } 1060 virtual bool validateAsmConstraint(const char *&Name, 1061 TargetInfo::ConstraintInfo &Info) const { 1062 // FIXME: Check if this is complete 1063 switch (*Name) { 1064 default: 1065 case 'l': // r0-r7 1066 case 'h': // r8-r15 1067 case 'w': // VFP Floating point register single precision 1068 case 'P': // VFP Floating point register double precision 1069 Info.setAllowsRegister(); 1070 return true; 1071 } 1072 return false; 1073 } 1074 virtual const char *getClobbers() const { 1075 // FIXME: Is this really right? 1076 return ""; 1077 } 1078}; 1079} // end anonymous namespace. 1080 1081 1082namespace { 1083class DarwinARMTargetInfo : 1084 public DarwinTargetInfo<ARMTargetInfo> { 1085protected: 1086 virtual void getOSDefines(const LangOptions &Opts, const char *Triple, 1087 std::vector<char> &Defines) const { 1088 getDarwinDefines(Defines, Opts); 1089 getDarwinIPhoneOSDefines(Defines, Triple); 1090 } 1091 1092public: 1093 DarwinARMTargetInfo(const std::string& triple) 1094 : DarwinTargetInfo<ARMTargetInfo>(triple) {} 1095}; 1096} // end anonymous namespace. 1097 1098namespace { 1099class SparcV8TargetInfo : public TargetInfo { 1100 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1101 static const char * const GCCRegNames[]; 1102public: 1103 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { 1104 // FIXME: Support Sparc quad-precision long double? 1105 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1106 "i64:64:64-f32:32:32-f64:64:64-v64:64:64"; 1107 } 1108 virtual void getTargetDefines(const LangOptions &Opts, 1109 std::vector<char> &Defines) const { 1110 DefineStd(Defines, "sparc", Opts); 1111 Define(Defines, "__sparcv8"); 1112 Define(Defines, "__REGISTER_PREFIX__", ""); 1113 } 1114 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1115 unsigned &NumRecords) const { 1116 // FIXME: Implement! 1117 } 1118 virtual const char *getVAListDeclaration() const { 1119 return "typedef void* __builtin_va_list;"; 1120 } 1121 virtual const char *getTargetPrefix() const { 1122 return "sparc"; 1123 } 1124 virtual void getGCCRegNames(const char * const *&Names, 1125 unsigned &NumNames) const; 1126 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1127 unsigned &NumAliases) const; 1128 virtual bool validateAsmConstraint(const char *&Name, 1129 TargetInfo::ConstraintInfo &info) const { 1130 // FIXME: Implement! 1131 return false; 1132 } 1133 virtual const char *getClobbers() const { 1134 // FIXME: Implement! 1135 return ""; 1136 } 1137}; 1138 1139const char * const SparcV8TargetInfo::GCCRegNames[] = { 1140 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1141 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 1142 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 1143 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" 1144}; 1145 1146void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names, 1147 unsigned &NumNames) const { 1148 Names = GCCRegNames; 1149 NumNames = llvm::array_lengthof(GCCRegNames); 1150} 1151 1152const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = { 1153 { { "g0" }, "r0" }, 1154 { { "g1" }, "r1" }, 1155 { { "g2" }, "r2" }, 1156 { { "g3" }, "r3" }, 1157 { { "g4" }, "r4" }, 1158 { { "g5" }, "r5" }, 1159 { { "g6" }, "r6" }, 1160 { { "g7" }, "r7" }, 1161 { { "o0" }, "r8" }, 1162 { { "o1" }, "r9" }, 1163 { { "o2" }, "r10" }, 1164 { { "o3" }, "r11" }, 1165 { { "o4" }, "r12" }, 1166 { { "o5" }, "r13" }, 1167 { { "o6", "sp" }, "r14" }, 1168 { { "o7" }, "r15" }, 1169 { { "l0" }, "r16" }, 1170 { { "l1" }, "r17" }, 1171 { { "l2" }, "r18" }, 1172 { { "l3" }, "r19" }, 1173 { { "l4" }, "r20" }, 1174 { { "l5" }, "r21" }, 1175 { { "l6" }, "r22" }, 1176 { { "l7" }, "r23" }, 1177 { { "i0" }, "r24" }, 1178 { { "i1" }, "r25" }, 1179 { { "i2" }, "r26" }, 1180 { { "i3" }, "r27" }, 1181 { { "i4" }, "r28" }, 1182 { { "i5" }, "r29" }, 1183 { { "i6", "fp" }, "r30" }, 1184 { { "i7" }, "r31" }, 1185}; 1186 1187void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1188 unsigned &NumAliases) const { 1189 Aliases = GCCRegAliases; 1190 NumAliases = llvm::array_lengthof(GCCRegAliases); 1191} 1192} // end anonymous namespace. 1193 1194namespace { 1195class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> { 1196public: 1197 SolarisSparcV8TargetInfo(const std::string& triple) : 1198 SolarisTargetInfo<SparcV8TargetInfo>(triple) { 1199 SizeType = UnsignedInt; 1200 PtrDiffType = SignedInt; 1201 } 1202}; 1203} // end anonymous namespace. 1204 1205namespace { 1206 class PIC16TargetInfo : public TargetInfo{ 1207 public: 1208 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) { 1209 TLSSupported = false; 1210 IntWidth = 16; 1211 LongWidth = LongLongWidth = 32; 1212 IntMaxTWidth = 32; 1213 PointerWidth = 16; 1214 IntAlign = 8; 1215 LongAlign = LongLongAlign = 8; 1216 PointerAlign = 8; 1217 SizeType = UnsignedInt; 1218 IntMaxType = SignedLong; 1219 UIntMaxType = UnsignedLong; 1220 IntPtrType = SignedShort; 1221 PtrDiffType = SignedInt; 1222 FloatWidth = 32; 1223 FloatAlign = 32; 1224 DoubleWidth = 32; 1225 DoubleAlign = 32; 1226 LongDoubleWidth = 32; 1227 LongDoubleAlign = 32; 1228 FloatFormat = &llvm::APFloat::IEEEsingle; 1229 DoubleFormat = &llvm::APFloat::IEEEsingle; 1230 LongDoubleFormat = &llvm::APFloat::IEEEsingle; 1231 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32"; 1232 1233 } 1234 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; } 1235 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; } 1236 virtual void getTargetDefines(const LangOptions &Opts, 1237 std::vector<char> &Defines) const { 1238 Define(Defines, "__pic16"); 1239 } 1240 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1241 unsigned &NumRecords) const {} 1242 virtual const char *getVAListDeclaration() const { return "";} 1243 virtual const char *getClobbers() const {return "";} 1244 virtual const char *getTargetPrefix() const {return "pic16";} 1245 virtual void getGCCRegNames(const char * const *&Names, 1246 unsigned &NumNames) const {} 1247 virtual bool validateAsmConstraint(const char *&Name, 1248 TargetInfo::ConstraintInfo &info) const { 1249 return true; 1250 } 1251 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1252 unsigned &NumAliases) const {} 1253 virtual bool useGlobalsForAutomaticVariables() const {return true;} 1254 }; 1255} 1256 1257namespace { 1258 class MSP430TargetInfo : public TargetInfo { 1259 static const char * const GCCRegNames[]; 1260 public: 1261 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { 1262 TLSSupported = false; 1263 IntWidth = 16; 1264 LongWidth = LongLongWidth = 32; 1265 IntMaxTWidth = 32; 1266 PointerWidth = 16; 1267 IntAlign = 8; 1268 LongAlign = LongLongAlign = 8; 1269 PointerAlign = 8; 1270 SizeType = UnsignedInt; 1271 IntMaxType = SignedLong; 1272 UIntMaxType = UnsignedLong; 1273 IntPtrType = SignedShort; 1274 PtrDiffType = SignedInt; 1275 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"; 1276 } 1277 virtual void getTargetDefines(const LangOptions &Opts, 1278 std::vector<char> &Defines) const { 1279 Define(Defines, "MSP430"); 1280 Define(Defines, "__MSP430__"); 1281 // FIXME: defines for different 'flavours' of MCU 1282 } 1283 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1284 unsigned &NumRecords) const { 1285 // FIXME: Implement. 1286 Records = 0; 1287 NumRecords = 0; 1288 } 1289 virtual const char *getTargetPrefix() const { 1290 return "msp430"; 1291 } 1292 virtual void getGCCRegNames(const char * const *&Names, 1293 unsigned &NumNames) const; 1294 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1295 unsigned &NumAliases) const { 1296 // No aliases. 1297 Aliases = 0; 1298 NumAliases = 0; 1299 } 1300 virtual bool validateAsmConstraint(const char *&Name, 1301 TargetInfo::ConstraintInfo &info) const { 1302 // FIXME: implement 1303 return true; 1304 } 1305 virtual const char *getClobbers() const { 1306 // FIXME: Is this really right? 1307 return ""; 1308 } 1309 virtual const char *getVAListDeclaration() const { 1310 // FIXME: implement 1311 return "typedef char* __builtin_va_list;"; 1312 } 1313 }; 1314 1315 const char * const MSP430TargetInfo::GCCRegNames[] = { 1316 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1317 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1318 }; 1319 1320 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names, 1321 unsigned &NumNames) const { 1322 Names = GCCRegNames; 1323 NumNames = llvm::array_lengthof(GCCRegNames); 1324 } 1325} 1326 1327 1328//===----------------------------------------------------------------------===// 1329// Driver code 1330//===----------------------------------------------------------------------===// 1331 1332static inline bool IsX86(const std::string& TT) { 1333 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' && 1334 TT[4] == '-' && TT[1] - '3' < 6); 1335} 1336 1337/// CreateTargetInfo - Return the target info object for the specified target 1338/// triple. 1339TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) { 1340 // OS detection; this isn't really anywhere near complete. 1341 // Additions and corrections are welcome. 1342 bool isDarwin = T.find("-darwin") != std::string::npos; 1343 bool isDragonFly = T.find("-dragonfly") != std::string::npos; 1344 bool isOpenBSD = T.find("-openbsd") != std::string::npos; 1345 bool isFreeBSD = T.find("-freebsd") != std::string::npos; 1346 bool isSolaris = T.find("-solaris") != std::string::npos; 1347 bool isLinux = T.find("-linux") != std::string::npos; 1348 bool isWindows = T.find("-windows") != std::string::npos || 1349 T.find("-win32") != std::string::npos || 1350 T.find("-mingw") != std::string::npos; 1351 1352 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) { 1353 if (isDarwin) 1354 return new DarwinTargetInfo<PPCTargetInfo>(T); 1355 return new PPC32TargetInfo(T); 1356 } 1357 1358 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) { 1359 if (isDarwin) 1360 return new DarwinTargetInfo<PPC64TargetInfo>(T); 1361 return new PPC64TargetInfo(T); 1362 } 1363 1364 if (T.find("armv") == 0 || T.find("arm-") == 0 || T.find("xscale") == 0) { 1365 if (isDarwin) 1366 return new DarwinARMTargetInfo(T); 1367 if (isFreeBSD) 1368 return new FreeBSDTargetInfo<ARMTargetInfo>(T); 1369 return new ARMTargetInfo(T); 1370 } 1371 1372 if (T.find("sparc-") == 0) { 1373 if (isSolaris) 1374 return new SolarisSparcV8TargetInfo(T); 1375 return new SparcV8TargetInfo(T); 1376 } 1377 1378 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) { 1379 if (isDarwin) 1380 return new DarwinX86_64TargetInfo(T); 1381 if (isLinux) 1382 return new LinuxTargetInfo<X86_64TargetInfo>(T); 1383 if (isOpenBSD) 1384 return new OpenBSDTargetInfo<X86_64TargetInfo>(T); 1385 if (isFreeBSD) 1386 return new FreeBSDTargetInfo<X86_64TargetInfo>(T); 1387 if (isSolaris) 1388 return new SolarisTargetInfo<X86_64TargetInfo>(T); 1389 return new X86_64TargetInfo(T); 1390 } 1391 1392 if (T.find("pic16-") == 0) 1393 return new PIC16TargetInfo(T); 1394 1395 if (T.find("msp430-") == 0) 1396 return new MSP430TargetInfo(T); 1397 1398 if (IsX86(T)) { 1399 if (isDarwin) 1400 return new DarwinI386TargetInfo(T); 1401 if (isLinux) 1402 return new LinuxTargetInfo<X86_32TargetInfo>(T); 1403 if (isDragonFly) 1404 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T); 1405 if (isOpenBSD) 1406 return new OpenBSDTargetInfo<X86_32TargetInfo>(T); 1407 if (isFreeBSD) 1408 return new FreeBSDTargetInfo<X86_32TargetInfo>(T); 1409 if (isSolaris) 1410 return new SolarisTargetInfo<X86_32TargetInfo>(T); 1411 if (isWindows) 1412 return new WindowsX86_32TargetInfo(T); 1413 return new X86_32TargetInfo(T); 1414 } 1415 1416 return NULL; 1417} 1418