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