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