Targets.cpp revision eab96a269b9c8192426790b9fd0af0d03ea2b6b4
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; 640public: 641 X86TargetInfo(const std::string& triple) 642 : TargetInfo(triple), SSELevel(NoMMXSSE) { 643 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; 644 } 645 virtual void getTargetBuiltins(const Builtin::Info *&Records, 646 unsigned &NumRecords) const { 647 Records = BuiltinInfo; 648 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin; 649 } 650 virtual void getGCCRegNames(const char * const *&Names, 651 unsigned &NumNames) const { 652 Names = GCCRegNames; 653 NumNames = llvm::array_lengthof(GCCRegNames); 654 } 655 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 656 unsigned &NumAliases) const { 657 Aliases = GCCRegAliases; 658 NumAliases = llvm::array_lengthof(GCCRegAliases); 659 } 660 virtual bool validateAsmConstraint(const char *&Name, 661 TargetInfo::ConstraintInfo &info) const; 662 virtual std::string convertConstraint(const char Constraint) const; 663 virtual const char *getClobbers() const { 664 return "~{dirflag},~{fpsr},~{flags}"; 665 } 666 virtual void getTargetDefines(const LangOptions &Opts, 667 MacroBuilder &Builder) const; 668 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 669 const std::string &Name, 670 bool Enabled) const; 671 virtual void getDefaultFeatures(const std::string &CPU, 672 llvm::StringMap<bool> &Features) const; 673 virtual void HandleTargetFeatures(std::vector<std::string> &Features); 674}; 675 676void X86TargetInfo::getDefaultFeatures(const std::string &CPU, 677 llvm::StringMap<bool> &Features) const { 678 // FIXME: This should not be here. 679 Features["3dnow"] = false; 680 Features["3dnowa"] = false; 681 Features["mmx"] = false; 682 Features["sse"] = false; 683 Features["sse2"] = false; 684 Features["sse3"] = false; 685 Features["ssse3"] = false; 686 Features["sse41"] = false; 687 Features["sse42"] = false; 688 689 // LLVM does not currently recognize this. 690 // Features["sse4a"] = false; 691 692 // FIXME: This *really* should not be here. 693 694 // X86_64 always has SSE2. 695 if (PointerWidth == 64) 696 Features["sse2"] = Features["sse"] = Features["mmx"] = true; 697 698 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" || 699 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro") 700 ; 701 else if (CPU == "pentium-mmx" || CPU == "pentium2") 702 setFeatureEnabled(Features, "mmx", true); 703 else if (CPU == "pentium3") 704 setFeatureEnabled(Features, "sse", true); 705 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64") 706 setFeatureEnabled(Features, "sse2", true); 707 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona") 708 setFeatureEnabled(Features, "sse3", true); 709 else if (CPU == "core2") 710 setFeatureEnabled(Features, "ssse3", true); 711 else if (CPU == "penryn") { 712 setFeatureEnabled(Features, "sse4", true); 713 Features["sse42"] = false; 714 } else if (CPU == "atom") 715 setFeatureEnabled(Features, "sse3", true); 716 else if (CPU == "corei7") 717 setFeatureEnabled(Features, "sse4", true); 718 else if (CPU == "k6" || CPU == "winchip-c6") 719 setFeatureEnabled(Features, "mmx", true); 720 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" || 721 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") { 722 setFeatureEnabled(Features, "mmx", true); 723 setFeatureEnabled(Features, "3dnow", true); 724 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") { 725 setFeatureEnabled(Features, "sse", true); 726 setFeatureEnabled(Features, "3dnowa", true); 727 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" || 728 CPU == "athlon-fx") { 729 setFeatureEnabled(Features, "sse2", true); 730 setFeatureEnabled(Features, "3dnowa", true); 731 } else if (CPU == "c3-2") 732 setFeatureEnabled(Features, "sse", true); 733} 734 735bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, 736 const std::string &Name, 737 bool Enabled) const { 738 // FIXME: This *really* should not be here. 739 if (!Features.count(Name) && Name != "sse4") 740 return false; 741 742 if (Enabled) { 743 if (Name == "mmx") 744 Features["mmx"] = true; 745 else if (Name == "sse") 746 Features["mmx"] = Features["sse"] = true; 747 else if (Name == "sse2") 748 Features["mmx"] = Features["sse"] = Features["sse2"] = true; 749 else if (Name == "sse3") 750 Features["mmx"] = Features["sse"] = Features["sse2"] = 751 Features["sse3"] = true; 752 else if (Name == "ssse3") 753 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 754 Features["ssse3"] = true; 755 else if (Name == "sse4") 756 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 757 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true; 758 else if (Name == "3dnow") 759 Features["3dnowa"] = true; 760 else if (Name == "3dnowa") 761 Features["3dnow"] = Features["3dnowa"] = true; 762 } else { 763 if (Name == "mmx") 764 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 765 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; 766 else if (Name == "sse") 767 Features["sse"] = Features["sse2"] = Features["sse3"] = 768 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; 769 else if (Name == "sse2") 770 Features["sse2"] = Features["sse3"] = Features["ssse3"] = 771 Features["sse41"] = Features["sse42"] = false; 772 else if (Name == "sse3") 773 Features["sse3"] = Features["ssse3"] = Features["sse41"] = 774 Features["sse42"] = false; 775 else if (Name == "ssse3") 776 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false; 777 else if (Name == "sse4") 778 Features["sse41"] = Features["sse42"] = false; 779 else if (Name == "3dnow") 780 Features["3dnow"] = Features["3dnowa"] = false; 781 else if (Name == "3dnowa") 782 Features["3dnowa"] = false; 783 } 784 785 return true; 786} 787 788/// HandleTargetOptions - Perform initialization based on the user 789/// configured set of features. 790void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { 791 // Remember the maximum enabled sselevel. 792 for (unsigned i = 0, e = Features.size(); i !=e; ++i) { 793 // Ignore disabled features. 794 if (Features[i][0] == '-') 795 continue; 796 797 assert(Features[i][0] == '+' && "Invalid target feature!"); 798 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1)) 799 .Case("sse42", SSE42) 800 .Case("sse41", SSE41) 801 .Case("ssse3", SSSE3) 802 .Case("sse2", SSE2) 803 .Case("sse", SSE1) 804 .Case("mmx", MMX) 805 .Default(NoMMXSSE); 806 SSELevel = std::max(SSELevel, Level); 807 } 808} 809 810/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines 811/// that are not tied to a specific subtarget. 812void X86TargetInfo::getTargetDefines(const LangOptions &Opts, 813 MacroBuilder &Builder) const { 814 // Target identification. 815 if (PointerWidth == 64) { 816 Builder.defineMacro("_LP64"); 817 Builder.defineMacro("__LP64__"); 818 Builder.defineMacro("__amd64__"); 819 Builder.defineMacro("__amd64"); 820 Builder.defineMacro("__x86_64"); 821 Builder.defineMacro("__x86_64__"); 822 } else { 823 DefineStd(Builder, "i386", Opts); 824 } 825 826 // Target properties. 827 Builder.defineMacro("__LITTLE_ENDIAN__"); 828 829 // Subtarget options. 830 Builder.defineMacro("__nocona"); 831 Builder.defineMacro("__nocona__"); 832 Builder.defineMacro("__tune_nocona__"); 833 Builder.defineMacro("__REGISTER_PREFIX__", ""); 834 835 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline 836 // functions in glibc header files that use FP Stack inline asm which the 837 // backend can't deal with (PR879). 838 Builder.defineMacro("__NO_MATH_INLINES"); 839 840 // Each case falls through to the previous one here. 841 switch (SSELevel) { 842 case SSE42: 843 Builder.defineMacro("__SSE4_2__"); 844 case SSE41: 845 Builder.defineMacro("__SSE4_1__"); 846 case SSSE3: 847 Builder.defineMacro("__SSSE3__"); 848 case SSE3: 849 Builder.defineMacro("__SSE3__"); 850 case SSE2: 851 Builder.defineMacro("__SSE2__"); 852 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied. 853 case SSE1: 854 Builder.defineMacro("__SSE__"); 855 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied. 856 case MMX: 857 Builder.defineMacro("__MMX__"); 858 case NoMMXSSE: 859 break; 860 } 861} 862 863 864bool 865X86TargetInfo::validateAsmConstraint(const char *&Name, 866 TargetInfo::ConstraintInfo &Info) const { 867 switch (*Name) { 868 default: return false; 869 case 'a': // eax. 870 case 'b': // ebx. 871 case 'c': // ecx. 872 case 'd': // edx. 873 case 'S': // esi. 874 case 'D': // edi. 875 case 'A': // edx:eax. 876 case 't': // top of floating point stack. 877 case 'u': // second from top of floating point stack. 878 case 'q': // Any register accessible as [r]l: a, b, c, and d. 879 case 'y': // Any MMX register. 880 case 'x': // Any SSE register. 881 case 'Q': // Any register accessible as [r]h: a, b, c, and d. 882 case 'e': // 32-bit signed integer constant for use with zero-extending 883 // x86_64 instructions. 884 case 'Z': // 32-bit unsigned integer constant for use with zero-extending 885 // x86_64 instructions. 886 case 'N': // unsigned 8-bit integer constant for use with in and out 887 // instructions. 888 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp. 889 Info.setAllowsRegister(); 890 return true; 891 } 892} 893 894std::string 895X86TargetInfo::convertConstraint(const char Constraint) const { 896 switch (Constraint) { 897 case 'a': return std::string("{ax}"); 898 case 'b': return std::string("{bx}"); 899 case 'c': return std::string("{cx}"); 900 case 'd': return std::string("{dx}"); 901 case 'S': return std::string("{si}"); 902 case 'D': return std::string("{di}"); 903 case 't': // top of floating point stack. 904 return std::string("{st}"); 905 case 'u': // second from top of floating point stack. 906 return std::string("{st(1)}"); // second from top of floating point stack. 907 default: 908 return std::string(1, Constraint); 909 } 910} 911} // end anonymous namespace 912 913namespace { 914// X86-32 generic target 915class X86_32TargetInfo : public X86TargetInfo { 916public: 917 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) { 918 DoubleAlign = LongLongAlign = 32; 919 LongDoubleWidth = 96; 920 LongDoubleAlign = 32; 921 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 922 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 923 "a0:0:64-f80:32:32-n8:16:32"; 924 SizeType = UnsignedInt; 925 PtrDiffType = SignedInt; 926 IntPtrType = SignedInt; 927 RegParmMax = 3; 928 } 929 virtual const char *getVAListDeclaration() const { 930 return "typedef char* __builtin_va_list;"; 931 } 932 933 int getEHDataRegisterNumber(unsigned RegNo) const { 934 if (RegNo == 0) return 0; 935 if (RegNo == 1) return 2; 936 return -1; 937 } 938}; 939} // end anonymous namespace 940 941namespace { 942class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> { 943public: 944 OpenBSDI386TargetInfo(const std::string& triple) : 945 OpenBSDTargetInfo<X86_32TargetInfo>(triple) { 946 SizeType = UnsignedLong; 947 IntPtrType = SignedLong; 948 PtrDiffType = SignedLong; 949 } 950}; 951} // end anonymous namespace 952 953namespace { 954class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> { 955public: 956 DarwinI386TargetInfo(const std::string& triple) : 957 DarwinTargetInfo<X86_32TargetInfo>(triple) { 958 LongDoubleWidth = 128; 959 LongDoubleAlign = 128; 960 SizeType = UnsignedLong; 961 IntPtrType = SignedLong; 962 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 963 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 964 "a0:0:64-f80:128:128-n8:16:32"; 965 } 966 967}; 968} // end anonymous namespace 969 970namespace { 971// x86-32 Windows target 972class WindowsX86_32TargetInfo : public X86_32TargetInfo { 973public: 974 WindowsX86_32TargetInfo(const std::string& triple) 975 : X86_32TargetInfo(triple) { 976 TLSSupported = false; 977 WCharType = UnsignedShort; 978 DoubleAlign = LongLongAlign = 64; 979 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 980 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-" 981 "v128:128:128-a0:0:64-f80:32:32-n8:16:32"; 982 } 983 virtual void getTargetDefines(const LangOptions &Opts, 984 MacroBuilder &Builder) const { 985 X86_32TargetInfo::getTargetDefines(Opts, Builder); 986 // This list is based off of the the list of things MingW defines 987 Builder.defineMacro("_WIN32"); 988 DefineStd(Builder, "WIN32", Opts); 989 DefineStd(Builder, "WINNT", Opts); 990 Builder.defineMacro("_X86_"); 991 } 992}; 993} // end anonymous namespace 994 995namespace { 996 997// x86-32 Windows Visual Studio target 998class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo { 999public: 1000 VisualStudioWindowsX86_32TargetInfo(const std::string& triple) 1001 : WindowsX86_32TargetInfo(triple) { 1002 } 1003 virtual void getTargetDefines(const LangOptions &Opts, 1004 MacroBuilder &Builder) const { 1005 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); 1006 // The value of the following reflects processor type. 1007 // 300=386, 400=486, 500=Pentium, 600=Blend (default) 1008 // We lost the original triple, so we use the default. 1009 Builder.defineMacro("_M_IX86", "600"); 1010 } 1011}; 1012} // end anonymous namespace 1013 1014namespace { 1015// x86-32 MinGW target 1016class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo { 1017public: 1018 MinGWX86_32TargetInfo(const std::string& triple) 1019 : WindowsX86_32TargetInfo(triple) { 1020 } 1021 virtual void getTargetDefines(const LangOptions &Opts, 1022 MacroBuilder &Builder) const { 1023 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); 1024 Builder.defineMacro("__MSVCRT__"); 1025 Builder.defineMacro("__MINGW32__"); 1026 Builder.defineMacro("__declspec", "__declspec"); 1027 } 1028}; 1029} // end anonymous namespace 1030 1031namespace { 1032// x86-32 Cygwin target 1033class CygwinX86_32TargetInfo : public X86_32TargetInfo { 1034public: 1035 CygwinX86_32TargetInfo(const std::string& triple) 1036 : X86_32TargetInfo(triple) { 1037 TLSSupported = false; 1038 WCharType = UnsignedShort; 1039 DoubleAlign = LongLongAlign = 64; 1040 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1041 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 1042 "a0:0:64-f80:32:32-n8:16:32"; 1043 } 1044 virtual void getTargetDefines(const LangOptions &Opts, 1045 MacroBuilder &Builder) const { 1046 X86_32TargetInfo::getTargetDefines(Opts, Builder); 1047 Builder.defineMacro("__CYGWIN__"); 1048 Builder.defineMacro("__CYGWIN32__"); 1049 DefineStd(Builder, "unix", Opts); 1050 } 1051}; 1052} // end anonymous namespace 1053 1054namespace { 1055// x86-64 generic target 1056class X86_64TargetInfo : public X86TargetInfo { 1057public: 1058 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) { 1059 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 1060 LongDoubleWidth = 128; 1061 LongDoubleAlign = 128; 1062 IntMaxType = SignedLong; 1063 UIntMaxType = UnsignedLong; 1064 Int64Type = SignedLong; 1065 RegParmMax = 6; 1066 1067 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1068 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 1069 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"; 1070 } 1071 virtual const char *getVAListDeclaration() const { 1072 return "typedef struct __va_list_tag {" 1073 " unsigned gp_offset;" 1074 " unsigned fp_offset;" 1075 " void* overflow_arg_area;" 1076 " void* reg_save_area;" 1077 "} __va_list_tag;" 1078 "typedef __va_list_tag __builtin_va_list[1];"; 1079 } 1080 1081 int getEHDataRegisterNumber(unsigned RegNo) const { 1082 if (RegNo == 0) return 0; 1083 if (RegNo == 1) return 1; 1084 return -1; 1085 } 1086}; 1087} // end anonymous namespace 1088 1089namespace { 1090// x86-64 Windows target 1091class WindowsX86_64TargetInfo : public X86_64TargetInfo { 1092public: 1093 WindowsX86_64TargetInfo(const std::string& triple) 1094 : X86_64TargetInfo(triple) { 1095 TLSSupported = false; 1096 WCharType = UnsignedShort; 1097 LongWidth = LongAlign = 32; 1098 DoubleAlign = LongLongAlign = 64; 1099 } 1100 virtual void getTargetDefines(const LangOptions &Opts, 1101 MacroBuilder &Builder) const { 1102 X86_64TargetInfo::getTargetDefines(Opts, Builder); 1103 Builder.defineMacro("_WIN64"); 1104 DefineStd(Builder, "WIN64", Opts); 1105 } 1106}; 1107} // end anonymous namespace 1108 1109namespace { 1110// x86-64 Windows Visual Studio target 1111class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo { 1112public: 1113 VisualStudioWindowsX86_64TargetInfo(const std::string& triple) 1114 : WindowsX86_64TargetInfo(triple) { 1115 } 1116 virtual void getTargetDefines(const LangOptions &Opts, 1117 MacroBuilder &Builder) const { 1118 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder); 1119 Builder.defineMacro("_M_X64"); 1120 } 1121 virtual const char *getVAListDeclaration() const { 1122 return "typedef char* va_list;"; 1123 } 1124}; 1125} // end anonymous namespace 1126 1127namespace { 1128// x86-64 MinGW target 1129class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo { 1130public: 1131 MinGWX86_64TargetInfo(const std::string& triple) 1132 : WindowsX86_64TargetInfo(triple) { 1133 } 1134 virtual void getTargetDefines(const LangOptions &Opts, 1135 MacroBuilder &Builder) const { 1136 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder); 1137 Builder.defineMacro("__MSVCRT__"); 1138 Builder.defineMacro("__MINGW64__"); 1139 Builder.defineMacro("__declspec"); 1140 } 1141}; 1142} // end anonymous namespace 1143 1144namespace { 1145class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> { 1146public: 1147 DarwinX86_64TargetInfo(const std::string& triple) 1148 : DarwinTargetInfo<X86_64TargetInfo>(triple) { 1149 Int64Type = SignedLongLong; 1150 } 1151}; 1152} // end anonymous namespace 1153 1154namespace { 1155class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> { 1156public: 1157 OpenBSDX86_64TargetInfo(const std::string& triple) 1158 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) { 1159 IntMaxType = SignedLongLong; 1160 UIntMaxType = UnsignedLongLong; 1161 Int64Type = SignedLongLong; 1162 } 1163}; 1164} // end anonymous namespace 1165 1166namespace { 1167class ARMTargetInfo : public TargetInfo { 1168 // Possible FPU choices. 1169 enum FPUMode { 1170 NoFPU, 1171 VFP2FPU, 1172 VFP3FPU, 1173 NeonFPU 1174 }; 1175 1176 static bool FPUModeIsVFP(FPUMode Mode) { 1177 return Mode >= VFP2FPU && Mode <= NeonFPU; 1178 } 1179 1180 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1181 static const char * const GCCRegNames[]; 1182 1183 std::string ABI, CPU; 1184 1185 unsigned FPU : 3; 1186 1187 unsigned IsThumb : 1; 1188 1189 // Initialized via features. 1190 unsigned SoftFloat : 1; 1191 unsigned SoftFloatABI : 1; 1192 1193public: 1194 ARMTargetInfo(const std::string &TripleStr) 1195 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s") 1196 { 1197 SizeType = UnsignedInt; 1198 PtrDiffType = SignedInt; 1199 1200 // FIXME: Should we just treat this as a feature? 1201 IsThumb = getTriple().getArchName().startswith("thumb"); 1202 if (IsThumb) { 1203 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" 1204 "i64:64:64-f32:32:32-f64:64:64-" 1205 "v64:64:64-v128:128:128-a0:0:32-n32"); 1206 } else { 1207 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1208 "i64:64:64-f32:32:32-f64:64:64-" 1209 "v64:64:64-v128:128:128-a0:0:64-n32"); 1210 } 1211 } 1212 virtual const char *getABI() const { return ABI.c_str(); } 1213 virtual bool setABI(const std::string &Name) { 1214 ABI = Name; 1215 1216 // The defaults (above) are for AAPCS, check if we need to change them. 1217 // 1218 // FIXME: We need support for -meabi... we could just mangle it into the 1219 // name. 1220 if (Name == "apcs-gnu") { 1221 DoubleAlign = LongLongAlign = 32; 1222 SizeType = UnsignedLong; 1223 1224 if (IsThumb) { 1225 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" 1226 "i64:32:32-f32:32:32-f64:32:32-" 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:32:32-f32:32:32-f64:32:32-" 1231 "v64:64:64-v128:128:128-a0:0:64-n32"); 1232 } 1233 1234 // FIXME: Override "preferred align" for double and long long. 1235 } else if (Name == "aapcs") { 1236 // FIXME: Enumerated types are variable width in straight AAPCS. 1237 } else if (Name == "aapcs-linux") { 1238 ; 1239 } else 1240 return false; 1241 1242 return true; 1243 } 1244 1245 void getDefaultFeatures(const std::string &CPU, 1246 llvm::StringMap<bool> &Features) const { 1247 // FIXME: This should not be here. 1248 Features["vfp2"] = false; 1249 Features["vfp3"] = false; 1250 Features["neon"] = false; 1251 1252 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore") 1253 Features["vfp2"] = true; 1254 else if (CPU == "cortex-a8" || CPU == "cortex-a9") 1255 Features["neon"] = true; 1256 } 1257 1258 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 1259 const std::string &Name, 1260 bool Enabled) const { 1261 if (Name == "soft-float" || Name == "soft-float-abi") { 1262 Features[Name] = Enabled; 1263 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") { 1264 // These effectively are a single option, reset them when any is enabled. 1265 if (Enabled) 1266 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false; 1267 Features[Name] = Enabled; 1268 } else 1269 return false; 1270 1271 return true; 1272 } 1273 1274 virtual void HandleTargetFeatures(std::vector<std::string> &Features) { 1275 FPU = NoFPU; 1276 SoftFloat = SoftFloatABI = false; 1277 for (unsigned i = 0, e = Features.size(); i != e; ++i) { 1278 if (Features[i] == "+soft-float") 1279 SoftFloat = true; 1280 else if (Features[i] == "+soft-float-abi") 1281 SoftFloatABI = true; 1282 else if (Features[i] == "+vfp2") 1283 FPU = VFP2FPU; 1284 else if (Features[i] == "+vfp3") 1285 FPU = VFP3FPU; 1286 else if (Features[i] == "+neon") 1287 FPU = NeonFPU; 1288 } 1289 1290 // Remove front-end specific options which the backend handles differently. 1291 std::vector<std::string>::iterator it; 1292 it = std::find(Features.begin(), Features.end(), "+soft-float"); 1293 if (it != Features.end()) 1294 Features.erase(it); 1295 it = std::find(Features.begin(), Features.end(), "+soft-float-abi"); 1296 if (it != Features.end()) 1297 Features.erase(it); 1298 } 1299 1300 static const char *getCPUDefineSuffix(llvm::StringRef Name) { 1301 return llvm::StringSwitch<const char*>(Name) 1302 .Cases("arm8", "arm810", "4") 1303 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4") 1304 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T") 1305 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T") 1306 .Case("ep9312", "4T") 1307 .Cases("arm10tdmi", "arm1020t", "5T") 1308 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE") 1309 .Case("arm926ej-s", "5TEJ") 1310 .Cases("arm10e", "arm1020e", "arm1022e", "5TE") 1311 .Cases("xscale", "iwmmxt", "5TE") 1312 .Case("arm1136j-s", "6J") 1313 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK") 1314 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K") 1315 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2") 1316 .Cases("cortex-a8", "cortex-a9", "7A") 1317 .Default(0); 1318 } 1319 virtual bool setCPU(const std::string &Name) { 1320 if (!getCPUDefineSuffix(Name)) 1321 return false; 1322 1323 CPU = Name; 1324 return true; 1325 } 1326 virtual void getTargetDefines(const LangOptions &Opts, 1327 MacroBuilder &Builder) const { 1328 // Target identification. 1329 Builder.defineMacro("__arm"); 1330 Builder.defineMacro("__arm__"); 1331 1332 // Target properties. 1333 Builder.defineMacro("__ARMEL__"); 1334 Builder.defineMacro("__LITTLE_ENDIAN__"); 1335 Builder.defineMacro("__REGISTER_PREFIX__", ""); 1336 1337 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU); 1338 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__"); 1339 1340 // Subtarget options. 1341 1342 // FIXME: It's more complicated than this and we don't really support 1343 // interworking. 1344 if ('5' <= CPUArch[0] && CPUArch[0] <= '7') 1345 Builder.defineMacro("__THUMB_INTERWORK__"); 1346 1347 if (ABI == "aapcs" || ABI == "aapcs-linux") 1348 Builder.defineMacro("__ARM_EABI__"); 1349 1350 if (SoftFloat) 1351 Builder.defineMacro("__SOFTFP__"); 1352 1353 if (CPU == "xscale") 1354 Builder.defineMacro("__XSCALE__"); 1355 1356 bool IsThumb2 = IsThumb && (CPUArch == "6T2" || CPUArch.startswith("7")); 1357 if (IsThumb) { 1358 Builder.defineMacro("__THUMBEL__"); 1359 Builder.defineMacro("__thumb__"); 1360 if (IsThumb2) 1361 Builder.defineMacro("__thumb2__"); 1362 } 1363 1364 // Note, this is always on in gcc, even though it doesn't make sense. 1365 Builder.defineMacro("__APCS_32__"); 1366 1367 if (FPUModeIsVFP((FPUMode) FPU)) 1368 Builder.defineMacro("__VFP_FP__"); 1369 1370 // This only gets set when Neon instructions are actually available, unlike 1371 // the VFP define, hence the soft float and arch check. This is subtly 1372 // different from gcc, we follow the intent which was that it should be set 1373 // when Neon instructions are actually available. 1374 if (FPU == NeonFPU && !SoftFloat && IsThumb2) 1375 Builder.defineMacro("__ARM_NEON__"); 1376 1377 if (getTriple().getOS() == llvm::Triple::Darwin) 1378 Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__"); 1379 } 1380 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1381 unsigned &NumRecords) const { 1382 // FIXME: Implement. 1383 Records = 0; 1384 NumRecords = 0; 1385 } 1386 virtual const char *getVAListDeclaration() const { 1387 return "typedef char* __builtin_va_list;"; 1388 } 1389 virtual void getGCCRegNames(const char * const *&Names, 1390 unsigned &NumNames) const; 1391 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1392 unsigned &NumAliases) const; 1393 virtual bool validateAsmConstraint(const char *&Name, 1394 TargetInfo::ConstraintInfo &Info) const { 1395 // FIXME: Check if this is complete 1396 switch (*Name) { 1397 default: 1398 case 'l': // r0-r7 1399 case 'h': // r8-r15 1400 case 'w': // VFP Floating point register single precision 1401 case 'P': // VFP Floating point register double precision 1402 Info.setAllowsRegister(); 1403 return true; 1404 } 1405 return false; 1406 } 1407 virtual const char *getClobbers() const { 1408 // FIXME: Is this really right? 1409 return ""; 1410 } 1411}; 1412 1413const char * const ARMTargetInfo::GCCRegNames[] = { 1414 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1415 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1416}; 1417 1418void ARMTargetInfo::getGCCRegNames(const char * const *&Names, 1419 unsigned &NumNames) const { 1420 Names = GCCRegNames; 1421 NumNames = llvm::array_lengthof(GCCRegNames); 1422} 1423 1424const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 1425 1426 { { "a1" }, "r0" }, 1427 { { "a2" }, "r1" }, 1428 { { "a3" }, "r2" }, 1429 { { "a4" }, "r3" }, 1430 { { "v1" }, "r4" }, 1431 { { "v2" }, "r5" }, 1432 { { "v3" }, "r6" }, 1433 { { "v4" }, "r7" }, 1434 { { "v5" }, "r8" }, 1435 { { "v6", "rfp" }, "r9" }, 1436 { { "sl" }, "r10" }, 1437 { { "fp" }, "r11" }, 1438 { { "ip" }, "r12" }, 1439 { { "sp" }, "r13" }, 1440 { { "lr" }, "r14" }, 1441 { { "pc" }, "r15" }, 1442}; 1443 1444void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1445 unsigned &NumAliases) const { 1446 Aliases = GCCRegAliases; 1447 NumAliases = llvm::array_lengthof(GCCRegAliases); 1448} 1449} // end anonymous namespace. 1450 1451 1452namespace { 1453class DarwinARMTargetInfo : 1454 public DarwinTargetInfo<ARMTargetInfo> { 1455protected: 1456 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 1457 MacroBuilder &Builder) const { 1458 getDarwinDefines(Builder, Opts, Triple); 1459 } 1460 1461public: 1462 DarwinARMTargetInfo(const std::string& triple) 1463 : DarwinTargetInfo<ARMTargetInfo>(triple) {} 1464}; 1465} // end anonymous namespace. 1466 1467namespace { 1468class SparcV8TargetInfo : public TargetInfo { 1469 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1470 static const char * const GCCRegNames[]; 1471public: 1472 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { 1473 // FIXME: Support Sparc quad-precision long double? 1474 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1475 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; 1476 } 1477 virtual void getTargetDefines(const LangOptions &Opts, 1478 MacroBuilder &Builder) const { 1479 DefineStd(Builder, "sparc", Opts); 1480 Builder.defineMacro("__sparcv8"); 1481 Builder.defineMacro("__REGISTER_PREFIX__", ""); 1482 } 1483 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1484 unsigned &NumRecords) const { 1485 // FIXME: Implement! 1486 } 1487 virtual const char *getVAListDeclaration() const { 1488 return "typedef void* __builtin_va_list;"; 1489 } 1490 virtual void getGCCRegNames(const char * const *&Names, 1491 unsigned &NumNames) const; 1492 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1493 unsigned &NumAliases) const; 1494 virtual bool validateAsmConstraint(const char *&Name, 1495 TargetInfo::ConstraintInfo &info) const { 1496 // FIXME: Implement! 1497 return false; 1498 } 1499 virtual const char *getClobbers() const { 1500 // FIXME: Implement! 1501 return ""; 1502 } 1503}; 1504 1505const char * const SparcV8TargetInfo::GCCRegNames[] = { 1506 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1507 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 1508 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 1509 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" 1510}; 1511 1512void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names, 1513 unsigned &NumNames) const { 1514 Names = GCCRegNames; 1515 NumNames = llvm::array_lengthof(GCCRegNames); 1516} 1517 1518const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = { 1519 { { "g0" }, "r0" }, 1520 { { "g1" }, "r1" }, 1521 { { "g2" }, "r2" }, 1522 { { "g3" }, "r3" }, 1523 { { "g4" }, "r4" }, 1524 { { "g5" }, "r5" }, 1525 { { "g6" }, "r6" }, 1526 { { "g7" }, "r7" }, 1527 { { "o0" }, "r8" }, 1528 { { "o1" }, "r9" }, 1529 { { "o2" }, "r10" }, 1530 { { "o3" }, "r11" }, 1531 { { "o4" }, "r12" }, 1532 { { "o5" }, "r13" }, 1533 { { "o6", "sp" }, "r14" }, 1534 { { "o7" }, "r15" }, 1535 { { "l0" }, "r16" }, 1536 { { "l1" }, "r17" }, 1537 { { "l2" }, "r18" }, 1538 { { "l3" }, "r19" }, 1539 { { "l4" }, "r20" }, 1540 { { "l5" }, "r21" }, 1541 { { "l6" }, "r22" }, 1542 { { "l7" }, "r23" }, 1543 { { "i0" }, "r24" }, 1544 { { "i1" }, "r25" }, 1545 { { "i2" }, "r26" }, 1546 { { "i3" }, "r27" }, 1547 { { "i4" }, "r28" }, 1548 { { "i5" }, "r29" }, 1549 { { "i6", "fp" }, "r30" }, 1550 { { "i7" }, "r31" }, 1551}; 1552 1553void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1554 unsigned &NumAliases) const { 1555 Aliases = GCCRegAliases; 1556 NumAliases = llvm::array_lengthof(GCCRegAliases); 1557} 1558} // end anonymous namespace. 1559 1560namespace { 1561class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> { 1562public: 1563 AuroraUXSparcV8TargetInfo(const std::string& triple) : 1564 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) { 1565 SizeType = UnsignedInt; 1566 PtrDiffType = SignedInt; 1567 } 1568}; 1569class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> { 1570public: 1571 SolarisSparcV8TargetInfo(const std::string& triple) : 1572 SolarisTargetInfo<SparcV8TargetInfo>(triple) { 1573 SizeType = UnsignedInt; 1574 PtrDiffType = SignedInt; 1575 } 1576}; 1577} // end anonymous namespace. 1578 1579namespace { 1580 class PIC16TargetInfo : public TargetInfo{ 1581 public: 1582 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) { 1583 TLSSupported = false; 1584 IntWidth = 16; 1585 LongWidth = LongLongWidth = 32; 1586 PointerWidth = 16; 1587 IntAlign = 8; 1588 LongAlign = LongLongAlign = 8; 1589 PointerAlign = 8; 1590 SizeType = UnsignedInt; 1591 IntMaxType = SignedLong; 1592 UIntMaxType = UnsignedLong; 1593 IntPtrType = SignedShort; 1594 PtrDiffType = SignedInt; 1595 SigAtomicType = SignedLong; 1596 FloatWidth = 32; 1597 FloatAlign = 32; 1598 DoubleWidth = 32; 1599 DoubleAlign = 32; 1600 LongDoubleWidth = 32; 1601 LongDoubleAlign = 32; 1602 FloatFormat = &llvm::APFloat::IEEEsingle; 1603 DoubleFormat = &llvm::APFloat::IEEEsingle; 1604 LongDoubleFormat = &llvm::APFloat::IEEEsingle; 1605 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32-n8"; 1606 1607 } 1608 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; } 1609 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; } 1610 virtual void getTargetDefines(const LangOptions &Opts, 1611 MacroBuilder &Builder) const { 1612 Builder.defineMacro("__pic16"); 1613 Builder.defineMacro("rom", "__attribute__((address_space(1)))"); 1614 Builder.defineMacro("ram", "__attribute__((address_space(0)))"); 1615 Builder.defineMacro("_section(SectName)", 1616 "__attribute__((section(SectName)))"); 1617 Builder.defineMacro("near", 1618 "__attribute__((section(\"Address=NEAR\")))"); 1619 Builder.defineMacro("_address(Addr)", 1620 "__attribute__((section(\"Address=\"#Addr)))"); 1621 Builder.defineMacro("_CONFIG(conf)", "asm(\"CONFIG \"#conf)"); 1622 Builder.defineMacro("_interrupt", 1623 "__attribute__((section(\"interrupt=0x4\"))) \ 1624 __attribute__((used))"); 1625 } 1626 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1627 unsigned &NumRecords) const {} 1628 virtual const char *getVAListDeclaration() const { 1629 return ""; 1630 } 1631 virtual const char *getClobbers() const { 1632 return ""; 1633 } 1634 virtual void getGCCRegNames(const char * const *&Names, 1635 unsigned &NumNames) const {} 1636 virtual bool validateAsmConstraint(const char *&Name, 1637 TargetInfo::ConstraintInfo &info) const { 1638 return true; 1639 } 1640 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1641 unsigned &NumAliases) const {} 1642 virtual bool useGlobalsForAutomaticVariables() const {return true;} 1643 }; 1644} 1645 1646namespace { 1647 class MSP430TargetInfo : public TargetInfo { 1648 static const char * const GCCRegNames[]; 1649 public: 1650 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { 1651 TLSSupported = false; 1652 IntWidth = 16; 1653 LongWidth = 32; 1654 LongLongWidth = 64; 1655 PointerWidth = 16; 1656 IntAlign = 8; 1657 LongAlign = LongLongAlign = 8; 1658 PointerAlign = 8; 1659 SizeType = UnsignedInt; 1660 IntMaxType = SignedLong; 1661 UIntMaxType = UnsignedLong; 1662 IntPtrType = SignedShort; 1663 PtrDiffType = SignedInt; 1664 SigAtomicType = SignedLong; 1665 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"; 1666 } 1667 virtual void getTargetDefines(const LangOptions &Opts, 1668 MacroBuilder &Builder) const { 1669 Builder.defineMacro("MSP430"); 1670 Builder.defineMacro("__MSP430__"); 1671 // FIXME: defines for different 'flavours' of MCU 1672 } 1673 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1674 unsigned &NumRecords) const { 1675 // FIXME: Implement. 1676 Records = 0; 1677 NumRecords = 0; 1678 } 1679 virtual void getGCCRegNames(const char * const *&Names, 1680 unsigned &NumNames) const; 1681 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1682 unsigned &NumAliases) const { 1683 // No aliases. 1684 Aliases = 0; 1685 NumAliases = 0; 1686 } 1687 virtual bool validateAsmConstraint(const char *&Name, 1688 TargetInfo::ConstraintInfo &info) const { 1689 // No target constraints for now. 1690 return false; 1691 } 1692 virtual const char *getClobbers() const { 1693 // FIXME: Is this really right? 1694 return ""; 1695 } 1696 virtual const char *getVAListDeclaration() const { 1697 // FIXME: implement 1698 return "typedef char* __builtin_va_list;"; 1699 } 1700 }; 1701 1702 const char * const MSP430TargetInfo::GCCRegNames[] = { 1703 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1704 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1705 }; 1706 1707 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names, 1708 unsigned &NumNames) const { 1709 Names = GCCRegNames; 1710 NumNames = llvm::array_lengthof(GCCRegNames); 1711 } 1712} 1713 1714 1715namespace { 1716 class SystemZTargetInfo : public TargetInfo { 1717 static const char * const GCCRegNames[]; 1718 public: 1719 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) { 1720 TLSSupported = false; 1721 IntWidth = IntAlign = 32; 1722 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; 1723 PointerWidth = PointerAlign = 64; 1724 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-" 1725 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64"; 1726 } 1727 virtual void getTargetDefines(const LangOptions &Opts, 1728 MacroBuilder &Builder) const { 1729 Builder.defineMacro("__s390__"); 1730 Builder.defineMacro("__s390x__"); 1731 } 1732 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1733 unsigned &NumRecords) const { 1734 // FIXME: Implement. 1735 Records = 0; 1736 NumRecords = 0; 1737 } 1738 1739 virtual void getGCCRegNames(const char * const *&Names, 1740 unsigned &NumNames) const; 1741 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1742 unsigned &NumAliases) const { 1743 // No aliases. 1744 Aliases = 0; 1745 NumAliases = 0; 1746 } 1747 virtual bool validateAsmConstraint(const char *&Name, 1748 TargetInfo::ConstraintInfo &info) const { 1749 // FIXME: implement 1750 return true; 1751 } 1752 virtual const char *getClobbers() const { 1753 // FIXME: Is this really right? 1754 return ""; 1755 } 1756 virtual const char *getVAListDeclaration() const { 1757 // FIXME: implement 1758 return "typedef char* __builtin_va_list;"; 1759 } 1760 }; 1761 1762 const char * const SystemZTargetInfo::GCCRegNames[] = { 1763 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1764 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 1765 }; 1766 1767 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names, 1768 unsigned &NumNames) const { 1769 Names = GCCRegNames; 1770 NumNames = llvm::array_lengthof(GCCRegNames); 1771 } 1772} 1773 1774namespace { 1775 class BlackfinTargetInfo : public TargetInfo { 1776 static const char * const GCCRegNames[]; 1777 public: 1778 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) { 1779 TLSSupported = false; 1780 DoubleAlign = 32; 1781 LongLongAlign = 32; 1782 LongDoubleAlign = 32; 1783 DescriptionString = "e-p:32:32-i64:32-f64:32-n32"; 1784 } 1785 1786 virtual void getTargetDefines(const LangOptions &Opts, 1787 MacroBuilder &Builder) const { 1788 DefineStd(Builder, "bfin", Opts); 1789 DefineStd(Builder, "BFIN", Opts); 1790 Builder.defineMacro("__ADSPBLACKFIN__"); 1791 // FIXME: This one is really dependent on -mcpu 1792 Builder.defineMacro("__ADSPLPBLACKFIN__"); 1793 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__ 1794 } 1795 1796 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1797 unsigned &NumRecords) const { 1798 // FIXME: Implement. 1799 Records = 0; 1800 NumRecords = 0; 1801 } 1802 1803 virtual void getGCCRegNames(const char * const *&Names, 1804 unsigned &NumNames) const; 1805 1806 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1807 unsigned &NumAliases) const { 1808 // No aliases. 1809 Aliases = 0; 1810 NumAliases = 0; 1811 } 1812 1813 virtual bool validateAsmConstraint(const char *&Name, 1814 TargetInfo::ConstraintInfo &Info) const { 1815 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) { 1816 Info.setAllowsRegister(); 1817 return true; 1818 } 1819 return false; 1820 } 1821 1822 virtual const char *getClobbers() const { 1823 return ""; 1824 } 1825 1826 virtual const char *getVAListDeclaration() const { 1827 return "typedef char* __builtin_va_list;"; 1828 } 1829 }; 1830 1831 const char * const BlackfinTargetInfo::GCCRegNames[] = { 1832 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1833 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp", 1834 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3", 1835 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3", 1836 "a0", "a1", "cc", 1837 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp", 1838 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1" 1839 }; 1840 1841 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names, 1842 unsigned &NumNames) const { 1843 Names = GCCRegNames; 1844 NumNames = llvm::array_lengthof(GCCRegNames); 1845 } 1846} 1847 1848namespace { 1849 1850 // LLVM and Clang cannot be used directly to output native binaries for 1851 // target, but is used to compile C code to llvm bitcode with correct 1852 // type and alignment information. 1853 // 1854 // TCE uses the llvm bitcode as input and uses it for generating customized 1855 // target processor and program binary. TCE co-design environment is 1856 // publicly available in http://tce.cs.tut.fi 1857 1858 class TCETargetInfo : public TargetInfo{ 1859 public: 1860 TCETargetInfo(const std::string& triple) : TargetInfo(triple) { 1861 TLSSupported = false; 1862 IntWidth = 32; 1863 LongWidth = LongLongWidth = 32; 1864 PointerWidth = 32; 1865 IntAlign = 32; 1866 LongAlign = LongLongAlign = 32; 1867 PointerAlign = 32; 1868 SizeType = UnsignedInt; 1869 IntMaxType = SignedLong; 1870 UIntMaxType = UnsignedLong; 1871 IntPtrType = SignedInt; 1872 PtrDiffType = SignedInt; 1873 FloatWidth = 32; 1874 FloatAlign = 32; 1875 DoubleWidth = 32; 1876 DoubleAlign = 32; 1877 LongDoubleWidth = 32; 1878 LongDoubleAlign = 32; 1879 FloatFormat = &llvm::APFloat::IEEEsingle; 1880 DoubleFormat = &llvm::APFloat::IEEEsingle; 1881 LongDoubleFormat = &llvm::APFloat::IEEEsingle; 1882 DescriptionString = "E-p:32:32:32-a0:32:32" 1883 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64" 1884 "-f32:32:32-f64:32:64-n32"; 1885 } 1886 1887 virtual void getTargetDefines(const LangOptions &Opts, 1888 MacroBuilder &Builder) const { 1889 DefineStd(Builder, "tce", Opts); 1890 Builder.defineMacro("__TCE__"); 1891 Builder.defineMacro("__TCE_V1__"); 1892 } 1893 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1894 unsigned &NumRecords) const {} 1895 virtual const char *getClobbers() const { 1896 return ""; 1897 } 1898 virtual const char *getVAListDeclaration() const { 1899 return "typedef void* __builtin_va_list;"; 1900 } 1901 virtual void getGCCRegNames(const char * const *&Names, 1902 unsigned &NumNames) const {} 1903 virtual bool validateAsmConstraint(const char *&Name, 1904 TargetInfo::ConstraintInfo &info) const { 1905 return true; 1906 } 1907 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1908 unsigned &NumAliases) const {} 1909 }; 1910} 1911 1912namespace { 1913class MipsTargetInfo : public TargetInfo { 1914 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1915 static const char * const GCCRegNames[]; 1916public: 1917 MipsTargetInfo(const std::string& triple) : TargetInfo(triple) { 1918 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 1919 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32"; 1920 } 1921 virtual void getTargetDefines(const LangOptions &Opts, 1922 MacroBuilder &Builder) const { 1923 DefineStd(Builder, "mips", Opts); 1924 Builder.defineMacro("_mips"); 1925 DefineStd(Builder, "MIPSEB", Opts); 1926 Builder.defineMacro("_MIPSEB"); 1927 Builder.defineMacro("__REGISTER_PREFIX__", ""); 1928 } 1929 virtual void getTargetBuiltins(const Builtin::Info *&Records, 1930 unsigned &NumRecords) const { 1931 // FIXME: Implement! 1932 } 1933 virtual const char *getVAListDeclaration() const { 1934 return "typedef void* __builtin_va_list;"; 1935 } 1936 virtual void getGCCRegNames(const char * const *&Names, 1937 unsigned &NumNames) const; 1938 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1939 unsigned &NumAliases) const; 1940 virtual bool validateAsmConstraint(const char *&Name, 1941 TargetInfo::ConstraintInfo &Info) const { 1942 switch (*Name) { 1943 default: 1944 case 'r': // CPU registers. 1945 case 'd': // Equivalent to "r" unless generating MIPS16 code. 1946 case 'y': // Equivalent to "r", backwards compatibility only. 1947 case 'f': // floating-point registers. 1948 Info.setAllowsRegister(); 1949 return true; 1950 } 1951 return false; 1952 } 1953 1954 virtual const char *getClobbers() const { 1955 // FIXME: Implement! 1956 return ""; 1957 } 1958}; 1959 1960const char * const MipsTargetInfo::GCCRegNames[] = { 1961 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 1962 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 1963 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 1964 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31", 1965 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", 1966 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", 1967 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", 1968 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", 1969 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", 1970 "$fcc5","$fcc6","$fcc7" 1971}; 1972 1973void MipsTargetInfo::getGCCRegNames(const char * const *&Names, 1974 unsigned &NumNames) const { 1975 Names = GCCRegNames; 1976 NumNames = llvm::array_lengthof(GCCRegNames); 1977} 1978 1979const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = { 1980 { { "at" }, "$1" }, 1981 { { "v0" }, "$2" }, 1982 { { "v1" }, "$3" }, 1983 { { "a0" }, "$4" }, 1984 { { "a1" }, "$5" }, 1985 { { "a2" }, "$6" }, 1986 { { "a3" }, "$7" }, 1987 { { "t0" }, "$8" }, 1988 { { "t1" }, "$9" }, 1989 { { "t2" }, "$10" }, 1990 { { "t3" }, "$11" }, 1991 { { "t4" }, "$12" }, 1992 { { "t5" }, "$13" }, 1993 { { "t6" }, "$14" }, 1994 { { "t7" }, "$15" }, 1995 { { "s0" }, "$16" }, 1996 { { "s1" }, "$17" }, 1997 { { "s2" }, "$18" }, 1998 { { "s3" }, "$19" }, 1999 { { "s4" }, "$20" }, 2000 { { "s5" }, "$21" }, 2001 { { "s6" }, "$22" }, 2002 { { "s7" }, "$23" }, 2003 { { "t8" }, "$24" }, 2004 { { "t9" }, "$25" }, 2005 { { "k0" }, "$26" }, 2006 { { "k1" }, "$27" }, 2007 { { "gp" }, "$28" }, 2008 { { "sp" }, "$29" }, 2009 { { "fp" }, "$30" }, 2010 { { "ra" }, "$31" } 2011}; 2012 2013void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 2014 unsigned &NumAliases) const { 2015 Aliases = GCCRegAliases; 2016 NumAliases = llvm::array_lengthof(GCCRegAliases); 2017} 2018} // end anonymous namespace. 2019 2020namespace { 2021class MipselTargetInfo : public MipsTargetInfo { 2022public: 2023 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) { 2024 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 2025 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32"; 2026 } 2027 2028 virtual void getTargetDefines(const LangOptions &Opts, 2029 MacroBuilder &Builder) const; 2030}; 2031 2032void MipselTargetInfo::getTargetDefines(const LangOptions &Opts, 2033 MacroBuilder &Builder) const { 2034 DefineStd(Builder, "mips", Opts); 2035 Builder.defineMacro("_mips"); 2036 DefineStd(Builder, "MIPSEL", Opts); 2037 Builder.defineMacro("_MIPSEL"); 2038 Builder.defineMacro("__REGISTER_PREFIX__", ""); 2039} 2040} // end anonymous namespace. 2041 2042//===----------------------------------------------------------------------===// 2043// Driver code 2044//===----------------------------------------------------------------------===// 2045 2046static TargetInfo *AllocateTarget(const std::string &T) { 2047 llvm::Triple Triple(T); 2048 llvm::Triple::OSType os = Triple.getOS(); 2049 2050 switch (Triple.getArch()) { 2051 default: 2052 return NULL; 2053 2054 case llvm::Triple::arm: 2055 case llvm::Triple::thumb: 2056 switch (os) { 2057 case llvm::Triple::Darwin: 2058 return new DarwinARMTargetInfo(T); 2059 case llvm::Triple::FreeBSD: 2060 return new FreeBSDTargetInfo<ARMTargetInfo>(T); 2061 default: 2062 return new ARMTargetInfo(T); 2063 } 2064 2065 case llvm::Triple::bfin: 2066 return new BlackfinTargetInfo(T); 2067 2068 case llvm::Triple::msp430: 2069 return new MSP430TargetInfo(T); 2070 2071 case llvm::Triple::mips: 2072 if (os == llvm::Triple::Psp) 2073 return new PSPTargetInfo<MipsTargetInfo>(T); 2074 if (os == llvm::Triple::Linux) 2075 return new LinuxTargetInfo<MipsTargetInfo>(T); 2076 return new MipsTargetInfo(T); 2077 2078 case llvm::Triple::mipsel: 2079 if (os == llvm::Triple::Psp) 2080 return new PSPTargetInfo<MipselTargetInfo>(T); 2081 if (os == llvm::Triple::Linux) 2082 return new LinuxTargetInfo<MipselTargetInfo>(T); 2083 return new MipselTargetInfo(T); 2084 2085 case llvm::Triple::pic16: 2086 return new PIC16TargetInfo(T); 2087 2088 case llvm::Triple::ppc: 2089 if (os == llvm::Triple::Darwin) 2090 return new DarwinTargetInfo<PPCTargetInfo>(T); 2091 return new PPC32TargetInfo(T); 2092 2093 case llvm::Triple::ppc64: 2094 if (os == llvm::Triple::Darwin) 2095 return new DarwinTargetInfo<PPC64TargetInfo>(T); 2096 else if (os == llvm::Triple::Lv2) 2097 return new PS3PPUTargetInfo<PPC64TargetInfo>(T); 2098 return new PPC64TargetInfo(T); 2099 2100 case llvm::Triple::sparc: 2101 if (os == llvm::Triple::AuroraUX) 2102 return new AuroraUXSparcV8TargetInfo(T); 2103 if (os == llvm::Triple::Solaris) 2104 return new SolarisSparcV8TargetInfo(T); 2105 return new SparcV8TargetInfo(T); 2106 2107 // FIXME: Need a real SPU target. 2108 case llvm::Triple::cellspu: 2109 return new PS3SPUTargetInfo<PPC64TargetInfo>(T); 2110 2111 case llvm::Triple::systemz: 2112 return new SystemZTargetInfo(T); 2113 2114 case llvm::Triple::tce: 2115 return new TCETargetInfo(T); 2116 2117 case llvm::Triple::x86: 2118 switch (os) { 2119 case llvm::Triple::AuroraUX: 2120 return new AuroraUXTargetInfo<X86_32TargetInfo>(T); 2121 case llvm::Triple::Darwin: 2122 return new DarwinI386TargetInfo(T); 2123 case llvm::Triple::Linux: 2124 return new LinuxTargetInfo<X86_32TargetInfo>(T); 2125 case llvm::Triple::DragonFly: 2126 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T); 2127 case llvm::Triple::NetBSD: 2128 return new NetBSDTargetInfo<X86_32TargetInfo>(T); 2129 case llvm::Triple::OpenBSD: 2130 return new OpenBSDI386TargetInfo(T); 2131 case llvm::Triple::FreeBSD: 2132 return new FreeBSDTargetInfo<X86_32TargetInfo>(T); 2133 case llvm::Triple::Solaris: 2134 return new SolarisTargetInfo<X86_32TargetInfo>(T); 2135 case llvm::Triple::Cygwin: 2136 return new CygwinX86_32TargetInfo(T); 2137 case llvm::Triple::MinGW32: 2138 return new MinGWX86_32TargetInfo(T); 2139 case llvm::Triple::Win32: 2140 return new VisualStudioWindowsX86_32TargetInfo(T); 2141 default: 2142 return new X86_32TargetInfo(T); 2143 } 2144 2145 case llvm::Triple::x86_64: 2146 switch (os) { 2147 case llvm::Triple::AuroraUX: 2148 return new AuroraUXTargetInfo<X86_64TargetInfo>(T); 2149 case llvm::Triple::Darwin: 2150 return new DarwinX86_64TargetInfo(T); 2151 case llvm::Triple::Linux: 2152 return new LinuxTargetInfo<X86_64TargetInfo>(T); 2153 case llvm::Triple::DragonFly: 2154 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T); 2155 case llvm::Triple::NetBSD: 2156 return new NetBSDTargetInfo<X86_64TargetInfo>(T); 2157 case llvm::Triple::OpenBSD: 2158 return new OpenBSDX86_64TargetInfo(T); 2159 case llvm::Triple::FreeBSD: 2160 return new FreeBSDTargetInfo<X86_64TargetInfo>(T); 2161 case llvm::Triple::Solaris: 2162 return new SolarisTargetInfo<X86_64TargetInfo>(T); 2163 case llvm::Triple::MinGW64: 2164 return new MinGWX86_64TargetInfo(T); 2165 case llvm::Triple::Win32: // This is what Triple.h supports now. 2166 return new VisualStudioWindowsX86_64TargetInfo(T); 2167 default: 2168 return new X86_64TargetInfo(T); 2169 } 2170 } 2171} 2172 2173/// CreateTargetInfo - Return the target info object for the specified target 2174/// triple. 2175TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags, 2176 TargetOptions &Opts) { 2177 llvm::Triple Triple(Opts.Triple); 2178 2179 // Construct the target 2180 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str())); 2181 if (!Target) { 2182 Diags.Report(diag::err_target_unknown_triple) << Triple.str(); 2183 return 0; 2184 } 2185 2186 // Set the target CPU if specified. 2187 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) { 2188 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU; 2189 return 0; 2190 } 2191 2192 // Set the target ABI if specified. 2193 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) { 2194 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI; 2195 return 0; 2196 } 2197 2198 // Compute the default target features, we need the target to handle this 2199 // because features may have dependencies on one another. 2200 llvm::StringMap<bool> Features; 2201 Target->getDefaultFeatures(Opts.CPU, Features); 2202 2203 // Apply the user specified deltas. 2204 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(), 2205 ie = Opts.Features.end(); it != ie; ++it) { 2206 const char *Name = it->c_str(); 2207 2208 // Apply the feature via the target. 2209 if ((Name[0] != '-' && Name[0] != '+') || 2210 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) { 2211 Diags.Report(diag::err_target_invalid_feature) << Name; 2212 return 0; 2213 } 2214 } 2215 2216 // Add the features to the compile options. 2217 // 2218 // FIXME: If we are completely confident that we have the right set, we only 2219 // need to pass the minuses. 2220 Opts.Features.clear(); 2221 for (llvm::StringMap<bool>::const_iterator it = Features.begin(), 2222 ie = Features.end(); it != ie; ++it) 2223 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first()); 2224 Target->HandleTargetFeatures(Opts.Features); 2225 2226 return Target.take(); 2227} 2228