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 TargetInfo> 66 class OSTargetInfo : public TargetInfo { 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) : TargetInfo(triple) {} 72 virtual void getTargetDefines(const LangOptions &Opts, 73 std::vector<char> &Defines) const { 74 TargetInfo::getTargetDefines(Opts, Defines); 75 getOSDefines(Opts, TargetInfo::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 DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> { 893 public: 894 DarwinI386TargetInfo(const std::string& triple) : 895 DarwinTargetInfo<X86_32TargetInfo>(triple) { 896 LongDoubleWidth = 128; 897 LongDoubleAlign = 128; 898 SizeType = UnsignedLong; 899 IntPtrType = SignedLong; 900 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 901 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 902 "a0:0:64-f80:128:128"; 903 } 904 905 }; 906 } // end anonymous namespace 907 908 namespace { 909 // x86-32 Windows target 910 class WindowsX86_32TargetInfo : public X86_32TargetInfo { 911 public: 912 WindowsX86_32TargetInfo(const std::string& triple) 913 : X86_32TargetInfo(triple) { 914 TLSSupported = false; 915 WCharType = UnsignedShort; 916 WCharWidth = WCharAlign = 16; 917 DoubleAlign = LongLongAlign = 64; 918 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 919 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 920 "a0:0:64-f80:32:32"; 921 } 922 virtual void getTargetDefines(const LangOptions &Opts, 923 std::vector<char> &Defines) const { 924 X86_32TargetInfo::getTargetDefines(Opts, Defines); 925 // This list is based off of the the list of things MingW defines 926 Define(Defines, "_WIN32"); 927 DefineStd(Defines, "WIN32", Opts); 928 DefineStd(Defines, "WINNT", Opts); 929 Define(Defines, "_X86_"); 930 Define(Defines, "__MSVCRT__"); 931 } 932 933 virtual void getDefaultLangOptions(LangOptions &Opts) { 934 X86_32TargetInfo::getDefaultLangOptions(Opts); 935 GetWindowsLanguageOptions(Opts, getTargetTriple()); 936 } 937 }; 938 } // end anonymous namespace 939 940 namespace { 941 // x86-64 generic target 942 class X86_64TargetInfo : public X86TargetInfo { 943 public: 944 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) { 945 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 946 LongDoubleWidth = 128; 947 LongDoubleAlign = 128; 948 IntMaxType = SignedLong; 949 UIntMaxType = UnsignedLong; 950 Int64Type = SignedLong; 951 RegParmMax = 6; 952 953 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 954 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 955 "a0:0:64-s0:64:64-f80:128:128"; 956 } 957 virtual const char *getVAListDeclaration() const { 958 return "typedef struct __va_list_tag {" 959 " unsigned gp_offset;" 960 " unsigned fp_offset;" 961 " void* overflow_arg_area;" 962 " void* reg_save_area;" 963 "} __builtin_va_list[1];"; 964 } 965 }; 966 } // end anonymous namespace 967 968 namespace { 969 class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> { 970 public: 971 DarwinX86_64TargetInfo(const std::string& triple) 972 : DarwinTargetInfo<X86_64TargetInfo>(triple) { 973 Int64Type = SignedLongLong; 974 } 975 }; 976 } // end anonymous namespace 977 978 namespace { 979 class ARMTargetInfo : public TargetInfo { 980 enum { 981 Armv4t, 982 Armv5, 983 Armv6, 984 XScale 985 } ArmArch; 986 public: 987 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) { 988 // FIXME: Are the defaults correct for ARM? 989 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 990 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64"; 991 if (triple.find("arm-") == 0 || triple.find("armv6-") == 0) 992 ArmArch = Armv6; 993 else if (triple.find("armv5-") == 0) 994 ArmArch = Armv5; 995 else if (triple.find("armv4t-") == 0) 996 ArmArch = Armv4t; 997 else if (triple.find("xscale-") == 0) 998 ArmArch = XScale; 999 else if (triple.find("armv") == 0) { 1000 // FIXME: fuzzy match for other random weird arm triples. This is useful 1001 // for the static analyzer and other clients, but probably should be 1002 // re-evaluated when codegen is brought up. 1003 ArmArch = Armv6; 1004 } 1005 } 1006 virtual void getTargetDefines(const LangOptions &Opts, 1007 std::vector<char> &Defs) const { 1008 // Target identification. 1009 Define(Defs, "__arm"); 1010 Define(Defs, "__arm__"); 1011 1012 // Target properties. 1013 Define(Defs, "__LITTLE_ENDIAN__"); 1014 1015 // Subtarget options. 1016 if (ArmArch == Armv6) { 1017 Define(Defs, "__ARM_ARCH_6K__"); 1018 Define(Defs, "__THUMB_INTERWORK__"); 1019 } else if (ArmArch == Armv5) { 1020 Define(Defs, "__ARM_ARCH_5TEJ__"); 1021 Define(Defs, "__THUMB_INTERWORK__"); 1022 Define(Defs, "__SOFTFP__"); 1023 } else if (ArmArch == Armv4t) { 1024 Define(Defs, "__ARM_ARCH_4T__"); 1025 Define(Defs, "__SOFTFP__"); 1026 } else if (ArmArch == XScale) { 1027 Define(Defs, "__ARM_ARCH_5TE__"); 1028 Define(Defs, "__XSCALE__"); 1029 Define(Defs, "__SOFTFP__"); 1030 } 1031 Define(Defs, "__ARMEL__"); 1032 Define(Defs, "__APCS_32__"); 1033 Define(Defs, "__VFP_FP__"); 1034 } 1035 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1036 unsigned &NumRecords) const { 1037 // FIXME: Implement. 1038 Records = 0; 1039 NumRecords = 0; 1040 } 1041 virtual const char *getVAListDeclaration() const { 1042 return "typedef char* __builtin_va_list;"; 1043 } 1044 virtual const char *getTargetPrefix() const { 1045 return "arm"; 1046 } 1047 virtual void getGCCRegNames(const char * const *&Names, 1048 unsigned &NumNames) const { 1049 // FIXME: Implement. 1050 Names = 0; 1051 NumNames = 0; 1052 } 1053 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1054 unsigned &NumAliases) const { 1055 // FIXME: Implement. 1056 Aliases = 0; 1057 NumAliases = 0; 1058 } 1059 virtual bool validateAsmConstraint(const char *&Name, 1060 TargetInfo::ConstraintInfo &Info) const { 1061 // FIXME: Check if this is complete 1062 switch (*Name) { 1063 default: 1064 case 'l': // r0-r7 1065 case 'h': // r8-r15 1066 case 'w': // VFP Floating point register single precision 1067 case 'P': // VFP Floating point register double precision 1068 Info.setAllowsRegister(); 1069 return true; 1070 } 1071 return false; 1072 } 1073 virtual const char *getClobbers() const { 1074 // FIXME: Is this really right? 1075 return ""; 1076 } 1077 }; 1078 } // end anonymous namespace. 1079 1080 1081 namespace { 1082 class DarwinARMTargetInfo : 1083 public DarwinTargetInfo<ARMTargetInfo> { 1084 protected: 1085 virtual void getOSDefines(const LangOptions &Opts, const char *Triple, 1086 std::vector<char> &Defines) const { 1087 getDarwinDefines(Defines, Opts); 1088 getDarwinIPhoneOSDefines(Defines, Triple); 1089 } 1090 1091 public: 1092 DarwinARMTargetInfo(const std::string& triple) 1093 : DarwinTargetInfo<ARMTargetInfo>(triple) {} 1094 }; 1095 } // end anonymous namespace. 1096 1097 namespace { 1098 class SparcV8TargetInfo : public TargetInfo { 1099 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1100 static const char * const GCCRegNames[]; 1101 public: 1102 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { 1103 // FIXME: Support Sparc quad-precision long double? 1104 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1105 "i64:64:64-f32:32:32-f64:64:64-v64:64:64"; 1106 } 1107 virtual void getTargetDefines(const LangOptions &Opts, 1108 std::vector<char> &Defines) const { 1109 DefineStd(Defines, "sparc", Opts); 1110 Define(Defines, "__sparcv8"); 1111 Define(Defines, "__REGISTER_PREFIX__", ""); 1112 } 1113 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1114 unsigned &NumRecords) const { 1115 // FIXME: Implement! 1116 } 1117 virtual const char *getVAListDeclaration() const { 1118 return "typedef void* __builtin_va_list;"; 1119 } 1120 virtual const char *getTargetPrefix() const { 1121 return "sparc"; 1122 } 1123 virtual void getGCCRegNames(const char * const *&Names, 1124 unsigned &NumNames) const; 1125 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1126 unsigned &NumAliases) const; 1127 virtual bool validateAsmConstraint(const char *&Name, 1128 TargetInfo::ConstraintInfo &info) const { 1129 // FIXME: Implement! 1130 return false; 1131 } 1132 virtual const char *getClobbers() const { 1133 // FIXME: Implement! 1134 return ""; 1135 } 1136 }; 1137 1138 const char * const SparcV8TargetInfo::GCCRegNames[] = { 1139 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1140 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 1141 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 1142 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" 1143 }; 1144 1145 void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names, 1146 unsigned &NumNames) const { 1147 Names = GCCRegNames; 1148 NumNames = llvm::array_lengthof(GCCRegNames); 1149 } 1150 1151 const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = { 1152 { { "g0" }, "r0" }, 1153 { { "g1" }, "r1" }, 1154 { { "g2" }, "r2" }, 1155 { { "g3" }, "r3" }, 1156 { { "g4" }, "r4" }, 1157 { { "g5" }, "r5" }, 1158 { { "g6" }, "r6" }, 1159 { { "g7" }, "r7" }, 1160 { { "o0" }, "r8" }, 1161 { { "o1" }, "r9" }, 1162 { { "o2" }, "r10" }, 1163 { { "o3" }, "r11" }, 1164 { { "o4" }, "r12" }, 1165 { { "o5" }, "r13" }, 1166 { { "o6", "sp" }, "r14" }, 1167 { { "o7" }, "r15" }, 1168 { { "l0" }, "r16" }, 1169 { { "l1" }, "r17" }, 1170 { { "l2" }, "r18" }, 1171 { { "l3" }, "r19" }, 1172 { { "l4" }, "r20" }, 1173 { { "l5" }, "r21" }, 1174 { { "l6" }, "r22" }, 1175 { { "l7" }, "r23" }, 1176 { { "i0" }, "r24" }, 1177 { { "i1" }, "r25" }, 1178 { { "i2" }, "r26" }, 1179 { { "i3" }, "r27" }, 1180 { { "i4" }, "r28" }, 1181 { { "i5" }, "r29" }, 1182 { { "i6", "fp" }, "r30" }, 1183 { { "i7" }, "r31" }, 1184 }; 1185 1186 void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1187 unsigned &NumAliases) const { 1188 Aliases = GCCRegAliases; 1189 NumAliases = llvm::array_lengthof(GCCRegAliases); 1190 } 1191 } // end anonymous namespace. 1192 1193 namespace { 1194 class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> { 1195 public: 1196 SolarisSparcV8TargetInfo(const std::string& triple) : 1197 SolarisTargetInfo<SparcV8TargetInfo>(triple) { 1198 SizeType = UnsignedInt; 1199 PtrDiffType = SignedInt; 1200 } 1201 }; 1202 } // end anonymous namespace. 1203 1204 namespace { 1205 class PIC16TargetInfo : public TargetInfo{ 1206 public: 1207 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) { 1208 TLSSupported = false; 1209 IntWidth = 16; 1210 LongWidth = LongLongWidth = 32; 1211 IntMaxTWidth = 32; 1212 PointerWidth = 16; 1213 IntAlign = 8; 1214 LongAlign = LongLongAlign = 8; 1215 PointerAlign = 8; 1216 SizeType = UnsignedInt; 1217 IntMaxType = SignedLong; 1218 UIntMaxType = UnsignedLong; 1219 IntPtrType = SignedShort; 1220 PtrDiffType = SignedInt; 1221 FloatWidth = 32; 1222 FloatAlign = 32; 1223 DoubleWidth = 32; 1224 DoubleAlign = 32; 1225 LongDoubleWidth = 32; 1226 LongDoubleAlign = 32; 1227 FloatFormat = &llvm::APFloat::IEEEsingle; 1228 DoubleFormat = &llvm::APFloat::IEEEsingle; 1229 LongDoubleFormat = &llvm::APFloat::IEEEsingle; 1230 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32"; 1231 1232 } 1233 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; } 1234 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; } 1235 virtual void getTargetDefines(const LangOptions &Opts, 1236 std::vector<char> &Defines) const { 1237 Define(Defines, "__pic16"); 1238 } 1239 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1240 unsigned &NumRecords) const {} 1241 virtual const char *getVAListDeclaration() const { return "";} 1242 virtual const char *getClobbers() const {return "";} 1243 virtual const char *getTargetPrefix() const {return "pic16";} 1244 virtual void getGCCRegNames(const char * const *&Names, 1245 unsigned &NumNames) const {} 1246 virtual bool validateAsmConstraint(const char *&Name, 1247 TargetInfo::ConstraintInfo &info) const { 1248 return true; 1249 } 1250 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1251 unsigned &NumAliases) const {} 1252 virtual bool useGlobalsForAutomaticVariables() const {return true;} 1253 }; 1254 } 1255 1256 namespace { 1257 class MSP430TargetInfo : public TargetInfo { 1258 static const char * const GCCRegNames[]; 1259 public: 1260 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { 1261 TLSSupported = false; 1262 IntWidth = 16; 1263 LongWidth = LongLongWidth = 32; 1264 IntMaxTWidth = 32; 1265 PointerWidth = 16; 1266 IntAlign = 8; 1267 LongAlign = LongLongAlign = 8; 1268 PointerAlign = 8; 1269 SizeType = UnsignedInt; 1270 IntMaxType = SignedLong; 1271 UIntMaxType = UnsignedLong; 1272 IntPtrType = SignedShort; 1273 PtrDiffType = SignedInt; 1274 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"; 1275 } 1276 virtual void getTargetDefines(const LangOptions &Opts, 1277 std::vector<char> &Defines) const { 1278 Define(Defines, "MSP430"); 1279 Define(Defines, "__MSP430__"); 1280 // FIXME: defines for different 'flavours' of MCU 1281 } 1282 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1283 unsigned &NumRecords) const { 1284 // FIXME: Implement. 1285 Records = 0; 1286 NumRecords = 0; 1287 } 1288 virtual const char *getTargetPrefix() const { 1289 return "msp430"; 1290 } 1291 virtual void getGCCRegNames(const char * const *&Names, 1292 unsigned &NumNames) const; 1293 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1294 unsigned &NumAliases) const { 1295 // No aliases. 1296 Aliases = 0; 1297 NumAliases = 0; 1298 } 1299 virtual bool validateAsmConstraint(const char *&Name, 1300 TargetInfo::ConstraintInfo &info) const { 1301 // FIXME: implement 1302 return true; 1303 } 1304 virtual const char *getClobbers() const { 1305 // FIXME: Is this really right? 1306 return ""; 1307 } 1308 virtual const char *getVAListDeclaration() const { 1309 // FIXME: implement 1310 return "typedef char* __builtin_va_list;"; 1311 } 1312 }; 1313 1314 const char * const MSP430TargetInfo::GCCRegNames[] = { 1315 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1316 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1317 }; 1318 1319 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names, 1320 unsigned &NumNames) const { 1321 Names = GCCRegNames; 1322 NumNames = llvm::array_lengthof(GCCRegNames); 1323 } 1324 } 1325 1326 1327 //===----------------------------------------------------------------------===// 1328 // Driver code 1329 //===----------------------------------------------------------------------===// 1330 1331 static inline bool IsX86(const std::string& TT) { 1332 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' && 1333 TT[4] == '-' && TT[1] - '3' < 6); 1334 } 1335 1336 /// CreateTargetInfo - Return the target info object for the specified target 1337 /// triple. 1338 TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) { 1339 // OS detection; this isn't really anywhere near complete. 1340 // Additions and corrections are welcome. 1341 bool isDarwin = T.find("-darwin") != std::string::npos; 1342 bool isDragonFly = T.find("-dragonfly") != std::string::npos; 1343 bool isOpenBSD = T.find("-openbsd") != std::string::npos; 1344 bool isFreeBSD = T.find("-freebsd") != std::string::npos; 1345 bool isSolaris = T.find("-solaris") != std::string::npos; 1346 bool isLinux = T.find("-linux") != std::string::npos; 1347 bool isWindows = T.find("-windows") != std::string::npos || 1348 T.find("-win32") != std::string::npos || 1349 T.find("-mingw") != std::string::npos; 1350 1351 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) { 1352 if (isDarwin) 1353 return new DarwinTargetInfo<PPCTargetInfo>(T); 1354 return new PPC32TargetInfo(T); 1355 } 1356 1357 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) { 1358 if (isDarwin) 1359 return new DarwinTargetInfo<PPC64TargetInfo>(T); 1360 return new PPC64TargetInfo(T); 1361 } 1362 1363 if (T.find("armv") == 0 || T.find("arm-") == 0 || T.find("xscale") == 0) { 1364 if (isDarwin) 1365 return new DarwinARMTargetInfo(T); 1366 if (isFreeBSD) 1367 return new FreeBSDTargetInfo<ARMTargetInfo>(T); 1368 return new ARMTargetInfo(T); 1369 } 1370 1371 if (T.find("sparc-") == 0) { 1372 if (isSolaris) 1373 return new SolarisSparcV8TargetInfo(T); 1374 return new SparcV8TargetInfo(T); 1375 } 1376 1377 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) { 1378 if (isDarwin) 1379 return new DarwinX86_64TargetInfo(T); 1380 if (isLinux) 1381 return new LinuxTargetInfo<X86_64TargetInfo>(T); 1382 if (isOpenBSD) 1383 return new OpenBSDTargetInfo<X86_64TargetInfo>(T); 1384 if (isFreeBSD) 1385 return new FreeBSDTargetInfo<X86_64TargetInfo>(T); 1386 if (isSolaris) 1387 return new SolarisTargetInfo<X86_64TargetInfo>(T); 1388 return new X86_64TargetInfo(T); 1389 } 1390 1391 if (T.find("pic16-") == 0) 1392 return new PIC16TargetInfo(T); 1393 1394 if (T.find("msp430-") == 0) 1395 return new MSP430TargetInfo(T); 1396 1397 if (IsX86(T)) { 1398 if (isDarwin) 1399 return new DarwinI386TargetInfo(T); 1400 if (isLinux) 1401 return new LinuxTargetInfo<X86_32TargetInfo>(T); 1402 if (isDragonFly) 1403 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T); 1404 if (isOpenBSD) 1405 return new OpenBSDTargetInfo<X86_32TargetInfo>(T); 1406 if (isFreeBSD) 1407 return new FreeBSDTargetInfo<X86_32TargetInfo>(T); 1408 if (isSolaris) 1409 return new SolarisTargetInfo<X86_32TargetInfo>(T); 1410 if (isWindows) 1411 return new WindowsX86_32TargetInfo(T); 1412 return new X86_32TargetInfo(T); 1413 } 1414 1415 return NULL; 1416 } 1417