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