Targets.cpp revision 6a91648fe9226db360759a23c89bb5aec3f3ceab
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 657 virtual const char *getStringSymbolPrefix(bool IsConstant) const { 658 return IsConstant ? "\01LC" : "\01lC"; 659 } 660 661 virtual const char *getUnicodeStringSymbolPrefix() const { 662 return "__utf16_string_"; 663 } 664 665 virtual const char *getUnicodeStringSection() const { 666 return "__TEXT,__ustring"; 667 } 668 669 virtual const char *getCFStringSymbolPrefix() const { 670 return "\01LC"; 671 } 672 673 virtual void getTargetDefines(const LangOptions &Opts, 674 std::vector<char> &Defines) const { 675 X86_32TargetInfo::getTargetDefines(Opts, Defines); 676 getDarwinDefines(Defines, getTargetTriple()); 677 } 678 679 /// getDefaultLangOptions - Allow the target to specify default settings for 680 /// various language options. These may be overridden by command line 681 /// options. 682 virtual void getDefaultLangOptions(LangOptions &Opts) { 683 GetDarwinLanguageOptions(Opts, getTargetTriple()); 684 } 685}; 686} // end anonymous namespace 687 688namespace { 689// x86-32 FreeBSD target 690class FreeBSDX86_32TargetInfo : public X86_32TargetInfo { 691public: 692 FreeBSDX86_32TargetInfo(const std::string& triple) : 693 X86_32TargetInfo(triple) { } 694 virtual void getTargetDefines(const LangOptions &Opts, 695 std::vector<char> &Defines) const { 696 X86_32TargetInfo::getTargetDefines(Opts, Defines); 697 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines); 698 } 699}; 700} // end anonymous namespace 701 702namespace { 703// x86-32 DragonFly target 704class DragonFlyX86_32TargetInfo : public X86_32TargetInfo { 705public: 706 DragonFlyX86_32TargetInfo(const std::string& triple) : 707 X86_32TargetInfo(triple) { } 708 virtual void getTargetDefines(const LangOptions &Opts, 709 std::vector<char> &Defines) const { 710 X86_32TargetInfo::getTargetDefines(Opts, Defines); 711 getDragonFlyDefines(Opts, Defines); 712 } 713}; 714} // end anonymous namespace 715 716namespace { 717// x86-32 Linux target 718class LinuxX86_32TargetInfo : public X86_32TargetInfo { 719public: 720 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) { 721 UserLabelPrefix = ""; 722 } 723 virtual void getTargetDefines(const LangOptions &Opts, 724 std::vector<char> &Defines) const { 725 X86_32TargetInfo::getTargetDefines(Opts, Defines); 726 getLinuxDefines(Opts, Defines); 727 } 728}; 729} // end anonymous namespace 730 731namespace { 732// x86-32 Windows target 733class WindowsX86_32TargetInfo : public X86_32TargetInfo { 734public: 735 WindowsX86_32TargetInfo(const std::string& triple) 736 : X86_32TargetInfo(triple) { 737 // FIXME: Fix wchar_t. 738 // FIXME: We should probably enable -fms-extensions by default for 739 // this target. 740 } 741 virtual void getTargetDefines(const LangOptions &Opts, 742 std::vector<char> &Defines) const { 743 X86_32TargetInfo::getTargetDefines(Opts, Defines); 744 // This list is based off of the the list of things MingW defines 745 Define(Defines, "_WIN32"); 746 DefineStd(Defines, "WIN32", Opts); 747 DefineStd(Defines, "WINNT", Opts); 748 Define(Defines, "_X86_"); 749 Define(Defines, "__MSVCRT__"); 750 } 751}; 752} // end anonymous namespace 753 754namespace { 755// x86-64 generic target 756class X86_64TargetInfo : public X86TargetInfo { 757public: 758 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) { 759 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 760 DoubleAlign = LongLongAlign = 64; 761 LongDoubleWidth = 128; 762 LongDoubleAlign = 128; 763 IntMaxType = SignedLong; 764 UIntMaxType = UnsignedLong; 765 766 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 767 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 768 "a0:0:64-f80:128:128"; 769 } 770 virtual const char *getVAListDeclaration() const { 771 return "typedef struct __va_list_tag {" 772 " unsigned gp_offset;" 773 " unsigned fp_offset;" 774 " void* overflow_arg_area;" 775 " void* reg_save_area;" 776 "} __builtin_va_list[1];"; 777 } 778}; 779} // end anonymous namespace 780 781namespace { 782// x86-64 FreeBSD target 783class FreeBSDX86_64TargetInfo : public X86_64TargetInfo { 784public: 785 FreeBSDX86_64TargetInfo(const std::string &triple) 786 : X86_64TargetInfo(triple) {} 787 virtual void getTargetDefines(const LangOptions &Opts, 788 std::vector<char> &Defines) const { 789 X86_64TargetInfo::getTargetDefines(Opts, Defines); 790 getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines); 791 } 792}; 793} // end anonymous namespace 794 795namespace { 796// x86-64 Linux target 797class LinuxX86_64TargetInfo : public X86_64TargetInfo { 798public: 799 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) { 800 UserLabelPrefix = ""; 801 } 802 virtual void getTargetDefines(const LangOptions &Opts, 803 std::vector<char> &Defines) const { 804 X86_64TargetInfo::getTargetDefines(Opts, Defines); 805 getLinuxDefines(Opts, Defines); 806 } 807}; 808} // end anonymous namespace 809 810namespace { 811// x86-64 Darwin (OS X) target 812class DarwinX86_64TargetInfo : public X86_64TargetInfo { 813public: 814 DarwinX86_64TargetInfo(const std::string& triple) : 815 X86_64TargetInfo(triple) {} 816 817 virtual const char *getStringSymbolPrefix(bool IsConstant) const { 818 return IsConstant ? "\01LC" : "\01lC"; 819 } 820 821 virtual const char *getUnicodeStringSymbolPrefix() const { 822 return "__utf16_string_"; 823 } 824 825 virtual const char *getUnicodeStringSection() const { 826 return "__TEXT,__ustring"; 827 } 828 829 virtual const char *getCFStringSymbolPrefix() const { 830 return "\01L_unnamed_cfstring_"; 831 } 832 833 virtual void getTargetDefines(const LangOptions &Opts, 834 std::vector<char> &Defines) const { 835 X86_64TargetInfo::getTargetDefines(Opts, Defines); 836 getDarwinDefines(Defines, getTargetTriple()); 837 } 838 839 /// getDefaultLangOptions - Allow the target to specify default settings for 840 /// various language options. These may be overridden by command line 841 /// options. 842 virtual void getDefaultLangOptions(LangOptions &Opts) { 843 GetDarwinLanguageOptions(Opts, getTargetTriple()); 844 } 845}; 846} // end anonymous namespace. 847 848namespace { 849class ARMTargetInfo : public TargetInfo { 850public: 851 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) { 852 // FIXME: Are the defaults correct for ARM? 853 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 854 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64"; 855 } 856 virtual void getTargetDefines(const LangOptions &Opts, 857 std::vector<char> &Defs) const { 858 // Target identification. 859 Define(Defs, "__arm"); 860 Define(Defs, "__arm__"); 861 862 // Target properties. 863 Define(Defs, "__LITTLE_ENDIAN__"); 864 865 // Subtarget options. [hard coded to v6 for now] 866 Define(Defs, "__ARM_ARCH_6K__"); 867 Define(Defs, "__ARMEL__"); 868 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000"); 869 } 870 virtual void getTargetBuiltins(const Builtin::Info *&Records, 871 unsigned &NumRecords) const { 872 // FIXME: Implement. 873 Records = 0; 874 NumRecords = 0; 875 } 876 virtual const char *getVAListDeclaration() const { 877 return "typedef char* __builtin_va_list;"; 878 } 879 virtual const char *getTargetPrefix() const { 880 return "arm"; 881 } 882 virtual void getGCCRegNames(const char * const *&Names, 883 unsigned &NumNames) const { 884 // FIXME: Implement. 885 Names = 0; 886 NumNames = 0; 887 } 888 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 889 unsigned &NumAliases) const { 890 // FIXME: Implement. 891 Aliases = 0; 892 NumAliases = 0; 893 } 894 virtual bool validateAsmConstraint(const char *&Name, 895 TargetInfo::ConstraintInfo &info) const { 896 // FIXME: Check if this is complete 897 switch (*Name) { 898 default: 899 case 'l': // r0-r7 900 case 'h': // r8-r15 901 case 'w': // VFP Floating point register single precision 902 case 'P': // VFP Floating point register double precision 903 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister); 904 return true; 905 } 906 return false; 907 } 908 virtual const char *getClobbers() const { 909 // FIXME: Is this really right? 910 return ""; 911 } 912}; 913} // end anonymous namespace. 914 915 916namespace { 917class DarwinARMTargetInfo : public ARMTargetInfo { 918public: 919 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {} 920 921 virtual void getTargetDefines(const LangOptions &Opts, 922 std::vector<char> &Defines) const { 923 ARMTargetInfo::getTargetDefines(Opts, Defines); 924 getDarwinDefines(Defines, getTargetTriple()); 925 } 926}; 927} // end anonymous namespace. 928 929namespace { 930// arm FreeBSD target 931class FreeBSDARMTargetInfo : public ARMTargetInfo { 932public: 933 FreeBSDARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {} 934 virtual void getTargetDefines(const LangOptions &Opts, 935 std::vector<char> &Defines) const { 936 ARMTargetInfo::getTargetDefines(Opts, Defines); 937 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines); 938 } 939}; 940} // end anonymous namespace 941 942namespace { 943class SparcV8TargetInfo : public TargetInfo { 944 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 945 static const char * const GCCRegNames[]; 946public: 947 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { 948 // FIXME: Support Sparc quad-precision long double? 949 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 950 "i64:64:64-f32:32:32-f64:64:64-v64:64:64"; 951 } 952 virtual void getTargetDefines(const LangOptions &Opts, 953 std::vector<char> &Defines) const { 954 // FIXME: This is missing a lot of important defines; some of the 955 // missing stuff is likely to break system headers. 956 Define(Defines, "__sparc"); 957 Define(Defines, "__sparc__"); 958 Define(Defines, "__sparcv8"); 959 } 960 virtual void getTargetBuiltins(const Builtin::Info *&Records, 961 unsigned &NumRecords) const { 962 // FIXME: Implement! 963 } 964 virtual const char *getVAListDeclaration() const { 965 return "typedef void* __builtin_va_list;"; 966 } 967 virtual const char *getTargetPrefix() const { 968 return "sparc"; 969 } 970 virtual void getGCCRegNames(const char * const *&Names, 971 unsigned &NumNames) const; 972 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 973 unsigned &NumAliases) const; 974 virtual bool validateAsmConstraint(const char *&Name, 975 TargetInfo::ConstraintInfo &info) const { 976 // FIXME: Implement! 977 return false; 978 } 979 virtual const char *getClobbers() const { 980 // FIXME: Implement! 981 return ""; 982 } 983}; 984 985const char * const SparcV8TargetInfo::GCCRegNames[] = { 986 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 987 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 988 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 989 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" 990}; 991 992void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names, 993 unsigned &NumNames) const { 994 Names = GCCRegNames; 995 NumNames = llvm::array_lengthof(GCCRegNames); 996} 997 998const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = { 999 { { "g0" }, "r0" }, 1000 { { "g1" }, "r1" }, 1001 { { "g2" }, "r2" }, 1002 { { "g3" }, "r3" }, 1003 { { "g4" }, "r4" }, 1004 { { "g5" }, "r5" }, 1005 { { "g6" }, "r6" }, 1006 { { "g7" }, "r7" }, 1007 { { "o0" }, "r8" }, 1008 { { "o1" }, "r9" }, 1009 { { "o2" }, "r10" }, 1010 { { "o3" }, "r11" }, 1011 { { "o4" }, "r12" }, 1012 { { "o5" }, "r13" }, 1013 { { "o6", "sp" }, "r14" }, 1014 { { "o7" }, "r15" }, 1015 { { "l0" }, "r16" }, 1016 { { "l1" }, "r17" }, 1017 { { "l2" }, "r18" }, 1018 { { "l3" }, "r19" }, 1019 { { "l4" }, "r20" }, 1020 { { "l5" }, "r21" }, 1021 { { "l6" }, "r22" }, 1022 { { "l7" }, "r23" }, 1023 { { "i0" }, "r24" }, 1024 { { "i1" }, "r25" }, 1025 { { "i2" }, "r26" }, 1026 { { "i3" }, "r27" }, 1027 { { "i4" }, "r28" }, 1028 { { "i5" }, "r29" }, 1029 { { "i6", "fp" }, "r30" }, 1030 { { "i7" }, "r31" }, 1031}; 1032 1033void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1034 unsigned &NumAliases) const { 1035 Aliases = GCCRegAliases; 1036 NumAliases = llvm::array_lengthof(GCCRegAliases); 1037} 1038} // end anonymous namespace. 1039 1040namespace { 1041class SolarisSparcV8TargetInfo : public SparcV8TargetInfo { 1042public: 1043 SolarisSparcV8TargetInfo(const std::string& triple) : 1044 SparcV8TargetInfo(triple) { 1045 SizeType = UnsignedInt; 1046 PtrDiffType = SignedInt; 1047 } 1048 1049 virtual void getTargetDefines(const LangOptions &Opts, 1050 std::vector<char> &Defines) const { 1051 SparcV8TargetInfo::getTargetDefines(Opts, Defines); 1052 getSolarisDefines(Defines); 1053 } 1054}; 1055} // end anonymous namespace. 1056 1057namespace { 1058 class PIC16TargetInfo : public TargetInfo{ 1059 public: 1060 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) { 1061 IntWidth = 16; 1062 LongWidth = LongLongWidth = 32; 1063 PointerWidth = 16; 1064 IntAlign = 8; 1065 LongAlign = LongLongAlign = 8; 1066 PointerAlign = 8; 1067 SizeType = UnsignedInt; 1068 IntMaxType = SignedLong; 1069 UIntMaxType = UnsignedLong; 1070 IntPtrType = SignedShort; 1071 PtrDiffType = SignedInt; 1072 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"; 1073 } 1074 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; } 1075 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; } 1076 virtual void getTargetDefines(const LangOptions &Opts, 1077 std::vector<char> &Defines) const { 1078 Define(Defines, "__pic16"); 1079 } 1080 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1081 unsigned &NumRecords) const {} 1082 virtual const char *getVAListDeclaration() const { return "";} 1083 virtual const char *getClobbers() const {return "";} 1084 virtual const char *getTargetPrefix() const {return "";} 1085 virtual void getGCCRegNames(const char * const *&Names, 1086 unsigned &NumNames) const {} 1087 virtual bool validateAsmConstraint(const char *&Name, 1088 TargetInfo::ConstraintInfo &info) const { 1089 return true; 1090 } 1091 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1092 unsigned &NumAliases) const {} 1093 virtual bool useGlobalsForAutomaticVariables() const {return true;} 1094 }; 1095} 1096 1097//===----------------------------------------------------------------------===// 1098// Driver code 1099//===----------------------------------------------------------------------===// 1100 1101static inline bool IsX86(const std::string& TT) { 1102 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' && 1103 TT[4] == '-' && TT[1] - '3' < 6); 1104} 1105 1106/// CreateTargetInfo - Return the target info object for the specified target 1107/// triple. 1108TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) { 1109 // OS detection; this isn't really anywhere near complete. 1110 // Additions and corrections are welcome. 1111 bool isDarwin = T.find("-darwin") != std::string::npos; 1112 bool isDragonFly = T.find("-dragonfly") != std::string::npos; 1113 bool isFreeBSD = T.find("-freebsd") != std::string::npos; 1114 bool isSolaris = T.find("-solaris") != std::string::npos; 1115 bool isLinux = T.find("-linux") != std::string::npos; 1116 bool isWindows = T.find("-windows") != std::string::npos || 1117 T.find("-win32") != std::string::npos || 1118 T.find("-mingw") != std::string::npos; 1119 1120 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) { 1121 if (isDarwin) 1122 return new DarwinPPCTargetInfo(T); 1123 return new PPC32TargetInfo(T); 1124 } 1125 1126 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) { 1127 if (isDarwin) 1128 return new DarwinPPC64TargetInfo(T); 1129 return new PPC64TargetInfo(T); 1130 } 1131 1132 if (T.find("armv6-") == 0 || T.find("arm-") == 0) { 1133 if (isDarwin) 1134 return new DarwinARMTargetInfo(T); 1135 if (isFreeBSD) 1136 return new FreeBSDARMTargetInfo(T); 1137 return new ARMTargetInfo(T); 1138 } 1139 1140 if (T.find("sparc-") == 0) { 1141 if (isSolaris) 1142 return new SolarisSparcV8TargetInfo(T); 1143 return new SparcV8TargetInfo(T); 1144 } 1145 1146 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) { 1147 if (isDarwin) 1148 return new DarwinX86_64TargetInfo(T); 1149 if (isLinux) 1150 return new LinuxX86_64TargetInfo(T); 1151 if (isFreeBSD) 1152 return new FreeBSDX86_64TargetInfo(T); 1153 return new X86_64TargetInfo(T); 1154 } 1155 1156 if (T.find("pic16-") == 0) 1157 return new PIC16TargetInfo(T); 1158 1159 if (IsX86(T)) { 1160 if (isDarwin) 1161 return new DarwinI386TargetInfo(T); 1162 if (isLinux) 1163 return new LinuxX86_32TargetInfo(T); 1164 if (isDragonFly) 1165 return new DragonFlyX86_32TargetInfo(T); 1166 if (isFreeBSD) 1167 return new FreeBSDX86_32TargetInfo(T); 1168 if (isWindows) 1169 return new WindowsX86_32TargetInfo(T); 1170 return new X86_32TargetInfo(T); 1171 } 1172 1173 return NULL; 1174} 1175 1176