Targets.cpp revision bd00eb855a6080ff39b720d33bbb2db7ac08f58c
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#include "clang/AST/Builtins.h" 16#include "clang/AST/TargetBuiltins.h" 17#include "clang/Basic/TargetInfo.h" 18#include "llvm/ADT/STLExtras.h" 19#include "llvm/ADT/APFloat.h" 20using namespace clang; 21 22//===----------------------------------------------------------------------===// 23// Common code shared among targets. 24//===----------------------------------------------------------------------===// 25 26static void Define(std::vector<char> &Buf, const char *Macro, 27 const char *Val = "1") { 28 const char *Def = "#define "; 29 Buf.insert(Buf.end(), Def, Def+strlen(Def)); 30 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro)); 31 Buf.push_back(' '); 32 Buf.insert(Buf.end(), Val, Val+strlen(Val)); 33 Buf.push_back('\n'); 34} 35 36//===----------------------------------------------------------------------===// 37// Defines specific to certain operating systems. 38//===----------------------------------------------------------------------===// 39 40static void getSolarisDefines(std::vector<char> &Defs) { 41 Define(Defs, "__SUN__"); 42 Define(Defs, "__SOLARIS__"); 43} 44 45static void getDragonFlyDefines(std::vector<char> &Defs) { 46 // DragonFly defines; list based off of gcc output 47 Define(Defs, "__DragonFly__"); 48 Define(Defs, "__DragonFly_cc_version", "100001"); 49 Define(Defs, "__ELF__"); 50 Define(Defs, "__KPRINTF_ATTRIBUTE__"); 51 Define(Defs, "__tune_i386__"); 52 Define(Defs, "unix"); 53 Define(Defs, "__unix"); 54 Define(Defs, "__unix__"); 55} 56 57static void getLinuxDefines(std::vector<char> &Defs) { 58 // Linux defines; list based off of gcc output 59 Define(Defs, "__unix__"); 60 Define(Defs, "__unix"); 61 Define(Defs, "unix"); 62 Define(Defs, "__linux__"); 63 Define(Defs, "__linux"); 64 Define(Defs, "linux"); 65 Define(Defs, "__gnu_linux__"); 66} 67 68static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) { 69 Define(Defs, "__APPLE__"); 70 Define(Defs, "__MACH__"); 71 72 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5. 73 const char *Darwin = strstr(Triple, "-darwin"); 74 if (Darwin) { 75 char DarwinStr[] = "1000"; 76 Darwin += strlen("-darwin"); 77 if (Darwin[0] >= '0' && Darwin[0] <= '9') { 78 unsigned DarwinNo = Darwin[0]-'0'; 79 ++Darwin; 80 81 // Handle "darwin11". 82 if (DarwinNo == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') { 83 DarwinNo = 10+Darwin[0]-'0'; 84 ++Darwin; 85 } 86 87 if (DarwinNo >= 4 && DarwinNo <= 13) { // 10.0-10.9 88 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc. 89 DarwinStr[2] = '0' + DarwinNo-4; 90 } 91 92 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049" 93 if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' && 94 Darwin[2] == '\0') 95 DarwinStr[3] = Darwin[1]; 96 97 } 98 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr); 99 } 100} 101 102//===----------------------------------------------------------------------===// 103// Defines specific to certain architectures. 104//===----------------------------------------------------------------------===// 105 106/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are 107/// not tied to a specific subtarget. 108static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) { 109 // Target identification. 110 Define(Defs, "__ppc__"); 111 Define(Defs, "_ARCH_PPC"); 112 Define(Defs, "__POWERPC__"); 113 if (is64Bit) { 114 Define(Defs, "_ARCH_PPC64"); 115 Define(Defs, "_LP64"); 116 Define(Defs, "__LP64__"); 117 Define(Defs, "__ppc64__"); 118 } else { 119 Define(Defs, "__ppc__"); 120 } 121 122 // Target properties. 123 Define(Defs, "_BIG_ENDIAN"); 124 Define(Defs, "__BIG_ENDIAN__"); 125 126 // Subtarget options. 127 Define(Defs, "__NATURAL_ALIGNMENT__"); 128 Define(Defs, "__REGISTER_PREFIX__", ""); 129 130 // FIXME: Should be controlled by command line option. 131 Define(Defs, "__LONG_DOUBLE_128__"); 132} 133 134/// getX86Defines - Return a set of the X86-specific #defines that are 135/// not tied to a specific subtarget. 136static void getX86Defines(std::vector<char> &Defs, bool is64Bit) { 137 // Target identification. 138 if (is64Bit) { 139 Define(Defs, "_LP64"); 140 Define(Defs, "__LP64__"); 141 Define(Defs, "__amd64__"); 142 Define(Defs, "__amd64"); 143 Define(Defs, "__x86_64"); 144 Define(Defs, "__x86_64__"); 145 } else { 146 Define(Defs, "__i386__"); 147 Define(Defs, "__i386"); 148 Define(Defs, "i386"); 149 } 150 151 // Target properties. 152 Define(Defs, "__LITTLE_ENDIAN__"); 153 154 // Subtarget options. 155 Define(Defs, "__nocona"); 156 Define(Defs, "__nocona__"); 157 Define(Defs, "__tune_nocona__"); 158 Define(Defs, "__SSE2_MATH__"); 159 Define(Defs, "__SSE2__"); 160 Define(Defs, "__SSE_MATH__"); 161 Define(Defs, "__SSE__"); 162 Define(Defs, "__MMX__"); 163 Define(Defs, "__REGISTER_PREFIX__", ""); 164} 165 166/// getARMDefines - Return a set of the ARM-specific #defines that are 167/// not tied to a specific subtarget. 168static void getARMDefines(std::vector<char> &Defs) { 169 // Target identification. 170 Define(Defs, "__arm"); 171 Define(Defs, "__arm__"); 172 173 // Target properties. 174 Define(Defs, "__LITTLE_ENDIAN__"); 175 176 // Subtarget options. [hard coded to v6 for now] 177 Define(Defs, "__ARM_ARCH_6K__"); 178 Define(Defs, "__ARMEL__"); 179 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000"); 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 virtual const char *getVAListDeclaration() const { 203 return "typedef struct __va_list_tag {" 204 " unsigned char gpr;" 205 " unsigned char fpr;" 206 " unsigned short reserved;" 207 " void* overflow_arg_area;" 208 " void* reg_save_area;" 209 "} __builtin_va_list[1];"; 210 } 211 virtual const char *getTargetPrefix() const { 212 return "ppc"; 213 } 214 virtual void getGCCRegNames(const char * const *&Names, 215 unsigned &NumNames) const; 216 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 217 unsigned &NumAliases) const; 218 virtual bool validateAsmConstraint(char c, 219 TargetInfo::ConstraintInfo &info) const { 220 switch (c) { 221 default: return false; 222 case 'O': // Zero 223 return true; 224 case 'b': // Base register 225 case 'f': // Floating point register 226 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister); 227 return true; 228 } 229 } 230 virtual const char *getClobbers() const { 231 return ""; 232 } 233}; 234 235const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { 236#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS }, 237#include "clang/AST/PPCBuiltins.def" 238}; 239 240const char * const PPCTargetInfo::GCCRegNames[] = { 241 "0", "1", "2", "3", "4", "5", "6", "7", 242 "8", "9", "10", "11", "12", "13", "14", "15", 243 "16", "17", "18", "19", "20", "21", "22", "23", 244 "24", "25", "26", "27", "28", "29", "30", "31", 245 "0", "1", "2", "3", "4", "5", "6", "7", 246 "8", "9", "10", "11", "12", "13", "14", "15", 247 "16", "17", "18", "19", "20", "21", "22", "23", 248 "24", "25", "26", "27", "28", "29", "30", "31", 249 "mq", "lr", "ctr", "ap", 250 "0", "1", "2", "3", "4", "5", "6", "7", 251 "xer", 252 "0", "1", "2", "3", "4", "5", "6", "7", 253 "8", "9", "10", "11", "12", "13", "14", "15", 254 "16", "17", "18", "19", "20", "21", "22", "23", 255 "24", "25", "26", "27", "28", "29", "30", "31", 256 "vrsave", "vscr", 257 "spe_acc", "spefscr", 258 "sfp" 259}; 260 261void PPCTargetInfo::getGCCRegNames(const char * const *&Names, 262 unsigned &NumNames) const { 263 Names = GCCRegNames; 264 NumNames = llvm::array_lengthof(GCCRegNames); 265} 266 267const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { 268 // While some of these aliases do map to different registers 269 // they still share the same register name. 270 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" }, 271 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" }, 272 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" }, 273 { { "cr3", "fr3", "r3", "v3"}, "3" }, 274 { { "cr4", "fr4", "r4", "v4"}, "4" }, 275 { { "cr5", "fr5", "r5", "v5"}, "5" }, 276 { { "cr6", "fr6", "r6", "v6"}, "6" }, 277 { { "cr7", "fr7", "r7", "v7"}, "7" }, 278 { { "fr8", "r8", "v8"}, "8" }, 279 { { "fr9", "r9", "v9"}, "9" }, 280 { { "fr10", "r10", "v10"}, "10" }, 281 { { "fr11", "r11", "v11"}, "11" }, 282 { { "fr12", "r12", "v12"}, "12" }, 283 { { "fr13", "r13", "v13"}, "13" }, 284 { { "fr14", "r14", "v14"}, "14" }, 285 { { "fr15", "r15", "v15"}, "15" }, 286 { { "fr16", "r16", "v16"}, "16" }, 287 { { "fr17", "r17", "v17"}, "17" }, 288 { { "fr18", "r18", "v18"}, "18" }, 289 { { "fr19", "r19", "v19"}, "19" }, 290 { { "fr20", "r20", "v20"}, "20" }, 291 { { "fr21", "r21", "v21"}, "21" }, 292 { { "fr22", "r22", "v22"}, "22" }, 293 { { "fr23", "r23", "v23"}, "23" }, 294 { { "fr24", "r24", "v24"}, "24" }, 295 { { "fr25", "r25", "v25"}, "25" }, 296 { { "fr26", "r26", "v26"}, "26" }, 297 { { "fr27", "r27", "v27"}, "27" }, 298 { { "fr28", "r28", "v28"}, "28" }, 299 { { "fr29", "r29", "v29"}, "29" }, 300 { { "fr30", "r30", "v30"}, "30" }, 301 { { "fr31", "r31", "v31"}, "31" }, 302}; 303 304void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 305 unsigned &NumAliases) const { 306 Aliases = GCCRegAliases; 307 NumAliases = llvm::array_lengthof(GCCRegAliases); 308} 309} // end anonymous namespace. 310 311namespace { 312class PPC32TargetInfo : public PPCTargetInfo { 313public: 314 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) { 315 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 316 "i64:64:64-f32:32:32-f64:64:64-v128:128:128"; 317 } 318 virtual void getTargetDefines(std::vector<char> &Defines) const { 319 getPowerPCDefines(Defines, false); 320 } 321}; 322} // end anonymous namespace. 323 324namespace { 325class PPC64TargetInfo : public PPCTargetInfo { 326public: 327 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) { 328 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 329 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 330 "i64:64:64-f32:32:32-f64:64:64-v128:128:128"; 331 } 332 virtual void getTargetDefines(std::vector<char> &Defines) const { 333 getPowerPCDefines(Defines, true); 334 } 335}; 336} // end anonymous namespace. 337 338namespace { 339class DarwinPPCTargetInfo : public PPC32TargetInfo { 340public: 341 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {} 342 virtual void getTargetDefines(std::vector<char> &Defines) const { 343 PPC32TargetInfo::getTargetDefines(Defines); 344 getDarwinDefines(Defines, getTargetTriple()); 345 } 346 347 virtual bool useNeXTRuntimeAsDefault() const { return true; } 348}; 349} // end anonymous namespace. 350 351namespace { 352class DarwinPPC64TargetInfo : public PPC64TargetInfo { 353public: 354 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {} 355 virtual void getTargetDefines(std::vector<char> &Defines) const { 356 PPC64TargetInfo::getTargetDefines(Defines); 357 getDarwinDefines(Defines, getTargetTriple()); 358 } 359 360 virtual bool useNeXTRuntimeAsDefault() const { return true; } 361}; 362} // end anonymous namespace. 363 364namespace { 365// Namespace for x86 abstract base class 366const Builtin::Info BuiltinInfo[] = { 367#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS }, 368#include "clang/AST/X86Builtins.def" 369}; 370 371const char *GCCRegNames[] = { 372 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", 373 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", 374 "argp", "flags", "fspr", "dirflag", "frame", 375 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", 376 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", 377 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 378 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" 379}; 380 381const TargetInfo::GCCRegAlias GCCRegAliases[] = { 382 { { "al", "ah", "eax", "rax" }, "ax" }, 383 { { "bl", "bh", "ebx", "rbx" }, "bx" }, 384 { { "cl", "ch", "ecx", "rcx" }, "cx" }, 385 { { "dl", "dh", "edx", "rdx" }, "dx" }, 386 { { "esi", "rsi" }, "si" }, 387 { { "edi", "rdi" }, "di" }, 388 { { "esp", "rsp" }, "sp" }, 389 { { "ebp", "rbp" }, "bp" }, 390}; 391 392// X86 target abstract base class; x86-32 and x86-64 are very close, so 393// most of the implementation can be shared. 394class X86TargetInfo : public TargetInfo { 395public: 396 X86TargetInfo(const std::string& triple) : TargetInfo(triple) { 397 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; 398 } 399 virtual void getTargetBuiltins(const Builtin::Info *&Records, 400 unsigned &NumRecords) const { 401 Records = BuiltinInfo; 402 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin; 403 } 404 virtual const char *getTargetPrefix() const { 405 return "x86"; 406 } 407 virtual void getGCCRegNames(const char * const *&Names, 408 unsigned &NumNames) const { 409 Names = GCCRegNames; 410 NumNames = llvm::array_lengthof(GCCRegNames); 411 } 412 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 413 unsigned &NumAliases) const { 414 Aliases = GCCRegAliases; 415 NumAliases = llvm::array_lengthof(GCCRegAliases); 416 } 417 virtual bool validateAsmConstraint(char c, 418 TargetInfo::ConstraintInfo &info) const; 419 virtual std::string convertConstraint(const char Constraint) const; 420 virtual const char *getClobbers() const { 421 return "~{dirflag},~{fpsr},~{flags}"; 422 } 423}; 424 425bool 426X86TargetInfo::validateAsmConstraint(char c, 427 TargetInfo::ConstraintInfo &info) const { 428 switch (c) { 429 default: return false; 430 case 'a': // eax. 431 case 'b': // ebx. 432 case 'c': // ecx. 433 case 'd': // edx. 434 case 'S': // esi. 435 case 'D': // edi. 436 case 'A': // edx:eax. 437 case 't': // top of floating point stack. 438 case 'u': // second from top of floating point stack. 439 case 'q': // Any register accessible as [r]l: a, b, c, and d. 440 case 'Q': // Any register accessible as [r]h: a, b, c, and d. 441 case 'Z': // 32-bit integer constant for use with zero-extending x86_64 442 // instructions. 443 case 'N': // unsigned 8-bit integer constant for use with in and out 444 // instructions. 445 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister); 446 return true; 447 } 448} 449 450std::string 451X86TargetInfo::convertConstraint(const char Constraint) const { 452 switch (Constraint) { 453 case 'a': return std::string("{ax}"); 454 case 'b': return std::string("{bx}"); 455 case 'c': return std::string("{cx}"); 456 case 'd': return std::string("{dx}"); 457 case 'S': return std::string("{si}"); 458 case 'D': return std::string("{di}"); 459 case 't': // top of floating point stack. 460 return std::string("{st}"); 461 case 'u': // second from top of floating point stack. 462 return std::string("{st(1)}"); // second from top of floating point stack. 463 default: 464 return std::string(1, Constraint); 465 } 466} 467} // end anonymous namespace 468 469namespace { 470// X86-32 generic target 471class X86_32TargetInfo : public X86TargetInfo { 472public: 473 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) { 474 DoubleAlign = LongLongAlign = 32; 475 LongDoubleWidth = 96; 476 LongDoubleAlign = 32; 477 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 478 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 479 "a0:0:64-f80:32:32"; 480 } 481 virtual const char *getVAListDeclaration() const { 482 return "typedef char* __builtin_va_list;"; 483 } 484 virtual void getTargetDefines(std::vector<char> &Defines) const { 485 getX86Defines(Defines, false); 486 } 487}; 488} // end anonymous namespace 489 490namespace { 491// x86-32 Darwin (OS X) target 492class DarwinI386TargetInfo : public X86_32TargetInfo { 493public: 494 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) { 495 LongDoubleWidth = 128; 496 LongDoubleAlign = 128; 497 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 498 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 499 "a0:0:64-f80:128:128"; 500 } 501 virtual void getTargetDefines(std::vector<char> &Defines) const { 502 X86_32TargetInfo::getTargetDefines(Defines); 503 getDarwinDefines(Defines, getTargetTriple()); 504 } 505 virtual bool useNeXTRuntimeAsDefault() const { return true; } 506}; 507} // end anonymous namespace 508 509namespace { 510// x86-32 DragonFly target 511class DragonFlyX86_32TargetInfo : public X86_32TargetInfo { 512public: 513 DragonFlyX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) { 514 } 515 virtual void getTargetDefines(std::vector<char> &Defines) const { 516 X86_32TargetInfo::getTargetDefines(Defines); 517 getDragonFlyDefines(Defines); 518 } 519}; 520} // end anonymous namespace 521 522namespace { 523// x86-32 Linux target 524class LinuxX86_32TargetInfo : public X86_32TargetInfo { 525public: 526 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) { 527 UserLabelPrefix = ""; 528 } 529 virtual void getTargetDefines(std::vector<char> &Defines) const { 530 X86_32TargetInfo::getTargetDefines(Defines); 531 getLinuxDefines(Defines); 532 } 533}; 534} // end anonymous namespace 535 536namespace { 537// x86-32 Windows target 538class WindowsX86_32TargetInfo : public X86_32TargetInfo { 539public: 540 WindowsX86_32TargetInfo(const std::string& triple) 541 : X86_32TargetInfo(triple) { 542 // FIXME: Fix wchar_t. 543 // FIXME: We should probably enable -fms-extensions by default for 544 // this target. 545 } 546 virtual void getTargetDefines(std::vector<char> &Defines) const { 547 X86_32TargetInfo::getTargetDefines(Defines); 548 // This list is based off of the the list of things MingW defines 549 Define(Defines, "__WIN32__"); 550 Define(Defines, "__WIN32"); 551 Define(Defines, "_WIN32"); 552 Define(Defines, "WIN32"); 553 Define(Defines, "__WINNT__"); 554 Define(Defines, "__WINNT"); 555 Define(Defines, "WINNT"); 556 Define(Defines, "_X86_"); 557 Define(Defines, "__MSVCRT__"); 558 } 559}; 560} // end anonymous namespace 561 562namespace { 563// x86-64 generic target 564class X86_64TargetInfo : public X86TargetInfo { 565public: 566 X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) { 567 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 568 LongDoubleWidth = 128; 569 LongDoubleAlign = 128; 570 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 571 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 572 "a0:0:64-f80:128:128"; 573 } 574 virtual const char *getVAListDeclaration() const { 575 return "typedef struct __va_list_tag {" 576 " unsigned gp_offset;" 577 " unsigned fp_offset;" 578 " void* overflow_arg_area;" 579 " void* reg_save_area;" 580 "} __builtin_va_list[1];"; 581 } 582 virtual void getTargetDefines(std::vector<char> &Defines) const { 583 getX86Defines(Defines, true); 584 } 585}; 586} // end anonymous namespace 587 588namespace { 589// x86-64 Linux target 590class LinuxX86_64TargetInfo : public X86_64TargetInfo { 591public: 592 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) { 593 UserLabelPrefix = ""; 594 } 595 virtual void getTargetDefines(std::vector<char> &Defines) const { 596 X86_64TargetInfo::getTargetDefines(Defines); 597 getLinuxDefines(Defines); 598 } 599}; 600} // end anonymous namespace 601 602namespace { 603// x86-64 Darwin (OS X) target 604class DarwinX86_64TargetInfo : public X86_64TargetInfo { 605public: 606 DarwinX86_64TargetInfo(const std::string& triple) : 607 X86_64TargetInfo(triple) {} 608 609 virtual void getTargetDefines(std::vector<char> &Defines) const { 610 X86_64TargetInfo::getTargetDefines(Defines); 611 getDarwinDefines(Defines, getTargetTriple()); 612 } 613 614 virtual bool useNeXTRuntimeAsDefault() const { return true; } 615}; 616} // end anonymous namespace. 617 618namespace { 619class ARMTargetInfo : public TargetInfo { 620public: 621 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) { 622 // FIXME: Are the defaults correct for ARM? 623 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 624 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64"; 625 } 626 virtual void getTargetDefines(std::vector<char> &Defines) const { 627 getARMDefines(Defines); 628 } 629 virtual void getTargetBuiltins(const Builtin::Info *&Records, 630 unsigned &NumRecords) const { 631 // FIXME: Implement. 632 Records = 0; 633 NumRecords = 0; 634 } 635 virtual const char *getVAListDeclaration() const { 636 return "typedef char* __builtin_va_list;"; 637 } 638 virtual const char *getTargetPrefix() const { 639 return "arm"; 640 } 641 virtual void getGCCRegNames(const char * const *&Names, 642 unsigned &NumNames) const { 643 // FIXME: Implement. 644 Names = 0; 645 NumNames = 0; 646 } 647 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 648 unsigned &NumAliases) const { 649 // FIXME: Implement. 650 Aliases = 0; 651 NumAliases = 0; 652 } 653 virtual bool validateAsmConstraint(char c, 654 TargetInfo::ConstraintInfo &info) const { 655 // FIXME: Check if this is complete 656 switch (c) { 657 default: 658 case 'l': // r0-r7 659 case 'h': // r8-r15 660 case 'w': // VFP Floating point register single precision 661 case 'P': // VFP Floating point register double precision 662 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister); 663 return true; 664 } 665 return false; 666 } 667 virtual const char *getClobbers() const { 668 // FIXME: Is this really right? 669 return ""; 670 } 671}; 672} // end anonymous namespace. 673 674 675namespace { 676class DarwinARMTargetInfo : public ARMTargetInfo { 677public: 678 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {} 679 680 virtual void getTargetDefines(std::vector<char> &Defines) const { 681 ARMTargetInfo::getTargetDefines(Defines); 682 getDarwinDefines(Defines, getTargetTriple()); 683 } 684}; 685} // end anonymous namespace. 686 687namespace { 688class SparcV8TargetInfo : public TargetInfo { 689public: 690 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { 691 // FIXME: Support Sparc quad-precision long double? 692 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 693 "i64:64:64-f32:32:32-f64:64:64-v64:64:64"; 694 } 695 virtual void getTargetDefines(std::vector<char> &Defines) const { 696 // FIXME: This is missing a lot of important defines; some of the 697 // missing stuff is likely to break system headers. 698 Define(Defines, "__sparc"); 699 Define(Defines, "__sparc__"); 700 Define(Defines, "__sparcv8"); 701 } 702 virtual void getTargetBuiltins(const Builtin::Info *&Records, 703 unsigned &NumRecords) const { 704 // FIXME: Implement! 705 } 706 virtual const char *getVAListDeclaration() const { 707 return "typedef void* __builtin_va_list;"; 708 } 709 virtual const char *getTargetPrefix() const { 710 return "sparc"; 711 } 712 virtual void getGCCRegNames(const char * const *&Names, 713 unsigned &NumNames) const { 714 // FIXME: Implement! 715 Names = 0; 716 NumNames = 0; 717 } 718 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 719 unsigned &NumAliases) const { 720 // FIXME: Implement! 721 Aliases = 0; 722 NumAliases = 0; 723 } 724 virtual bool validateAsmConstraint(char c, 725 TargetInfo::ConstraintInfo &info) const { 726 // FIXME: Implement! 727 return false; 728 } 729 virtual const char *getClobbers() const { 730 // FIXME: Implement! 731 return ""; 732 } 733}; 734 735} // end anonymous namespace. 736 737namespace { 738class SolarisSparcV8TargetInfo : public SparcV8TargetInfo { 739public: 740 SolarisSparcV8TargetInfo(const std::string& triple) : 741 SparcV8TargetInfo(triple) {} 742 743 virtual void getTargetDefines(std::vector<char> &Defines) const { 744 SparcV8TargetInfo::getTargetDefines(Defines); 745 getSolarisDefines(Defines); 746 } 747}; 748} // end anonymous namespace. 749 750namespace { 751 class PIC16TargetInfo : public TargetInfo{ 752 public: 753 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) { 754 // FIXME: Is IntAlign really supposed to be 16? There seems 755 // little point on a platform with 8-bit loads. 756 IntWidth = IntAlign = LongAlign = LongLongAlign = PointerWidth = 16; 757 LongWidth = 16; 758 PointerAlign = 8; 759 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"; 760 } 761 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; } 762 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; } 763 virtual void getTargetDefines(std::vector<char> &Defines) const { 764 Define(Defines, "__pic16"); 765 } 766 virtual void getTargetBuiltins(const Builtin::Info *&Records, 767 unsigned &NumRecords) const {} 768 virtual const char *getVAListDeclaration() const { return "";} 769 virtual const char *getClobbers() const {return "";} 770 virtual const char *getTargetPrefix() const {return "";} 771 virtual void getGCCRegNames(const char * const *&Names, 772 unsigned &NumNames) const {} 773 virtual bool validateAsmConstraint(char c, 774 TargetInfo::ConstraintInfo &info) const { 775 return true; 776 } 777 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 778 unsigned &NumAliases) const {} 779 virtual bool useGlobalsForAutomaticVariables() const {return true;} 780 }; 781} 782 783//===----------------------------------------------------------------------===// 784// Driver code 785//===----------------------------------------------------------------------===// 786 787static inline bool IsX86(const std::string& TT) { 788 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' && 789 TT[4] == '-' && TT[1] - '3' < 6); 790} 791 792/// CreateTargetInfo - Return the target info object for the specified target 793/// triple. 794TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) { 795 // OS detection; this isn't really anywhere near complete. 796 // Additions and corrections are welcome. 797 bool isDarwin = T.find("-darwin") != std::string::npos; 798 bool isDragonFly = T.find("-dragonfly") != std::string::npos; 799 bool isSolaris = T.find("-solaris") != std::string::npos; 800 bool isLinux = T.find("-linux") != std::string::npos; 801 bool isWindows = T.find("-windows") != std::string::npos || 802 T.find("-win32") != std::string::npos || 803 T.find("-mingw") != std::string::npos; 804 805 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) { 806 if (isDarwin) 807 return new DarwinPPCTargetInfo(T); 808 return new PPC32TargetInfo(T); 809 } 810 811 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) { 812 if (isDarwin) 813 return new DarwinPPC64TargetInfo(T); 814 return new PPC64TargetInfo(T); 815 } 816 817 if (T.find("armv6-") == 0 || T.find("arm-") == 0) { 818 if (isDarwin) 819 return new DarwinARMTargetInfo(T); 820 return new ARMTargetInfo(T); 821 } 822 823 if (T.find("sparc-") == 0) { 824 if (isSolaris) 825 return new SolarisSparcV8TargetInfo(T); 826 return new SparcV8TargetInfo(T); 827 } 828 829 if (T.find("x86_64-") == 0) { 830 if (isDarwin) 831 return new DarwinX86_64TargetInfo(T); 832 if (isLinux) 833 return new LinuxX86_64TargetInfo(T); 834 return new X86_64TargetInfo(T); 835 } 836 837 if (T.find("pic16-") == 0) 838 return new PIC16TargetInfo(T); 839 840 if (IsX86(T)) { 841 if (isDarwin) 842 return new DarwinI386TargetInfo(T); 843 if (isLinux) 844 return new LinuxX86_32TargetInfo(T); 845 if (isDragonFly) 846 return new DragonFlyX86_32TargetInfo(T); 847 if (isWindows) 848 return new WindowsX86_32TargetInfo(T); 849 return new X86_32TargetInfo(T); 850 } 851 852 return NULL; 853} 854 855