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