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