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