Targets.cpp revision 9b0fb629fd12bc772a32fa2cb693b06fe5863316
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/Basic/TargetInfo.h" 16#include "clang/Basic/Builtins.h" 17#include "clang/Basic/Diagnostic.h" 18#include "clang/Basic/LangOptions.h" 19#include "clang/Basic/MacroBuilder.h" 20#include "clang/Basic/TargetBuiltins.h" 21#include "clang/Basic/TargetOptions.h" 22#include "llvm/ADT/APFloat.h" 23#include "llvm/ADT/OwningPtr.h" 24#include "llvm/ADT/STLExtras.h" 25#include "llvm/ADT/StringRef.h" 26#include "llvm/ADT/StringSwitch.h" 27#include "llvm/ADT/Triple.h" 28#include "llvm/MC/MCSectionMachO.h" 29#include <algorithm> 30using namespace clang; 31 32//===----------------------------------------------------------------------===// 33// Common code shared among targets. 34//===----------------------------------------------------------------------===// 35 36/// DefineStd - Define a macro name and standard variants. For example if 37/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix" 38/// when in GNU mode. 39static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName, 40 const LangOptions &Opts) { 41 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace"); 42 43 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier 44 // in the user's namespace. 45 if (Opts.GNUMode) 46 Builder.defineMacro(MacroName); 47 48 // Define __unix. 49 Builder.defineMacro("__" + MacroName); 50 51 // Define __unix__. 52 Builder.defineMacro("__" + MacroName + "__"); 53} 54 55//===----------------------------------------------------------------------===// 56// Defines specific to certain operating systems. 57//===----------------------------------------------------------------------===// 58 59namespace { 60template<typename TgtInfo> 61class OSTargetInfo : public TgtInfo { 62protected: 63 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 64 MacroBuilder &Builder) const=0; 65public: 66 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {} 67 virtual void getTargetDefines(const LangOptions &Opts, 68 MacroBuilder &Builder) const { 69 TgtInfo::getTargetDefines(Opts, Builder); 70 getOSDefines(Opts, TgtInfo::getTriple(), Builder); 71 } 72 73}; 74} // end anonymous namespace 75 76 77static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, 78 const llvm::Triple &Triple) { 79 Builder.defineMacro("__APPLE_CC__", "5621"); 80 Builder.defineMacro("__APPLE__"); 81 Builder.defineMacro("__MACH__"); 82 Builder.defineMacro("OBJC_NEW_PROPERTIES"); 83 84 // __weak is always defined, for use in blocks and with objc pointers. 85 Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); 86 87 // Darwin defines __strong even in C mode (just to nothing). 88 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC) 89 Builder.defineMacro("__strong", ""); 90 else 91 Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))"); 92 93 if (Opts.Static) 94 Builder.defineMacro("__STATIC__"); 95 else 96 Builder.defineMacro("__DYNAMIC__"); 97 98 if (Opts.POSIXThreads) 99 Builder.defineMacro("_REENTRANT"); 100 101 // Get the OS version number from the triple. 102 unsigned Maj, Min, Rev; 103 104 // If no version was given, default to to 10.4.0, for simplifying tests. 105 if (Triple.getOSName() == "darwin") { 106 Min = Rev = 0; 107 Maj = 8; 108 } else 109 Triple.getDarwinNumber(Maj, Min, Rev); 110 111 // Set the appropriate OS version define. 112 if (Triple.getEnvironmentName() == "iphoneos") { 113 assert(Maj < 10 && Min < 99 && Rev < 99 && "Invalid version!"); 114 char Str[6]; 115 Str[0] = '0' + Maj; 116 Str[1] = '0' + (Min / 10); 117 Str[2] = '0' + (Min % 10); 118 Str[3] = '0' + (Rev / 10); 119 Str[4] = '0' + (Rev % 10); 120 Str[5] = '\0'; 121 Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str); 122 } else { 123 // For historical reasons that make little sense, the version passed here is 124 // the "darwin" version, which drops the 10 and offsets by 4. 125 Rev = Min; 126 Min = Maj - 4; 127 Maj = 10; 128 129 assert(Triple.getEnvironmentName().empty() && "Invalid environment!"); 130 assert(Maj < 99 && Min < 10 && Rev < 10 && "Invalid version!"); 131 char Str[5]; 132 Str[0] = '0' + (Maj / 10); 133 Str[1] = '0' + (Maj % 10); 134 Str[2] = '0' + Min; 135 Str[3] = '0' + Rev; 136 Str[4] = '\0'; 137 Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str); 138 } 139} 140 141namespace { 142template<typename Target> 143class DarwinTargetInfo : public OSTargetInfo<Target> { 144protected: 145 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 146 MacroBuilder &Builder) const { 147 getDarwinDefines(Builder, Opts, Triple); 148 } 149 150public: 151 DarwinTargetInfo(const std::string& triple) : 152 OSTargetInfo<Target>(triple) { 153 this->TLSSupported = false; 154 } 155 156 virtual const char *getUnicodeStringSection() const { 157 return "__TEXT,__ustring"; 158 } 159 160 virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const { 161 // Let MCSectionMachO validate this. 162 llvm::StringRef Segment, Section; 163 unsigned TAA, StubSize; 164 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section, 165 TAA, StubSize); 166 } 167}; 168 169 170// DragonFlyBSD Target 171template<typename Target> 172class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> { 173protected: 174 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 175 MacroBuilder &Builder) const { 176 // DragonFly defines; list based off of gcc output 177 Builder.defineMacro("__DragonFly__"); 178 Builder.defineMacro("__DragonFly_cc_version", "100001"); 179 Builder.defineMacro("__ELF__"); 180 Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); 181 Builder.defineMacro("__tune_i386__"); 182 DefineStd(Builder, "unix", Opts); 183 } 184public: 185 DragonFlyBSDTargetInfo(const std::string &triple) 186 : OSTargetInfo<Target>(triple) {} 187}; 188 189// FreeBSD Target 190template<typename Target> 191class FreeBSDTargetInfo : public OSTargetInfo<Target> { 192protected: 193 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 194 MacroBuilder &Builder) const { 195 // FreeBSD defines; list based off of gcc output 196 197 // FIXME: Move version number handling to llvm::Triple. 198 const char *FreeBSD = strstr(Triple.getTriple().c_str(), 199 "-freebsd"); 200 FreeBSD += strlen("-freebsd"); 201 char release[] = "X"; 202 release[0] = FreeBSD[0]; 203 char version[] = "X00001"; 204 version[0] = FreeBSD[0]; 205 206 Builder.defineMacro("__FreeBSD__", release); 207 Builder.defineMacro("__FreeBSD_cc_version", version); 208 Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); 209 DefineStd(Builder, "unix", Opts); 210 Builder.defineMacro("__ELF__"); 211 } 212public: 213 FreeBSDTargetInfo(const std::string &triple) 214 : OSTargetInfo<Target>(triple) { 215 this->UserLabelPrefix = ""; 216 } 217}; 218 219// Linux target 220template<typename Target> 221class LinuxTargetInfo : public OSTargetInfo<Target> { 222protected: 223 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 224 MacroBuilder &Builder) const { 225 // Linux defines; list based off of gcc output 226 DefineStd(Builder, "unix", Opts); 227 DefineStd(Builder, "linux", Opts); 228 Builder.defineMacro("__gnu_linux__"); 229 Builder.defineMacro("__ELF__"); 230 if (Opts.POSIXThreads) 231 Builder.defineMacro("_REENTRANT"); 232 } 233public: 234 LinuxTargetInfo(const std::string& triple) 235 : OSTargetInfo<Target>(triple) { 236 this->UserLabelPrefix = ""; 237 } 238}; 239 240// NetBSD Target 241template<typename Target> 242class NetBSDTargetInfo : public OSTargetInfo<Target> { 243protected: 244 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 245 MacroBuilder &Builder) const { 246 // NetBSD defines; list based off of gcc output 247 Builder.defineMacro("__NetBSD__"); 248 Builder.defineMacro("__unix__"); 249 Builder.defineMacro("__ELF__"); 250 if (Opts.POSIXThreads) 251 Builder.defineMacro("_POSIX_THREADS"); 252 } 253public: 254 NetBSDTargetInfo(const std::string &triple) 255 : OSTargetInfo<Target>(triple) { 256 this->UserLabelPrefix = ""; 257 } 258}; 259 260// OpenBSD Target 261template<typename Target> 262class OpenBSDTargetInfo : public OSTargetInfo<Target> { 263protected: 264 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 265 MacroBuilder &Builder) const { 266 // OpenBSD defines; list based off of gcc output 267 268 Builder.defineMacro("__OpenBSD__"); 269 DefineStd(Builder, "unix", Opts); 270 Builder.defineMacro("__ELF__"); 271 if (Opts.POSIXThreads) 272 Builder.defineMacro("_POSIX_THREADS"); 273 } 274public: 275 OpenBSDTargetInfo(const std::string &triple) 276 : OSTargetInfo<Target>(triple) {} 277}; 278 279// PSP Target 280template<typename Target> 281class PSPTargetInfo : public OSTargetInfo<Target> { 282protected: 283 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 284 MacroBuilder &Builder) const { 285 // PSP defines; list based on the output of the pspdev gcc toolchain. 286 Builder.defineMacro("PSP"); 287 Builder.defineMacro("_PSP"); 288 Builder.defineMacro("__psp__"); 289 Builder.defineMacro("__ELF__"); 290 } 291public: 292 PSPTargetInfo(const std::string& triple) 293 : OSTargetInfo<Target>(triple) { 294 this->UserLabelPrefix = ""; 295 } 296}; 297 298// PS3 PPU Target 299template<typename Target> 300class PS3PPUTargetInfo : public OSTargetInfo<Target> { 301protected: 302 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 303 MacroBuilder &Builder) const { 304 // PS3 PPU defines. 305 Builder.defineMacro("__PPU__"); 306 Builder.defineMacro("__CELLOS_LV2__"); 307 Builder.defineMacro("__ELF__"); 308 Builder.defineMacro("__LP32__"); 309 } 310public: 311 PS3PPUTargetInfo(const std::string& triple) 312 : OSTargetInfo<Target>(triple) { 313 this->UserLabelPrefix = ""; 314 this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32; 315 this->SizeType = TargetInfo::UnsignedInt; 316 } 317}; 318 319// FIXME: Need a real SPU target. 320// PS3 SPU Target 321template<typename Target> 322class PS3SPUTargetInfo : public OSTargetInfo<Target> { 323protected: 324 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 325 MacroBuilder &Builder) const { 326 // PS3 PPU defines. 327 Builder.defineMacro("__SPU__"); 328 Builder.defineMacro("__ELF__"); 329 } 330public: 331 PS3SPUTargetInfo(const std::string& triple) 332 : OSTargetInfo<Target>(triple) { 333 this->UserLabelPrefix = ""; 334 } 335}; 336 337// AuroraUX target 338template<typename Target> 339class AuroraUXTargetInfo : public OSTargetInfo<Target> { 340protected: 341 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 342 MacroBuilder &Builder) const { 343 DefineStd(Builder, "sun", Opts); 344 DefineStd(Builder, "unix", Opts); 345 Builder.defineMacro("__ELF__"); 346 Builder.defineMacro("__svr4__"); 347 Builder.defineMacro("__SVR4"); 348 } 349public: 350 AuroraUXTargetInfo(const std::string& triple) 351 : OSTargetInfo<Target>(triple) { 352 this->UserLabelPrefix = ""; 353 this->WCharType = this->SignedLong; 354 // FIXME: WIntType should be SignedLong 355 } 356}; 357 358// Solaris target 359template<typename Target> 360class SolarisTargetInfo : public OSTargetInfo<Target> { 361protected: 362 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 363 MacroBuilder &Builder) const { 364 DefineStd(Builder, "sun", Opts); 365 DefineStd(Builder, "unix", Opts); 366 Builder.defineMacro("__ELF__"); 367 Builder.defineMacro("__svr4__"); 368 Builder.defineMacro("__SVR4"); 369 } 370public: 371 SolarisTargetInfo(const std::string& triple) 372 : OSTargetInfo<Target>(triple) { 373 this->UserLabelPrefix = ""; 374 this->WCharType = this->SignedLong; 375 // FIXME: WIntType should be SignedLong 376 } 377}; 378} // end anonymous namespace. 379 380//===----------------------------------------------------------------------===// 381// Specific target implementations. 382//===----------------------------------------------------------------------===// 383 384namespace { 385// PPC abstract base class 386class PPCTargetInfo : public TargetInfo { 387 static const Builtin::Info BuiltinInfo[]; 388 static const char * const GCCRegNames[]; 389 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 390 391public: 392 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {} 393 394 virtual void getTargetBuiltins(const Builtin::Info *&Records, 395 unsigned &NumRecords) const { 396 Records = BuiltinInfo; 397 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin; 398 } 399 400 virtual void getTargetDefines(const LangOptions &Opts, 401 MacroBuilder &Builder) const; 402 403 virtual const char *getVAListDeclaration() const { 404 return "typedef char* __builtin_va_list;"; 405 // This is the right definition for ABI/V4: System V.4/eabi. 406 /*return "typedef struct __va_list_tag {" 407 " unsigned char gpr;" 408 " unsigned char fpr;" 409 " unsigned short reserved;" 410 " void* overflow_arg_area;" 411 " void* reg_save_area;" 412 "} __builtin_va_list[1];";*/ 413 } 414 virtual void getGCCRegNames(const char * const *&Names, 415 unsigned &NumNames) const; 416 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 417 unsigned &NumAliases) const; 418 virtual bool validateAsmConstraint(const char *&Name, 419 TargetInfo::ConstraintInfo &Info) const { 420 switch (*Name) { 421 default: return false; 422 case 'O': // Zero 423 return true; 424 case 'b': // Base register 425 case 'f': // Floating point register 426 Info.setAllowsRegister(); 427 return true; 428 } 429 } 430 virtual const char *getClobbers() const { 431 return ""; 432 } 433}; 434 435const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { 436#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false }, 437#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false }, 438#include "clang/Basic/BuiltinsPPC.def" 439}; 440 441 442/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific 443/// #defines that are not tied to a specific subtarget. 444void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, 445 MacroBuilder &Builder) const { 446 // Target identification. 447 Builder.defineMacro("__ppc__"); 448 Builder.defineMacro("_ARCH_PPC"); 449 Builder.defineMacro("__POWERPC__"); 450 if (PointerWidth == 64) { 451 Builder.defineMacro("_ARCH_PPC64"); 452 Builder.defineMacro("_LP64"); 453 Builder.defineMacro("__LP64__"); 454 Builder.defineMacro("__ppc64__"); 455 } else { 456 Builder.defineMacro("__ppc__"); 457 } 458 459 // Target properties. 460 Builder.defineMacro("_BIG_ENDIAN"); 461 Builder.defineMacro("__BIG_ENDIAN__"); 462 463 // Subtarget options. 464 Builder.defineMacro("__NATURAL_ALIGNMENT__"); 465 Builder.defineMacro("__REGISTER_PREFIX__", ""); 466 467 // FIXME: Should be controlled by command line option. 468 Builder.defineMacro("__LONG_DOUBLE_128__"); 469 470 if (Opts.AltiVec) { 471 Builder.defineMacro("__VEC__", "10206"); 472 Builder.defineMacro("__ALTIVEC__"); 473 } 474} 475 476 477const char * const PPCTargetInfo::GCCRegNames[] = { 478 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 479 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 480 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 481 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 482 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 483 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", 484 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 485 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", 486 "mq", "lr", "ctr", "ap", 487 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", 488 "xer", 489 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", 490 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", 491 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", 492 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", 493 "vrsave", "vscr", 494 "spe_acc", "spefscr", 495 "sfp" 496}; 497 498void PPCTargetInfo::getGCCRegNames(const char * const *&Names, 499 unsigned &NumNames) const { 500 Names = GCCRegNames; 501 NumNames = llvm::array_lengthof(GCCRegNames); 502} 503 504const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { 505 // While some of these aliases do map to different registers 506 // they still share the same register name. 507 { { "0" }, "r0" }, 508 { { "1"}, "r1" }, 509 { { "2" }, "r2" }, 510 { { "3" }, "r3" }, 511 { { "4" }, "r4" }, 512 { { "5" }, "r5" }, 513 { { "6" }, "r6" }, 514 { { "7" }, "r7" }, 515 { { "8" }, "r8" }, 516 { { "9" }, "r9" }, 517 { { "10" }, "r10" }, 518 { { "11" }, "r11" }, 519 { { "12" }, "r12" }, 520 { { "13" }, "r13" }, 521 { { "14" }, "r14" }, 522 { { "15" }, "r15" }, 523 { { "16" }, "r16" }, 524 { { "17" }, "r17" }, 525 { { "18" }, "r18" }, 526 { { "19" }, "r19" }, 527 { { "20" }, "r20" }, 528 { { "21" }, "r21" }, 529 { { "22" }, "r22" }, 530 { { "23" }, "r23" }, 531 { { "24" }, "r24" }, 532 { { "25" }, "r25" }, 533 { { "26" }, "r26" }, 534 { { "27" }, "r27" }, 535 { { "28" }, "r28" }, 536 { { "29" }, "r29" }, 537 { { "30" }, "r30" }, 538 { { "31" }, "r31" }, 539 { { "fr0" }, "f0" }, 540 { { "fr1" }, "f1" }, 541 { { "fr2" }, "f2" }, 542 { { "fr3" }, "f3" }, 543 { { "fr4" }, "f4" }, 544 { { "fr5" }, "f5" }, 545 { { "fr6" }, "f6" }, 546 { { "fr7" }, "f7" }, 547 { { "fr8" }, "f8" }, 548 { { "fr9" }, "f9" }, 549 { { "fr10" }, "f10" }, 550 { { "fr11" }, "f11" }, 551 { { "fr12" }, "f12" }, 552 { { "fr13" }, "f13" }, 553 { { "fr14" }, "f14" }, 554 { { "fr15" }, "f15" }, 555 { { "fr16" }, "f16" }, 556 { { "fr17" }, "f17" }, 557 { { "fr18" }, "f18" }, 558 { { "fr19" }, "f19" }, 559 { { "fr20" }, "f20" }, 560 { { "fr21" }, "f21" }, 561 { { "fr22" }, "f22" }, 562 { { "fr23" }, "f23" }, 563 { { "fr24" }, "f24" }, 564 { { "fr25" }, "f25" }, 565 { { "fr26" }, "f26" }, 566 { { "fr27" }, "f27" }, 567 { { "fr28" }, "f28" }, 568 { { "fr29" }, "f29" }, 569 { { "fr30" }, "f30" }, 570 { { "fr31" }, "f31" }, 571 { { "cc" }, "cr0" }, 572}; 573 574void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 575 unsigned &NumAliases) const { 576 Aliases = GCCRegAliases; 577 NumAliases = llvm::array_lengthof(GCCRegAliases); 578} 579} // end anonymous namespace. 580 581namespace { 582class PPC32TargetInfo : public PPCTargetInfo { 583public: 584 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) { 585 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 586 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32"; 587 } 588}; 589} // end anonymous namespace. 590 591namespace { 592class PPC64TargetInfo : public PPCTargetInfo { 593public: 594 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) { 595 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 596 IntMaxType = SignedLong; 597 UIntMaxType = UnsignedLong; 598 Int64Type = SignedLong; 599 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 600 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"; 601 } 602}; 603} // end anonymous namespace. 604 605namespace { 606// Namespace for x86 abstract base class 607const Builtin::Info BuiltinInfo[] = { 608#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false }, 609#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false }, 610#include "clang/Basic/BuiltinsX86.def" 611}; 612 613static const char* const GCCRegNames[] = { 614 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", 615 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", 616 "argp", "flags", "fspr", "dirflag", "frame", 617 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", 618 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", 619 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 620 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" 621}; 622 623const TargetInfo::GCCRegAlias GCCRegAliases[] = { 624 { { "al", "ah", "eax", "rax" }, "ax" }, 625 { { "bl", "bh", "ebx", "rbx" }, "bx" }, 626 { { "cl", "ch", "ecx", "rcx" }, "cx" }, 627 { { "dl", "dh", "edx", "rdx" }, "dx" }, 628 { { "esi", "rsi" }, "si" }, 629 { { "edi", "rdi" }, "di" }, 630 { { "esp", "rsp" }, "sp" }, 631 { { "ebp", "rbp" }, "bp" }, 632}; 633 634// X86 target abstract base class; x86-32 and x86-64 are very close, so 635// most of the implementation can be shared. 636class X86TargetInfo : public TargetInfo { 637 enum X86SSEEnum { 638 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42 639 } SSELevel; 640 enum AMD3DNowEnum { 641 NoAMD3DNow, AMD3DNow, AMD3DNowAthlon 642 } AMD3DNowLevel; 643 644public: 645 X86TargetInfo(const std::string& triple) 646 : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow) { 647 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; 648 } 649 virtual void getTargetBuiltins(const Builtin::Info *&Records, 650 unsigned &NumRecords) const { 651 Records = BuiltinInfo; 652 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin; 653 } 654 virtual void getGCCRegNames(const char * const *&Names, 655 unsigned &NumNames) const { 656 Names = GCCRegNames; 657 NumNames = llvm::array_lengthof(GCCRegNames); 658 } 659 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 660 unsigned &NumAliases) const { 661 Aliases = GCCRegAliases; 662 NumAliases = llvm::array_lengthof(GCCRegAliases); 663 } 664 virtual bool validateAsmConstraint(const char *&Name, 665 TargetInfo::ConstraintInfo &info) const; 666 virtual std::string convertConstraint(const char Constraint) const; 667 virtual const char *getClobbers() const { 668 return "~{dirflag},~{fpsr},~{flags}"; 669 } 670 virtual void getTargetDefines(const LangOptions &Opts, 671 MacroBuilder &Builder) const; 672 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 673 const std::string &Name, 674 bool Enabled) const; 675 virtual void getDefaultFeatures(const std::string &CPU, 676 llvm::StringMap<bool> &Features) const; 677 virtual void HandleTargetFeatures(std::vector<std::string> &Features); 678}; 679 680void X86TargetInfo::getDefaultFeatures(const std::string &CPU, 681 llvm::StringMap<bool> &Features) const { 682 // FIXME: This should not be here. 683 Features["3dnow"] = false; 684 Features["3dnowa"] = false; 685 Features["mmx"] = false; 686 Features["sse"] = false; 687 Features["sse2"] = false; 688 Features["sse3"] = false; 689 Features["ssse3"] = false; 690 Features["sse41"] = false; 691 Features["sse42"] = false; 692 693 // LLVM does not currently recognize this. 694 // Features["sse4a"] = false; 695 696 // FIXME: This *really* should not be here. 697 698 // X86_64 always has SSE2. 699 if (PointerWidth == 64) 700 Features["sse2"] = Features["sse"] = Features["mmx"] = true; 701 702 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" || 703 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro") 704 ; 705 else if (CPU == "pentium-mmx" || CPU == "pentium2") 706 setFeatureEnabled(Features, "mmx", true); 707 else if (CPU == "pentium3") 708 setFeatureEnabled(Features, "sse", true); 709 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64") 710 setFeatureEnabled(Features, "sse2", true); 711 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona") 712 setFeatureEnabled(Features, "sse3", true); 713 else if (CPU == "core2") 714 setFeatureEnabled(Features, "ssse3", true); 715 else if (CPU == "penryn") { 716 setFeatureEnabled(Features, "sse4", true); 717 Features["sse42"] = false; 718 } else if (CPU == "atom") 719 setFeatureEnabled(Features, "sse3", true); 720 else if (CPU == "corei7") 721 setFeatureEnabled(Features, "sse4", true); 722 else if (CPU == "k6" || CPU == "winchip-c6") 723 setFeatureEnabled(Features, "mmx", true); 724 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" || 725 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") { 726 setFeatureEnabled(Features, "mmx", true); 727 setFeatureEnabled(Features, "3dnow", true); 728 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") { 729 setFeatureEnabled(Features, "sse", true); 730 setFeatureEnabled(Features, "3dnowa", true); 731 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" || 732 CPU == "athlon-fx") { 733 setFeatureEnabled(Features, "sse2", true); 734 setFeatureEnabled(Features, "3dnowa", true); 735 } else if (CPU == "c3-2") 736 setFeatureEnabled(Features, "sse", true); 737} 738 739bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, 740 const std::string &Name, 741 bool Enabled) const { 742 // FIXME: This *really* should not be here. 743 if (!Features.count(Name) && Name != "sse4") 744 return false; 745 746 if (Enabled) { 747 if (Name == "mmx") 748 Features["mmx"] = true; 749 else if (Name == "sse") 750 Features["mmx"] = Features["sse"] = true; 751 else if (Name == "sse2") 752 Features["mmx"] = Features["sse"] = Features["sse2"] = true; 753 else if (Name == "sse3") 754 Features["mmx"] = Features["sse"] = Features["sse2"] = 755 Features["sse3"] = true; 756 else if (Name == "ssse3") 757 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 758 Features["ssse3"] = true; 759 else if (Name == "sse4") 760 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 761 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true; 762 else if (Name == "3dnow") 763 Features["3dnowa"] = true; 764 else if (Name == "3dnowa") 765 Features["3dnow"] = Features["3dnowa"] = true; 766 } else { 767 if (Name == "mmx") 768 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 769 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; 770 else if (Name == "sse") 771 Features["sse"] = Features["sse2"] = Features["sse3"] = 772 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; 773 else if (Name == "sse2") 774 Features["sse2"] = Features["sse3"] = Features["ssse3"] = 775 Features["sse41"] = Features["sse42"] = false; 776 else if (Name == "sse3") 777 Features["sse3"] = Features["ssse3"] = Features["sse41"] = 778 Features["sse42"] = false; 779 else if (Name == "ssse3") 780 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; 781 else if (Name == "sse4") 782 Features["sse41"] = Features["sse42"] = false; 783 else if (Name == "3dnow") 784 Features["3dnow"] = Features["3dnowa"] = false; 785 else if (Name == "3dnowa") 786 Features["3dnowa"] = false; 787 } 788 789 return true; 790} 791 792/// HandleTargetOptions - Perform initialization based on the user 793/// configured set of features. 794void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { 795 // Remember the maximum enabled sselevel. 796 for (unsigned i = 0, e = Features.size(); i !=e; ++i) { 797 // Ignore disabled features. 798 if (Features[i][0] == '-') 799 continue; 800 801 assert(Features[i][0] == '+' && "Invalid target feature!"); 802 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1)) 803 .Case("sse42", SSE42) 804 .Case("sse41", SSE41) 805 .Case("ssse3", SSSE3) 806 .Case("sse2", SSE2) 807 .Case("sse", SSE1) 808 .Case("mmx", MMX) 809 .Default(NoMMXSSE); 810 SSELevel = std::max(SSELevel, Level); 811 812 AMD3DNowEnum ThreeDNowLevel = 813 llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1)) 814 .Case("3dnowa", AMD3DNowAthlon) 815 .Case("3dnow", AMD3DNow) 816 .Default(NoAMD3DNow); 817 818 AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel); 819 } 820} 821 822/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines 823/// that are not tied to a specific subtarget. 824void X86TargetInfo::getTargetDefines(const LangOptions &Opts, 825 MacroBuilder &Builder) const { 826 // Target identification. 827 if (PointerWidth == 64) { 828 Builder.defineMacro("_LP64"); 829 Builder.defineMacro("__LP64__"); 830 Builder.defineMacro("__amd64__"); 831 Builder.defineMacro("__amd64"); 832 Builder.defineMacro("__x86_64"); 833 Builder.defineMacro("__x86_64__"); 834 } else { 835 DefineStd(Builder, "i386", Opts); 836 } 837 838 // Target properties. 839 Builder.defineMacro("__LITTLE_ENDIAN__"); 840 841 // Subtarget options. 842 Builder.defineMacro("__nocona"); 843 Builder.defineMacro("__nocona__"); 844 Builder.defineMacro("__tune_nocona__"); 845 Builder.defineMacro("__REGISTER_PREFIX__", ""); 846 847 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline 848 // functions in glibc header files that use FP Stack inline asm which the 849 // backend can't deal with (PR879). 850 Builder.defineMacro("__NO_MATH_INLINES"); 851 852 // Each case falls through to the previous one here. 853 switch (SSELevel) { 854 case SSE42: 855 Builder.defineMacro("__SSE4_2__"); 856 case SSE41: 857 Builder.defineMacro("__SSE4_1__"); 858 case SSSE3: 859 Builder.defineMacro("__SSSE3__"); 860 case SSE3: 861 Builder.defineMacro("__SSE3__"); 862 case SSE2: 863 Builder.defineMacro("__SSE2__"); 864 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied. 865 case SSE1: 866 Builder.defineMacro("__SSE__"); 867 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied. 868 case MMX: 869 Builder.defineMacro("__MMX__"); 870 case NoMMXSSE: 871 break; 872 } 873 874 // Each case falls through to the previous one here. 875 switch (AMD3DNowLevel) { 876 case AMD3DNowAthlon: 877 Builder.defineMacro("__3dNOW_A__"); 878 case AMD3DNow: 879 Builder.defineMacro("__3dNOW__"); 880 case NoAMD3DNow: 881 break; 882 } 883} 884 885 886bool 887X86TargetInfo::validateAsmConstraint(const char *&Name, 888 TargetInfo::ConstraintInfo &Info) const { 889 switch (*Name) { 890 default: return false; 891 case 'a': // eax. 892 case 'b': // ebx. 893 case 'c': // ecx. 894 case 'd': // edx. 895 case 'S': // esi. 896 case 'D': // edi. 897 case 'A': // edx:eax. 898 case 't': // top of floating point stack. 899 case 'u': // second from top of floating point stack. 900 case 'q': // Any register accessible as [r]l: a, b, c, and d. 901 case 'y': // Any MMX register. 902 case 'x': // Any SSE register. 903 case 'Q': // Any register accessible as [r]h: a, b, c, and d. 904 case 'e': // 32-bit signed integer constant for use with zero-extending 905 // x86_64 instructions. 906 case 'Z': // 32-bit unsigned integer constant for use with zero-extending 907 // x86_64 instructions. 908 case 'N': // unsigned 8-bit integer constant for use with in and out 909 // instructions. 910 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp. 911 Info.setAllowsRegister(); 912 return true; 913 } 914} 915 916std::string 917X86TargetInfo::convertConstraint(const char Constraint) const { 918 switch (Constraint) { 919 case 'a': return std::string("{ax}"); 920 case 'b': return std::string("{bx}"); 921 case 'c': return std::string("{cx}"); 922 case 'd': return std::string("{dx}"); 923 case 'S': return std::string("{si}"); 924 case 'D': return std::string("{di}"); 925 case 't': // top of floating point stack. 926 return std::string("{st}"); 927 case 'u': // second from top of floating point stack. 928 return std::string("{st(1)}"); // second from top of floating point stack. 929 default: 930 return std::string(1, Constraint); 931 } 932} 933} // end anonymous namespace 934 935namespace { 936// X86-32 generic target 937class X86_32TargetInfo : public X86TargetInfo { 938public: 939 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) { 940 DoubleAlign = LongLongAlign = 32; 941 LongDoubleWidth = 96; 942 LongDoubleAlign = 32; 943 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 944 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 945 "a0:0:64-f80:32:32-n8:16:32"; 946 SizeType = UnsignedInt; 947 PtrDiffType = SignedInt; 948 IntPtrType = SignedInt; 949 RegParmMax = 3; 950 } 951 virtual const char *getVAListDeclaration() const { 952 return "typedef char* __builtin_va_list;"; 953 } 954 955 int getEHDataRegisterNumber(unsigned RegNo) const { 956 if (RegNo == 0) return 0; 957 if (RegNo == 1) return 2; 958 return -1; 959 } 960}; 961} // end anonymous namespace 962 963namespace { 964class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> { 965public: 966 OpenBSDI386TargetInfo(const std::string& triple) : 967 OpenBSDTargetInfo<X86_32TargetInfo>(triple) { 968 SizeType = UnsignedLong; 969 IntPtrType = SignedLong; 970 PtrDiffType = SignedLong; 971 } 972}; 973} // end anonymous namespace 974 975namespace { 976class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> { 977public: 978 DarwinI386TargetInfo(const std::string& triple) : 979 DarwinTargetInfo<X86_32TargetInfo>(triple) { 980 LongDoubleWidth = 128; 981 LongDoubleAlign = 128; 982 SizeType = UnsignedLong; 983 IntPtrType = SignedLong; 984 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 985 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 986 "a0:0:64-f80:128:128-n8:16:32"; 987 } 988 989}; 990} // end anonymous namespace 991 992namespace { 993// x86-32 Windows target 994class WindowsX86_32TargetInfo : public X86_32TargetInfo { 995public: 996 WindowsX86_32TargetInfo(const std::string& triple) 997 : X86_32TargetInfo(triple) { 998 TLSSupported = false; 999 WCharType = UnsignedShort; 1000 DoubleAlign = LongLongAlign = 64; 1001 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1002 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-" 1003 "v128:128:128-a0:0:64-f80:32:32-n8:16:32"; 1004 } 1005 virtual void getTargetDefines(const LangOptions &Opts, 1006 MacroBuilder &Builder) const { 1007 X86_32TargetInfo::getTargetDefines(Opts, Builder); 1008 // This list is based off of the the list of things MingW defines 1009 Builder.defineMacro("_WIN32"); 1010 DefineStd(Builder, "WIN32", Opts); 1011 DefineStd(Builder, "WINNT", Opts); 1012 Builder.defineMacro("_X86_"); 1013 } 1014}; 1015} // end anonymous namespace 1016 1017namespace { 1018 1019// x86-32 Windows Visual Studio target 1020class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo { 1021public: 1022 VisualStudioWindowsX86_32TargetInfo(const std::string& triple) 1023 : WindowsX86_32TargetInfo(triple) { 1024 } 1025 virtual void getTargetDefines(const LangOptions &Opts, 1026 MacroBuilder &Builder) const { 1027 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); 1028 // The value of the following reflects processor type. 1029 // 300=386, 400=486, 500=Pentium, 600=Blend (default) 1030 // We lost the original triple, so we use the default. 1031 Builder.defineMacro("_M_IX86", "600"); 1032 } 1033}; 1034} // end anonymous namespace 1035 1036namespace { 1037// x86-32 MinGW target 1038class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo { 1039public: 1040 MinGWX86_32TargetInfo(const std::string& triple) 1041 : WindowsX86_32TargetInfo(triple) { 1042 } 1043 virtual void getTargetDefines(const LangOptions &Opts, 1044 MacroBuilder &Builder) const { 1045 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); 1046 Builder.defineMacro("__MSVCRT__"); 1047 Builder.defineMacro("__MINGW32__"); 1048 Builder.defineMacro("__declspec", "__declspec"); 1049 } 1050}; 1051} // end anonymous namespace 1052 1053namespace { 1054// x86-32 Cygwin target 1055class CygwinX86_32TargetInfo : public X86_32TargetInfo { 1056public: 1057 CygwinX86_32TargetInfo(const std::string& triple) 1058 : X86_32TargetInfo(triple) { 1059 TLSSupported = false; 1060 WCharType = UnsignedShort; 1061 DoubleAlign = LongLongAlign = 64; 1062 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1063 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 1064 "a0:0:64-f80:32:32-n8:16:32"; 1065 } 1066 virtual void getTargetDefines(const LangOptions &Opts, 1067 MacroBuilder &Builder) const { 1068 X86_32TargetInfo::getTargetDefines(Opts, Builder); 1069 Builder.defineMacro("__CYGWIN__"); 1070 Builder.defineMacro("__CYGWIN32__"); 1071 DefineStd(Builder, "unix", Opts); 1072 } 1073}; 1074} // end anonymous namespace 1075 1076namespace { 1077// x86-64 generic target 1078class X86_64TargetInfo : public X86TargetInfo { 1079public: 1080 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) { 1081 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 1082 LongDoubleWidth = 128; 1083 LongDoubleAlign = 128; 1084 IntMaxType = SignedLong; 1085 UIntMaxType = UnsignedLong; 1086 Int64Type = SignedLong; 1087 RegParmMax = 6; 1088 1089 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1090 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 1091 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"; 1092 } 1093 virtual const char *getVAListDeclaration() const { 1094 return "typedef struct __va_list_tag {" 1095 " unsigned gp_offset;" 1096 " unsigned fp_offset;" 1097 " void* overflow_arg_area;" 1098 " void* reg_save_area;" 1099 "} __va_list_tag;" 1100 "typedef __va_list_tag __builtin_va_list[1];"; 1101 } 1102 1103 int getEHDataRegisterNumber(unsigned RegNo) const { 1104 if (RegNo == 0) return 0; 1105 if (RegNo == 1) return 1; 1106 return -1; 1107 } 1108}; 1109} // end anonymous namespace 1110 1111namespace { 1112// x86-64 Windows target 1113class WindowsX86_64TargetInfo : public X86_64TargetInfo { 1114public: 1115 WindowsX86_64TargetInfo(const std::string& triple) 1116 : X86_64TargetInfo(triple) { 1117 TLSSupported = false; 1118 WCharType = UnsignedShort; 1119 LongWidth = LongAlign = 32; 1120 DoubleAlign = LongLongAlign = 64; 1121 } 1122 virtual void getTargetDefines(const LangOptions &Opts, 1123 MacroBuilder &Builder) const { 1124 X86_64TargetInfo::getTargetDefines(Opts, Builder); 1125 Builder.defineMacro("_WIN64"); 1126 DefineStd(Builder, "WIN64", Opts); 1127 } 1128}; 1129} // end anonymous namespace 1130 1131namespace { 1132// x86-64 Windows Visual Studio target 1133class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo { 1134public: 1135 VisualStudioWindowsX86_64TargetInfo(const std::string& triple) 1136 : WindowsX86_64TargetInfo(triple) { 1137 } 1138 virtual void getTargetDefines(const LangOptions &Opts, 1139 MacroBuilder &Builder) const { 1140 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder); 1141 Builder.defineMacro("_M_X64"); 1142 } 1143 virtual const char *getVAListDeclaration() const { 1144 return "typedef char* va_list;"; 1145 } 1146}; 1147} // end anonymous namespace 1148 1149namespace { 1150// x86-64 MinGW target 1151class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo { 1152public: 1153 MinGWX86_64TargetInfo(const std::string& triple) 1154 : WindowsX86_64TargetInfo(triple) { 1155 } 1156 virtual void getTargetDefines(const LangOptions &Opts, 1157 MacroBuilder &Builder) const { 1158 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder); 1159 Builder.defineMacro("__MSVCRT__"); 1160 Builder.defineMacro("__MINGW64__"); 1161 Builder.defineMacro("__declspec"); 1162 } 1163}; 1164} // end anonymous namespace 1165 1166namespace { 1167class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> { 1168public: 1169 DarwinX86_64TargetInfo(const std::string& triple) 1170 : DarwinTargetInfo<X86_64TargetInfo>(triple) { 1171 Int64Type = SignedLongLong; 1172 } 1173}; 1174} // end anonymous namespace 1175 1176namespace { 1177class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> { 1178public: 1179 OpenBSDX86_64TargetInfo(const std::string& triple) 1180 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) { 1181 IntMaxType = SignedLongLong; 1182 UIntMaxType = UnsignedLongLong; 1183 Int64Type = SignedLongLong; 1184 } 1185}; 1186} // end anonymous namespace 1187 1188namespace { 1189class ARMTargetInfo : public TargetInfo { 1190 // Possible FPU choices. 1191 enum FPUMode { 1192 NoFPU, 1193 VFP2FPU, 1194 VFP3FPU, 1195 NeonFPU 1196 }; 1197 1198 static bool FPUModeIsVFP(FPUMode Mode) { 1199 return Mode >= VFP2FPU && Mode <= NeonFPU; 1200 } 1201 1202 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1203 static const char * const GCCRegNames[]; 1204 1205 std::string ABI, CPU; 1206 1207 unsigned FPU : 3; 1208 1209 unsigned IsThumb : 1; 1210 1211 // Initialized via features. 1212 unsigned SoftFloat : 1; 1213 unsigned SoftFloatABI : 1; 1214 1215public: 1216 ARMTargetInfo(const std::string &TripleStr) 1217 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s") 1218 { 1219 SizeType = UnsignedInt; 1220 PtrDiffType = SignedInt; 1221 1222 // FIXME: Should we just treat this as a feature? 1223 IsThumb = getTriple().getArchName().startswith("thumb"); 1224 if (IsThumb) { 1225 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" 1226 "i64:64:64-f32:32:32-f64:64:64-" 1227 "v64:64:64-v128:128:128-a0:0:32-n32"); 1228 } else { 1229 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1230 "i64:64:64-f32:32:32-f64:64:64-" 1231 "v64:64:64-v128:128:128-a0:0:64-n32"); 1232 } 1233 } 1234 virtual const char *getABI() const { return ABI.c_str(); } 1235 virtual bool setABI(const std::string &Name) { 1236 ABI = Name; 1237 1238 // The defaults (above) are for AAPCS, check if we need to change them. 1239 // 1240 // FIXME: We need support for -meabi... we could just mangle it into the 1241 // name. 1242 if (Name == "apcs-gnu") { 1243 DoubleAlign = LongLongAlign = 32; 1244 SizeType = UnsignedLong; 1245 1246 if (IsThumb) { 1247 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" 1248 "i64:32:32-f32:32:32-f64:32:32-" 1249 "v64:64:64-v128:128:128-a0:0:32-n32"); 1250 } else { 1251 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1252 "i64:32:32-f32:32:32-f64:32:32-" 1253 "v64:64:64-v128:128:128-a0:0:64-n32"); 1254 } 1255 1256 // FIXME: Override "preferred align" for double and long long. 1257 } else if (Name == "aapcs") { 1258 // FIXME: Enumerated types are variable width in straight AAPCS. 1259 } else if (Name == "aapcs-linux") { 1260 ; 1261 } else 1262 return false; 1263 1264 return true; 1265 } 1266 1267 void getDefaultFeatures(const std::string &CPU, 1268 llvm::StringMap<bool> &Features) const { 1269 // FIXME: This should not be here. 1270 Features["vfp2"] = false; 1271 Features["vfp3"] = false; 1272 Features["neon"] = false; 1273 1274 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore") 1275 Features["vfp2"] = true; 1276 else if (CPU == "cortex-a8" || CPU == "cortex-a9") 1277 Features["neon"] = true; 1278 } 1279 1280 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 1281 const std::string &Name, 1282 bool Enabled) const { 1283 if (Name == "soft-float" || Name == "soft-float-abi") { 1284 Features[Name] = Enabled; 1285 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") { 1286 // These effectively are a single option, reset them when any is enabled. 1287 if (Enabled) 1288 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false; 1289 Features[Name] = Enabled; 1290 } else 1291 return false; 1292 1293 return true; 1294 } 1295 1296 virtual void HandleTargetFeatures(std::vector<std::string> &Features) { 1297 FPU = NoFPU; 1298 SoftFloat = SoftFloatABI = false; 1299 for (unsigned i = 0, e = Features.size(); i != e; ++i) { 1300 if (Features[i] == "+soft-float") 1301 SoftFloat = true; 1302 else if (Features[i] == "+soft-float-abi") 1303 SoftFloatABI = true; 1304 else if (Features[i] == "+vfp2") 1305 FPU = VFP2FPU; 1306 else if (Features[i] == "+vfp3") 1307 FPU = VFP3FPU; 1308 else if (Features[i] == "+neon") 1309 FPU = NeonFPU; 1310 } 1311 1312 // Remove front-end specific options which the backend handles differently. 1313 std::vector<std::string>::iterator it; 1314 it = std::find(Features.begin(), Features.end(), "+soft-float"); 1315 if (it != Features.end()) 1316 Features.erase(it); 1317 it = std::find(Features.begin(), Features.end(), "+soft-float-abi"); 1318 if (it != Features.end()) 1319 Features.erase(it); 1320 } 1321 1322 static const char *getCPUDefineSuffix(llvm::StringRef Name) { 1323 return llvm::StringSwitch<const char*>(Name) 1324 .Cases("arm8", "arm810", "4") 1325 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4") 1326 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T") 1327 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T") 1328 .Case("ep9312", "4T") 1329 .Cases("arm10tdmi", "arm1020t", "5T") 1330 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE") 1331 .Case("arm926ej-s", "5TEJ") 1332 .Cases("arm10e", "arm1020e", "arm1022e", "5TE") 1333 .Cases("xscale", "iwmmxt", "5TE") 1334 .Case("arm1136j-s", "6J") 1335 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK") 1336 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K") 1337 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2") 1338 .Cases("cortex-a8", "cortex-a9", "7A") 1339 .Default(0); 1340 } 1341 virtual bool setCPU(const std::string &Name) { 1342 if (!getCPUDefineSuffix(Name)) 1343 return false; 1344 1345 CPU = Name; 1346 return true; 1347 } 1348 virtual void getTargetDefines(const LangOptions &Opts, 1349 MacroBuilder &Builder) const { 1350 // Target identification. 1351 Builder.defineMacro("__arm"); 1352 Builder.defineMacro("__arm__"); 1353 1354 // Target properties. 1355 Builder.defineMacro("__ARMEL__"); 1356 Builder.defineMacro("__LITTLE_ENDIAN__"); 1357 Builder.defineMacro("__REGISTER_PREFIX__", ""); 1358 1359 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU); 1360 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__"); 1361 1362 // Subtarget options. 1363 1364 // FIXME: It's more complicated than this and we don't really support 1365 // interworking. 1366 if ('5' <= CPUArch[0] && CPUArch[0] <= '7') 1367 Builder.defineMacro("__THUMB_INTERWORK__"); 1368 1369 if (ABI == "aapcs" || ABI == "aapcs-linux") 1370 Builder.defineMacro("__ARM_EABI__"); 1371 1372 if (SoftFloat) 1373 Builder.defineMacro("__SOFTFP__"); 1374 1375 if (CPU == "xscale") 1376 Builder.defineMacro("__XSCALE__"); 1377 1378 bool IsThumb2 = IsThumb && (CPUArch == "6T2" || CPUArch.startswith("7")); 1379 if (IsThumb) { 1380 Builder.defineMacro("__THUMBEL__"); 1381 Builder.defineMacro("__thumb__"); 1382 if (IsThumb2) 1383 Builder.defineMacro("__thumb2__"); 1384 } 1385 1386 // Note, this is always on in gcc, even though it doesn't make sense. 1387 Builder.defineMacro("__APCS_32__"); 1388 1389 if (FPUModeIsVFP((FPUMode) FPU)) 1390 Builder.defineMacro("__VFP_FP__"); 1391 1392 // This only gets set when Neon instructions are actually available, unlike 1393 // the VFP define, hence the soft float and arch check. This is subtly 1394 // different from gcc, we follow the intent which was that it should be set 1395 // when Neon instructions are actually available. 1396 if (FPU == NeonFPU && !SoftFloat && IsThumb2) 1397 Builder.defineMacro("__ARM_NEON__"); 1398 1399 if (getTriple().getOS() == llvm::Triple::Darwin) 1400 Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__"); 1401 } 1402 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1403 unsigned &NumRecords) const { 1404 // FIXME: Implement. 1405 Records = 0; 1406 NumRecords = 0; 1407 } 1408 virtual const char *getVAListDeclaration() const { 1409 return "typedef char* __builtin_va_list;"; 1410 } 1411 virtual void getGCCRegNames(const char * const *&Names, 1412 unsigned &NumNames) const; 1413 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1414 unsigned &NumAliases) const; 1415 virtual bool validateAsmConstraint(const char *&Name, 1416 TargetInfo::ConstraintInfo &Info) const { 1417 // FIXME: Check if this is complete 1418 switch (*Name) { 1419 default: 1420 case 'l': // r0-r7 1421 case 'h': // r8-r15 1422 case 'w': // VFP Floating point register single precision 1423 case 'P': // VFP Floating point register double precision 1424 Info.setAllowsRegister(); 1425 return true; 1426 } 1427 return false; 1428 } 1429 virtual const char *getClobbers() const { 1430 // FIXME: Is this really right? 1431 return ""; 1432 } 1433}; 1434 1435const char * const ARMTargetInfo::GCCRegNames[] = { 1436 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1437 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1438}; 1439 1440void ARMTargetInfo::getGCCRegNames(const char * const *&Names, 1441 unsigned &NumNames) const { 1442 Names = GCCRegNames; 1443 NumNames = llvm::array_lengthof(GCCRegNames); 1444} 1445 1446const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 1447 1448 { { "a1" }, "r0" }, 1449 { { "a2" }, "r1" }, 1450 { { "a3" }, "r2" }, 1451 { { "a4" }, "r3" }, 1452 { { "v1" }, "r4" }, 1453 { { "v2" }, "r5" }, 1454 { { "v3" }, "r6" }, 1455 { { "v4" }, "r7" }, 1456 { { "v5" }, "r8" }, 1457 { { "v6", "rfp" }, "r9" }, 1458 { { "sl" }, "r10" }, 1459 { { "fp" }, "r11" }, 1460 { { "ip" }, "r12" }, 1461 { { "sp" }, "r13" }, 1462 { { "lr" }, "r14" }, 1463 { { "pc" }, "r15" }, 1464}; 1465 1466void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1467 unsigned &NumAliases) const { 1468 Aliases = GCCRegAliases; 1469 NumAliases = llvm::array_lengthof(GCCRegAliases); 1470} 1471} // end anonymous namespace. 1472 1473 1474namespace { 1475class DarwinARMTargetInfo : 1476 public DarwinTargetInfo<ARMTargetInfo> { 1477protected: 1478 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 1479 MacroBuilder &Builder) const { 1480 getDarwinDefines(Builder, Opts, Triple); 1481 } 1482 1483public: 1484 DarwinARMTargetInfo(const std::string& triple) 1485 : DarwinTargetInfo<ARMTargetInfo>(triple) {} 1486}; 1487} // end anonymous namespace. 1488 1489namespace { 1490class SparcV8TargetInfo : public TargetInfo { 1491 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1492 static const char * const GCCRegNames[]; 1493public: 1494 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { 1495 // FIXME: Support Sparc quad-precision long double? 1496 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1497 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; 1498 } 1499 virtual void getTargetDefines(const LangOptions &Opts, 1500 MacroBuilder &Builder) const { 1501 DefineStd(Builder, "sparc", Opts); 1502 Builder.defineMacro("__sparcv8"); 1503 Builder.defineMacro("__REGISTER_PREFIX__", ""); 1504 } 1505 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1506 unsigned &NumRecords) const { 1507 // FIXME: Implement! 1508 } 1509 virtual const char *getVAListDeclaration() const { 1510 return "typedef void* __builtin_va_list;"; 1511 } 1512 virtual void getGCCRegNames(const char * const *&Names, 1513 unsigned &NumNames) const; 1514 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1515 unsigned &NumAliases) const; 1516 virtual bool validateAsmConstraint(const char *&Name, 1517 TargetInfo::ConstraintInfo &info) const { 1518 // FIXME: Implement! 1519 return false; 1520 } 1521 virtual const char *getClobbers() const { 1522 // FIXME: Implement! 1523 return ""; 1524 } 1525}; 1526 1527const char * const SparcV8TargetInfo::GCCRegNames[] = { 1528 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1529 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 1530 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 1531 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" 1532}; 1533 1534void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names, 1535 unsigned &NumNames) const { 1536 Names = GCCRegNames; 1537 NumNames = llvm::array_lengthof(GCCRegNames); 1538} 1539 1540const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = { 1541 { { "g0" }, "r0" }, 1542 { { "g1" }, "r1" }, 1543 { { "g2" }, "r2" }, 1544 { { "g3" }, "r3" }, 1545 { { "g4" }, "r4" }, 1546 { { "g5" }, "r5" }, 1547 { { "g6" }, "r6" }, 1548 { { "g7" }, "r7" }, 1549 { { "o0" }, "r8" }, 1550 { { "o1" }, "r9" }, 1551 { { "o2" }, "r10" }, 1552 { { "o3" }, "r11" }, 1553 { { "o4" }, "r12" }, 1554 { { "o5" }, "r13" }, 1555 { { "o6", "sp" }, "r14" }, 1556 { { "o7" }, "r15" }, 1557 { { "l0" }, "r16" }, 1558 { { "l1" }, "r17" }, 1559 { { "l2" }, "r18" }, 1560 { { "l3" }, "r19" }, 1561 { { "l4" }, "r20" }, 1562 { { "l5" }, "r21" }, 1563 { { "l6" }, "r22" }, 1564 { { "l7" }, "r23" }, 1565 { { "i0" }, "r24" }, 1566 { { "i1" }, "r25" }, 1567 { { "i2" }, "r26" }, 1568 { { "i3" }, "r27" }, 1569 { { "i4" }, "r28" }, 1570 { { "i5" }, "r29" }, 1571 { { "i6", "fp" }, "r30" }, 1572 { { "i7" }, "r31" }, 1573}; 1574 1575void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1576 unsigned &NumAliases) const { 1577 Aliases = GCCRegAliases; 1578 NumAliases = llvm::array_lengthof(GCCRegAliases); 1579} 1580} // end anonymous namespace. 1581 1582namespace { 1583class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> { 1584public: 1585 AuroraUXSparcV8TargetInfo(const std::string& triple) : 1586 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) { 1587 SizeType = UnsignedInt; 1588 PtrDiffType = SignedInt; 1589 } 1590}; 1591class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> { 1592public: 1593 SolarisSparcV8TargetInfo(const std::string& triple) : 1594 SolarisTargetInfo<SparcV8TargetInfo>(triple) { 1595 SizeType = UnsignedInt; 1596 PtrDiffType = SignedInt; 1597 } 1598}; 1599} // end anonymous namespace. 1600 1601namespace { 1602 class PIC16TargetInfo : public TargetInfo{ 1603 public: 1604 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) { 1605 TLSSupported = false; 1606 IntWidth = 16; 1607 LongWidth = LongLongWidth = 32; 1608 PointerWidth = 16; 1609 IntAlign = 8; 1610 LongAlign = LongLongAlign = 8; 1611 PointerAlign = 8; 1612 SizeType = UnsignedInt; 1613 IntMaxType = SignedLong; 1614 UIntMaxType = UnsignedLong; 1615 IntPtrType = SignedShort; 1616 PtrDiffType = SignedInt; 1617 SigAtomicType = SignedLong; 1618 FloatWidth = 32; 1619 FloatAlign = 32; 1620 DoubleWidth = 32; 1621 DoubleAlign = 32; 1622 LongDoubleWidth = 32; 1623 LongDoubleAlign = 32; 1624 FloatFormat = &llvm::APFloat::IEEEsingle; 1625 DoubleFormat = &llvm::APFloat::IEEEsingle; 1626 LongDoubleFormat = &llvm::APFloat::IEEEsingle; 1627 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32-n8"; 1628 1629 } 1630 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; } 1631 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; } 1632 virtual void getTargetDefines(const LangOptions &Opts, 1633 MacroBuilder &Builder) const { 1634 Builder.defineMacro("__pic16"); 1635 Builder.defineMacro("rom", "__attribute__((address_space(1)))"); 1636 Builder.defineMacro("ram", "__attribute__((address_space(0)))"); 1637 Builder.defineMacro("_section(SectName)", 1638 "__attribute__((section(SectName)))"); 1639 Builder.defineMacro("near", 1640 "__attribute__((section(\"Address=NEAR\")))"); 1641 Builder.defineMacro("_address(Addr)", 1642 "__attribute__((section(\"Address=\"#Addr)))"); 1643 Builder.defineMacro("_CONFIG(conf)", "asm(\"CONFIG \"#conf)"); 1644 Builder.defineMacro("_interrupt", 1645 "__attribute__((section(\"interrupt=0x4\"))) \ 1646 __attribute__((used))"); 1647 } 1648 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1649 unsigned &NumRecords) const {} 1650 virtual const char *getVAListDeclaration() const { 1651 return ""; 1652 } 1653 virtual const char *getClobbers() const { 1654 return ""; 1655 } 1656 virtual void getGCCRegNames(const char * const *&Names, 1657 unsigned &NumNames) const {} 1658 virtual bool validateAsmConstraint(const char *&Name, 1659 TargetInfo::ConstraintInfo &info) const { 1660 return true; 1661 } 1662 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1663 unsigned &NumAliases) const {} 1664 virtual bool useGlobalsForAutomaticVariables() const {return true;} 1665 }; 1666} 1667 1668namespace { 1669 class MSP430TargetInfo : public TargetInfo { 1670 static const char * const GCCRegNames[]; 1671 public: 1672 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { 1673 TLSSupported = false; 1674 IntWidth = 16; 1675 LongWidth = 32; 1676 LongLongWidth = 64; 1677 PointerWidth = 16; 1678 IntAlign = 8; 1679 LongAlign = LongLongAlign = 8; 1680 PointerAlign = 8; 1681 SizeType = UnsignedInt; 1682 IntMaxType = SignedLong; 1683 UIntMaxType = UnsignedLong; 1684 IntPtrType = SignedShort; 1685 PtrDiffType = SignedInt; 1686 SigAtomicType = SignedLong; 1687 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"; 1688 } 1689 virtual void getTargetDefines(const LangOptions &Opts, 1690 MacroBuilder &Builder) const { 1691 Builder.defineMacro("MSP430"); 1692 Builder.defineMacro("__MSP430__"); 1693 // FIXME: defines for different 'flavours' of MCU 1694 } 1695 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1696 unsigned &NumRecords) const { 1697 // FIXME: Implement. 1698 Records = 0; 1699 NumRecords = 0; 1700 } 1701 virtual void getGCCRegNames(const char * const *&Names, 1702 unsigned &NumNames) const; 1703 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1704 unsigned &NumAliases) const { 1705 // No aliases. 1706 Aliases = 0; 1707 NumAliases = 0; 1708 } 1709 virtual bool validateAsmConstraint(const char *&Name, 1710 TargetInfo::ConstraintInfo &info) const { 1711 // No target constraints for now. 1712 return false; 1713 } 1714 virtual const char *getClobbers() const { 1715 // FIXME: Is this really right? 1716 return ""; 1717 } 1718 virtual const char *getVAListDeclaration() const { 1719 // FIXME: implement 1720 return "typedef char* __builtin_va_list;"; 1721 } 1722 }; 1723 1724 const char * const MSP430TargetInfo::GCCRegNames[] = { 1725 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1726 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1727 }; 1728 1729 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names, 1730 unsigned &NumNames) const { 1731 Names = GCCRegNames; 1732 NumNames = llvm::array_lengthof(GCCRegNames); 1733 } 1734} 1735 1736 1737namespace { 1738 class SystemZTargetInfo : public TargetInfo { 1739 static const char * const GCCRegNames[]; 1740 public: 1741 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) { 1742 TLSSupported = false; 1743 IntWidth = IntAlign = 32; 1744 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; 1745 PointerWidth = PointerAlign = 64; 1746 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-" 1747 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64"; 1748 } 1749 virtual void getTargetDefines(const LangOptions &Opts, 1750 MacroBuilder &Builder) const { 1751 Builder.defineMacro("__s390__"); 1752 Builder.defineMacro("__s390x__"); 1753 } 1754 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1755 unsigned &NumRecords) const { 1756 // FIXME: Implement. 1757 Records = 0; 1758 NumRecords = 0; 1759 } 1760 1761 virtual void getGCCRegNames(const char * const *&Names, 1762 unsigned &NumNames) const; 1763 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1764 unsigned &NumAliases) const { 1765 // No aliases. 1766 Aliases = 0; 1767 NumAliases = 0; 1768 } 1769 virtual bool validateAsmConstraint(const char *&Name, 1770 TargetInfo::ConstraintInfo &info) const { 1771 // FIXME: implement 1772 return true; 1773 } 1774 virtual const char *getClobbers() const { 1775 // FIXME: Is this really right? 1776 return ""; 1777 } 1778 virtual const char *getVAListDeclaration() const { 1779 // FIXME: implement 1780 return "typedef char* __builtin_va_list;"; 1781 } 1782 }; 1783 1784 const char * const SystemZTargetInfo::GCCRegNames[] = { 1785 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1786 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1787 }; 1788 1789 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names, 1790 unsigned &NumNames) const { 1791 Names = GCCRegNames; 1792 NumNames = llvm::array_lengthof(GCCRegNames); 1793 } 1794} 1795 1796namespace { 1797 class BlackfinTargetInfo : public TargetInfo { 1798 static const char * const GCCRegNames[]; 1799 public: 1800 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) { 1801 TLSSupported = false; 1802 DoubleAlign = 32; 1803 LongLongAlign = 32; 1804 LongDoubleAlign = 32; 1805 DescriptionString = "e-p:32:32-i64:32-f64:32-n32"; 1806 } 1807 1808 virtual void getTargetDefines(const LangOptions &Opts, 1809 MacroBuilder &Builder) const { 1810 DefineStd(Builder, "bfin", Opts); 1811 DefineStd(Builder, "BFIN", Opts); 1812 Builder.defineMacro("__ADSPBLACKFIN__"); 1813 // FIXME: This one is really dependent on -mcpu 1814 Builder.defineMacro("__ADSPLPBLACKFIN__"); 1815 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__ 1816 } 1817 1818 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1819 unsigned &NumRecords) const { 1820 // FIXME: Implement. 1821 Records = 0; 1822 NumRecords = 0; 1823 } 1824 1825 virtual void getGCCRegNames(const char * const *&Names, 1826 unsigned &NumNames) const; 1827 1828 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1829 unsigned &NumAliases) const { 1830 // No aliases. 1831 Aliases = 0; 1832 NumAliases = 0; 1833 } 1834 1835 virtual bool validateAsmConstraint(const char *&Name, 1836 TargetInfo::ConstraintInfo &Info) const { 1837 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) { 1838 Info.setAllowsRegister(); 1839 return true; 1840 } 1841 return false; 1842 } 1843 1844 virtual const char *getClobbers() const { 1845 return ""; 1846 } 1847 1848 virtual const char *getVAListDeclaration() const { 1849 return "typedef char* __builtin_va_list;"; 1850 } 1851 }; 1852 1853 const char * const BlackfinTargetInfo::GCCRegNames[] = { 1854 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1855 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp", 1856 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3", 1857 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3", 1858 "a0", "a1", "cc", 1859 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp", 1860 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1" 1861 }; 1862 1863 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names, 1864 unsigned &NumNames) const { 1865 Names = GCCRegNames; 1866 NumNames = llvm::array_lengthof(GCCRegNames); 1867 } 1868} 1869 1870namespace { 1871 1872 // LLVM and Clang cannot be used directly to output native binaries for 1873 // target, but is used to compile C code to llvm bitcode with correct 1874 // type and alignment information. 1875 // 1876 // TCE uses the llvm bitcode as input and uses it for generating customized 1877 // target processor and program binary. TCE co-design environment is 1878 // publicly available in http://tce.cs.tut.fi 1879 1880 class TCETargetInfo : public TargetInfo{ 1881 public: 1882 TCETargetInfo(const std::string& triple) : TargetInfo(triple) { 1883 TLSSupported = false; 1884 IntWidth = 32; 1885 LongWidth = LongLongWidth = 32; 1886 PointerWidth = 32; 1887 IntAlign = 32; 1888 LongAlign = LongLongAlign = 32; 1889 PointerAlign = 32; 1890 SizeType = UnsignedInt; 1891 IntMaxType = SignedLong; 1892 UIntMaxType = UnsignedLong; 1893 IntPtrType = SignedInt; 1894 PtrDiffType = SignedInt; 1895 FloatWidth = 32; 1896 FloatAlign = 32; 1897 DoubleWidth = 32; 1898 DoubleAlign = 32; 1899 LongDoubleWidth = 32; 1900 LongDoubleAlign = 32; 1901 FloatFormat = &llvm::APFloat::IEEEsingle; 1902 DoubleFormat = &llvm::APFloat::IEEEsingle; 1903 LongDoubleFormat = &llvm::APFloat::IEEEsingle; 1904 DescriptionString = "E-p:32:32:32-a0:32:32" 1905 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64" 1906 "-f32:32:32-f64:32:64-n32"; 1907 } 1908 1909 virtual void getTargetDefines(const LangOptions &Opts, 1910 MacroBuilder &Builder) const { 1911 DefineStd(Builder, "tce", Opts); 1912 Builder.defineMacro("__TCE__"); 1913 Builder.defineMacro("__TCE_V1__"); 1914 } 1915 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1916 unsigned &NumRecords) const {} 1917 virtual const char *getClobbers() const { 1918 return ""; 1919 } 1920 virtual const char *getVAListDeclaration() const { 1921 return "typedef void* __builtin_va_list;"; 1922 } 1923 virtual void getGCCRegNames(const char * const *&Names, 1924 unsigned &NumNames) const {} 1925 virtual bool validateAsmConstraint(const char *&Name, 1926 TargetInfo::ConstraintInfo &info) const { 1927 return true; 1928 } 1929 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1930 unsigned &NumAliases) const {} 1931 }; 1932} 1933 1934namespace { 1935class MipsTargetInfo : public TargetInfo { 1936 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1937 static const char * const GCCRegNames[]; 1938public: 1939 MipsTargetInfo(const std::string& triple) : TargetInfo(triple) { 1940 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 1941 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32"; 1942 } 1943 virtual void getTargetDefines(const LangOptions &Opts, 1944 MacroBuilder &Builder) const { 1945 DefineStd(Builder, "mips", Opts); 1946 Builder.defineMacro("_mips"); 1947 DefineStd(Builder, "MIPSEB", Opts); 1948 Builder.defineMacro("_MIPSEB"); 1949 Builder.defineMacro("__REGISTER_PREFIX__", ""); 1950 } 1951 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1952 unsigned &NumRecords) const { 1953 // FIXME: Implement! 1954 } 1955 virtual const char *getVAListDeclaration() const { 1956 return "typedef void* __builtin_va_list;"; 1957 } 1958 virtual void getGCCRegNames(const char * const *&Names, 1959 unsigned &NumNames) const; 1960 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1961 unsigned &NumAliases) const; 1962 virtual bool validateAsmConstraint(const char *&Name, 1963 TargetInfo::ConstraintInfo &Info) const { 1964 switch (*Name) { 1965 default: 1966 case 'r': // CPU registers. 1967 case 'd': // Equivalent to "r" unless generating MIPS16 code. 1968 case 'y': // Equivalent to "r", backwards compatibility only. 1969 case 'f': // floating-point registers. 1970 Info.setAllowsRegister(); 1971 return true; 1972 } 1973 return false; 1974 } 1975 1976 virtual const char *getClobbers() const { 1977 // FIXME: Implement! 1978 return ""; 1979 } 1980}; 1981 1982const char * const MipsTargetInfo::GCCRegNames[] = { 1983 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 1984 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 1985 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 1986 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31", 1987 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", 1988 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", 1989 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", 1990 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", 1991 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", 1992 "$fcc5","$fcc6","$fcc7" 1993}; 1994 1995void MipsTargetInfo::getGCCRegNames(const char * const *&Names, 1996 unsigned &NumNames) const { 1997 Names = GCCRegNames; 1998 NumNames = llvm::array_lengthof(GCCRegNames); 1999} 2000 2001const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = { 2002 { { "at" }, "$1" }, 2003 { { "v0" }, "$2" }, 2004 { { "v1" }, "$3" }, 2005 { { "a0" }, "$4" }, 2006 { { "a1" }, "$5" }, 2007 { { "a2" }, "$6" }, 2008 { { "a3" }, "$7" }, 2009 { { "t0" }, "$8" }, 2010 { { "t1" }, "$9" }, 2011 { { "t2" }, "$10" }, 2012 { { "t3" }, "$11" }, 2013 { { "t4" }, "$12" }, 2014 { { "t5" }, "$13" }, 2015 { { "t6" }, "$14" }, 2016 { { "t7" }, "$15" }, 2017 { { "s0" }, "$16" }, 2018 { { "s1" }, "$17" }, 2019 { { "s2" }, "$18" }, 2020 { { "s3" }, "$19" }, 2021 { { "s4" }, "$20" }, 2022 { { "s5" }, "$21" }, 2023 { { "s6" }, "$22" }, 2024 { { "s7" }, "$23" }, 2025 { { "t8" }, "$24" }, 2026 { { "t9" }, "$25" }, 2027 { { "k0" }, "$26" }, 2028 { { "k1" }, "$27" }, 2029 { { "gp" }, "$28" }, 2030 { { "sp" }, "$29" }, 2031 { { "fp" }, "$30" }, 2032 { { "ra" }, "$31" } 2033}; 2034 2035void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 2036 unsigned &NumAliases) const { 2037 Aliases = GCCRegAliases; 2038 NumAliases = llvm::array_lengthof(GCCRegAliases); 2039} 2040} // end anonymous namespace. 2041 2042namespace { 2043class MipselTargetInfo : public MipsTargetInfo { 2044public: 2045 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) { 2046 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 2047 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32"; 2048 } 2049 2050 virtual void getTargetDefines(const LangOptions &Opts, 2051 MacroBuilder &Builder) const; 2052}; 2053 2054void MipselTargetInfo::getTargetDefines(const LangOptions &Opts, 2055 MacroBuilder &Builder) const { 2056 DefineStd(Builder, "mips", Opts); 2057 Builder.defineMacro("_mips"); 2058 DefineStd(Builder, "MIPSEL", Opts); 2059 Builder.defineMacro("_MIPSEL"); 2060 Builder.defineMacro("__REGISTER_PREFIX__", ""); 2061} 2062} // end anonymous namespace. 2063 2064//===----------------------------------------------------------------------===// 2065// Driver code 2066//===----------------------------------------------------------------------===// 2067 2068static TargetInfo *AllocateTarget(const std::string &T) { 2069 llvm::Triple Triple(T); 2070 llvm::Triple::OSType os = Triple.getOS(); 2071 2072 switch (Triple.getArch()) { 2073 default: 2074 return NULL; 2075 2076 case llvm::Triple::arm: 2077 case llvm::Triple::thumb: 2078 switch (os) { 2079 case llvm::Triple::Darwin: 2080 return new DarwinARMTargetInfo(T); 2081 case llvm::Triple::FreeBSD: 2082 return new FreeBSDTargetInfo<ARMTargetInfo>(T); 2083 default: 2084 return new ARMTargetInfo(T); 2085 } 2086 2087 case llvm::Triple::bfin: 2088 return new BlackfinTargetInfo(T); 2089 2090 case llvm::Triple::msp430: 2091 return new MSP430TargetInfo(T); 2092 2093 case llvm::Triple::mips: 2094 if (os == llvm::Triple::Psp) 2095 return new PSPTargetInfo<MipsTargetInfo>(T); 2096 if (os == llvm::Triple::Linux) 2097 return new LinuxTargetInfo<MipsTargetInfo>(T); 2098 return new MipsTargetInfo(T); 2099 2100 case llvm::Triple::mipsel: 2101 if (os == llvm::Triple::Psp) 2102 return new PSPTargetInfo<MipselTargetInfo>(T); 2103 if (os == llvm::Triple::Linux) 2104 return new LinuxTargetInfo<MipselTargetInfo>(T); 2105 return new MipselTargetInfo(T); 2106 2107 case llvm::Triple::pic16: 2108 return new PIC16TargetInfo(T); 2109 2110 case llvm::Triple::ppc: 2111 if (os == llvm::Triple::Darwin) 2112 return new DarwinTargetInfo<PPCTargetInfo>(T); 2113 return new PPC32TargetInfo(T); 2114 2115 case llvm::Triple::ppc64: 2116 if (os == llvm::Triple::Darwin) 2117 return new DarwinTargetInfo<PPC64TargetInfo>(T); 2118 else if (os == llvm::Triple::Lv2) 2119 return new PS3PPUTargetInfo<PPC64TargetInfo>(T); 2120 return new PPC64TargetInfo(T); 2121 2122 case llvm::Triple::sparc: 2123 if (os == llvm::Triple::AuroraUX) 2124 return new AuroraUXSparcV8TargetInfo(T); 2125 if (os == llvm::Triple::Solaris) 2126 return new SolarisSparcV8TargetInfo(T); 2127 return new SparcV8TargetInfo(T); 2128 2129 // FIXME: Need a real SPU target. 2130 case llvm::Triple::cellspu: 2131 return new PS3SPUTargetInfo<PPC64TargetInfo>(T); 2132 2133 case llvm::Triple::systemz: 2134 return new SystemZTargetInfo(T); 2135 2136 case llvm::Triple::tce: 2137 return new TCETargetInfo(T); 2138 2139 case llvm::Triple::x86: 2140 switch (os) { 2141 case llvm::Triple::AuroraUX: 2142 return new AuroraUXTargetInfo<X86_32TargetInfo>(T); 2143 case llvm::Triple::Darwin: 2144 return new DarwinI386TargetInfo(T); 2145 case llvm::Triple::Linux: 2146 return new LinuxTargetInfo<X86_32TargetInfo>(T); 2147 case llvm::Triple::DragonFly: 2148 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T); 2149 case llvm::Triple::NetBSD: 2150 return new NetBSDTargetInfo<X86_32TargetInfo>(T); 2151 case llvm::Triple::OpenBSD: 2152 return new OpenBSDI386TargetInfo(T); 2153 case llvm::Triple::FreeBSD: 2154 return new FreeBSDTargetInfo<X86_32TargetInfo>(T); 2155 case llvm::Triple::Solaris: 2156 return new SolarisTargetInfo<X86_32TargetInfo>(T); 2157 case llvm::Triple::Cygwin: 2158 return new CygwinX86_32TargetInfo(T); 2159 case llvm::Triple::MinGW32: 2160 return new MinGWX86_32TargetInfo(T); 2161 case llvm::Triple::Win32: 2162 return new VisualStudioWindowsX86_32TargetInfo(T); 2163 default: 2164 return new X86_32TargetInfo(T); 2165 } 2166 2167 case llvm::Triple::x86_64: 2168 switch (os) { 2169 case llvm::Triple::AuroraUX: 2170 return new AuroraUXTargetInfo<X86_64TargetInfo>(T); 2171 case llvm::Triple::Darwin: 2172 return new DarwinX86_64TargetInfo(T); 2173 case llvm::Triple::Linux: 2174 return new LinuxTargetInfo<X86_64TargetInfo>(T); 2175 case llvm::Triple::DragonFly: 2176 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T); 2177 case llvm::Triple::NetBSD: 2178 return new NetBSDTargetInfo<X86_64TargetInfo>(T); 2179 case llvm::Triple::OpenBSD: 2180 return new OpenBSDX86_64TargetInfo(T); 2181 case llvm::Triple::FreeBSD: 2182 return new FreeBSDTargetInfo<X86_64TargetInfo>(T); 2183 case llvm::Triple::Solaris: 2184 return new SolarisTargetInfo<X86_64TargetInfo>(T); 2185 case llvm::Triple::MinGW64: 2186 return new MinGWX86_64TargetInfo(T); 2187 case llvm::Triple::Win32: // This is what Triple.h supports now. 2188 return new VisualStudioWindowsX86_64TargetInfo(T); 2189 default: 2190 return new X86_64TargetInfo(T); 2191 } 2192 } 2193} 2194 2195/// CreateTargetInfo - Return the target info object for the specified target 2196/// triple. 2197TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags, 2198 TargetOptions &Opts) { 2199 llvm::Triple Triple(Opts.Triple); 2200 2201 // Construct the target 2202 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str())); 2203 if (!Target) { 2204 Diags.Report(diag::err_target_unknown_triple) << Triple.str(); 2205 return 0; 2206 } 2207 2208 // Set the target CPU if specified. 2209 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) { 2210 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU; 2211 return 0; 2212 } 2213 2214 // Set the target ABI if specified. 2215 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) { 2216 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI; 2217 return 0; 2218 } 2219 2220 // Compute the default target features, we need the target to handle this 2221 // because features may have dependencies on one another. 2222 llvm::StringMap<bool> Features; 2223 Target->getDefaultFeatures(Opts.CPU, Features); 2224 2225 // Apply the user specified deltas. 2226 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(), 2227 ie = Opts.Features.end(); it != ie; ++it) { 2228 const char *Name = it->c_str(); 2229 2230 // Apply the feature via the target. 2231 if ((Name[0] != '-' && Name[0] != '+') || 2232 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) { 2233 Diags.Report(diag::err_target_invalid_feature) << Name; 2234 return 0; 2235 } 2236 } 2237 2238 // Add the features to the compile options. 2239 // 2240 // FIXME: If we are completely confident that we have the right set, we only 2241 // need to pass the minuses. 2242 Opts.Features.clear(); 2243 for (llvm::StringMap<bool>::const_iterator it = Features.begin(), 2244 ie = Features.end(); it != ie; ++it) 2245 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first()); 2246 Target->HandleTargetFeatures(Opts.Features); 2247 2248 return Target.take(); 2249} 2250