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