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