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