Targets.cpp revision fce0934560b0e3cc55e95e54883c0f540c98cdb6
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 'y': // Any MMX register. 441 case 'Q': // Any register accessible as [r]h: a, b, c, and d. 442 case 'Z': // 32-bit integer constant for use with zero-extending x86_64 443 // instructions. 444 case 'N': // unsigned 8-bit integer constant for use with in and out 445 // instructions. 446 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister); 447 return true; 448 } 449} 450 451std::string 452X86TargetInfo::convertConstraint(const char Constraint) const { 453 switch (Constraint) { 454 case 'a': return std::string("{ax}"); 455 case 'b': return std::string("{bx}"); 456 case 'c': return std::string("{cx}"); 457 case 'd': return std::string("{dx}"); 458 case 'S': return std::string("{si}"); 459 case 'D': return std::string("{di}"); 460 case 't': // top of floating point stack. 461 return std::string("{st}"); 462 case 'u': // second from top of floating point stack. 463 return std::string("{st(1)}"); // second from top of floating point stack. 464 default: 465 return std::string(1, Constraint); 466 } 467} 468} // end anonymous namespace 469 470namespace { 471// X86-32 generic target 472class X86_32TargetInfo : public X86TargetInfo { 473public: 474 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) { 475 DoubleAlign = LongLongAlign = 32; 476 LongDoubleWidth = 96; 477 LongDoubleAlign = 32; 478 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 479 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 480 "a0:0:64-f80:32:32"; 481 } 482 virtual const char *getVAListDeclaration() const { 483 return "typedef char* __builtin_va_list;"; 484 } 485 virtual void getTargetDefines(std::vector<char> &Defines) const { 486 getX86Defines(Defines, false); 487 } 488}; 489} // end anonymous namespace 490 491namespace { 492// x86-32 Darwin (OS X) target 493class DarwinI386TargetInfo : public X86_32TargetInfo { 494public: 495 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) { 496 LongDoubleWidth = 128; 497 LongDoubleAlign = 128; 498 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 499 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 500 "a0:0:64-f80:128:128"; 501 } 502 virtual void getTargetDefines(std::vector<char> &Defines) const { 503 X86_32TargetInfo::getTargetDefines(Defines); 504 getDarwinDefines(Defines, getTargetTriple()); 505 } 506 virtual bool useNeXTRuntimeAsDefault() const { return true; } 507}; 508} // end anonymous namespace 509 510namespace { 511// x86-32 DragonFly target 512class DragonFlyX86_32TargetInfo : public X86_32TargetInfo { 513public: 514 DragonFlyX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) { 515 } 516 virtual void getTargetDefines(std::vector<char> &Defines) const { 517 X86_32TargetInfo::getTargetDefines(Defines); 518 getDragonFlyDefines(Defines); 519 } 520}; 521} // end anonymous namespace 522 523namespace { 524// x86-32 Linux target 525class LinuxX86_32TargetInfo : public X86_32TargetInfo { 526public: 527 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) { 528 UserLabelPrefix = ""; 529 } 530 virtual void getTargetDefines(std::vector<char> &Defines) const { 531 X86_32TargetInfo::getTargetDefines(Defines); 532 getLinuxDefines(Defines); 533 } 534}; 535} // end anonymous namespace 536 537namespace { 538// x86-32 Windows target 539class WindowsX86_32TargetInfo : public X86_32TargetInfo { 540public: 541 WindowsX86_32TargetInfo(const std::string& triple) 542 : X86_32TargetInfo(triple) { 543 // FIXME: Fix wchar_t. 544 // FIXME: We should probably enable -fms-extensions by default for 545 // this target. 546 } 547 virtual void getTargetDefines(std::vector<char> &Defines) const { 548 X86_32TargetInfo::getTargetDefines(Defines); 549 // This list is based off of the the list of things MingW defines 550 Define(Defines, "__WIN32__"); 551 Define(Defines, "__WIN32"); 552 Define(Defines, "_WIN32"); 553 Define(Defines, "WIN32"); 554 Define(Defines, "__WINNT__"); 555 Define(Defines, "__WINNT"); 556 Define(Defines, "WINNT"); 557 Define(Defines, "_X86_"); 558 Define(Defines, "__MSVCRT__"); 559 } 560}; 561} // end anonymous namespace 562 563namespace { 564// x86-64 generic target 565class X86_64TargetInfo : public X86TargetInfo { 566public: 567 X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) { 568 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 569 LongDoubleWidth = 128; 570 LongDoubleAlign = 128; 571 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 572 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 573 "a0:0:64-f80:128:128"; 574 } 575 virtual const char *getVAListDeclaration() const { 576 return "typedef struct __va_list_tag {" 577 " unsigned gp_offset;" 578 " unsigned fp_offset;" 579 " void* overflow_arg_area;" 580 " void* reg_save_area;" 581 "} __builtin_va_list[1];"; 582 } 583 virtual void getTargetDefines(std::vector<char> &Defines) const { 584 getX86Defines(Defines, true); 585 } 586}; 587} // end anonymous namespace 588 589namespace { 590// x86-64 Linux target 591class LinuxX86_64TargetInfo : public X86_64TargetInfo { 592public: 593 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) { 594 UserLabelPrefix = ""; 595 } 596 virtual void getTargetDefines(std::vector<char> &Defines) const { 597 X86_64TargetInfo::getTargetDefines(Defines); 598 getLinuxDefines(Defines); 599 } 600}; 601} // end anonymous namespace 602 603namespace { 604// x86-64 Darwin (OS X) target 605class DarwinX86_64TargetInfo : public X86_64TargetInfo { 606public: 607 DarwinX86_64TargetInfo(const std::string& triple) : 608 X86_64TargetInfo(triple) {} 609 610 virtual void getTargetDefines(std::vector<char> &Defines) const { 611 X86_64TargetInfo::getTargetDefines(Defines); 612 getDarwinDefines(Defines, getTargetTriple()); 613 } 614 615 virtual bool useNeXTRuntimeAsDefault() const { return true; } 616}; 617} // end anonymous namespace. 618 619namespace { 620class ARMTargetInfo : public TargetInfo { 621public: 622 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) { 623 // FIXME: Are the defaults correct for ARM? 624 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 625 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64"; 626 } 627 virtual void getTargetDefines(std::vector<char> &Defines) const { 628 getARMDefines(Defines); 629 } 630 virtual void getTargetBuiltins(const Builtin::Info *&Records, 631 unsigned &NumRecords) const { 632 // FIXME: Implement. 633 Records = 0; 634 NumRecords = 0; 635 } 636 virtual const char *getVAListDeclaration() const { 637 return "typedef char* __builtin_va_list;"; 638 } 639 virtual const char *getTargetPrefix() const { 640 return "arm"; 641 } 642 virtual void getGCCRegNames(const char * const *&Names, 643 unsigned &NumNames) const { 644 // FIXME: Implement. 645 Names = 0; 646 NumNames = 0; 647 } 648 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 649 unsigned &NumAliases) const { 650 // FIXME: Implement. 651 Aliases = 0; 652 NumAliases = 0; 653 } 654 virtual bool validateAsmConstraint(char c, 655 TargetInfo::ConstraintInfo &info) const { 656 // FIXME: Check if this is complete 657 switch (c) { 658 default: 659 case 'l': // r0-r7 660 case 'h': // r8-r15 661 case 'w': // VFP Floating point register single precision 662 case 'P': // VFP Floating point register double precision 663 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister); 664 return true; 665 } 666 return false; 667 } 668 virtual const char *getClobbers() const { 669 // FIXME: Is this really right? 670 return ""; 671 } 672}; 673} // end anonymous namespace. 674 675 676namespace { 677class DarwinARMTargetInfo : public ARMTargetInfo { 678public: 679 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {} 680 681 virtual void getTargetDefines(std::vector<char> &Defines) const { 682 ARMTargetInfo::getTargetDefines(Defines); 683 getDarwinDefines(Defines, getTargetTriple()); 684 } 685}; 686} // end anonymous namespace. 687 688namespace { 689class SparcV8TargetInfo : public TargetInfo { 690public: 691 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { 692 // FIXME: Support Sparc quad-precision long double? 693 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 694 "i64:64:64-f32:32:32-f64:64:64-v64:64:64"; 695 } 696 virtual void getTargetDefines(std::vector<char> &Defines) const { 697 // FIXME: This is missing a lot of important defines; some of the 698 // missing stuff is likely to break system headers. 699 Define(Defines, "__sparc"); 700 Define(Defines, "__sparc__"); 701 Define(Defines, "__sparcv8"); 702 } 703 virtual void getTargetBuiltins(const Builtin::Info *&Records, 704 unsigned &NumRecords) const { 705 // FIXME: Implement! 706 } 707 virtual const char *getVAListDeclaration() const { 708 return "typedef void* __builtin_va_list;"; 709 } 710 virtual const char *getTargetPrefix() const { 711 return "sparc"; 712 } 713 virtual void getGCCRegNames(const char * const *&Names, 714 unsigned &NumNames) const { 715 // FIXME: Implement! 716 Names = 0; 717 NumNames = 0; 718 } 719 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 720 unsigned &NumAliases) const { 721 // FIXME: Implement! 722 Aliases = 0; 723 NumAliases = 0; 724 } 725 virtual bool validateAsmConstraint(char c, 726 TargetInfo::ConstraintInfo &info) const { 727 // FIXME: Implement! 728 return false; 729 } 730 virtual const char *getClobbers() const { 731 // FIXME: Implement! 732 return ""; 733 } 734}; 735 736} // end anonymous namespace. 737 738namespace { 739class SolarisSparcV8TargetInfo : public SparcV8TargetInfo { 740public: 741 SolarisSparcV8TargetInfo(const std::string& triple) : 742 SparcV8TargetInfo(triple) {} 743 744 virtual void getTargetDefines(std::vector<char> &Defines) const { 745 SparcV8TargetInfo::getTargetDefines(Defines); 746 getSolarisDefines(Defines); 747 } 748}; 749} // end anonymous namespace. 750 751namespace { 752 class PIC16TargetInfo : public TargetInfo{ 753 public: 754 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) { 755 // FIXME: Is IntAlign really supposed to be 16? There seems 756 // little point on a platform with 8-bit loads. 757 IntWidth = IntAlign = LongAlign = LongLongAlign = PointerWidth = 16; 758 LongWidth = 16; 759 PointerAlign = 8; 760 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"; 761 } 762 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; } 763 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; } 764 virtual void getTargetDefines(std::vector<char> &Defines) const { 765 Define(Defines, "__pic16"); 766 } 767 virtual void getTargetBuiltins(const Builtin::Info *&Records, 768 unsigned &NumRecords) const {} 769 virtual const char *getVAListDeclaration() const { return "";} 770 virtual const char *getClobbers() const {return "";} 771 virtual const char *getTargetPrefix() const {return "";} 772 virtual void getGCCRegNames(const char * const *&Names, 773 unsigned &NumNames) const {} 774 virtual bool validateAsmConstraint(char c, 775 TargetInfo::ConstraintInfo &info) const { 776 return true; 777 } 778 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 779 unsigned &NumAliases) const {} 780 virtual bool useGlobalsForAutomaticVariables() const {return true;} 781 }; 782} 783 784//===----------------------------------------------------------------------===// 785// Driver code 786//===----------------------------------------------------------------------===// 787 788static inline bool IsX86(const std::string& TT) { 789 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' && 790 TT[4] == '-' && TT[1] - '3' < 6); 791} 792 793/// CreateTargetInfo - Return the target info object for the specified target 794/// triple. 795TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) { 796 // OS detection; this isn't really anywhere near complete. 797 // Additions and corrections are welcome. 798 bool isDarwin = T.find("-darwin") != std::string::npos; 799 bool isDragonFly = T.find("-dragonfly") != std::string::npos; 800 bool isSolaris = T.find("-solaris") != std::string::npos; 801 bool isLinux = T.find("-linux") != std::string::npos; 802 bool isWindows = T.find("-windows") != std::string::npos || 803 T.find("-win32") != std::string::npos || 804 T.find("-mingw") != std::string::npos; 805 806 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) { 807 if (isDarwin) 808 return new DarwinPPCTargetInfo(T); 809 return new PPC32TargetInfo(T); 810 } 811 812 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) { 813 if (isDarwin) 814 return new DarwinPPC64TargetInfo(T); 815 return new PPC64TargetInfo(T); 816 } 817 818 if (T.find("armv6-") == 0 || T.find("arm-") == 0) { 819 if (isDarwin) 820 return new DarwinARMTargetInfo(T); 821 return new ARMTargetInfo(T); 822 } 823 824 if (T.find("sparc-") == 0) { 825 if (isSolaris) 826 return new SolarisSparcV8TargetInfo(T); 827 return new SparcV8TargetInfo(T); 828 } 829 830 if (T.find("x86_64-") == 0) { 831 if (isDarwin) 832 return new DarwinX86_64TargetInfo(T); 833 if (isLinux) 834 return new LinuxX86_64TargetInfo(T); 835 return new X86_64TargetInfo(T); 836 } 837 838 if (T.find("pic16-") == 0) 839 return new PIC16TargetInfo(T); 840 841 if (IsX86(T)) { 842 if (isDarwin) 843 return new DarwinI386TargetInfo(T); 844 if (isLinux) 845 return new LinuxX86_32TargetInfo(T); 846 if (isDragonFly) 847 return new DragonFlyX86_32TargetInfo(T); 848 if (isWindows) 849 return new WindowsX86_32TargetInfo(T); 850 return new X86_32TargetInfo(T); 851 } 852 853 return NULL; 854} 855 856