Targets.cpp revision 07181d709860d06026afa3b4ee5b6a65b48c9005
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.setAllowsRegister(); 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), SSELevel(NoMMXSSE) { 507 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; 508 } 509 virtual void getTargetBuiltins(const Builtin::Info *&Records, 510 unsigned &NumRecords) const { 511 Records = BuiltinInfo; 512 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin; 513 } 514 virtual const char *getTargetPrefix() const { 515 return "x86"; 516 } 517 virtual void getGCCRegNames(const char * const *&Names, 518 unsigned &NumNames) const { 519 Names = GCCRegNames; 520 NumNames = llvm::array_lengthof(GCCRegNames); 521 } 522 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 523 unsigned &NumAliases) const { 524 Aliases = GCCRegAliases; 525 NumAliases = llvm::array_lengthof(GCCRegAliases); 526 } 527 virtual bool validateAsmConstraint(const char *&Name, 528 TargetInfo::ConstraintInfo &info) const; 529 virtual std::string convertConstraint(const char Constraint) const; 530 virtual const char *getClobbers() const { 531 return "~{dirflag},~{fpsr},~{flags}"; 532 } 533 virtual void getTargetDefines(const LangOptions &Opts, 534 std::vector<char> &Defines) const; 535 536 virtual void getDefaultFeatures(const std::string &CPU, 537 llvm::StringMap<bool> &Features); 538 virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features); 539}; 540 541void X86TargetInfo::getDefaultFeatures(const std::string &CPU, 542 llvm::StringMap<bool> &Features) { 543 // FIXME: This should not be here. 544 Features["3dnow"] = false; 545 Features["3dnowa"] = false; 546 Features["mmx"] = false; 547 Features["sse"] = false; 548 Features["sse2"] = false; 549 Features["sse3"] = false; 550 Features["ssse3"] = false; 551 Features["sse41"] = false; 552 Features["sse42"] = false; 553 554 // LLVM does not currently recognize this. 555 // Features["sse4a"] = false; 556 557 // FIXME: This *really* should not be here. 558 559 // X86_64 always has SSE2. 560 if (PointerWidth == 64) 561 Features["sse2"] = Features["sse"] = Features["mmx"] = true; 562 563 // FIXME: LLVM says core2 has SSSE3, but gcc doesn't define 564 // __SSSE3__ with it? What else is going on here? 565 if (CPU == "core2") 566 Features["ssse3"] = Features["sse3"] = Features["sse2"] = Features["sse"] = 567 Features["mmx"] = true; 568 else if (CPU == "pentium4") 569 Features["sse2"] = Features["sse"] = Features["mmx"] = true; 570} 571 572/// HandleTargetOptions - Perform initialization based on the user 573/// configured set of features. 574void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) { 575 if (Features.lookup("sse42")) 576 SSELevel = SSE42; 577 else if (Features.lookup("sse41")) 578 SSELevel = SSE41; 579 else if (Features.lookup("ssse3")) 580 SSELevel = SSSE3; 581 else if (Features.lookup("sse3")) 582 SSELevel = SSE3; 583 else if (Features.lookup("sse2")) 584 SSELevel = SSE2; 585 else if (Features.lookup("sse")) 586 SSELevel = SSE1; 587 else if (Features.lookup("mmx")) 588 SSELevel = MMX; 589} 590 591/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines 592/// that are not tied to a specific subtarget. 593void X86TargetInfo::getTargetDefines(const LangOptions &Opts, 594 std::vector<char> &Defs) const { 595 // Target identification. 596 if (PointerWidth == 64) { 597 Define(Defs, "_LP64"); 598 Define(Defs, "__LP64__"); 599 Define(Defs, "__amd64__"); 600 Define(Defs, "__amd64"); 601 Define(Defs, "__x86_64"); 602 Define(Defs, "__x86_64__"); 603 Define(Defs, "__SSE3__"); 604 } else { 605 DefineStd(Defs, "i386", Opts); 606 } 607 608 // Target properties. 609 Define(Defs, "__LITTLE_ENDIAN__"); 610 611 // Subtarget options. 612 Define(Defs, "__nocona"); 613 Define(Defs, "__nocona__"); 614 Define(Defs, "__tune_nocona__"); 615 Define(Defs, "__REGISTER_PREFIX__", ""); 616 617 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline 618 // functions in glibc header files that use FP Stack inline asm which the 619 // backend can't deal with (PR879). 620 Define(Defs, "__NO_MATH_INLINES"); 621 622 // Each case falls through to the previous one here. 623 switch (SSELevel) { 624 case SSE42: 625 Define(Defs, "__SSE4_2__"); 626 case SSE41: 627 Define(Defs, "__SSE4_1__"); 628 case SSSE3: 629 Define(Defs, "__SSSE3__"); 630 case SSE3: 631 Define(Defs, "__SSE3__"); 632 case SSE2: 633 Define(Defs, "__SSE2__"); 634 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied. 635 case SSE1: 636 Define(Defs, "__SSE__"); 637 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied. 638 case MMX: 639 Define(Defs, "__MMX__"); 640 case NoMMXSSE: 641 break; 642 } 643} 644 645 646bool 647X86TargetInfo::validateAsmConstraint(const char *&Name, 648 TargetInfo::ConstraintInfo &Info) const { 649 switch (*Name) { 650 default: return false; 651 case 'a': // eax. 652 case 'b': // ebx. 653 case 'c': // ecx. 654 case 'd': // edx. 655 case 'S': // esi. 656 case 'D': // edi. 657 case 'A': // edx:eax. 658 case 't': // top of floating point stack. 659 case 'u': // second from top of floating point stack. 660 case 'q': // Any register accessible as [r]l: a, b, c, and d. 661 case 'y': // Any MMX register. 662 case 'x': // Any SSE register. 663 case 'Q': // Any register accessible as [r]h: a, b, c, and d. 664 case 'e': // 32-bit signed integer constant for use with zero-extending 665 // x86_64 instructions. 666 case 'Z': // 32-bit unsigned integer constant for use with zero-extending 667 // x86_64 instructions. 668 case 'N': // unsigned 8-bit integer constant for use with in and out 669 // instructions. 670 Info.setAllowsRegister(); 671 return true; 672 } 673} 674 675std::string 676X86TargetInfo::convertConstraint(const char Constraint) const { 677 switch (Constraint) { 678 case 'a': return std::string("{ax}"); 679 case 'b': return std::string("{bx}"); 680 case 'c': return std::string("{cx}"); 681 case 'd': return std::string("{dx}"); 682 case 'S': return std::string("{si}"); 683 case 'D': return std::string("{di}"); 684 case 't': // top of floating point stack. 685 return std::string("{st}"); 686 case 'u': // second from top of floating point stack. 687 return std::string("{st(1)}"); // second from top of floating point stack. 688 default: 689 return std::string(1, Constraint); 690 } 691} 692} // end anonymous namespace 693 694namespace { 695// X86-32 generic target 696class X86_32TargetInfo : public X86TargetInfo { 697public: 698 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) { 699 DoubleAlign = LongLongAlign = 32; 700 LongDoubleWidth = 96; 701 LongDoubleAlign = 32; 702 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 703 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 704 "a0:0:64-f80:32:32"; 705 SizeType = UnsignedInt; 706 PtrDiffType = SignedInt; 707 IntPtrType = SignedInt; 708 RegParmMax = 3; 709 } 710 virtual const char *getVAListDeclaration() const { 711 return "typedef char* __builtin_va_list;"; 712 } 713}; 714} // end anonymous namespace 715 716namespace { 717// x86-32 Darwin (OS X) target 718class DarwinI386TargetInfo : public X86_32TargetInfo { 719public: 720 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) { 721 LongDoubleWidth = 128; 722 LongDoubleAlign = 128; 723 SizeType = UnsignedLong; 724 IntPtrType = SignedLong; 725 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 726 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 727 "a0:0:64-f80:128:128"; 728 TLSSupported = false; 729 } 730 731 virtual const char *getStringSymbolPrefix(bool IsConstant) const { 732 return IsConstant ? "\01LC" : "\01lC"; 733 } 734 735 virtual const char *getUnicodeStringSymbolPrefix() const { 736 return "__utf16_string_"; 737 } 738 739 virtual const char *getUnicodeStringSection() const { 740 return "__TEXT,__ustring"; 741 } 742 743 virtual const char *getCFStringSymbolPrefix() const { 744 return "\01LC"; 745 } 746 747 virtual void getTargetDefines(const LangOptions &Opts, 748 std::vector<char> &Defines) const { 749 X86_32TargetInfo::getTargetDefines(Opts, Defines); 750 getDarwinDefines(Defines, Opts); 751 getDarwinOSXDefines(Defines, getTargetTriple()); 752 } 753 754 /// getDefaultLangOptions - Allow the target to specify default settings for 755 /// various language options. These may be overridden by command line 756 /// options. 757 virtual void getDefaultLangOptions(LangOptions &Opts) { 758 GetDarwinLanguageOptions(Opts, getTargetTriple()); 759 } 760}; 761} // end anonymous namespace 762 763namespace { 764// x86-32 FreeBSD target 765class FreeBSDX86_32TargetInfo : public X86_32TargetInfo { 766public: 767 FreeBSDX86_32TargetInfo(const std::string& triple) : 768 X86_32TargetInfo(triple) { } 769 virtual void getTargetDefines(const LangOptions &Opts, 770 std::vector<char> &Defines) const { 771 X86_32TargetInfo::getTargetDefines(Opts, Defines); 772 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines); 773 } 774}; 775} // end anonymous namespace 776 777namespace { 778// x86-32 DragonFly target 779class DragonFlyX86_32TargetInfo : public X86_32TargetInfo { 780public: 781 DragonFlyX86_32TargetInfo(const std::string& triple) : 782 X86_32TargetInfo(triple) { } 783 virtual void getTargetDefines(const LangOptions &Opts, 784 std::vector<char> &Defines) const { 785 X86_32TargetInfo::getTargetDefines(Opts, Defines); 786 getDragonFlyDefines(Opts, Defines); 787 } 788}; 789} // end anonymous namespace 790 791namespace { 792// x86-32 Linux target 793class LinuxX86_32TargetInfo : public X86_32TargetInfo { 794public: 795 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) { 796 UserLabelPrefix = ""; 797 } 798 virtual void getTargetDefines(const LangOptions &Opts, 799 std::vector<char> &Defines) const { 800 X86_32TargetInfo::getTargetDefines(Opts, Defines); 801 getLinuxDefines(Opts, Defines); 802 } 803}; 804} // end anonymous namespace 805 806namespace { 807// x86-32 Windows target 808class WindowsX86_32TargetInfo : public X86_32TargetInfo { 809public: 810 WindowsX86_32TargetInfo(const std::string& triple) 811 : X86_32TargetInfo(triple) { 812 TLSSupported = false; 813 // FIXME: Fix wchar_t. 814 // FIXME: We should probably enable -fms-extensions by default for 815 // this target. 816 } 817 virtual void getTargetDefines(const LangOptions &Opts, 818 std::vector<char> &Defines) const { 819 X86_32TargetInfo::getTargetDefines(Opts, Defines); 820 // This list is based off of the the list of things MingW defines 821 Define(Defines, "_WIN32"); 822 DefineStd(Defines, "WIN32", Opts); 823 DefineStd(Defines, "WINNT", Opts); 824 Define(Defines, "_X86_"); 825 Define(Defines, "__MSVCRT__"); 826 } 827}; 828} // end anonymous namespace 829 830namespace { 831// x86-64 generic target 832class X86_64TargetInfo : public X86TargetInfo { 833public: 834 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) { 835 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 836 DoubleAlign = LongLongAlign = 64; 837 LongDoubleWidth = 128; 838 LongDoubleAlign = 128; 839 IntMaxType = SignedLong; 840 UIntMaxType = UnsignedLong; 841 RegParmMax = 6; 842 843 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 844 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 845 "a0:0:64-f80:128:128"; 846 } 847 virtual const char *getVAListDeclaration() const { 848 return "typedef struct __va_list_tag {" 849 " unsigned gp_offset;" 850 " unsigned fp_offset;" 851 " void* overflow_arg_area;" 852 " void* reg_save_area;" 853 "} __builtin_va_list[1];"; 854 } 855}; 856} // end anonymous namespace 857 858namespace { 859// x86-64 FreeBSD target 860class FreeBSDX86_64TargetInfo : public X86_64TargetInfo { 861public: 862 FreeBSDX86_64TargetInfo(const std::string &triple) 863 : X86_64TargetInfo(triple) {} 864 virtual void getTargetDefines(const LangOptions &Opts, 865 std::vector<char> &Defines) const { 866 X86_64TargetInfo::getTargetDefines(Opts, Defines); 867 getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines); 868 } 869}; 870} // end anonymous namespace 871 872namespace { 873// x86-64 Linux target 874class LinuxX86_64TargetInfo : public X86_64TargetInfo { 875public: 876 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) { 877 UserLabelPrefix = ""; 878 } 879 virtual void getTargetDefines(const LangOptions &Opts, 880 std::vector<char> &Defines) const { 881 X86_64TargetInfo::getTargetDefines(Opts, Defines); 882 getLinuxDefines(Opts, Defines); 883 } 884}; 885} // end anonymous namespace 886 887namespace { 888// x86-64 Darwin (OS X) target 889class DarwinX86_64TargetInfo : public X86_64TargetInfo { 890public: 891 DarwinX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) { 892 TLSSupported = false; 893 } 894 895 virtual const char *getStringSymbolPrefix(bool IsConstant) const { 896 return IsConstant ? "\01LC" : "\01lC"; 897 } 898 899 virtual const char *getUnicodeStringSymbolPrefix() const { 900 return "__utf16_string_"; 901 } 902 903 virtual const char *getUnicodeStringSection() const { 904 return "__TEXT,__ustring"; 905 } 906 907 virtual const char *getCFStringSymbolPrefix() const { 908 return "\01L_unnamed_cfstring_"; 909 } 910 911 virtual void getTargetDefines(const LangOptions &Opts, 912 std::vector<char> &Defines) const { 913 X86_64TargetInfo::getTargetDefines(Opts, Defines); 914 getDarwinDefines(Defines, Opts); 915 getDarwinOSXDefines(Defines, getTargetTriple()); 916 } 917 918 /// getDefaultLangOptions - Allow the target to specify default settings for 919 /// various language options. These may be overridden by command line 920 /// options. 921 virtual void getDefaultLangOptions(LangOptions &Opts) { 922 GetDarwinLanguageOptions(Opts, getTargetTriple()); 923 } 924}; 925} // end anonymous namespace. 926 927namespace { 928class ARMTargetInfo : public TargetInfo { 929 enum { 930 Armv4t, 931 Armv5, 932 Armv6, 933 XScale 934 } ArmArch; 935public: 936 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) { 937 // FIXME: Are the defaults correct for ARM? 938 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 939 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64"; 940 if (triple.find("arm-") == 0 || triple.find("armv6-") == 0) 941 ArmArch = Armv6; 942 else if (triple.find("armv5-") == 0) 943 ArmArch = Armv5; 944 else if (triple.find("armv4t-") == 0) 945 ArmArch = Armv4t; 946 else if (triple.find("xscale-") == 0) 947 ArmArch = XScale; 948 else if (triple.find("armv") == 0) { 949 // FIXME: fuzzy match for other random weird arm triples. This is useful 950 // for the static analyzer and other clients, but probably should be 951 // re-evaluated when codegen is brought up. 952 ArmArch = Armv6; 953 } 954 } 955 virtual void getTargetDefines(const LangOptions &Opts, 956 std::vector<char> &Defs) const { 957 // Target identification. 958 Define(Defs, "__arm"); 959 Define(Defs, "__arm__"); 960 961 // Target properties. 962 Define(Defs, "__LITTLE_ENDIAN__"); 963 964 // Subtarget options. 965 if (ArmArch == Armv6) { 966 Define(Defs, "__ARM_ARCH_6K__"); 967 Define(Defs, "__THUMB_INTERWORK__"); 968 } else if (ArmArch == Armv5) { 969 Define(Defs, "__ARM_ARCH_5TEJ__"); 970 Define(Defs, "__THUMB_INTERWORK__"); 971 Define(Defs, "__SOFTFP__"); 972 } else if (ArmArch == Armv4t) { 973 Define(Defs, "__ARM_ARCH_4T__"); 974 Define(Defs, "__SOFTFP__"); 975 } else if (ArmArch == XScale) { 976 Define(Defs, "__ARM_ARCH_5TE__"); 977 Define(Defs, "__XSCALE__"); 978 Define(Defs, "__SOFTFP__"); 979 } 980 Define(Defs, "__ARMEL__"); 981 } 982 virtual void getTargetBuiltins(const Builtin::Info *&Records, 983 unsigned &NumRecords) const { 984 // FIXME: Implement. 985 Records = 0; 986 NumRecords = 0; 987 } 988 virtual const char *getVAListDeclaration() const { 989 return "typedef char* __builtin_va_list;"; 990 } 991 virtual const char *getTargetPrefix() const { 992 return "arm"; 993 } 994 virtual void getGCCRegNames(const char * const *&Names, 995 unsigned &NumNames) const { 996 // FIXME: Implement. 997 Names = 0; 998 NumNames = 0; 999 } 1000 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1001 unsigned &NumAliases) const { 1002 // FIXME: Implement. 1003 Aliases = 0; 1004 NumAliases = 0; 1005 } 1006 virtual bool validateAsmConstraint(const char *&Name, 1007 TargetInfo::ConstraintInfo &Info) const { 1008 // FIXME: Check if this is complete 1009 switch (*Name) { 1010 default: 1011 case 'l': // r0-r7 1012 case 'h': // r8-r15 1013 case 'w': // VFP Floating point register single precision 1014 case 'P': // VFP Floating point register double precision 1015 Info.setAllowsRegister(); 1016 return true; 1017 } 1018 return false; 1019 } 1020 virtual const char *getClobbers() const { 1021 // FIXME: Is this really right? 1022 return ""; 1023 } 1024}; 1025} // end anonymous namespace. 1026 1027 1028namespace { 1029class DarwinARMTargetInfo : public ARMTargetInfo { 1030public: 1031 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) { 1032 TLSSupported = false; 1033 } 1034 1035 virtual void getTargetDefines(const LangOptions &Opts, 1036 std::vector<char> &Defines) const { 1037 ARMTargetInfo::getTargetDefines(Opts, Defines); 1038 getDarwinDefines(Defines, Opts); 1039 getDarwinIPhoneOSDefines(Defines, getTargetTriple()); 1040 } 1041}; 1042} // end anonymous namespace. 1043 1044namespace { 1045// arm FreeBSD target 1046class FreeBSDARMTargetInfo : public ARMTargetInfo { 1047public: 1048 FreeBSDARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {} 1049 virtual void getTargetDefines(const LangOptions &Opts, 1050 std::vector<char> &Defines) const { 1051 ARMTargetInfo::getTargetDefines(Opts, Defines); 1052 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines); 1053 } 1054}; 1055} // end anonymous namespace 1056 1057namespace { 1058class SparcV8TargetInfo : public TargetInfo { 1059 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1060 static const char * const GCCRegNames[]; 1061public: 1062 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { 1063 // FIXME: Support Sparc quad-precision long double? 1064 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1065 "i64:64:64-f32:32:32-f64:64:64-v64:64:64"; 1066 } 1067 virtual void getTargetDefines(const LangOptions &Opts, 1068 std::vector<char> &Defines) const { 1069 // FIXME: This is missing a lot of important defines; some of the 1070 // missing stuff is likely to break system headers. 1071 Define(Defines, "__sparc"); 1072 Define(Defines, "__sparc__"); 1073 Define(Defines, "__sparcv8"); 1074 } 1075 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1076 unsigned &NumRecords) const { 1077 // FIXME: Implement! 1078 } 1079 virtual const char *getVAListDeclaration() const { 1080 return "typedef void* __builtin_va_list;"; 1081 } 1082 virtual const char *getTargetPrefix() const { 1083 return "sparc"; 1084 } 1085 virtual void getGCCRegNames(const char * const *&Names, 1086 unsigned &NumNames) const; 1087 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1088 unsigned &NumAliases) const; 1089 virtual bool validateAsmConstraint(const char *&Name, 1090 TargetInfo::ConstraintInfo &info) const { 1091 // FIXME: Implement! 1092 return false; 1093 } 1094 virtual const char *getClobbers() const { 1095 // FIXME: Implement! 1096 return ""; 1097 } 1098}; 1099 1100const char * const SparcV8TargetInfo::GCCRegNames[] = { 1101 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1102 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 1103 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 1104 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" 1105}; 1106 1107void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names, 1108 unsigned &NumNames) const { 1109 Names = GCCRegNames; 1110 NumNames = llvm::array_lengthof(GCCRegNames); 1111} 1112 1113const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = { 1114 { { "g0" }, "r0" }, 1115 { { "g1" }, "r1" }, 1116 { { "g2" }, "r2" }, 1117 { { "g3" }, "r3" }, 1118 { { "g4" }, "r4" }, 1119 { { "g5" }, "r5" }, 1120 { { "g6" }, "r6" }, 1121 { { "g7" }, "r7" }, 1122 { { "o0" }, "r8" }, 1123 { { "o1" }, "r9" }, 1124 { { "o2" }, "r10" }, 1125 { { "o3" }, "r11" }, 1126 { { "o4" }, "r12" }, 1127 { { "o5" }, "r13" }, 1128 { { "o6", "sp" }, "r14" }, 1129 { { "o7" }, "r15" }, 1130 { { "l0" }, "r16" }, 1131 { { "l1" }, "r17" }, 1132 { { "l2" }, "r18" }, 1133 { { "l3" }, "r19" }, 1134 { { "l4" }, "r20" }, 1135 { { "l5" }, "r21" }, 1136 { { "l6" }, "r22" }, 1137 { { "l7" }, "r23" }, 1138 { { "i0" }, "r24" }, 1139 { { "i1" }, "r25" }, 1140 { { "i2" }, "r26" }, 1141 { { "i3" }, "r27" }, 1142 { { "i4" }, "r28" }, 1143 { { "i5" }, "r29" }, 1144 { { "i6", "fp" }, "r30" }, 1145 { { "i7" }, "r31" }, 1146}; 1147 1148void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1149 unsigned &NumAliases) const { 1150 Aliases = GCCRegAliases; 1151 NumAliases = llvm::array_lengthof(GCCRegAliases); 1152} 1153} // end anonymous namespace. 1154 1155namespace { 1156class SolarisSparcV8TargetInfo : public SparcV8TargetInfo { 1157public: 1158 SolarisSparcV8TargetInfo(const std::string& triple) : 1159 SparcV8TargetInfo(triple) { 1160 SizeType = UnsignedInt; 1161 PtrDiffType = SignedInt; 1162 } 1163 1164 virtual void getTargetDefines(const LangOptions &Opts, 1165 std::vector<char> &Defines) const { 1166 SparcV8TargetInfo::getTargetDefines(Opts, Defines); 1167 getSolarisDefines(Defines); 1168 } 1169}; 1170} // end anonymous namespace. 1171 1172namespace { 1173 class PIC16TargetInfo : public TargetInfo{ 1174 public: 1175 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) { 1176 TLSSupported = false; 1177 IntWidth = 16; 1178 LongWidth = LongLongWidth = 32; 1179 PointerWidth = 16; 1180 IntAlign = 8; 1181 LongAlign = LongLongAlign = 8; 1182 PointerAlign = 8; 1183 SizeType = UnsignedInt; 1184 IntMaxType = SignedLong; 1185 UIntMaxType = UnsignedLong; 1186 IntPtrType = SignedShort; 1187 PtrDiffType = SignedInt; 1188 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"; 1189 } 1190 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; } 1191 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; } 1192 virtual void getTargetDefines(const LangOptions &Opts, 1193 std::vector<char> &Defines) const { 1194 Define(Defines, "__pic16"); 1195 } 1196 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1197 unsigned &NumRecords) const {} 1198 virtual const char *getVAListDeclaration() const { return "";} 1199 virtual const char *getClobbers() const {return "";} 1200 virtual const char *getTargetPrefix() const {return "pic16";} 1201 virtual void getGCCRegNames(const char * const *&Names, 1202 unsigned &NumNames) const {} 1203 virtual bool validateAsmConstraint(const char *&Name, 1204 TargetInfo::ConstraintInfo &info) const { 1205 return true; 1206 } 1207 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1208 unsigned &NumAliases) const {} 1209 virtual bool useGlobalsForAutomaticVariables() const {return true;} 1210 }; 1211} 1212 1213namespace { 1214 class MSP430TargetInfo : public TargetInfo { 1215 static const char * const GCCRegNames[]; 1216 public: 1217 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { 1218 TLSSupported = false; 1219 IntWidth = 16; 1220 LongWidth = LongLongWidth = 32; 1221 PointerWidth = 16; 1222 IntAlign = 8; 1223 LongAlign = LongLongAlign = 8; 1224 PointerAlign = 8; 1225 SizeType = UnsignedInt; 1226 IntMaxType = SignedLong; 1227 UIntMaxType = UnsignedLong; 1228 IntPtrType = SignedShort; 1229 PtrDiffType = SignedInt; 1230 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"; 1231 } 1232 virtual void getTargetDefines(const LangOptions &Opts, 1233 std::vector<char> &Defines) const { 1234 Define(Defines, "MSP430"); 1235 Define(Defines, "__MSP430__"); 1236 // FIXME: defines for different 'flavours' of MCU 1237 } 1238 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1239 unsigned &NumRecords) const { 1240 // FIXME: Implement. 1241 Records = 0; 1242 NumRecords = 0; 1243 } 1244 virtual const char *getTargetPrefix() const { 1245 return "msp430"; 1246 } 1247 virtual void getGCCRegNames(const char * const *&Names, 1248 unsigned &NumNames) const; 1249 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1250 unsigned &NumAliases) const { 1251 // No aliases. 1252 Aliases = 0; 1253 NumAliases = 0; 1254 } 1255 virtual bool validateAsmConstraint(const char *&Name, 1256 TargetInfo::ConstraintInfo &info) const { 1257 // FIXME: implement 1258 return true; 1259 } 1260 virtual const char *getClobbers() const { 1261 // FIXME: Is this really right? 1262 return ""; 1263 } 1264 virtual const char *getVAListDeclaration() const { 1265 // FIXME: implement 1266 return ""; 1267 } 1268 }; 1269 1270 const char * const MSP430TargetInfo::GCCRegNames[] = { 1271 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1272 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1273 }; 1274 1275 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names, 1276 unsigned &NumNames) const { 1277 Names = GCCRegNames; 1278 NumNames = llvm::array_lengthof(GCCRegNames); 1279 } 1280} 1281 1282 1283//===----------------------------------------------------------------------===// 1284// Driver code 1285//===----------------------------------------------------------------------===// 1286 1287static inline bool IsX86(const std::string& TT) { 1288 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' && 1289 TT[4] == '-' && TT[1] - '3' < 6); 1290} 1291 1292/// CreateTargetInfo - Return the target info object for the specified target 1293/// triple. 1294TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) { 1295 // OS detection; this isn't really anywhere near complete. 1296 // Additions and corrections are welcome. 1297 bool isDarwin = T.find("-darwin") != std::string::npos; 1298 bool isDragonFly = T.find("-dragonfly") != std::string::npos; 1299 bool isFreeBSD = T.find("-freebsd") != std::string::npos; 1300 bool isSolaris = T.find("-solaris") != std::string::npos; 1301 bool isLinux = T.find("-linux") != std::string::npos; 1302 bool isWindows = T.find("-windows") != std::string::npos || 1303 T.find("-win32") != std::string::npos || 1304 T.find("-mingw") != std::string::npos; 1305 1306 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) { 1307 if (isDarwin) 1308 return new DarwinPPCTargetInfo(T); 1309 return new PPC32TargetInfo(T); 1310 } 1311 1312 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) { 1313 if (isDarwin) 1314 return new DarwinPPC64TargetInfo(T); 1315 return new PPC64TargetInfo(T); 1316 } 1317 1318 if (T.find("armv") == 0 || T.find("arm-") == 0 || T.find("xscale") == 0) { 1319 if (isDarwin) 1320 return new DarwinARMTargetInfo(T); 1321 if (isFreeBSD) 1322 return new FreeBSDARMTargetInfo(T); 1323 return new ARMTargetInfo(T); 1324 } 1325 1326 if (T.find("sparc-") == 0) { 1327 if (isSolaris) 1328 return new SolarisSparcV8TargetInfo(T); 1329 return new SparcV8TargetInfo(T); 1330 } 1331 1332 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) { 1333 if (isDarwin) 1334 return new DarwinX86_64TargetInfo(T); 1335 if (isLinux) 1336 return new LinuxX86_64TargetInfo(T); 1337 if (isFreeBSD) 1338 return new FreeBSDX86_64TargetInfo(T); 1339 return new X86_64TargetInfo(T); 1340 } 1341 1342 if (T.find("pic16-") == 0) 1343 return new PIC16TargetInfo(T); 1344 1345 if (T.find("msp430-") == 0) 1346 return new MSP430TargetInfo(T); 1347 1348 if (IsX86(T)) { 1349 if (isDarwin) 1350 return new DarwinI386TargetInfo(T); 1351 if (isLinux) 1352 return new LinuxX86_32TargetInfo(T); 1353 if (isDragonFly) 1354 return new DragonFlyX86_32TargetInfo(T); 1355 if (isFreeBSD) 1356 return new FreeBSDX86_32TargetInfo(T); 1357 if (isWindows) 1358 return new WindowsX86_32TargetInfo(T); 1359 return new X86_32TargetInfo(T); 1360 } 1361 1362 return NULL; 1363} 1364