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