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