Targets.cpp revision 4c3bd3f9f8f1937c1faf2225d14a802f7ea017f0
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/TargetInfo.h" 16#include "clang/Basic/Builtins.h" 17#include "clang/Basic/Diagnostic.h" 18#include "clang/Basic/LangOptions.h" 19#include "clang/Basic/TargetBuiltins.h" 20#include "clang/Basic/TargetOptions.h" 21#include "llvm/ADT/APFloat.h" 22#include "llvm/ADT/OwningPtr.h" 23#include "llvm/ADT/STLExtras.h" 24#include "llvm/ADT/SmallString.h" 25#include "llvm/ADT/StringRef.h" 26#include "llvm/ADT/StringSwitch.h" 27#include "llvm/ADT/Triple.h" 28#include "llvm/MC/MCSectionMachO.h" 29using namespace clang; 30 31//===----------------------------------------------------------------------===// 32// Common code shared among targets. 33//===----------------------------------------------------------------------===// 34 35static void Define(std::vector<char> &Buf, const llvm::StringRef &Macro, 36 const llvm::StringRef &Val = "1") { 37 const char *Def = "#define "; 38 Buf.insert(Buf.end(), Def, Def+strlen(Def)); 39 Buf.insert(Buf.end(), Macro.begin(), Macro.end()); 40 Buf.push_back(' '); 41 Buf.insert(Buf.end(), Val.begin(), Val.end()); 42 Buf.push_back('\n'); 43} 44 45/// DefineStd - Define a macro name and standard variants. For example if 46/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix" 47/// when in GNU mode. 48static void DefineStd(std::vector<char> &Buf, const char *MacroName, 49 const LangOptions &Opts) { 50 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace"); 51 52 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier 53 // in the user's namespace. 54 if (Opts.GNUMode) 55 Define(Buf, MacroName); 56 57 // Define __unix. 58 llvm::SmallString<20> TmpStr; 59 TmpStr = "__"; 60 TmpStr += MacroName; 61 Define(Buf, TmpStr.str()); 62 63 // Define __unix__. 64 TmpStr += "__"; 65 Define(Buf, TmpStr.str()); 66} 67 68//===----------------------------------------------------------------------===// 69// Defines specific to certain operating systems. 70//===----------------------------------------------------------------------===// 71 72namespace { 73template<typename TgtInfo> 74class OSTargetInfo : public TgtInfo { 75protected: 76 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 77 std::vector<char> &Defines) const=0; 78public: 79 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {} 80 virtual void getTargetDefines(const LangOptions &Opts, 81 std::vector<char> &Defines) const { 82 TgtInfo::getTargetDefines(Opts, Defines); 83 getOSDefines(Opts, TgtInfo::getTriple(), Defines); 84 } 85 86}; 87} // end anonymous namespace 88 89 90static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) { 91 Define(Defs, "__APPLE_CC__", "5621"); 92 Define(Defs, "__APPLE__"); 93 Define(Defs, "__MACH__"); 94 Define(Defs, "OBJC_NEW_PROPERTIES"); 95 96 // __weak is always defined, for use in blocks and with objc pointers. 97 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))"); 98 99 // Darwin defines __strong even in C mode (just to nothing). 100 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC) 101 Define(Defs, "__strong", ""); 102 else 103 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))"); 104 105 if (Opts.Static) 106 Define(Defs, "__STATIC__"); 107 else 108 Define(Defs, "__DYNAMIC__"); 109 110 if (Opts.POSIXThreads) 111 Define(Defs, "_REENTRANT", "1"); 112} 113 114static void getDarwinOSXDefines(std::vector<char> &Defs, 115 const llvm::Triple &Triple) { 116 if (Triple.getOS() != llvm::Triple::Darwin) 117 return; 118 119 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5. 120 unsigned Maj, Min, Rev; 121 Triple.getDarwinNumber(Maj, Min, Rev); 122 123 char MacOSXStr[] = "1000"; 124 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9 125 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc. 126 MacOSXStr[2] = '0' + Maj-4; 127 } 128 129 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049" 130 // Cap 10.4.11 -> darwin8.11 -> "1049" 131 MacOSXStr[3] = std::min(Min, 9U)+'0'; 132 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr); 133} 134 135static void getDarwinIPhoneOSDefines(std::vector<char> &Defs, 136 const llvm::Triple &Triple) { 137 if (Triple.getOS() != llvm::Triple::Darwin) 138 return; 139 140 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5. 141 unsigned Maj, Min, Rev; 142 Triple.getDarwinNumber(Maj, Min, Rev); 143 144 // When targetting iPhone OS, interpret the minor version and 145 // revision as the iPhone OS version 146 char iPhoneOSStr[] = "10000"; 147 if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0 148 // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc. 149 iPhoneOSStr[0] = '0' + Min; 150 } 151 152 // Handle minor version: 2.2 -> darwin9.2.2 -> 20200 153 iPhoneOSStr[2] = std::min(Rev, 9U)+'0'; 154 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", 155 iPhoneOSStr); 156} 157 158namespace { 159template<typename Target> 160class DarwinTargetInfo : public OSTargetInfo<Target> { 161protected: 162 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 163 std::vector<char> &Defines) const { 164 getDarwinDefines(Defines, Opts); 165 getDarwinOSXDefines(Defines, Triple); 166 } 167 168public: 169 DarwinTargetInfo(const std::string& triple) : 170 OSTargetInfo<Target>(triple) { 171 this->TLSSupported = false; 172 } 173 174 virtual const char *getUnicodeStringSection() const { 175 return "__TEXT,__ustring"; 176 } 177 178 virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const { 179 // Let MCSectionMachO validate this. 180 llvm::StringRef Segment, Section; 181 unsigned TAA, StubSize; 182 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section, 183 TAA, StubSize); 184 } 185}; 186 187 188// DragonFlyBSD Target 189template<typename Target> 190class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> { 191protected: 192 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 193 std::vector<char> &Defs) const { 194 // DragonFly defines; list based off of gcc output 195 Define(Defs, "__DragonFly__"); 196 Define(Defs, "__DragonFly_cc_version", "100001"); 197 Define(Defs, "__ELF__"); 198 Define(Defs, "__KPRINTF_ATTRIBUTE__"); 199 Define(Defs, "__tune_i386__"); 200 DefineStd(Defs, "unix", Opts); 201 } 202public: 203 DragonFlyBSDTargetInfo(const std::string &triple) 204 : OSTargetInfo<Target>(triple) {} 205}; 206 207// FreeBSD Target 208template<typename Target> 209class FreeBSDTargetInfo : public OSTargetInfo<Target> { 210protected: 211 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 212 std::vector<char> &Defs) const { 213 // FreeBSD defines; list based off of gcc output 214 215 // FIXME: Move version number handling to llvm::Triple. 216 const char *FreeBSD = strstr(Triple.getTriple().c_str(), 217 "-freebsd"); 218 FreeBSD += strlen("-freebsd"); 219 char release[] = "X"; 220 release[0] = FreeBSD[0]; 221 char version[] = "X00001"; 222 version[0] = FreeBSD[0]; 223 224 Define(Defs, "__FreeBSD__", release); 225 Define(Defs, "__FreeBSD_cc_version", version); 226 Define(Defs, "__KPRINTF_ATTRIBUTE__"); 227 DefineStd(Defs, "unix", Opts); 228 Define(Defs, "__ELF__", "1"); 229 } 230public: 231 FreeBSDTargetInfo(const std::string &triple) 232 : OSTargetInfo<Target>(triple) { 233 this->UserLabelPrefix = ""; 234 } 235}; 236 237// Linux target 238template<typename Target> 239class LinuxTargetInfo : public OSTargetInfo<Target> { 240protected: 241 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 242 std::vector<char> &Defs) const { 243 // Linux defines; list based off of gcc output 244 DefineStd(Defs, "unix", Opts); 245 DefineStd(Defs, "linux", Opts); 246 Define(Defs, "__gnu_linux__"); 247 Define(Defs, "__ELF__", "1"); 248 if (Opts.POSIXThreads) 249 Define(Defs, "_REENTRANT", "1"); 250 } 251public: 252 LinuxTargetInfo(const std::string& triple) 253 : OSTargetInfo<Target>(triple) { 254 this->UserLabelPrefix = ""; 255 } 256}; 257 258// NetBSD Target 259template<typename Target> 260class NetBSDTargetInfo : public OSTargetInfo<Target> { 261protected: 262 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 263 std::vector<char> &Defs) const { 264 // NetBSD defines; list based off of gcc output 265 Define(Defs, "__NetBSD__", "1"); 266 Define(Defs, "__unix__", "1"); 267 Define(Defs, "__ELF__", "1"); 268 if (Opts.POSIXThreads) 269 Define(Defs, "_POSIX_THREADS", "1"); 270 } 271public: 272 NetBSDTargetInfo(const std::string &triple) 273 : OSTargetInfo<Target>(triple) { 274 this->UserLabelPrefix = ""; 275 } 276}; 277 278// OpenBSD Target 279template<typename Target> 280class OpenBSDTargetInfo : public OSTargetInfo<Target> { 281protected: 282 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 283 std::vector<char> &Defs) const { 284 // OpenBSD defines; list based off of gcc output 285 286 Define(Defs, "__OpenBSD__", "1"); 287 DefineStd(Defs, "unix", Opts); 288 Define(Defs, "__ELF__", "1"); 289 if (Opts.POSIXThreads) 290 Define(Defs, "_POSIX_THREADS", "1"); 291 } 292public: 293 OpenBSDTargetInfo(const std::string &triple) 294 : OSTargetInfo<Target>(triple) {} 295}; 296 297// PSP Target 298template<typename Target> 299class PSPTargetInfo : public OSTargetInfo<Target> { 300protected: 301 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 302 std::vector<char> &Defs) const { 303 // PSP defines; list based on the output of the pspdev gcc toolchain. 304 Define(Defs, "PSP", "1"); 305 Define(Defs, "_PSP", "1"); 306 Define(Defs, "__psp__", "1"); 307 Define(Defs, "__ELF__", "1"); 308 } 309public: 310 PSPTargetInfo(const std::string& triple) 311 : OSTargetInfo<Target>(triple) { 312 this->UserLabelPrefix = ""; 313 } 314}; 315 316// PS3 PPU Target 317template<typename Target> 318class PS3PPUTargetInfo : public OSTargetInfo<Target> { 319protected: 320 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 321 std::vector<char> &Defs) const { 322 // PS3 PPU defines. 323 Define(Defs, "__PPU__", "1"); 324 Define(Defs, "__CELLOS_LV2__", "1"); 325 Define(Defs, "__ELF__", "1"); 326 Define(Defs, "__LP32__", "1"); 327 } 328public: 329 PS3PPUTargetInfo(const std::string& triple) 330 : OSTargetInfo<Target>(triple) { 331 this->UserLabelPrefix = ""; 332 this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32; 333 this->SizeType = TargetInfo::UnsignedInt; 334 } 335}; 336 337// FIXME: Need a real SPU target. 338// PS3 SPU Target 339template<typename Target> 340class PS3SPUTargetInfo : public OSTargetInfo<Target> { 341protected: 342 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 343 std::vector<char> &Defs) const { 344 // PS3 PPU defines. 345 Define(Defs, "__SPU__", "1"); 346 Define(Defs, "__ELF__", "1"); 347 } 348public: 349 PS3SPUTargetInfo(const std::string& triple) 350 : OSTargetInfo<Target>(triple) { 351 this->UserLabelPrefix = ""; 352 } 353}; 354 355// AuroraUX target 356template<typename Target> 357class AuroraUXTargetInfo : public OSTargetInfo<Target> { 358protected: 359 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 360 std::vector<char> &Defs) const { 361 DefineStd(Defs, "sun", Opts); 362 DefineStd(Defs, "unix", Opts); 363 Define(Defs, "__ELF__"); 364 Define(Defs, "__svr4__"); 365 Define(Defs, "__SVR4"); 366 } 367public: 368 AuroraUXTargetInfo(const std::string& triple) 369 : OSTargetInfo<Target>(triple) { 370 this->UserLabelPrefix = ""; 371 this->WCharType = this->SignedLong; 372 // FIXME: WIntType should be SignedLong 373 } 374}; 375 376// Solaris target 377template<typename Target> 378class SolarisTargetInfo : public OSTargetInfo<Target> { 379protected: 380 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 381 std::vector<char> &Defs) const { 382 DefineStd(Defs, "sun", Opts); 383 DefineStd(Defs, "unix", Opts); 384 Define(Defs, "__ELF__"); 385 Define(Defs, "__svr4__"); 386 Define(Defs, "__SVR4"); 387 } 388public: 389 SolarisTargetInfo(const std::string& triple) 390 : OSTargetInfo<Target>(triple) { 391 this->UserLabelPrefix = ""; 392 this->WCharType = this->SignedLong; 393 // FIXME: WIntType should be SignedLong 394 } 395}; 396} // end anonymous namespace. 397 398//===----------------------------------------------------------------------===// 399// Specific target implementations. 400//===----------------------------------------------------------------------===// 401 402namespace { 403// PPC abstract base class 404class PPCTargetInfo : public TargetInfo { 405 static const Builtin::Info BuiltinInfo[]; 406 static const char * const GCCRegNames[]; 407 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 408 409public: 410 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {} 411 412 virtual void getTargetBuiltins(const Builtin::Info *&Records, 413 unsigned &NumRecords) const { 414 Records = BuiltinInfo; 415 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin; 416 } 417 418 virtual void getTargetDefines(const LangOptions &Opts, 419 std::vector<char> &Defines) const; 420 421 virtual const char *getVAListDeclaration() const { 422 return "typedef char* __builtin_va_list;"; 423 // This is the right definition for ABI/V4: System V.4/eabi. 424 /*return "typedef struct __va_list_tag {" 425 " unsigned char gpr;" 426 " unsigned char fpr;" 427 " unsigned short reserved;" 428 " void* overflow_arg_area;" 429 " void* reg_save_area;" 430 "} __builtin_va_list[1];";*/ 431 } 432 virtual void getGCCRegNames(const char * const *&Names, 433 unsigned &NumNames) const; 434 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 435 unsigned &NumAliases) const; 436 virtual bool validateAsmConstraint(const char *&Name, 437 TargetInfo::ConstraintInfo &Info) const { 438 switch (*Name) { 439 default: return false; 440 case 'O': // Zero 441 return true; 442 case 'b': // Base register 443 case 'f': // Floating point register 444 Info.setAllowsRegister(); 445 return true; 446 } 447 } 448 virtual const char *getClobbers() const { 449 return ""; 450 } 451}; 452 453const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { 454#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false }, 455#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false }, 456#include "clang/Basic/BuiltinsPPC.def" 457}; 458 459 460/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific 461/// #defines that are not tied to a specific subtarget. 462void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, 463 std::vector<char> &Defs) const { 464 // Target identification. 465 Define(Defs, "__ppc__"); 466 Define(Defs, "_ARCH_PPC"); 467 Define(Defs, "__POWERPC__"); 468 if (PointerWidth == 64) { 469 Define(Defs, "_ARCH_PPC64"); 470 Define(Defs, "_LP64"); 471 Define(Defs, "__LP64__"); 472 Define(Defs, "__ppc64__"); 473 } else { 474 Define(Defs, "__ppc__"); 475 } 476 477 // Target properties. 478 Define(Defs, "_BIG_ENDIAN"); 479 Define(Defs, "__BIG_ENDIAN__"); 480 481 // Subtarget options. 482 Define(Defs, "__NATURAL_ALIGNMENT__"); 483 Define(Defs, "__REGISTER_PREFIX__", ""); 484 485 // FIXME: Should be controlled by command line option. 486 Define(Defs, "__LONG_DOUBLE_128__"); 487 488 if (Opts.AltiVec) { 489 Define(Defs, "__VEC__", "10206"); 490 Define(Defs, "__ALTIVEC__", "1"); 491 } 492} 493 494 495const char * const PPCTargetInfo::GCCRegNames[] = { 496 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 497 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 498 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 499 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 500 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 501 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", 502 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 503 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", 504 "mq", "lr", "ctr", "ap", 505 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", 506 "xer", 507 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", 508 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", 509 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", 510 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", 511 "vrsave", "vscr", 512 "spe_acc", "spefscr", 513 "sfp" 514}; 515 516void PPCTargetInfo::getGCCRegNames(const char * const *&Names, 517 unsigned &NumNames) const { 518 Names = GCCRegNames; 519 NumNames = llvm::array_lengthof(GCCRegNames); 520} 521 522const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { 523 // While some of these aliases do map to different registers 524 // they still share the same register name. 525 { { "0" }, "r0" }, 526 { { "1"}, "r1" }, 527 { { "2" }, "r2" }, 528 { { "3" }, "r3" }, 529 { { "4" }, "r4" }, 530 { { "5" }, "r5" }, 531 { { "6" }, "r6" }, 532 { { "7" }, "r7" }, 533 { { "8" }, "r8" }, 534 { { "9" }, "r9" }, 535 { { "10" }, "r10" }, 536 { { "11" }, "r11" }, 537 { { "12" }, "r12" }, 538 { { "13" }, "r13" }, 539 { { "14" }, "r14" }, 540 { { "15" }, "r15" }, 541 { { "16" }, "r16" }, 542 { { "17" }, "r17" }, 543 { { "18" }, "r18" }, 544 { { "19" }, "r19" }, 545 { { "20" }, "r20" }, 546 { { "21" }, "r21" }, 547 { { "22" }, "r22" }, 548 { { "23" }, "r23" }, 549 { { "24" }, "r24" }, 550 { { "25" }, "r25" }, 551 { { "26" }, "r26" }, 552 { { "27" }, "r27" }, 553 { { "28" }, "r28" }, 554 { { "29" }, "r29" }, 555 { { "30" }, "r30" }, 556 { { "31" }, "r31" }, 557 { { "fr0" }, "f0" }, 558 { { "fr1" }, "f1" }, 559 { { "fr2" }, "f2" }, 560 { { "fr3" }, "f3" }, 561 { { "fr4" }, "f4" }, 562 { { "fr5" }, "f5" }, 563 { { "fr6" }, "f6" }, 564 { { "fr7" }, "f7" }, 565 { { "fr8" }, "f8" }, 566 { { "fr9" }, "f9" }, 567 { { "fr10" }, "f10" }, 568 { { "fr11" }, "f11" }, 569 { { "fr12" }, "f12" }, 570 { { "fr13" }, "f13" }, 571 { { "fr14" }, "f14" }, 572 { { "fr15" }, "f15" }, 573 { { "fr16" }, "f16" }, 574 { { "fr17" }, "f17" }, 575 { { "fr18" }, "f18" }, 576 { { "fr19" }, "f19" }, 577 { { "fr20" }, "f20" }, 578 { { "fr21" }, "f21" }, 579 { { "fr22" }, "f22" }, 580 { { "fr23" }, "f23" }, 581 { { "fr24" }, "f24" }, 582 { { "fr25" }, "f25" }, 583 { { "fr26" }, "f26" }, 584 { { "fr27" }, "f27" }, 585 { { "fr28" }, "f28" }, 586 { { "fr29" }, "f29" }, 587 { { "fr30" }, "f30" }, 588 { { "fr31" }, "f31" }, 589 { { "cc" }, "cr0" }, 590}; 591 592void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 593 unsigned &NumAliases) const { 594 Aliases = GCCRegAliases; 595 NumAliases = llvm::array_lengthof(GCCRegAliases); 596} 597} // end anonymous namespace. 598 599namespace { 600class PPC32TargetInfo : public PPCTargetInfo { 601public: 602 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) { 603 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 604 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32"; 605 } 606}; 607} // end anonymous namespace. 608 609namespace { 610class PPC64TargetInfo : public PPCTargetInfo { 611public: 612 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) { 613 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 614 IntMaxType = SignedLong; 615 UIntMaxType = UnsignedLong; 616 Int64Type = SignedLong; 617 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 618 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"; 619 } 620}; 621} // end anonymous namespace. 622 623namespace { 624// Namespace for x86 abstract base class 625const Builtin::Info BuiltinInfo[] = { 626#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false }, 627#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false }, 628#include "clang/Basic/BuiltinsX86.def" 629}; 630 631const char *GCCRegNames[] = { 632 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", 633 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", 634 "argp", "flags", "fspr", "dirflag", "frame", 635 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", 636 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", 637 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 638 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" 639}; 640 641const TargetInfo::GCCRegAlias GCCRegAliases[] = { 642 { { "al", "ah", "eax", "rax" }, "ax" }, 643 { { "bl", "bh", "ebx", "rbx" }, "bx" }, 644 { { "cl", "ch", "ecx", "rcx" }, "cx" }, 645 { { "dl", "dh", "edx", "rdx" }, "dx" }, 646 { { "esi", "rsi" }, "si" }, 647 { { "edi", "rdi" }, "di" }, 648 { { "esp", "rsp" }, "sp" }, 649 { { "ebp", "rbp" }, "bp" }, 650}; 651 652// X86 target abstract base class; x86-32 and x86-64 are very close, so 653// most of the implementation can be shared. 654class X86TargetInfo : public TargetInfo { 655 enum X86SSEEnum { 656 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42 657 } SSELevel; 658public: 659 X86TargetInfo(const std::string& triple) 660 : TargetInfo(triple), SSELevel(NoMMXSSE) { 661 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; 662 } 663 virtual void getTargetBuiltins(const Builtin::Info *&Records, 664 unsigned &NumRecords) const { 665 Records = BuiltinInfo; 666 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin; 667 } 668 virtual void getGCCRegNames(const char * const *&Names, 669 unsigned &NumNames) const { 670 Names = GCCRegNames; 671 NumNames = llvm::array_lengthof(GCCRegNames); 672 } 673 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 674 unsigned &NumAliases) const { 675 Aliases = GCCRegAliases; 676 NumAliases = llvm::array_lengthof(GCCRegAliases); 677 } 678 virtual bool validateAsmConstraint(const char *&Name, 679 TargetInfo::ConstraintInfo &info) const; 680 virtual std::string convertConstraint(const char Constraint) const; 681 virtual const char *getClobbers() const { 682 return "~{dirflag},~{fpsr},~{flags}"; 683 } 684 virtual void getTargetDefines(const LangOptions &Opts, 685 std::vector<char> &Defines) const; 686 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 687 const std::string &Name, 688 bool Enabled) const; 689 virtual void getDefaultFeatures(const std::string &CPU, 690 llvm::StringMap<bool> &Features) const; 691 virtual void HandleTargetFeatures(const std::vector<std::string> &Features); 692}; 693 694void X86TargetInfo::getDefaultFeatures(const std::string &CPU, 695 llvm::StringMap<bool> &Features) const { 696 // FIXME: This should not be here. 697 Features["3dnow"] = false; 698 Features["3dnowa"] = false; 699 Features["mmx"] = false; 700 Features["sse"] = false; 701 Features["sse2"] = false; 702 Features["sse3"] = false; 703 Features["ssse3"] = false; 704 Features["sse41"] = false; 705 Features["sse42"] = false; 706 707 // LLVM does not currently recognize this. 708 // Features["sse4a"] = false; 709 710 // FIXME: This *really* should not be here. 711 712 // X86_64 always has SSE2. 713 if (PointerWidth == 64) 714 Features["sse2"] = Features["sse"] = Features["mmx"] = true; 715 716 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" || 717 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro") 718 ; 719 else if (CPU == "pentium-mmx" || CPU == "pentium2") 720 setFeatureEnabled(Features, "mmx", true); 721 else if (CPU == "pentium3") 722 setFeatureEnabled(Features, "sse", true); 723 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64") 724 setFeatureEnabled(Features, "sse2", true); 725 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona") 726 setFeatureEnabled(Features, "sse3", true); 727 else if (CPU == "core2") 728 setFeatureEnabled(Features, "ssse3", true); 729 else if (CPU == "penryn") { 730 setFeatureEnabled(Features, "sse4", true); 731 Features["sse42"] = false; 732 } else if (CPU == "atom") 733 setFeatureEnabled(Features, "sse3", true); 734 else if (CPU == "corei7") 735 setFeatureEnabled(Features, "sse4", true); 736 else if (CPU == "k6" || CPU == "winchip-c6") 737 setFeatureEnabled(Features, "mmx", true); 738 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" || 739 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") { 740 setFeatureEnabled(Features, "mmx", true); 741 setFeatureEnabled(Features, "3dnow", true); 742 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") { 743 setFeatureEnabled(Features, "sse", true); 744 setFeatureEnabled(Features, "3dnowa", true); 745 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" || 746 CPU == "athlon-fx") { 747 setFeatureEnabled(Features, "sse2", true); 748 setFeatureEnabled(Features, "3dnowa", true); 749 } else if (CPU == "c3-2") 750 setFeatureEnabled(Features, "sse", true); 751} 752 753bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, 754 const std::string &Name, 755 bool Enabled) const { 756 // FIXME: This *really* should not be here. 757 if (!Features.count(Name) && Name != "sse4") 758 return false; 759 760 if (Enabled) { 761 if (Name == "mmx") 762 Features["mmx"] = true; 763 else if (Name == "sse") 764 Features["mmx"] = Features["sse"] = true; 765 else if (Name == "sse2") 766 Features["mmx"] = Features["sse"] = Features["sse2"] = true; 767 else if (Name == "sse3") 768 Features["mmx"] = Features["sse"] = Features["sse2"] = 769 Features["sse3"] = true; 770 else if (Name == "ssse3") 771 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 772 Features["ssse3"] = true; 773 else if (Name == "sse4") 774 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 775 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true; 776 else if (Name == "3dnow") 777 Features["3dnowa"] = true; 778 else if (Name == "3dnowa") 779 Features["3dnow"] = Features["3dnowa"] = true; 780 } else { 781 if (Name == "mmx") 782 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 783 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; 784 else if (Name == "sse") 785 Features["sse"] = Features["sse2"] = Features["sse3"] = 786 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; 787 else if (Name == "sse2") 788 Features["sse2"] = Features["sse3"] = Features["ssse3"] = 789 Features["sse41"] = Features["sse42"] = false; 790 else if (Name == "sse3") 791 Features["sse3"] = Features["ssse3"] = Features["sse41"] = 792 Features["sse42"] = false; 793 else if (Name == "ssse3") 794 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; 795 else if (Name == "sse4") 796 Features["sse41"] = Features["sse42"] = false; 797 else if (Name == "3dnow") 798 Features["3dnow"] = Features["3dnowa"] = false; 799 else if (Name == "3dnowa") 800 Features["3dnowa"] = false; 801 } 802 803 return true; 804} 805 806/// HandleTargetOptions - Perform initialization based on the user 807/// configured set of features. 808void 809X86TargetInfo::HandleTargetFeatures(const std::vector<std::string> &Features) { 810 // Remember the maximum enabled sselevel. 811 for (unsigned i = 0, e = Features.size(); i !=e; ++i) { 812 // Ignore disabled features. 813 if (Features[i][0] == '-') 814 continue; 815 816 assert(Features[i][0] == '+' && "Invalid target feature!"); 817 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1)) 818 .Case("sse42", SSE42) 819 .Case("sse41", SSE41) 820 .Case("ssse3", SSSE3) 821 .Case("sse2", SSE2) 822 .Case("sse", SSE1) 823 .Case("mmx", MMX) 824 .Default(NoMMXSSE); 825 SSELevel = std::max(SSELevel, Level); 826 } 827} 828 829/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines 830/// that are not tied to a specific subtarget. 831void X86TargetInfo::getTargetDefines(const LangOptions &Opts, 832 std::vector<char> &Defs) const { 833 // Target identification. 834 if (PointerWidth == 64) { 835 Define(Defs, "_LP64"); 836 Define(Defs, "__LP64__"); 837 Define(Defs, "__amd64__"); 838 Define(Defs, "__amd64"); 839 Define(Defs, "__x86_64"); 840 Define(Defs, "__x86_64__"); 841 } else { 842 DefineStd(Defs, "i386", Opts); 843 } 844 845 // Target properties. 846 Define(Defs, "__LITTLE_ENDIAN__"); 847 848 // Subtarget options. 849 Define(Defs, "__nocona"); 850 Define(Defs, "__nocona__"); 851 Define(Defs, "__tune_nocona__"); 852 Define(Defs, "__REGISTER_PREFIX__", ""); 853 854 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline 855 // functions in glibc header files that use FP Stack inline asm which the 856 // backend can't deal with (PR879). 857 Define(Defs, "__NO_MATH_INLINES"); 858 859 // Each case falls through to the previous one here. 860 switch (SSELevel) { 861 case SSE42: 862 Define(Defs, "__SSE4_2__"); 863 case SSE41: 864 Define(Defs, "__SSE4_1__"); 865 case SSSE3: 866 Define(Defs, "__SSSE3__"); 867 case SSE3: 868 Define(Defs, "__SSE3__"); 869 case SSE2: 870 Define(Defs, "__SSE2__"); 871 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied. 872 case SSE1: 873 Define(Defs, "__SSE__"); 874 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied. 875 case MMX: 876 Define(Defs, "__MMX__"); 877 case NoMMXSSE: 878 break; 879 } 880} 881 882 883bool 884X86TargetInfo::validateAsmConstraint(const char *&Name, 885 TargetInfo::ConstraintInfo &Info) const { 886 switch (*Name) { 887 default: return false; 888 case 'a': // eax. 889 case 'b': // ebx. 890 case 'c': // ecx. 891 case 'd': // edx. 892 case 'S': // esi. 893 case 'D': // edi. 894 case 'A': // edx:eax. 895 case 't': // top of floating point stack. 896 case 'u': // second from top of floating point stack. 897 case 'q': // Any register accessible as [r]l: a, b, c, and d. 898 case 'y': // Any MMX register. 899 case 'x': // Any SSE register. 900 case 'Q': // Any register accessible as [r]h: a, b, c, and d. 901 case 'e': // 32-bit signed integer constant for use with zero-extending 902 // x86_64 instructions. 903 case 'Z': // 32-bit unsigned integer constant for use with zero-extending 904 // x86_64 instructions. 905 case 'N': // unsigned 8-bit integer constant for use with in and out 906 // instructions. 907 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp. 908 Info.setAllowsRegister(); 909 return true; 910 } 911} 912 913std::string 914X86TargetInfo::convertConstraint(const char Constraint) const { 915 switch (Constraint) { 916 case 'a': return std::string("{ax}"); 917 case 'b': return std::string("{bx}"); 918 case 'c': return std::string("{cx}"); 919 case 'd': return std::string("{dx}"); 920 case 'S': return std::string("{si}"); 921 case 'D': return std::string("{di}"); 922 case 't': // top of floating point stack. 923 return std::string("{st}"); 924 case 'u': // second from top of floating point stack. 925 return std::string("{st(1)}"); // second from top of floating point stack. 926 default: 927 return std::string(1, Constraint); 928 } 929} 930} // end anonymous namespace 931 932namespace { 933// X86-32 generic target 934class X86_32TargetInfo : public X86TargetInfo { 935public: 936 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) { 937 DoubleAlign = LongLongAlign = 32; 938 LongDoubleWidth = 96; 939 LongDoubleAlign = 32; 940 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 941 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 942 "a0:0:64-f80:32:32-n8:16:32"; 943 SizeType = UnsignedInt; 944 PtrDiffType = SignedInt; 945 IntPtrType = SignedInt; 946 RegParmMax = 3; 947 } 948 virtual const char *getVAListDeclaration() const { 949 return "typedef char* __builtin_va_list;"; 950 } 951 952 int getEHDataRegisterNumber(unsigned RegNo) const { 953 if (RegNo == 0) return 0; 954 if (RegNo == 1) return 2; 955 return -1; 956 } 957}; 958} // end anonymous namespace 959 960namespace { 961class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> { 962public: 963 OpenBSDI386TargetInfo(const std::string& triple) : 964 OpenBSDTargetInfo<X86_32TargetInfo>(triple) { 965 SizeType = UnsignedLong; 966 IntPtrType = SignedLong; 967 PtrDiffType = SignedLong; 968 } 969}; 970} // end anonymous namespace 971 972namespace { 973class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> { 974public: 975 DarwinI386TargetInfo(const std::string& triple) : 976 DarwinTargetInfo<X86_32TargetInfo>(triple) { 977 LongDoubleWidth = 128; 978 LongDoubleAlign = 128; 979 SizeType = UnsignedLong; 980 IntPtrType = SignedLong; 981 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 982 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 983 "a0:0:64-f80:128:128-n8:16:32"; 984 } 985 986}; 987} // end anonymous namespace 988 989namespace { 990// x86-32 Windows target 991class WindowsX86_32TargetInfo : public X86_32TargetInfo { 992public: 993 WindowsX86_32TargetInfo(const std::string& triple) 994 : X86_32TargetInfo(triple) { 995 TLSSupported = false; 996 WCharType = UnsignedShort; 997 DoubleAlign = LongLongAlign = 64; 998 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 999 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 1000 "a0:0:64-f80:32:32-n8:16:32"; 1001 } 1002 virtual void getTargetDefines(const LangOptions &Opts, 1003 std::vector<char> &Defines) const { 1004 X86_32TargetInfo::getTargetDefines(Opts, Defines); 1005 // This list is based off of the the list of things MingW defines 1006 Define(Defines, "_WIN32"); 1007 DefineStd(Defines, "WIN32", Opts); 1008 DefineStd(Defines, "WINNT", Opts); 1009 Define(Defines, "_X86_"); 1010 } 1011}; 1012} // end anonymous namespace 1013 1014namespace { 1015 1016// x86-32 Windows Visual Studio target 1017class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo { 1018public: 1019 VisualStudioWindowsX86_32TargetInfo(const std::string& triple) 1020 : WindowsX86_32TargetInfo(triple) { 1021 } 1022 virtual void getTargetDefines(const LangOptions &Opts, 1023 std::vector<char> &Defines) const { 1024 WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines); 1025 // The value of the following reflects processor type. 1026 // 300=386, 400=486, 500=Pentium, 600=Blend (default) 1027 // We lost the original triple, so we use the default. 1028 Define(Defines, "_M_IX86", "600"); 1029 } 1030}; 1031} // end anonymous namespace 1032 1033namespace { 1034// x86-32 MinGW target 1035class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo { 1036public: 1037 MinGWX86_32TargetInfo(const std::string& triple) 1038 : WindowsX86_32TargetInfo(triple) { 1039 } 1040 virtual void getTargetDefines(const LangOptions &Opts, 1041 std::vector<char> &Defines) const { 1042 WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines); 1043 Define(Defines, "__MSVCRT__"); 1044 Define(Defines, "__MINGW32__"); 1045 Define(Defines, "__declspec", "__declspec"); 1046 } 1047}; 1048} // end anonymous namespace 1049 1050namespace { 1051// x86-32 Cygwin target 1052class CygwinX86_32TargetInfo : public X86_32TargetInfo { 1053public: 1054 CygwinX86_32TargetInfo(const std::string& triple) 1055 : X86_32TargetInfo(triple) { 1056 TLSSupported = false; 1057 WCharType = UnsignedShort; 1058 DoubleAlign = LongLongAlign = 64; 1059 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1060 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 1061 "a0:0:64-f80:32:32-n8:16:32"; 1062 } 1063 virtual void getTargetDefines(const LangOptions &Opts, 1064 std::vector<char> &Defines) const { 1065 X86_32TargetInfo::getTargetDefines(Opts, Defines); 1066 Define(Defines, "__CYGWIN__"); 1067 Define(Defines, "__CYGWIN32__"); 1068 DefineStd(Defines, "unix", Opts); 1069 } 1070}; 1071} // end anonymous namespace 1072 1073namespace { 1074// x86-64 generic target 1075class X86_64TargetInfo : public X86TargetInfo { 1076public: 1077 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) { 1078 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 1079 LongDoubleWidth = 128; 1080 LongDoubleAlign = 128; 1081 IntMaxType = SignedLong; 1082 UIntMaxType = UnsignedLong; 1083 Int64Type = SignedLong; 1084 RegParmMax = 6; 1085 1086 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1087 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 1088 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"; 1089 } 1090 virtual const char *getVAListDeclaration() const { 1091 return "typedef struct __va_list_tag {" 1092 " unsigned gp_offset;" 1093 " unsigned fp_offset;" 1094 " void* overflow_arg_area;" 1095 " void* reg_save_area;" 1096 "} __va_list_tag;" 1097 "typedef __va_list_tag __builtin_va_list[1];"; 1098 } 1099 1100 int getEHDataRegisterNumber(unsigned RegNo) const { 1101 if (RegNo == 0) return 0; 1102 if (RegNo == 1) return 1; 1103 return -1; 1104 } 1105}; 1106} // end anonymous namespace 1107 1108namespace { 1109// x86-64 Windows target 1110class WindowsX86_64TargetInfo : public X86_64TargetInfo { 1111public: 1112 WindowsX86_64TargetInfo(const std::string& triple) 1113 : X86_64TargetInfo(triple) { 1114 TLSSupported = false; 1115 WCharType = UnsignedShort; 1116 LongWidth = LongAlign = 32; 1117 DoubleAlign = LongLongAlign = 64; 1118 } 1119 virtual void getTargetDefines(const LangOptions &Opts, 1120 std::vector<char> &Defines) const { 1121 X86_64TargetInfo::getTargetDefines(Opts, Defines); 1122 Define(Defines, "_WIN64"); 1123 DefineStd(Defines, "WIN64", Opts); 1124 } 1125}; 1126} // end anonymous namespace 1127 1128namespace { 1129// x86-64 Windows Visual Studio target 1130class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo { 1131public: 1132 VisualStudioWindowsX86_64TargetInfo(const std::string& triple) 1133 : WindowsX86_64TargetInfo(triple) { 1134 } 1135 virtual void getTargetDefines(const LangOptions &Opts, 1136 std::vector<char> &Defines) const { 1137 WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines); 1138 Define(Defines, "_M_X64"); 1139 } 1140 virtual const char *getVAListDeclaration() const { 1141 return "typedef char* va_list;"; 1142 } 1143}; 1144} // end anonymous namespace 1145 1146namespace { 1147// x86-64 MinGW target 1148class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo { 1149public: 1150 MinGWX86_64TargetInfo(const std::string& triple) 1151 : WindowsX86_64TargetInfo(triple) { 1152 } 1153 virtual void getTargetDefines(const LangOptions &Opts, 1154 std::vector<char> &Defines) const { 1155 WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines); 1156 Define(Defines, "__MSVCRT__"); 1157 Define(Defines, "__MINGW64__"); 1158 Define(Defines, "__declspec"); 1159 } 1160}; 1161} // end anonymous namespace 1162 1163namespace { 1164class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> { 1165public: 1166 DarwinX86_64TargetInfo(const std::string& triple) 1167 : DarwinTargetInfo<X86_64TargetInfo>(triple) { 1168 Int64Type = SignedLongLong; 1169 } 1170}; 1171} // end anonymous namespace 1172 1173namespace { 1174class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> { 1175public: 1176 OpenBSDX86_64TargetInfo(const std::string& triple) 1177 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) { 1178 IntMaxType = SignedLongLong; 1179 UIntMaxType = UnsignedLongLong; 1180 Int64Type = SignedLongLong; 1181 } 1182}; 1183} // end anonymous namespace 1184 1185namespace { 1186class ARMTargetInfo : public TargetInfo { 1187 enum { 1188 Armv4t, 1189 Armv5, 1190 Armv6, 1191 Armv7a, 1192 XScale 1193 } ArmArch; 1194 1195 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1196 static const char * const GCCRegNames[]; 1197 1198 std::string ABI; 1199 bool IsThumb; 1200 1201public: 1202 ARMTargetInfo(const std::string &TripleStr) 1203 : TargetInfo(TripleStr), ABI("aapcs-linux"), IsThumb(false) 1204 { 1205 llvm::Triple Triple(TripleStr); 1206 1207 SizeType = UnsignedInt; 1208 PtrDiffType = SignedInt; 1209 1210 // FIXME: This shouldn't be done this way, we should use features to 1211 // indicate the arch. See lib/Driver/Tools.cpp. 1212 llvm::StringRef Version(""), Arch = Triple.getArchName(); 1213 if (Arch.startswith("arm")) 1214 Version = Arch.substr(3); 1215 else if (Arch.startswith("thumb")) 1216 Version = Arch.substr(5); 1217 if (Version == "v7") 1218 ArmArch = Armv7a; 1219 else if (Version.empty() || Version == "v6" || Version == "v6t2") 1220 ArmArch = Armv6; 1221 else if (Version == "v5") 1222 ArmArch = Armv5; 1223 else if (Version == "v4t") 1224 ArmArch = Armv4t; 1225 else if (Arch == "xscale" || Arch == "thumbv5e") 1226 ArmArch = XScale; 1227 else 1228 ArmArch = Armv6; 1229 1230 if (Arch.startswith("thumb")) 1231 IsThumb = true; 1232 1233 if (IsThumb) { 1234 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" 1235 "i64:64:64-f32:32:32-f64:64:64-" 1236 "v64:64:64-v128:128:128-a0:0:32-n32"); 1237 } else { 1238 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1239 "i64:64:64-f32:32:32-f64:64:64-" 1240 "v64:64:64-v128:128:128-a0:0:64-n32"); 1241 } 1242 } 1243 virtual const char *getABI() const { return ABI.c_str(); } 1244 virtual bool setABI(const std::string &Name) { 1245 ABI = Name; 1246 1247 // The defaults (above) are for AAPCS, check if we need to change them. 1248 // 1249 // FIXME: We need support for -meabi... we could just mangle it into the 1250 // name. 1251 if (Name == "apcs-gnu") { 1252 DoubleAlign = LongLongAlign = 32; 1253 SizeType = UnsignedLong; 1254 1255 if (IsThumb) { 1256 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" 1257 "i64:32:32-f32:32:32-f64:32:32-" 1258 "v64:64:64-v128:128:128-a0:0:32-n32"); 1259 } else { 1260 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1261 "i64:32:32-f32:32:32-f64:32:32-" 1262 "v64:64:64-v128:128:128-a0:0:64-n32"); 1263 } 1264 1265 // FIXME: Override "preferred align" for double and long long. 1266 } else if (Name == "aapcs") { 1267 // FIXME: Enumerated types are variable width in straight AAPCS. 1268 } else if (Name == "aapcs-linux") { 1269 ; 1270 } else 1271 return false; 1272 1273 return true; 1274 } 1275 virtual void getTargetDefines(const LangOptions &Opts, 1276 std::vector<char> &Defs) const { 1277 // Target identification. 1278 Define(Defs, "__arm"); 1279 Define(Defs, "__arm__"); 1280 1281 // Target properties. 1282 Define(Defs, "__LITTLE_ENDIAN__"); 1283 1284 // Subtarget options. 1285 // 1286 // FIXME: Neither THUMB_INTERWORK nor SOFTFP is not being set correctly 1287 // here. 1288 if (ArmArch == Armv7a) { 1289 Define(Defs, "__ARM_ARCH_7A__"); 1290 Define(Defs, "__THUMB_INTERWORK__"); 1291 } else if (ArmArch == Armv6) { 1292 Define(Defs, "__ARM_ARCH_6K__"); 1293 Define(Defs, "__THUMB_INTERWORK__"); 1294 } else if (ArmArch == Armv5) { 1295 Define(Defs, "__ARM_ARCH_5TEJ__"); 1296 Define(Defs, "__THUMB_INTERWORK__"); 1297 Define(Defs, "__SOFTFP__"); 1298 } else if (ArmArch == Armv4t) { 1299 Define(Defs, "__ARM_ARCH_4T__"); 1300 Define(Defs, "__SOFTFP__"); 1301 } else if (ArmArch == XScale) { 1302 Define(Defs, "__ARM_ARCH_5TE__"); 1303 Define(Defs, "__XSCALE__"); 1304 Define(Defs, "__SOFTFP__"); 1305 } 1306 1307 Define(Defs, "__ARMEL__"); 1308 1309 if (IsThumb) { 1310 Define(Defs, "__THUMBEL__"); 1311 Define(Defs, "__thumb__"); 1312 if (ArmArch == Armv7a) 1313 Define(Defs, "__thumb2__"); 1314 } 1315 1316 // Note, this is always on in gcc, even though it doesn't make sense. 1317 Define(Defs, "__APCS_32__"); 1318 // FIXME: This should be conditional on VFP instruction support. 1319 Define(Defs, "__VFP_FP__"); 1320 1321 Define(Defs, "__USING_SJLJ_EXCEPTIONS__"); 1322 } 1323 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1324 unsigned &NumRecords) const { 1325 // FIXME: Implement. 1326 Records = 0; 1327 NumRecords = 0; 1328 } 1329 virtual const char *getVAListDeclaration() const { 1330 return "typedef char* __builtin_va_list;"; 1331 } 1332 virtual void getGCCRegNames(const char * const *&Names, 1333 unsigned &NumNames) const; 1334 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1335 unsigned &NumAliases) const; 1336 virtual bool validateAsmConstraint(const char *&Name, 1337 TargetInfo::ConstraintInfo &Info) const { 1338 // FIXME: Check if this is complete 1339 switch (*Name) { 1340 default: 1341 case 'l': // r0-r7 1342 case 'h': // r8-r15 1343 case 'w': // VFP Floating point register single precision 1344 case 'P': // VFP Floating point register double precision 1345 Info.setAllowsRegister(); 1346 return true; 1347 } 1348 return false; 1349 } 1350 virtual const char *getClobbers() const { 1351 // FIXME: Is this really right? 1352 return ""; 1353 } 1354}; 1355 1356const char * const ARMTargetInfo::GCCRegNames[] = { 1357 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1358 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1359}; 1360 1361void ARMTargetInfo::getGCCRegNames(const char * const *&Names, 1362 unsigned &NumNames) const { 1363 Names = GCCRegNames; 1364 NumNames = llvm::array_lengthof(GCCRegNames); 1365} 1366 1367const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 1368 1369 { { "a1" }, "r0" }, 1370 { { "a2" }, "r1" }, 1371 { { "a3" }, "r2" }, 1372 { { "a4" }, "r3" }, 1373 { { "v1" }, "r4" }, 1374 { { "v2" }, "r5" }, 1375 { { "v3" }, "r6" }, 1376 { { "v4" }, "r7" }, 1377 { { "v5" }, "r8" }, 1378 { { "v6", "rfp" }, "r9" }, 1379 { { "sl" }, "r10" }, 1380 { { "fp" }, "r11" }, 1381 { { "ip" }, "r12" }, 1382 { { "sp" }, "r13" }, 1383 { { "lr" }, "r14" }, 1384 { { "pc" }, "r15" }, 1385}; 1386 1387void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1388 unsigned &NumAliases) const { 1389 Aliases = GCCRegAliases; 1390 NumAliases = llvm::array_lengthof(GCCRegAliases); 1391} 1392} // end anonymous namespace. 1393 1394 1395namespace { 1396class DarwinARMTargetInfo : 1397 public DarwinTargetInfo<ARMTargetInfo> { 1398protected: 1399 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 1400 std::vector<char> &Defines) const { 1401 getDarwinDefines(Defines, Opts); 1402 getDarwinIPhoneOSDefines(Defines, Triple); 1403 } 1404 1405public: 1406 DarwinARMTargetInfo(const std::string& triple) 1407 : DarwinTargetInfo<ARMTargetInfo>(triple) {} 1408}; 1409} // end anonymous namespace. 1410 1411namespace { 1412class SparcV8TargetInfo : public TargetInfo { 1413 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1414 static const char * const GCCRegNames[]; 1415public: 1416 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { 1417 // FIXME: Support Sparc quad-precision long double? 1418 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1419 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; 1420 } 1421 virtual void getTargetDefines(const LangOptions &Opts, 1422 std::vector<char> &Defines) const { 1423 DefineStd(Defines, "sparc", Opts); 1424 Define(Defines, "__sparcv8"); 1425 Define(Defines, "__REGISTER_PREFIX__", ""); 1426 } 1427 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1428 unsigned &NumRecords) const { 1429 // FIXME: Implement! 1430 } 1431 virtual const char *getVAListDeclaration() const { 1432 return "typedef void* __builtin_va_list;"; 1433 } 1434 virtual void getGCCRegNames(const char * const *&Names, 1435 unsigned &NumNames) const; 1436 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1437 unsigned &NumAliases) const; 1438 virtual bool validateAsmConstraint(const char *&Name, 1439 TargetInfo::ConstraintInfo &info) const { 1440 // FIXME: Implement! 1441 return false; 1442 } 1443 virtual const char *getClobbers() const { 1444 // FIXME: Implement! 1445 return ""; 1446 } 1447}; 1448 1449const char * const SparcV8TargetInfo::GCCRegNames[] = { 1450 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1451 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 1452 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 1453 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" 1454}; 1455 1456void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names, 1457 unsigned &NumNames) const { 1458 Names = GCCRegNames; 1459 NumNames = llvm::array_lengthof(GCCRegNames); 1460} 1461 1462const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = { 1463 { { "g0" }, "r0" }, 1464 { { "g1" }, "r1" }, 1465 { { "g2" }, "r2" }, 1466 { { "g3" }, "r3" }, 1467 { { "g4" }, "r4" }, 1468 { { "g5" }, "r5" }, 1469 { { "g6" }, "r6" }, 1470 { { "g7" }, "r7" }, 1471 { { "o0" }, "r8" }, 1472 { { "o1" }, "r9" }, 1473 { { "o2" }, "r10" }, 1474 { { "o3" }, "r11" }, 1475 { { "o4" }, "r12" }, 1476 { { "o5" }, "r13" }, 1477 { { "o6", "sp" }, "r14" }, 1478 { { "o7" }, "r15" }, 1479 { { "l0" }, "r16" }, 1480 { { "l1" }, "r17" }, 1481 { { "l2" }, "r18" }, 1482 { { "l3" }, "r19" }, 1483 { { "l4" }, "r20" }, 1484 { { "l5" }, "r21" }, 1485 { { "l6" }, "r22" }, 1486 { { "l7" }, "r23" }, 1487 { { "i0" }, "r24" }, 1488 { { "i1" }, "r25" }, 1489 { { "i2" }, "r26" }, 1490 { { "i3" }, "r27" }, 1491 { { "i4" }, "r28" }, 1492 { { "i5" }, "r29" }, 1493 { { "i6", "fp" }, "r30" }, 1494 { { "i7" }, "r31" }, 1495}; 1496 1497void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1498 unsigned &NumAliases) const { 1499 Aliases = GCCRegAliases; 1500 NumAliases = llvm::array_lengthof(GCCRegAliases); 1501} 1502} // end anonymous namespace. 1503 1504namespace { 1505class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> { 1506public: 1507 AuroraUXSparcV8TargetInfo(const std::string& triple) : 1508 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) { 1509 SizeType = UnsignedInt; 1510 PtrDiffType = SignedInt; 1511 } 1512}; 1513class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> { 1514public: 1515 SolarisSparcV8TargetInfo(const std::string& triple) : 1516 SolarisTargetInfo<SparcV8TargetInfo>(triple) { 1517 SizeType = UnsignedInt; 1518 PtrDiffType = SignedInt; 1519 } 1520}; 1521} // end anonymous namespace. 1522 1523namespace { 1524 class PIC16TargetInfo : public TargetInfo{ 1525 public: 1526 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) { 1527 TLSSupported = false; 1528 IntWidth = 16; 1529 LongWidth = LongLongWidth = 32; 1530 PointerWidth = 16; 1531 IntAlign = 8; 1532 LongAlign = LongLongAlign = 8; 1533 PointerAlign = 8; 1534 SizeType = UnsignedInt; 1535 IntMaxType = SignedLong; 1536 UIntMaxType = UnsignedLong; 1537 IntPtrType = SignedShort; 1538 PtrDiffType = SignedInt; 1539 SigAtomicType = SignedLong; 1540 FloatWidth = 32; 1541 FloatAlign = 32; 1542 DoubleWidth = 32; 1543 DoubleAlign = 32; 1544 LongDoubleWidth = 32; 1545 LongDoubleAlign = 32; 1546 FloatFormat = &llvm::APFloat::IEEEsingle; 1547 DoubleFormat = &llvm::APFloat::IEEEsingle; 1548 LongDoubleFormat = &llvm::APFloat::IEEEsingle; 1549 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32-n8"; 1550 1551 } 1552 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; } 1553 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; } 1554 virtual void getTargetDefines(const LangOptions &Opts, 1555 std::vector<char> &Defines) const { 1556 Define(Defines, "__pic16"); 1557 Define(Defines, "rom", "__attribute__((address_space(1)))"); 1558 Define(Defines, "ram", "__attribute__((address_space(0)))"); 1559 Define(Defines, "_section(SectName)", 1560 "__attribute__((section(SectName)))"); 1561 Define(Defines, "near", 1562 "__attribute__((section(\"Address=NEAR\")))"); 1563 Define(Defines, "_address(Addr)", 1564 "__attribute__((section(\"Address=\"#Addr)))"); 1565 Define(Defines, "_CONFIG(conf)", "asm(\"CONFIG \"#conf)"); 1566 Define(Defines, "_interrupt", 1567 "__attribute__((section(\"interrupt=0x4\"))) \ 1568 __attribute__((used))"); 1569 } 1570 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1571 unsigned &NumRecords) const {} 1572 virtual const char *getVAListDeclaration() const { 1573 return ""; 1574 } 1575 virtual const char *getClobbers() const { 1576 return ""; 1577 } 1578 virtual void getGCCRegNames(const char * const *&Names, 1579 unsigned &NumNames) const {} 1580 virtual bool validateAsmConstraint(const char *&Name, 1581 TargetInfo::ConstraintInfo &info) const { 1582 return true; 1583 } 1584 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1585 unsigned &NumAliases) const {} 1586 virtual bool useGlobalsForAutomaticVariables() const {return true;} 1587 }; 1588} 1589 1590namespace { 1591 class MSP430TargetInfo : public TargetInfo { 1592 static const char * const GCCRegNames[]; 1593 public: 1594 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { 1595 TLSSupported = false; 1596 IntWidth = 16; 1597 LongWidth = LongLongWidth = 32; 1598 PointerWidth = 16; 1599 IntAlign = 8; 1600 LongAlign = LongLongAlign = 8; 1601 PointerAlign = 8; 1602 SizeType = UnsignedInt; 1603 IntMaxType = SignedLong; 1604 UIntMaxType = UnsignedLong; 1605 IntPtrType = SignedShort; 1606 PtrDiffType = SignedInt; 1607 SigAtomicType = SignedLong; 1608 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-n8:16"; 1609 } 1610 virtual void getTargetDefines(const LangOptions &Opts, 1611 std::vector<char> &Defines) const { 1612 Define(Defines, "MSP430"); 1613 Define(Defines, "__MSP430__"); 1614 // FIXME: defines for different 'flavours' of MCU 1615 } 1616 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1617 unsigned &NumRecords) const { 1618 // FIXME: Implement. 1619 Records = 0; 1620 NumRecords = 0; 1621 } 1622 virtual void getGCCRegNames(const char * const *&Names, 1623 unsigned &NumNames) const; 1624 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1625 unsigned &NumAliases) const { 1626 // No aliases. 1627 Aliases = 0; 1628 NumAliases = 0; 1629 } 1630 virtual bool validateAsmConstraint(const char *&Name, 1631 TargetInfo::ConstraintInfo &info) const { 1632 // No target constraints for now. 1633 return false; 1634 } 1635 virtual const char *getClobbers() const { 1636 // FIXME: Is this really right? 1637 return ""; 1638 } 1639 virtual const char *getVAListDeclaration() const { 1640 // FIXME: implement 1641 return "typedef char* __builtin_va_list;"; 1642 } 1643 }; 1644 1645 const char * const MSP430TargetInfo::GCCRegNames[] = { 1646 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1647 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1648 }; 1649 1650 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names, 1651 unsigned &NumNames) const { 1652 Names = GCCRegNames; 1653 NumNames = llvm::array_lengthof(GCCRegNames); 1654 } 1655} 1656 1657 1658namespace { 1659 class SystemZTargetInfo : public TargetInfo { 1660 static const char * const GCCRegNames[]; 1661 public: 1662 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) { 1663 TLSSupported = false; 1664 IntWidth = IntAlign = 32; 1665 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; 1666 PointerWidth = PointerAlign = 64; 1667 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-" 1668 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64"; 1669 } 1670 virtual void getTargetDefines(const LangOptions &Opts, 1671 std::vector<char> &Defines) const { 1672 Define(Defines, "__s390__"); 1673 Define(Defines, "__s390x__"); 1674 } 1675 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1676 unsigned &NumRecords) const { 1677 // FIXME: Implement. 1678 Records = 0; 1679 NumRecords = 0; 1680 } 1681 1682 virtual void getGCCRegNames(const char * const *&Names, 1683 unsigned &NumNames) const; 1684 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1685 unsigned &NumAliases) const { 1686 // No aliases. 1687 Aliases = 0; 1688 NumAliases = 0; 1689 } 1690 virtual bool validateAsmConstraint(const char *&Name, 1691 TargetInfo::ConstraintInfo &info) const { 1692 // FIXME: implement 1693 return true; 1694 } 1695 virtual const char *getClobbers() const { 1696 // FIXME: Is this really right? 1697 return ""; 1698 } 1699 virtual const char *getVAListDeclaration() const { 1700 // FIXME: implement 1701 return "typedef char* __builtin_va_list;"; 1702 } 1703 }; 1704 1705 const char * const SystemZTargetInfo::GCCRegNames[] = { 1706 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1707 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1708 }; 1709 1710 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names, 1711 unsigned &NumNames) const { 1712 Names = GCCRegNames; 1713 NumNames = llvm::array_lengthof(GCCRegNames); 1714 } 1715} 1716 1717namespace { 1718 class BlackfinTargetInfo : public TargetInfo { 1719 static const char * const GCCRegNames[]; 1720 public: 1721 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) { 1722 TLSSupported = false; 1723 DoubleAlign = 32; 1724 LongLongAlign = 32; 1725 LongDoubleAlign = 32; 1726 DescriptionString = "e-p:32:32-i64:32-f64:32-n32"; 1727 } 1728 1729 virtual void getTargetDefines(const LangOptions &Opts, 1730 std::vector<char> &Defines) const { 1731 DefineStd(Defines, "bfin", Opts); 1732 DefineStd(Defines, "BFIN", Opts); 1733 Define(Defines, "__ADSPBLACKFIN__"); 1734 // FIXME: This one is really dependent on -mcpu 1735 Define(Defines, "__ADSPLPBLACKFIN__"); 1736 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__ 1737 } 1738 1739 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1740 unsigned &NumRecords) const { 1741 // FIXME: Implement. 1742 Records = 0; 1743 NumRecords = 0; 1744 } 1745 1746 virtual void getGCCRegNames(const char * const *&Names, 1747 unsigned &NumNames) const; 1748 1749 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1750 unsigned &NumAliases) const { 1751 // No aliases. 1752 Aliases = 0; 1753 NumAliases = 0; 1754 } 1755 1756 virtual bool validateAsmConstraint(const char *&Name, 1757 TargetInfo::ConstraintInfo &Info) const { 1758 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) { 1759 Info.setAllowsRegister(); 1760 return true; 1761 } 1762 return false; 1763 } 1764 1765 virtual const char *getClobbers() const { 1766 return ""; 1767 } 1768 1769 virtual const char *getVAListDeclaration() const { 1770 return "typedef char* __builtin_va_list;"; 1771 } 1772 }; 1773 1774 const char * const BlackfinTargetInfo::GCCRegNames[] = { 1775 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1776 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp", 1777 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3", 1778 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3", 1779 "a0", "a1", "cc", 1780 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp", 1781 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1" 1782 }; 1783 1784 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names, 1785 unsigned &NumNames) const { 1786 Names = GCCRegNames; 1787 NumNames = llvm::array_lengthof(GCCRegNames); 1788 } 1789} 1790 1791namespace { 1792 1793 // LLVM and Clang cannot be used directly to output native binaries for 1794 // target, but is used to compile C code to llvm bitcode with correct 1795 // type and alignment information. 1796 // 1797 // TCE uses the llvm bitcode as input and uses it for generating customized 1798 // target processor and program binary. TCE co-design environment is 1799 // publicly available in http://tce.cs.tut.fi 1800 1801 class TCETargetInfo : public TargetInfo{ 1802 public: 1803 TCETargetInfo(const std::string& triple) : TargetInfo(triple) { 1804 TLSSupported = false; 1805 IntWidth = 32; 1806 LongWidth = LongLongWidth = 32; 1807 PointerWidth = 32; 1808 IntAlign = 32; 1809 LongAlign = LongLongAlign = 32; 1810 PointerAlign = 32; 1811 SizeType = UnsignedInt; 1812 IntMaxType = SignedLong; 1813 UIntMaxType = UnsignedLong; 1814 IntPtrType = SignedInt; 1815 PtrDiffType = SignedInt; 1816 FloatWidth = 32; 1817 FloatAlign = 32; 1818 DoubleWidth = 32; 1819 DoubleAlign = 32; 1820 LongDoubleWidth = 32; 1821 LongDoubleAlign = 32; 1822 FloatFormat = &llvm::APFloat::IEEEsingle; 1823 DoubleFormat = &llvm::APFloat::IEEEsingle; 1824 LongDoubleFormat = &llvm::APFloat::IEEEsingle; 1825 DescriptionString = "E-p:32:32:32-a0:32:32" 1826 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64" 1827 "-f32:32:32-f64:32:64-n32"; 1828 } 1829 1830 virtual void getTargetDefines(const LangOptions &Opts, 1831 std::vector<char> &Defines) const { 1832 DefineStd(Defines, "tce", Opts); 1833 Define(Defines, "__TCE__"); 1834 Define(Defines, "__TCE_V1__"); 1835 } 1836 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1837 unsigned &NumRecords) const {} 1838 virtual const char *getClobbers() const { 1839 return ""; 1840 } 1841 virtual const char *getVAListDeclaration() const { 1842 return "typedef void* __builtin_va_list;"; 1843 } 1844 virtual void getGCCRegNames(const char * const *&Names, 1845 unsigned &NumNames) const {} 1846 virtual bool validateAsmConstraint(const char *&Name, 1847 TargetInfo::ConstraintInfo &info) const { 1848 return true; 1849 } 1850 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1851 unsigned &NumAliases) const {} 1852 }; 1853} 1854 1855namespace { 1856class MipsTargetInfo : public TargetInfo { 1857 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1858 static const char * const GCCRegNames[]; 1859public: 1860 MipsTargetInfo(const std::string& triple) : TargetInfo(triple) { 1861 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 1862 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32"; 1863 } 1864 virtual void getTargetDefines(const LangOptions &Opts, 1865 std::vector<char> &Defines) const { 1866 DefineStd(Defines, "mips", Opts); 1867 Define(Defines, "_mips"); 1868 DefineStd(Defines, "MIPSEB", Opts); 1869 Define(Defines, "_MIPSEB"); 1870 Define(Defines, "__REGISTER_PREFIX__", ""); 1871 } 1872 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1873 unsigned &NumRecords) const { 1874 // FIXME: Implement! 1875 } 1876 virtual const char *getVAListDeclaration() const { 1877 return "typedef void* __builtin_va_list;"; 1878 } 1879 virtual void getGCCRegNames(const char * const *&Names, 1880 unsigned &NumNames) const; 1881 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1882 unsigned &NumAliases) const; 1883 virtual bool validateAsmConstraint(const char *&Name, 1884 TargetInfo::ConstraintInfo &Info) const { 1885 switch (*Name) { 1886 default: 1887 case 'r': // CPU registers. 1888 case 'd': // Equivalent to "r" unless generating MIPS16 code. 1889 case 'y': // Equivalent to "r", backwards compatibility only. 1890 case 'f': // floating-point registers. 1891 Info.setAllowsRegister(); 1892 return true; 1893 } 1894 return false; 1895 } 1896 1897 virtual const char *getClobbers() const { 1898 // FIXME: Implement! 1899 return ""; 1900 } 1901}; 1902 1903const char * const MipsTargetInfo::GCCRegNames[] = { 1904 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 1905 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 1906 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 1907 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31", 1908 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", 1909 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", 1910 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", 1911 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", 1912 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", 1913 "$fcc5","$fcc6","$fcc7" 1914}; 1915 1916void MipsTargetInfo::getGCCRegNames(const char * const *&Names, 1917 unsigned &NumNames) const { 1918 Names = GCCRegNames; 1919 NumNames = llvm::array_lengthof(GCCRegNames); 1920} 1921 1922const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = { 1923 { { "at" }, "$1" }, 1924 { { "v0" }, "$2" }, 1925 { { "v1" }, "$3" }, 1926 { { "a0" }, "$4" }, 1927 { { "a1" }, "$5" }, 1928 { { "a2" }, "$6" }, 1929 { { "a3" }, "$7" }, 1930 { { "t0" }, "$8" }, 1931 { { "t1" }, "$9" }, 1932 { { "t2" }, "$10" }, 1933 { { "t3" }, "$11" }, 1934 { { "t4" }, "$12" }, 1935 { { "t5" }, "$13" }, 1936 { { "t6" }, "$14" }, 1937 { { "t7" }, "$15" }, 1938 { { "s0" }, "$16" }, 1939 { { "s1" }, "$17" }, 1940 { { "s2" }, "$18" }, 1941 { { "s3" }, "$19" }, 1942 { { "s4" }, "$20" }, 1943 { { "s5" }, "$21" }, 1944 { { "s6" }, "$22" }, 1945 { { "s7" }, "$23" }, 1946 { { "t8" }, "$24" }, 1947 { { "t9" }, "$25" }, 1948 { { "k0" }, "$26" }, 1949 { { "k1" }, "$27" }, 1950 { { "gp" }, "$28" }, 1951 { { "sp" }, "$29" }, 1952 { { "fp" }, "$30" }, 1953 { { "ra" }, "$31" } 1954}; 1955 1956void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1957 unsigned &NumAliases) const { 1958 Aliases = GCCRegAliases; 1959 NumAliases = llvm::array_lengthof(GCCRegAliases); 1960} 1961} // end anonymous namespace. 1962 1963namespace { 1964class MipselTargetInfo : public MipsTargetInfo { 1965public: 1966 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) { 1967 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 1968 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32"; 1969 } 1970 1971 virtual void getTargetDefines(const LangOptions &Opts, 1972 std::vector<char> &Defines) const; 1973}; 1974 1975void MipselTargetInfo::getTargetDefines(const LangOptions &Opts, 1976 std::vector<char> &Defines) const { 1977 DefineStd(Defines, "mips", Opts); 1978 Define(Defines, "_mips"); 1979 DefineStd(Defines, "MIPSEL", Opts); 1980 Define(Defines, "_MIPSEL"); 1981 Define(Defines, "__REGISTER_PREFIX__", ""); 1982} 1983} // end anonymous namespace. 1984 1985//===----------------------------------------------------------------------===// 1986// Driver code 1987//===----------------------------------------------------------------------===// 1988 1989static TargetInfo *AllocateTarget(const std::string &T) { 1990 llvm::Triple Triple(T); 1991 llvm::Triple::OSType os = Triple.getOS(); 1992 1993 switch (Triple.getArch()) { 1994 default: 1995 return NULL; 1996 1997 case llvm::Triple::arm: 1998 case llvm::Triple::thumb: 1999 switch (os) { 2000 case llvm::Triple::Darwin: 2001 return new DarwinARMTargetInfo(T); 2002 case llvm::Triple::FreeBSD: 2003 return new FreeBSDTargetInfo<ARMTargetInfo>(T); 2004 default: 2005 return new ARMTargetInfo(T); 2006 } 2007 2008 case llvm::Triple::bfin: 2009 return new BlackfinTargetInfo(T); 2010 2011 case llvm::Triple::msp430: 2012 return new MSP430TargetInfo(T); 2013 2014 case llvm::Triple::mips: 2015 if (os == llvm::Triple::Psp) 2016 return new PSPTargetInfo<MipsTargetInfo>(T); 2017 if (os == llvm::Triple::Linux) 2018 return new LinuxTargetInfo<MipsTargetInfo>(T); 2019 return new MipsTargetInfo(T); 2020 2021 case llvm::Triple::mipsel: 2022 if (os == llvm::Triple::Psp) 2023 return new PSPTargetInfo<MipselTargetInfo>(T); 2024 if (os == llvm::Triple::Linux) 2025 return new LinuxTargetInfo<MipselTargetInfo>(T); 2026 return new MipselTargetInfo(T); 2027 2028 case llvm::Triple::pic16: 2029 return new PIC16TargetInfo(T); 2030 2031 case llvm::Triple::ppc: 2032 if (os == llvm::Triple::Darwin) 2033 return new DarwinTargetInfo<PPCTargetInfo>(T); 2034 return new PPC32TargetInfo(T); 2035 2036 case llvm::Triple::ppc64: 2037 if (os == llvm::Triple::Darwin) 2038 return new DarwinTargetInfo<PPC64TargetInfo>(T); 2039 else if (os == llvm::Triple::Lv2) 2040 return new PS3PPUTargetInfo<PPC64TargetInfo>(T); 2041 return new PPC64TargetInfo(T); 2042 2043 case llvm::Triple::sparc: 2044 if (os == llvm::Triple::AuroraUX) 2045 return new AuroraUXSparcV8TargetInfo(T); 2046 if (os == llvm::Triple::Solaris) 2047 return new SolarisSparcV8TargetInfo(T); 2048 return new SparcV8TargetInfo(T); 2049 2050 // FIXME: Need a real SPU target. 2051 case llvm::Triple::cellspu: 2052 return new PS3SPUTargetInfo<PPC64TargetInfo>(T); 2053 2054 case llvm::Triple::systemz: 2055 return new SystemZTargetInfo(T); 2056 2057 case llvm::Triple::tce: 2058 return new TCETargetInfo(T); 2059 2060 case llvm::Triple::x86: 2061 switch (os) { 2062 case llvm::Triple::AuroraUX: 2063 return new AuroraUXTargetInfo<X86_32TargetInfo>(T); 2064 case llvm::Triple::Darwin: 2065 return new DarwinI386TargetInfo(T); 2066 case llvm::Triple::Linux: 2067 return new LinuxTargetInfo<X86_32TargetInfo>(T); 2068 case llvm::Triple::DragonFly: 2069 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T); 2070 case llvm::Triple::NetBSD: 2071 return new NetBSDTargetInfo<X86_32TargetInfo>(T); 2072 case llvm::Triple::OpenBSD: 2073 return new OpenBSDI386TargetInfo(T); 2074 case llvm::Triple::FreeBSD: 2075 return new FreeBSDTargetInfo<X86_32TargetInfo>(T); 2076 case llvm::Triple::Solaris: 2077 return new SolarisTargetInfo<X86_32TargetInfo>(T); 2078 case llvm::Triple::Cygwin: 2079 return new CygwinX86_32TargetInfo(T); 2080 case llvm::Triple::MinGW32: 2081 return new MinGWX86_32TargetInfo(T); 2082 case llvm::Triple::Win32: 2083 return new VisualStudioWindowsX86_32TargetInfo(T); 2084 default: 2085 return new X86_32TargetInfo(T); 2086 } 2087 2088 case llvm::Triple::x86_64: 2089 switch (os) { 2090 case llvm::Triple::AuroraUX: 2091 return new AuroraUXTargetInfo<X86_64TargetInfo>(T); 2092 case llvm::Triple::Darwin: 2093 return new DarwinX86_64TargetInfo(T); 2094 case llvm::Triple::Linux: 2095 return new LinuxTargetInfo<X86_64TargetInfo>(T); 2096 case llvm::Triple::NetBSD: 2097 return new NetBSDTargetInfo<X86_64TargetInfo>(T); 2098 case llvm::Triple::OpenBSD: 2099 return new OpenBSDX86_64TargetInfo(T); 2100 case llvm::Triple::FreeBSD: 2101 return new FreeBSDTargetInfo<X86_64TargetInfo>(T); 2102 case llvm::Triple::Solaris: 2103 return new SolarisTargetInfo<X86_64TargetInfo>(T); 2104 case llvm::Triple::MinGW64: 2105 return new MinGWX86_64TargetInfo(T); 2106 case llvm::Triple::Win32: // This is what Triple.h supports now. 2107 return new VisualStudioWindowsX86_64TargetInfo(T); 2108 default: 2109 return new X86_64TargetInfo(T); 2110 } 2111 } 2112} 2113 2114/// CreateTargetInfo - Return the target info object for the specified target 2115/// triple. 2116TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags, 2117 const TargetOptions &Opts) { 2118 llvm::Triple Triple(Opts.Triple); 2119 2120 // Construct the target 2121 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str())); 2122 if (!Target) { 2123 Diags.Report(diag::err_target_unknown_triple) << Triple.str(); 2124 return 0; 2125 } 2126 2127 // Set the target ABI if specified. 2128 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) { 2129 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI; 2130 return 0; 2131 } 2132 2133 // Compute the default target features, we need the target to handle this 2134 // because features may have dependencies on one another. 2135 llvm::StringMap<bool> Features; 2136 Target->getDefaultFeatures(Opts.CPU, Features); 2137 2138 // Apply the user specified deltas. 2139 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(), 2140 ie = Opts.Features.end(); it != ie; ++it) { 2141 const char *Name = it->c_str(); 2142 2143 // Apply the feature via the target. 2144 if ((Name[0] != '-' && Name[0] != '+') || 2145 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) { 2146 Diags.Report(diag::err_target_invalid_feature) << Name; 2147 return 0; 2148 } 2149 } 2150 2151 // Add the features to the compile options. 2152 // 2153 // FIXME: If we are completely confident that we have the right set, we only 2154 // need to pass the minuses. 2155 std::vector<std::string> StrFeatures; 2156 for (llvm::StringMap<bool>::const_iterator it = Features.begin(), 2157 ie = Features.end(); it != ie; ++it) 2158 StrFeatures.push_back(std::string(it->second ? "+" : "-") + it->first()); 2159 Target->HandleTargetFeatures(StrFeatures); 2160 2161 return Target.take(); 2162} 2163