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