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