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