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