1193326Sed//===--- Targets.cpp - Implement -arch option and targets -----------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements construction of a TargetInfo object from a 11193326Sed// target triple. 12193326Sed// 13193326Sed//===----------------------------------------------------------------------===// 14193326Sed 15199482Srdivacky#include "clang/Basic/TargetInfo.h" 16194179Sed#include "clang/Basic/Builtins.h" 17199482Srdivacky#include "clang/Basic/Diagnostic.h" 18199482Srdivacky#include "clang/Basic/LangOptions.h" 19202879Srdivacky#include "clang/Basic/MacroBuilder.h" 20194179Sed#include "clang/Basic/TargetBuiltins.h" 21199482Srdivacky#include "clang/Basic/TargetOptions.h" 22193326Sed#include "llvm/ADT/APFloat.h" 23199482Srdivacky#include "llvm/ADT/OwningPtr.h" 24199482Srdivacky#include "llvm/ADT/STLExtras.h" 25198092Srdivacky#include "llvm/ADT/StringRef.h" 26199482Srdivacky#include "llvm/ADT/StringSwitch.h" 27198092Srdivacky#include "llvm/ADT/Triple.h" 28249423Sdim#include "llvm/IR/Type.h" 29198092Srdivacky#include "llvm/MC/MCSectionMachO.h" 30226633Sdim#include "llvm/Support/ErrorHandling.h" 31202379Srdivacky#include <algorithm> 32193326Sedusing namespace clang; 33193326Sed 34193326Sed//===----------------------------------------------------------------------===// 35193326Sed// Common code shared among targets. 36193326Sed//===----------------------------------------------------------------------===// 37193326Sed 38193326Sed/// DefineStd - Define a macro name and standard variants. For example if 39193326Sed/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix" 40193326Sed/// when in GNU mode. 41226633Sdimstatic void DefineStd(MacroBuilder &Builder, StringRef MacroName, 42193326Sed const LangOptions &Opts) { 43193326Sed assert(MacroName[0] != '_' && "Identifier should be in the user's namespace"); 44193326Sed 45193326Sed // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier 46193326Sed // in the user's namespace. 47193326Sed if (Opts.GNUMode) 48202379Srdivacky Builder.defineMacro(MacroName); 49193326Sed 50193326Sed // Define __unix. 51202379Srdivacky Builder.defineMacro("__" + MacroName); 52193326Sed 53193326Sed // Define __unix__. 54202379Srdivacky Builder.defineMacro("__" + MacroName + "__"); 55193326Sed} 56193326Sed 57234353Sdimstatic void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName, 58234353Sdim bool Tuning = true) { 59234353Sdim Builder.defineMacro("__" + CPUName); 60234353Sdim Builder.defineMacro("__" + CPUName + "__"); 61234353Sdim if (Tuning) 62234353Sdim Builder.defineMacro("__tune_" + CPUName + "__"); 63234353Sdim} 64234353Sdim 65193326Sed//===----------------------------------------------------------------------===// 66193326Sed// Defines specific to certain operating systems. 67193326Sed//===----------------------------------------------------------------------===// 68198092Srdivacky 69195341Sednamespace { 70195341Sedtemplate<typename TgtInfo> 71195341Sedclass OSTargetInfo : public TgtInfo { 72195341Sedprotected: 73198092Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 74202379Srdivacky MacroBuilder &Builder) const=0; 75195341Sedpublic: 76195341Sed OSTargetInfo(const std::string& triple) : TgtInfo(triple) {} 77195341Sed virtual void getTargetDefines(const LangOptions &Opts, 78202379Srdivacky MacroBuilder &Builder) const { 79202379Srdivacky TgtInfo::getTargetDefines(Opts, Builder); 80202379Srdivacky getOSDefines(Opts, TgtInfo::getTriple(), Builder); 81193326Sed } 82193326Sed 83195341Sed}; 84198092Srdivacky} // end anonymous namespace 85193326Sed 86193326Sed 87203955Srdivackystatic void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, 88221345Sdim const llvm::Triple &Triple, 89226633Sdim StringRef &PlatformName, 90221345Sdim VersionTuple &PlatformMinVersion) { 91202379Srdivacky Builder.defineMacro("__APPLE_CC__", "5621"); 92202379Srdivacky Builder.defineMacro("__APPLE__"); 93202379Srdivacky Builder.defineMacro("__MACH__"); 94202379Srdivacky Builder.defineMacro("OBJC_NEW_PROPERTIES"); 95243830Sdim // AddressSanitizer doesn't play well with source fortification, which is on 96243830Sdim // by default on Darwin. 97249423Sdim if (Opts.Sanitize.Address) Builder.defineMacro("_FORTIFY_SOURCE", "0"); 98193326Sed 99224145Sdim if (!Opts.ObjCAutoRefCount) { 100224145Sdim // __weak is always defined, for use in blocks and with objc pointers. 101224145Sdim Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); 102193326Sed 103224145Sdim // Darwin defines __strong even in C mode (just to nothing). 104226633Sdim if (Opts.getGC() != LangOptions::NonGC) 105224145Sdim Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))"); 106224145Sdim else 107224145Sdim Builder.defineMacro("__strong", ""); 108193576Sed 109224145Sdim // __unsafe_unretained is defined to nothing in non-ARC mode. We even 110224145Sdim // allow this in C, since one might have block pointers in structs that 111224145Sdim // are used in pure C code and in Objective-C ARC. 112224145Sdim Builder.defineMacro("__unsafe_unretained", ""); 113224145Sdim } 114224145Sdim 115193576Sed if (Opts.Static) 116202379Srdivacky Builder.defineMacro("__STATIC__"); 117193576Sed else 118202379Srdivacky Builder.defineMacro("__DYNAMIC__"); 119198092Srdivacky 120198092Srdivacky if (Opts.POSIXThreads) 121202379Srdivacky Builder.defineMacro("_REENTRANT"); 122193326Sed 123221345Sdim // Get the platform type and version number from the triple. 124193326Sed unsigned Maj, Min, Rev; 125234353Sdim if (Triple.isMacOSX()) { 126234353Sdim Triple.getMacOSXVersion(Maj, Min, Rev); 127221345Sdim PlatformName = "macosx"; 128221345Sdim } else { 129234353Sdim Triple.getOSVersion(Maj, Min, Rev); 130234353Sdim PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); 131221345Sdim } 132221345Sdim 133234353Sdim // If -target arch-pc-win32-macho option specified, we're 134226633Sdim // generating code for Win32 ABI. No need to emit 135226633Sdim // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__. 136226633Sdim if (PlatformName == "win32") { 137226633Sdim PlatformMinVersion = VersionTuple(Maj, Min, Rev); 138226633Sdim return; 139226633Sdim } 140226633Sdim 141203955Srdivacky // Set the appropriate OS version define. 142234353Sdim if (Triple.getOS() == llvm::Triple::IOS) { 143221345Sdim assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); 144203955Srdivacky char Str[6]; 145203955Srdivacky Str[0] = '0' + Maj; 146203955Srdivacky Str[1] = '0' + (Min / 10); 147203955Srdivacky Str[2] = '0' + (Min % 10); 148203955Srdivacky Str[3] = '0' + (Rev / 10); 149203955Srdivacky Str[4] = '0' + (Rev % 10); 150203955Srdivacky Str[5] = '\0'; 151203955Srdivacky Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str); 152203955Srdivacky } else { 153221345Sdim // Note that the Driver allows versions which aren't representable in the 154221345Sdim // define (because we only get a single digit for the minor and micro 155221345Sdim // revision numbers). So, we limit them to the maximum representable 156221345Sdim // version. 157203955Srdivacky assert(Triple.getEnvironmentName().empty() && "Invalid environment!"); 158221345Sdim assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); 159203955Srdivacky char Str[5]; 160203955Srdivacky Str[0] = '0' + (Maj / 10); 161203955Srdivacky Str[1] = '0' + (Maj % 10); 162221345Sdim Str[2] = '0' + std::min(Min, 9U); 163221345Sdim Str[3] = '0' + std::min(Rev, 9U); 164203955Srdivacky Str[4] = '\0'; 165203955Srdivacky Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str); 166193326Sed } 167221345Sdim 168221345Sdim PlatformMinVersion = VersionTuple(Maj, Min, Rev); 169193326Sed} 170193326Sed 171198092Srdivackynamespace { 172195341Sedtemplate<typename Target> 173195341Sedclass DarwinTargetInfo : public OSTargetInfo<Target> { 174195341Sedprotected: 175198092Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 176202379Srdivacky MacroBuilder &Builder) const { 177224145Sdim getDarwinDefines(Builder, Opts, Triple, this->PlatformName, 178221345Sdim this->PlatformMinVersion); 179195341Sed } 180198092Srdivacky 181195341Sedpublic: 182195341Sed DarwinTargetInfo(const std::string& triple) : 183195341Sed OSTargetInfo<Target>(triple) { 184224145Sdim llvm::Triple T = llvm::Triple(triple); 185224145Sdim this->TLSSupported = T.isMacOSX() && !T.isMacOSXVersionLT(10,7); 186219077Sdim this->MCountName = "\01mcount"; 187195341Sed } 188195341Sed 189226633Sdim virtual std::string isValidSectionSpecifier(StringRef SR) const { 190198092Srdivacky // Let MCSectionMachO validate this. 191226633Sdim StringRef Segment, Section; 192198092Srdivacky unsigned TAA, StubSize; 193221345Sdim bool HasTAA; 194198092Srdivacky return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section, 195221345Sdim TAA, HasTAA, StubSize); 196195341Sed } 197218893Sdim 198210299Sed virtual const char *getStaticInitSectionSpecifier() const { 199210299Sed // FIXME: We should return 0 when building kexts. 200210299Sed return "__TEXT,__StaticInit,regular,pure_instructions"; 201210299Sed } 202218893Sdim 203234353Sdim /// Darwin does not support protected visibility. Darwin's "default" 204234353Sdim /// is very similar to ELF's "protected"; Darwin requires a "weak" 205234353Sdim /// attribute on declarations that can be dynamically replaced. 206234353Sdim virtual bool hasProtectedVisibility() const { 207234353Sdim return false; 208234353Sdim } 209198092Srdivacky}; 210195341Sed 211195341Sed 212195341Sed// DragonFlyBSD Target 213195341Sedtemplate<typename Target> 214195341Sedclass DragonFlyBSDTargetInfo : public OSTargetInfo<Target> { 215195341Sedprotected: 216198092Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 217202379Srdivacky MacroBuilder &Builder) const { 218195341Sed // DragonFly defines; list based off of gcc output 219202379Srdivacky Builder.defineMacro("__DragonFly__"); 220202379Srdivacky Builder.defineMacro("__DragonFly_cc_version", "100001"); 221202379Srdivacky Builder.defineMacro("__ELF__"); 222202379Srdivacky Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); 223202379Srdivacky Builder.defineMacro("__tune_i386__"); 224202379Srdivacky DefineStd(Builder, "unix", Opts); 225195341Sed } 226195341Sedpublic: 227198092Srdivacky DragonFlyBSDTargetInfo(const std::string &triple) 228234353Sdim : OSTargetInfo<Target>(triple) { 229234353Sdim this->UserLabelPrefix = ""; 230234353Sdim 231234353Sdim llvm::Triple Triple(triple); 232234353Sdim switch (Triple.getArch()) { 233234353Sdim default: 234234353Sdim case llvm::Triple::x86: 235234353Sdim case llvm::Triple::x86_64: 236234353Sdim this->MCountName = ".mcount"; 237234353Sdim break; 238234353Sdim } 239234353Sdim } 240195341Sed}; 241195341Sed 242195341Sed// FreeBSD Target 243195341Sedtemplate<typename Target> 244195341Sedclass FreeBSDTargetInfo : public OSTargetInfo<Target> { 245195341Sedprotected: 246198092Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 247202379Srdivacky MacroBuilder &Builder) const { 248195341Sed // FreeBSD defines; list based off of gcc output 249195341Sed 250226518Sdim unsigned Release = Triple.getOSMajorVersion(); 251226518Sdim if (Release == 0U) 252234353Sdim Release = 8; 253195341Sed 254226633Sdim Builder.defineMacro("__FreeBSD__", Twine(Release)); 255226633Sdim Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U)); 256202379Srdivacky Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); 257202379Srdivacky DefineStd(Builder, "unix", Opts); 258202379Srdivacky Builder.defineMacro("__ELF__"); 259195341Sed } 260195341Sedpublic: 261198092Srdivacky FreeBSDTargetInfo(const std::string &triple) 262198092Srdivacky : OSTargetInfo<Target>(triple) { 263198092Srdivacky this->UserLabelPrefix = ""; 264218893Sdim 265218893Sdim llvm::Triple Triple(triple); 266218893Sdim switch (Triple.getArch()) { 267218893Sdim default: 268218893Sdim case llvm::Triple::x86: 269218893Sdim case llvm::Triple::x86_64: 270218893Sdim this->MCountName = ".mcount"; 271218893Sdim break; 272218893Sdim case llvm::Triple::mips: 273218893Sdim case llvm::Triple::mipsel: 274218893Sdim case llvm::Triple::ppc: 275218893Sdim case llvm::Triple::ppc64: 276218893Sdim this->MCountName = "_mcount"; 277218893Sdim break; 278218893Sdim case llvm::Triple::arm: 279218893Sdim this->MCountName = "__mcount"; 280218893Sdim break; 281218893Sdim } 282218893Sdim 283198092Srdivacky } 284195341Sed}; 285195341Sed 286210299Sed// Minix Target 287210299Sedtemplate<typename Target> 288210299Sedclass MinixTargetInfo : public OSTargetInfo<Target> { 289210299Sedprotected: 290210299Sed virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 291210299Sed MacroBuilder &Builder) const { 292210299Sed // Minix defines 293210299Sed 294210299Sed Builder.defineMacro("__minix", "3"); 295210299Sed Builder.defineMacro("_EM_WSIZE", "4"); 296210299Sed Builder.defineMacro("_EM_PSIZE", "4"); 297210299Sed Builder.defineMacro("_EM_SSIZE", "2"); 298210299Sed Builder.defineMacro("_EM_LSIZE", "4"); 299210299Sed Builder.defineMacro("_EM_FSIZE", "4"); 300210299Sed Builder.defineMacro("_EM_DSIZE", "8"); 301234353Sdim Builder.defineMacro("__ELF__"); 302210299Sed DefineStd(Builder, "unix", Opts); 303210299Sed } 304210299Sedpublic: 305210299Sed MinixTargetInfo(const std::string &triple) 306210299Sed : OSTargetInfo<Target>(triple) { 307210299Sed this->UserLabelPrefix = ""; 308210299Sed } 309210299Sed}; 310210299Sed 311195341Sed// Linux target 312195341Sedtemplate<typename Target> 313195341Sedclass LinuxTargetInfo : public OSTargetInfo<Target> { 314195341Sedprotected: 315198092Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 316202379Srdivacky MacroBuilder &Builder) const { 317195341Sed // Linux defines; list based off of gcc output 318202379Srdivacky DefineStd(Builder, "unix", Opts); 319202379Srdivacky DefineStd(Builder, "linux", Opts); 320202379Srdivacky Builder.defineMacro("__gnu_linux__"); 321202379Srdivacky Builder.defineMacro("__ELF__"); 322243830Sdim if (Triple.getEnvironment() == llvm::Triple::Android) 323239462Sdim Builder.defineMacro("__ANDROID__", "1"); 324198092Srdivacky if (Opts.POSIXThreads) 325202379Srdivacky Builder.defineMacro("_REENTRANT"); 326207619Srdivacky if (Opts.CPlusPlus) 327207619Srdivacky Builder.defineMacro("_GNU_SOURCE"); 328195341Sed } 329195341Sedpublic: 330198092Srdivacky LinuxTargetInfo(const std::string& triple) 331195341Sed : OSTargetInfo<Target>(triple) { 332195341Sed this->UserLabelPrefix = ""; 333218893Sdim this->WIntType = TargetInfo::UnsignedInt; 334195341Sed } 335234353Sdim 336234353Sdim virtual const char *getStaticInitSectionSpecifier() const { 337234353Sdim return ".text.startup"; 338234353Sdim } 339195341Sed}; 340195341Sed 341198092Srdivacky// NetBSD Target 342198092Srdivackytemplate<typename Target> 343198092Srdivackyclass NetBSDTargetInfo : public OSTargetInfo<Target> { 344198092Srdivackyprotected: 345198092Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 346202379Srdivacky MacroBuilder &Builder) const { 347198092Srdivacky // NetBSD defines; list based off of gcc output 348202379Srdivacky Builder.defineMacro("__NetBSD__"); 349202379Srdivacky Builder.defineMacro("__unix__"); 350202379Srdivacky Builder.defineMacro("__ELF__"); 351198092Srdivacky if (Opts.POSIXThreads) 352202379Srdivacky Builder.defineMacro("_POSIX_THREADS"); 353198092Srdivacky } 354198092Srdivackypublic: 355198092Srdivacky NetBSDTargetInfo(const std::string &triple) 356198092Srdivacky : OSTargetInfo<Target>(triple) { 357198092Srdivacky this->UserLabelPrefix = ""; 358198092Srdivacky } 359198092Srdivacky}; 360198092Srdivacky 361195341Sed// OpenBSD Target 362195341Sedtemplate<typename Target> 363195341Sedclass OpenBSDTargetInfo : public OSTargetInfo<Target> { 364195341Sedprotected: 365198092Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 366202379Srdivacky MacroBuilder &Builder) const { 367195341Sed // OpenBSD defines; list based off of gcc output 368195341Sed 369202379Srdivacky Builder.defineMacro("__OpenBSD__"); 370202379Srdivacky DefineStd(Builder, "unix", Opts); 371202379Srdivacky Builder.defineMacro("__ELF__"); 372198092Srdivacky if (Opts.POSIXThreads) 373234982Sdim Builder.defineMacro("_REENTRANT"); 374195341Sed } 375195341Sedpublic: 376198092Srdivacky OpenBSDTargetInfo(const std::string &triple) 377234353Sdim : OSTargetInfo<Target>(triple) { 378234353Sdim this->UserLabelPrefix = ""; 379239462Sdim this->TLSSupported = false; 380234353Sdim 381234353Sdim llvm::Triple Triple(triple); 382234353Sdim switch (Triple.getArch()) { 383234353Sdim default: 384234353Sdim case llvm::Triple::x86: 385234353Sdim case llvm::Triple::x86_64: 386234353Sdim case llvm::Triple::arm: 387249423Sdim case llvm::Triple::sparc: 388234353Sdim this->MCountName = "__mcount"; 389234353Sdim break; 390234353Sdim case llvm::Triple::mips64: 391234353Sdim case llvm::Triple::mips64el: 392234353Sdim case llvm::Triple::ppc: 393249423Sdim case llvm::Triple::sparcv9: 394234353Sdim this->MCountName = "_mcount"; 395234353Sdim break; 396234353Sdim } 397234353Sdim } 398195341Sed}; 399195341Sed 400239462Sdim// Bitrig Target 401239462Sdimtemplate<typename Target> 402239462Sdimclass BitrigTargetInfo : public OSTargetInfo<Target> { 403239462Sdimprotected: 404239462Sdim virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 405239462Sdim MacroBuilder &Builder) const { 406239462Sdim // Bitrig defines; list based off of gcc output 407239462Sdim 408239462Sdim Builder.defineMacro("__Bitrig__"); 409239462Sdim DefineStd(Builder, "unix", Opts); 410239462Sdim Builder.defineMacro("__ELF__"); 411239462Sdim if (Opts.POSIXThreads) 412239462Sdim Builder.defineMacro("_REENTRANT"); 413239462Sdim } 414239462Sdimpublic: 415239462Sdim BitrigTargetInfo(const std::string &triple) 416239462Sdim : OSTargetInfo<Target>(triple) { 417239462Sdim this->UserLabelPrefix = ""; 418239462Sdim this->TLSSupported = false; 419239462Sdim this->MCountName = "__mcount"; 420239462Sdim } 421239462Sdim}; 422239462Sdim 423199482Srdivacky// PSP Target 424199482Srdivackytemplate<typename Target> 425199482Srdivackyclass PSPTargetInfo : public OSTargetInfo<Target> { 426199482Srdivackyprotected: 427199482Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 428202379Srdivacky MacroBuilder &Builder) const { 429199482Srdivacky // PSP defines; list based on the output of the pspdev gcc toolchain. 430202379Srdivacky Builder.defineMacro("PSP"); 431202379Srdivacky Builder.defineMacro("_PSP"); 432202379Srdivacky Builder.defineMacro("__psp__"); 433202379Srdivacky Builder.defineMacro("__ELF__"); 434199482Srdivacky } 435199482Srdivackypublic: 436199482Srdivacky PSPTargetInfo(const std::string& triple) 437199482Srdivacky : OSTargetInfo<Target>(triple) { 438199482Srdivacky this->UserLabelPrefix = ""; 439199482Srdivacky } 440199482Srdivacky}; 441199482Srdivacky 442199990Srdivacky// PS3 PPU Target 443199990Srdivackytemplate<typename Target> 444199990Srdivackyclass PS3PPUTargetInfo : public OSTargetInfo<Target> { 445199990Srdivackyprotected: 446199990Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 447202379Srdivacky MacroBuilder &Builder) const { 448199990Srdivacky // PS3 PPU defines. 449206084Srdivacky Builder.defineMacro("__PPC__"); 450202379Srdivacky Builder.defineMacro("__PPU__"); 451202379Srdivacky Builder.defineMacro("__CELLOS_LV2__"); 452202379Srdivacky Builder.defineMacro("__ELF__"); 453202379Srdivacky Builder.defineMacro("__LP32__"); 454210299Sed Builder.defineMacro("_ARCH_PPC64"); 455210299Sed Builder.defineMacro("__powerpc64__"); 456199990Srdivacky } 457199990Srdivackypublic: 458199990Srdivacky PS3PPUTargetInfo(const std::string& triple) 459199990Srdivacky : OSTargetInfo<Target>(triple) { 460199990Srdivacky this->UserLabelPrefix = ""; 461234353Sdim this->LongWidth = this->LongAlign = 32; 462234353Sdim this->PointerWidth = this->PointerAlign = 32; 463210299Sed this->IntMaxType = TargetInfo::SignedLongLong; 464210299Sed this->UIntMaxType = TargetInfo::UnsignedLongLong; 465210299Sed this->Int64Type = TargetInfo::SignedLongLong; 466201361Srdivacky this->SizeType = TargetInfo::UnsignedInt; 467210299Sed this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 468234353Sdim "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32"; 469199990Srdivacky } 470199990Srdivacky}; 471199990Srdivacky 472199990Srdivacky// FIXME: Need a real SPU target. 473199990Srdivacky// PS3 SPU Target 474199990Srdivackytemplate<typename Target> 475199990Srdivackyclass PS3SPUTargetInfo : public OSTargetInfo<Target> { 476199990Srdivackyprotected: 477199990Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 478202379Srdivacky MacroBuilder &Builder) const { 479199990Srdivacky // PS3 PPU defines. 480202379Srdivacky Builder.defineMacro("__SPU__"); 481202379Srdivacky Builder.defineMacro("__ELF__"); 482199990Srdivacky } 483199990Srdivackypublic: 484199990Srdivacky PS3SPUTargetInfo(const std::string& triple) 485199990Srdivacky : OSTargetInfo<Target>(triple) { 486199990Srdivacky this->UserLabelPrefix = ""; 487199990Srdivacky } 488199990Srdivacky}; 489199990Srdivacky 490198398Srdivacky// AuroraUX target 491198398Srdivackytemplate<typename Target> 492198398Srdivackyclass AuroraUXTargetInfo : public OSTargetInfo<Target> { 493198398Srdivackyprotected: 494198398Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 495202379Srdivacky MacroBuilder &Builder) const { 496202379Srdivacky DefineStd(Builder, "sun", Opts); 497202379Srdivacky DefineStd(Builder, "unix", Opts); 498202379Srdivacky Builder.defineMacro("__ELF__"); 499202379Srdivacky Builder.defineMacro("__svr4__"); 500202379Srdivacky Builder.defineMacro("__SVR4"); 501198398Srdivacky } 502198398Srdivackypublic: 503198398Srdivacky AuroraUXTargetInfo(const std::string& triple) 504198398Srdivacky : OSTargetInfo<Target>(triple) { 505198398Srdivacky this->UserLabelPrefix = ""; 506198398Srdivacky this->WCharType = this->SignedLong; 507198398Srdivacky // FIXME: WIntType should be SignedLong 508198398Srdivacky } 509198398Srdivacky}; 510198398Srdivacky 511195341Sed// Solaris target 512195341Sedtemplate<typename Target> 513195341Sedclass SolarisTargetInfo : public OSTargetInfo<Target> { 514195341Sedprotected: 515198092Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 516202379Srdivacky MacroBuilder &Builder) const { 517202379Srdivacky DefineStd(Builder, "sun", Opts); 518202379Srdivacky DefineStd(Builder, "unix", Opts); 519202379Srdivacky Builder.defineMacro("__ELF__"); 520202379Srdivacky Builder.defineMacro("__svr4__"); 521202379Srdivacky Builder.defineMacro("__SVR4"); 522234353Sdim // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and 523234353Sdim // newer, but to 500 for everything else. feature_test.h has a check to 524234353Sdim // ensure that you are not using C99 with an old version of X/Open or C89 525234353Sdim // with a new version. 526234353Sdim if (Opts.C99 || Opts.C11) 527234353Sdim Builder.defineMacro("_XOPEN_SOURCE", "600"); 528234353Sdim else 529234353Sdim Builder.defineMacro("_XOPEN_SOURCE", "500"); 530234353Sdim if (Opts.CPlusPlus) 531234353Sdim Builder.defineMacro("__C99FEATURES__"); 532234353Sdim Builder.defineMacro("_LARGEFILE_SOURCE"); 533234353Sdim Builder.defineMacro("_LARGEFILE64_SOURCE"); 534234353Sdim Builder.defineMacro("__EXTENSIONS__"); 535234353Sdim Builder.defineMacro("_REENTRANT"); 536195341Sed } 537195341Sedpublic: 538198092Srdivacky SolarisTargetInfo(const std::string& triple) 539195341Sed : OSTargetInfo<Target>(triple) { 540195341Sed this->UserLabelPrefix = ""; 541234353Sdim this->WCharType = this->SignedInt; 542195341Sed // FIXME: WIntType should be SignedLong 543195341Sed } 544195341Sed}; 545218893Sdim 546218893Sdim// Windows target 547218893Sdimtemplate<typename Target> 548218893Sdimclass WindowsTargetInfo : public OSTargetInfo<Target> { 549218893Sdimprotected: 550218893Sdim virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 551218893Sdim MacroBuilder &Builder) const { 552218893Sdim Builder.defineMacro("_WIN32"); 553218893Sdim } 554218893Sdim void getVisualStudioDefines(const LangOptions &Opts, 555218893Sdim MacroBuilder &Builder) const { 556218893Sdim if (Opts.CPlusPlus) { 557218893Sdim if (Opts.RTTI) 558218893Sdim Builder.defineMacro("_CPPRTTI"); 559218893Sdim 560218893Sdim if (Opts.Exceptions) 561218893Sdim Builder.defineMacro("_CPPUNWIND"); 562218893Sdim } 563218893Sdim 564218893Sdim if (!Opts.CharIsSigned) 565218893Sdim Builder.defineMacro("_CHAR_UNSIGNED"); 566218893Sdim 567218893Sdim // FIXME: POSIXThreads isn't exactly the option this should be defined for, 568218893Sdim // but it works for now. 569218893Sdim if (Opts.POSIXThreads) 570218893Sdim Builder.defineMacro("_MT"); 571218893Sdim 572218893Sdim if (Opts.MSCVersion != 0) 573226633Sdim Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion)); 574218893Sdim 575226633Sdim if (Opts.MicrosoftExt) { 576218893Sdim Builder.defineMacro("_MSC_EXTENSIONS"); 577218893Sdim 578249423Sdim if (Opts.CPlusPlus11) { 579218893Sdim Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED"); 580218893Sdim Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED"); 581218893Sdim Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED"); 582218893Sdim } 583218893Sdim } 584218893Sdim 585218893Sdim Builder.defineMacro("_INTEGRAL_MAX_BITS", "64"); 586218893Sdim } 587218893Sdim 588218893Sdimpublic: 589218893Sdim WindowsTargetInfo(const std::string &triple) 590218893Sdim : OSTargetInfo<Target>(triple) {} 591218893Sdim}; 592218893Sdim 593243830Sdimtemplate <typename Target> 594243830Sdimclass NaClTargetInfo : public OSTargetInfo<Target> { 595243830Sdim protected: 596243830Sdim virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 597243830Sdim MacroBuilder &Builder) const { 598243830Sdim if (Opts.POSIXThreads) 599243830Sdim Builder.defineMacro("_REENTRANT"); 600243830Sdim if (Opts.CPlusPlus) 601243830Sdim Builder.defineMacro("_GNU_SOURCE"); 602243830Sdim 603243830Sdim DefineStd(Builder, "unix", Opts); 604243830Sdim Builder.defineMacro("__ELF__"); 605243830Sdim Builder.defineMacro("__native_client__"); 606243830Sdim } 607243830Sdim public: 608243830Sdim NaClTargetInfo(const std::string &triple) 609243830Sdim : OSTargetInfo<Target>(triple) { 610243830Sdim this->UserLabelPrefix = ""; 611243830Sdim this->LongAlign = 32; 612243830Sdim this->LongWidth = 32; 613243830Sdim this->PointerAlign = 32; 614243830Sdim this->PointerWidth = 32; 615243830Sdim this->IntMaxType = TargetInfo::SignedLongLong; 616243830Sdim this->UIntMaxType = TargetInfo::UnsignedLongLong; 617243830Sdim this->Int64Type = TargetInfo::SignedLongLong; 618243830Sdim this->DoubleAlign = 64; 619243830Sdim this->LongDoubleWidth = 64; 620243830Sdim this->LongDoubleAlign = 64; 621243830Sdim this->SizeType = TargetInfo::UnsignedInt; 622243830Sdim this->PtrDiffType = TargetInfo::SignedInt; 623243830Sdim this->IntPtrType = TargetInfo::SignedInt; 624251662Sdim // RegParmMax is inherited from the underlying architecture 625243830Sdim this->LongDoubleFormat = &llvm::APFloat::IEEEdouble; 626243830Sdim this->DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" 627243830Sdim "f32:32:32-f64:64:64-p:32:32:32-v128:32:32"; 628243830Sdim } 629243830Sdim virtual typename Target::CallingConvCheckResult checkCallingConvention( 630243830Sdim CallingConv CC) const { 631243830Sdim return CC == CC_PnaclCall ? Target::CCCR_OK : 632243830Sdim Target::checkCallingConvention(CC); 633243830Sdim } 634243830Sdim}; 635198092Srdivacky} // end anonymous namespace. 636195341Sed 637193326Sed//===----------------------------------------------------------------------===// 638193326Sed// Specific target implementations. 639193326Sed//===----------------------------------------------------------------------===// 640193326Sed 641193326Sednamespace { 642193326Sed// PPC abstract base class 643193326Sedclass PPCTargetInfo : public TargetInfo { 644193326Sed static const Builtin::Info BuiltinInfo[]; 645193326Sed static const char * const GCCRegNames[]; 646193326Sed static const TargetInfo::GCCRegAlias GCCRegAliases[]; 647239462Sdim std::string CPU; 648193326Sedpublic: 649234353Sdim PPCTargetInfo(const std::string& triple) : TargetInfo(triple) { 650234353Sdim LongDoubleWidth = LongDoubleAlign = 128; 651234353Sdim LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; 652234353Sdim } 653193576Sed 654239462Sdim /// \brief Flags for architecture specific defines. 655239462Sdim typedef enum { 656239462Sdim ArchDefineNone = 0, 657239462Sdim ArchDefineName = 1 << 0, // <name> is substituted for arch name. 658239462Sdim ArchDefinePpcgr = 1 << 1, 659239462Sdim ArchDefinePpcsq = 1 << 2, 660239462Sdim ArchDefine440 = 1 << 3, 661239462Sdim ArchDefine603 = 1 << 4, 662239462Sdim ArchDefine604 = 1 << 5, 663239462Sdim ArchDefinePwr4 = 1 << 6, 664249423Sdim ArchDefinePwr5 = 1 << 7, 665249423Sdim ArchDefinePwr5x = 1 << 8, 666249423Sdim ArchDefinePwr6 = 1 << 9, 667249423Sdim ArchDefinePwr6x = 1 << 10, 668249423Sdim ArchDefinePwr7 = 1 << 11, 669249423Sdim ArchDefineA2 = 1 << 12, 670249423Sdim ArchDefineA2q = 1 << 13 671239462Sdim } ArchDefineTypes; 672239462Sdim 673249423Sdim // Note: GCC recognizes the following additional cpus: 674249423Sdim // 401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801, 675249423Sdim // 821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell, 676249423Sdim // titan, rs64. 677239462Sdim virtual bool setCPU(const std::string &Name) { 678239462Sdim bool CPUKnown = llvm::StringSwitch<bool>(Name) 679239462Sdim .Case("generic", true) 680239462Sdim .Case("440", true) 681239462Sdim .Case("450", true) 682239462Sdim .Case("601", true) 683239462Sdim .Case("602", true) 684239462Sdim .Case("603", true) 685239462Sdim .Case("603e", true) 686239462Sdim .Case("603ev", true) 687239462Sdim .Case("604", true) 688239462Sdim .Case("604e", true) 689239462Sdim .Case("620", true) 690249423Sdim .Case("630", true) 691239462Sdim .Case("g3", true) 692239462Sdim .Case("7400", true) 693239462Sdim .Case("g4", true) 694239462Sdim .Case("7450", true) 695239462Sdim .Case("g4+", true) 696239462Sdim .Case("750", true) 697239462Sdim .Case("970", true) 698239462Sdim .Case("g5", true) 699239462Sdim .Case("a2", true) 700249423Sdim .Case("a2q", true) 701243830Sdim .Case("e500mc", true) 702243830Sdim .Case("e5500", true) 703249423Sdim .Case("power3", true) 704249423Sdim .Case("pwr3", true) 705249423Sdim .Case("power4", true) 706249423Sdim .Case("pwr4", true) 707249423Sdim .Case("power5", true) 708249423Sdim .Case("pwr5", true) 709249423Sdim .Case("power5x", true) 710249423Sdim .Case("pwr5x", true) 711249423Sdim .Case("power6", true) 712239462Sdim .Case("pwr6", true) 713249423Sdim .Case("power6x", true) 714249423Sdim .Case("pwr6x", true) 715249423Sdim .Case("power7", true) 716239462Sdim .Case("pwr7", true) 717249423Sdim .Case("powerpc", true) 718239462Sdim .Case("ppc", true) 719249423Sdim .Case("powerpc64", true) 720239462Sdim .Case("ppc64", true) 721239462Sdim .Default(false); 722239462Sdim 723239462Sdim if (CPUKnown) 724239462Sdim CPU = Name; 725239462Sdim 726239462Sdim return CPUKnown; 727239462Sdim } 728239462Sdim 729193326Sed virtual void getTargetBuiltins(const Builtin::Info *&Records, 730193326Sed unsigned &NumRecords) const { 731193326Sed Records = BuiltinInfo; 732193326Sed NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin; 733193326Sed } 734193326Sed 735234353Sdim virtual bool isCLZForZeroUndef() const { return false; } 736234353Sdim 737193326Sed virtual void getTargetDefines(const LangOptions &Opts, 738202379Srdivacky MacroBuilder &Builder) const; 739193326Sed 740249423Sdim virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const; 741249423Sdim 742249423Sdim virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 743249423Sdim StringRef Name, 744249423Sdim bool Enabled) const; 745249423Sdim 746234353Sdim virtual bool hasFeature(StringRef Feature) const; 747234353Sdim 748193326Sed virtual void getGCCRegNames(const char * const *&Names, 749193326Sed unsigned &NumNames) const; 750193326Sed virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 751193326Sed unsigned &NumAliases) const; 752193326Sed virtual bool validateAsmConstraint(const char *&Name, 753193326Sed TargetInfo::ConstraintInfo &Info) const { 754193326Sed switch (*Name) { 755193326Sed default: return false; 756193326Sed case 'O': // Zero 757210299Sed break; 758193326Sed case 'b': // Base register 759193326Sed case 'f': // Floating point register 760193326Sed Info.setAllowsRegister(); 761210299Sed break; 762210299Sed // FIXME: The following are added to allow parsing. 763210299Sed // I just took a guess at what the actions should be. 764210299Sed // Also, is more specific checking needed? I.e. specific registers? 765218893Sdim case 'd': // Floating point register (containing 64-bit value) 766210299Sed case 'v': // Altivec vector register 767210299Sed Info.setAllowsRegister(); 768210299Sed break; 769210299Sed case 'w': 770210299Sed switch (Name[1]) { 771218893Sdim case 'd':// VSX vector register to hold vector double data 772218893Sdim case 'f':// VSX vector register to hold vector float data 773218893Sdim case 's':// VSX vector register to hold scalar float data 774218893Sdim case 'a':// Any VSX register 775210299Sed break; 776210299Sed default: 777210299Sed return false; 778210299Sed } 779210299Sed Info.setAllowsRegister(); 780210299Sed Name++; // Skip over 'w'. 781210299Sed break; 782218893Sdim case 'h': // `MQ', `CTR', or `LINK' register 783218893Sdim case 'q': // `MQ' register 784218893Sdim case 'c': // `CTR' register 785218893Sdim case 'l': // `LINK' register 786218893Sdim case 'x': // `CR' register (condition register) number 0 787218893Sdim case 'y': // `CR' register (condition register) 788218893Sdim case 'z': // `XER[CA]' carry bit (part of the XER register) 789210299Sed Info.setAllowsRegister(); 790210299Sed break; 791218893Sdim case 'I': // Signed 16-bit constant 792210299Sed case 'J': // Unsigned 16-bit constant shifted left 16 bits 793218893Sdim // (use `L' instead for SImode constants) 794218893Sdim case 'K': // Unsigned 16-bit constant 795218893Sdim case 'L': // Signed 16-bit constant shifted left 16 bits 796218893Sdim case 'M': // Constant larger than 31 797218893Sdim case 'N': // Exact power of 2 798218893Sdim case 'P': // Constant whose negation is a signed 16-bit constant 799210299Sed case 'G': // Floating point constant that can be loaded into a 800218893Sdim // register with one instruction per word 801210299Sed case 'H': // Integer/Floating point constant that can be loaded 802218893Sdim // into a register using three instructions 803210299Sed break; 804210299Sed case 'm': // Memory operand. Note that on PowerPC targets, m can 805210299Sed // include addresses that update the base register. It 806210299Sed // is therefore only safe to use `m' in an asm statement 807210299Sed // if that asm statement accesses the operand exactly once. 808210299Sed // The asm statement must also use `%U<opno>' as a 809212904Sdim // placeholder for the "update" flag in the corresponding 810218893Sdim // load or store instruction. For example: 811210299Sed // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val)); 812218893Sdim // is correct but: 813210299Sed // asm ("st %1,%0" : "=m" (mem) : "r" (val)); 814210299Sed // is not. Use es rather than m if you don't want the base 815218893Sdim // register to be updated. 816218893Sdim case 'e': 817210299Sed if (Name[1] != 's') 818210299Sed return false; 819212904Sdim // es: A "stable" memory operand; that is, one which does not 820210299Sed // include any automodification of the base register. Unlike 821210299Sed // `m', this constraint can be used in asm statements that 822210299Sed // might access the operand several times, or that might not 823210299Sed // access it at all. 824210299Sed Info.setAllowsMemory(); 825210299Sed Name++; // Skip over 'e'. 826210299Sed break; 827210299Sed case 'Q': // Memory operand that is an offset from a register (it is 828218893Sdim // usually better to use `m' or `es' in asm statements) 829210299Sed case 'Z': // Memory operand that is an indexed or indirect from a 830210299Sed // register (it is usually better to use `m' or `es' in 831218893Sdim // asm statements) 832210299Sed Info.setAllowsMemory(); 833210299Sed Info.setAllowsRegister(); 834210299Sed break; 835218893Sdim case 'R': // AIX TOC entry 836210299Sed case 'a': // Address operand that is an indexed or indirect from a 837218893Sdim // register (`p' is preferable for asm statements) 838218893Sdim case 'S': // Constant suitable as a 64-bit mask operand 839218893Sdim case 'T': // Constant suitable as a 32-bit mask operand 840218893Sdim case 'U': // System V Release 4 small data area reference 841210299Sed case 't': // AND masks that can be performed by two rldic{l, r} 842218893Sdim // instructions 843218893Sdim case 'W': // Vector constant that does not require memory 844218893Sdim case 'j': // Vector constant that is all zeros. 845210299Sed break; 846210299Sed // End FIXME. 847193326Sed } 848210299Sed return true; 849193326Sed } 850193326Sed virtual const char *getClobbers() const { 851193326Sed return ""; 852193326Sed } 853249423Sdim int getEHDataRegisterNumber(unsigned RegNo) const { 854249423Sdim if (RegNo == 0) return 3; 855249423Sdim if (RegNo == 1) return 4; 856249423Sdim return -1; 857249423Sdim } 858193326Sed}; 859193326Sed 860193326Sedconst Builtin::Info PPCTargetInfo::BuiltinInfo[] = { 861224145Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, 862218893Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\ 863224145Sdim ALL_LANGUAGES }, 864194179Sed#include "clang/Basic/BuiltinsPPC.def" 865193326Sed}; 866193326Sed 867193326Sed 868193326Sed/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific 869193326Sed/// #defines that are not tied to a specific subtarget. 870193326Sedvoid PPCTargetInfo::getTargetDefines(const LangOptions &Opts, 871202379Srdivacky MacroBuilder &Builder) const { 872193326Sed // Target identification. 873202379Srdivacky Builder.defineMacro("__ppc__"); 874202379Srdivacky Builder.defineMacro("_ARCH_PPC"); 875204643Srdivacky Builder.defineMacro("__powerpc__"); 876202379Srdivacky Builder.defineMacro("__POWERPC__"); 877193326Sed if (PointerWidth == 64) { 878202379Srdivacky Builder.defineMacro("_ARCH_PPC64"); 879204643Srdivacky Builder.defineMacro("__powerpc64__"); 880202379Srdivacky Builder.defineMacro("__ppc64__"); 881193326Sed } else { 882202379Srdivacky Builder.defineMacro("__ppc__"); 883193326Sed } 884193326Sed 885193326Sed // Target properties. 886239462Sdim if (getTriple().getOS() != llvm::Triple::NetBSD && 887239462Sdim getTriple().getOS() != llvm::Triple::OpenBSD) 888224145Sdim Builder.defineMacro("_BIG_ENDIAN"); 889202379Srdivacky Builder.defineMacro("__BIG_ENDIAN__"); 890193326Sed 891193326Sed // Subtarget options. 892202379Srdivacky Builder.defineMacro("__NATURAL_ALIGNMENT__"); 893202379Srdivacky Builder.defineMacro("__REGISTER_PREFIX__", ""); 894193326Sed 895193326Sed // FIXME: Should be controlled by command line option. 896202379Srdivacky Builder.defineMacro("__LONG_DOUBLE_128__"); 897218893Sdim 898199990Srdivacky if (Opts.AltiVec) { 899202379Srdivacky Builder.defineMacro("__VEC__", "10206"); 900202379Srdivacky Builder.defineMacro("__ALTIVEC__"); 901199990Srdivacky } 902239462Sdim 903239462Sdim // CPU identification. 904239462Sdim ArchDefineTypes defs = (ArchDefineTypes)llvm::StringSwitch<int>(CPU) 905239462Sdim .Case("440", ArchDefineName) 906239462Sdim .Case("450", ArchDefineName | ArchDefine440) 907239462Sdim .Case("601", ArchDefineName) 908239462Sdim .Case("602", ArchDefineName | ArchDefinePpcgr) 909239462Sdim .Case("603", ArchDefineName | ArchDefinePpcgr) 910239462Sdim .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) 911239462Sdim .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) 912239462Sdim .Case("604", ArchDefineName | ArchDefinePpcgr) 913239462Sdim .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr) 914239462Sdim .Case("620", ArchDefineName | ArchDefinePpcgr) 915249423Sdim .Case("630", ArchDefineName | ArchDefinePpcgr) 916239462Sdim .Case("7400", ArchDefineName | ArchDefinePpcgr) 917239462Sdim .Case("7450", ArchDefineName | ArchDefinePpcgr) 918239462Sdim .Case("750", ArchDefineName | ArchDefinePpcgr) 919239462Sdim .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr 920239462Sdim | ArchDefinePpcsq) 921249423Sdim .Case("a2", ArchDefineA2) 922249423Sdim .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q) 923249423Sdim .Case("pwr3", ArchDefinePpcgr) 924249423Sdim .Case("pwr4", ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq) 925249423Sdim .Case("pwr5", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr 926239462Sdim | ArchDefinePpcsq) 927249423Sdim .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4 928249423Sdim | ArchDefinePpcgr | ArchDefinePpcsq) 929249423Sdim .Case("pwr6", ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5 930249423Sdim | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) 931249423Sdim .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x 932249423Sdim | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr 933249423Sdim | ArchDefinePpcsq) 934249423Sdim .Case("pwr7", ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6 935249423Sdim | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 936249423Sdim | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq) 937249423Sdim .Case("power3", ArchDefinePpcgr) 938249423Sdim .Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) 939249423Sdim .Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr 940249423Sdim | ArchDefinePpcsq) 941249423Sdim .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 942249423Sdim | ArchDefinePpcgr | ArchDefinePpcsq) 943249423Sdim .Case("power6", ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 944249423Sdim | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) 945249423Sdim .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x 946249423Sdim | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr 947249423Sdim | ArchDefinePpcsq) 948249423Sdim .Case("power7", ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 949249423Sdim | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 950249423Sdim | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq) 951239462Sdim .Default(ArchDefineNone); 952239462Sdim 953239462Sdim if (defs & ArchDefineName) 954239462Sdim Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper())); 955239462Sdim if (defs & ArchDefinePpcgr) 956239462Sdim Builder.defineMacro("_ARCH_PPCGR"); 957239462Sdim if (defs & ArchDefinePpcsq) 958239462Sdim Builder.defineMacro("_ARCH_PPCSQ"); 959239462Sdim if (defs & ArchDefine440) 960239462Sdim Builder.defineMacro("_ARCH_440"); 961239462Sdim if (defs & ArchDefine603) 962239462Sdim Builder.defineMacro("_ARCH_603"); 963239462Sdim if (defs & ArchDefine604) 964239462Sdim Builder.defineMacro("_ARCH_604"); 965249423Sdim if (defs & ArchDefinePwr4) 966239462Sdim Builder.defineMacro("_ARCH_PWR4"); 967249423Sdim if (defs & ArchDefinePwr5) 968239462Sdim Builder.defineMacro("_ARCH_PWR5"); 969249423Sdim if (defs & ArchDefinePwr5x) 970249423Sdim Builder.defineMacro("_ARCH_PWR5X"); 971249423Sdim if (defs & ArchDefinePwr6) 972239462Sdim Builder.defineMacro("_ARCH_PWR6"); 973249423Sdim if (defs & ArchDefinePwr6x) 974249423Sdim Builder.defineMacro("_ARCH_PWR6X"); 975249423Sdim if (defs & ArchDefinePwr7) 976249423Sdim Builder.defineMacro("_ARCH_PWR7"); 977249423Sdim if (defs & ArchDefineA2) 978249423Sdim Builder.defineMacro("_ARCH_A2"); 979249423Sdim if (defs & ArchDefineA2q) { 980249423Sdim Builder.defineMacro("_ARCH_A2Q"); 981249423Sdim Builder.defineMacro("_ARCH_QP"); 982239462Sdim } 983249423Sdim 984249423Sdim if (getTriple().getVendor() == llvm::Triple::BGQ) { 985249423Sdim Builder.defineMacro("__bg__"); 986249423Sdim Builder.defineMacro("__THW_BLUEGENE__"); 987249423Sdim Builder.defineMacro("__bgq__"); 988249423Sdim Builder.defineMacro("__TOS_BGQ__"); 989249423Sdim } 990249423Sdim 991249423Sdim // FIXME: The following are not yet generated here by Clang, but are 992249423Sdim // generated by GCC: 993249423Sdim // 994249423Sdim // _SOFT_FLOAT_ 995249423Sdim // __RECIP_PRECISION__ 996249423Sdim // __APPLE_ALTIVEC__ 997249423Sdim // __VSX__ 998249423Sdim // __RECIP__ 999249423Sdim // __RECIPF__ 1000249423Sdim // __RSQRTE__ 1001249423Sdim // __RSQRTEF__ 1002249423Sdim // _SOFT_DOUBLE_ 1003249423Sdim // __NO_LWSYNC__ 1004249423Sdim // __HAVE_BSWAP__ 1005249423Sdim // __LONGDOUBLE128 1006249423Sdim // __CMODEL_MEDIUM__ 1007249423Sdim // __CMODEL_LARGE__ 1008249423Sdim // _CALL_SYSV 1009249423Sdim // _CALL_DARWIN 1010249423Sdim // __NO_FPRS__ 1011193326Sed} 1012193326Sed 1013249423Sdimvoid PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { 1014249423Sdim Features["altivec"] = llvm::StringSwitch<bool>(CPU) 1015249423Sdim .Case("7400", true) 1016249423Sdim .Case("g4", true) 1017249423Sdim .Case("7450", true) 1018249423Sdim .Case("g4+", true) 1019249423Sdim .Case("970", true) 1020249423Sdim .Case("g5", true) 1021249423Sdim .Case("pwr6", true) 1022249423Sdim .Case("pwr7", true) 1023249423Sdim .Case("ppc64", true) 1024249423Sdim .Default(false); 1025249423Sdim 1026249423Sdim Features["qpx"] = (CPU == "a2q"); 1027249423Sdim} 1028249423Sdim 1029249423Sdimbool PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, 1030249423Sdim StringRef Name, 1031249423Sdim bool Enabled) const { 1032249423Sdim if (Name == "altivec" || Name == "fprnd" || Name == "mfocrf" || 1033249423Sdim Name == "popcntd" || Name == "qpx") { 1034249423Sdim Features[Name] = Enabled; 1035249423Sdim return true; 1036249423Sdim } 1037249423Sdim 1038249423Sdim return false; 1039249423Sdim} 1040249423Sdim 1041234353Sdimbool PPCTargetInfo::hasFeature(StringRef Feature) const { 1042234353Sdim return Feature == "powerpc"; 1043234353Sdim} 1044193326Sed 1045234353Sdim 1046193326Sedconst char * const PPCTargetInfo::GCCRegNames[] = { 1047198092Srdivacky "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1048198092Srdivacky "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 1049198092Srdivacky "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 1050198092Srdivacky "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 1051198092Srdivacky "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 1052198092Srdivacky "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", 1053198092Srdivacky "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 1054198092Srdivacky "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", 1055193326Sed "mq", "lr", "ctr", "ap", 1056198092Srdivacky "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", 1057193326Sed "xer", 1058198092Srdivacky "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", 1059198092Srdivacky "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", 1060198092Srdivacky "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", 1061198092Srdivacky "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", 1062193326Sed "vrsave", "vscr", 1063193326Sed "spe_acc", "spefscr", 1064193326Sed "sfp" 1065193326Sed}; 1066193326Sed 1067193326Sedvoid PPCTargetInfo::getGCCRegNames(const char * const *&Names, 1068193326Sed unsigned &NumNames) const { 1069193326Sed Names = GCCRegNames; 1070193326Sed NumNames = llvm::array_lengthof(GCCRegNames); 1071193326Sed} 1072193326Sed 1073193326Sedconst TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = { 1074193326Sed // While some of these aliases do map to different registers 1075193326Sed // they still share the same register name. 1076198092Srdivacky { { "0" }, "r0" }, 1077198092Srdivacky { { "1"}, "r1" }, 1078198092Srdivacky { { "2" }, "r2" }, 1079198092Srdivacky { { "3" }, "r3" }, 1080198092Srdivacky { { "4" }, "r4" }, 1081198092Srdivacky { { "5" }, "r5" }, 1082198092Srdivacky { { "6" }, "r6" }, 1083198092Srdivacky { { "7" }, "r7" }, 1084198092Srdivacky { { "8" }, "r8" }, 1085198092Srdivacky { { "9" }, "r9" }, 1086198092Srdivacky { { "10" }, "r10" }, 1087198092Srdivacky { { "11" }, "r11" }, 1088198092Srdivacky { { "12" }, "r12" }, 1089198092Srdivacky { { "13" }, "r13" }, 1090198092Srdivacky { { "14" }, "r14" }, 1091198092Srdivacky { { "15" }, "r15" }, 1092198092Srdivacky { { "16" }, "r16" }, 1093198092Srdivacky { { "17" }, "r17" }, 1094198092Srdivacky { { "18" }, "r18" }, 1095198092Srdivacky { { "19" }, "r19" }, 1096198092Srdivacky { { "20" }, "r20" }, 1097198092Srdivacky { { "21" }, "r21" }, 1098198092Srdivacky { { "22" }, "r22" }, 1099198092Srdivacky { { "23" }, "r23" }, 1100198092Srdivacky { { "24" }, "r24" }, 1101198092Srdivacky { { "25" }, "r25" }, 1102198092Srdivacky { { "26" }, "r26" }, 1103198092Srdivacky { { "27" }, "r27" }, 1104198092Srdivacky { { "28" }, "r28" }, 1105198092Srdivacky { { "29" }, "r29" }, 1106198092Srdivacky { { "30" }, "r30" }, 1107198092Srdivacky { { "31" }, "r31" }, 1108198092Srdivacky { { "fr0" }, "f0" }, 1109198092Srdivacky { { "fr1" }, "f1" }, 1110198092Srdivacky { { "fr2" }, "f2" }, 1111198092Srdivacky { { "fr3" }, "f3" }, 1112198092Srdivacky { { "fr4" }, "f4" }, 1113198092Srdivacky { { "fr5" }, "f5" }, 1114198092Srdivacky { { "fr6" }, "f6" }, 1115198092Srdivacky { { "fr7" }, "f7" }, 1116198092Srdivacky { { "fr8" }, "f8" }, 1117198092Srdivacky { { "fr9" }, "f9" }, 1118198092Srdivacky { { "fr10" }, "f10" }, 1119198092Srdivacky { { "fr11" }, "f11" }, 1120198092Srdivacky { { "fr12" }, "f12" }, 1121198092Srdivacky { { "fr13" }, "f13" }, 1122198092Srdivacky { { "fr14" }, "f14" }, 1123198092Srdivacky { { "fr15" }, "f15" }, 1124198092Srdivacky { { "fr16" }, "f16" }, 1125198092Srdivacky { { "fr17" }, "f17" }, 1126198092Srdivacky { { "fr18" }, "f18" }, 1127198092Srdivacky { { "fr19" }, "f19" }, 1128198092Srdivacky { { "fr20" }, "f20" }, 1129198092Srdivacky { { "fr21" }, "f21" }, 1130198092Srdivacky { { "fr22" }, "f22" }, 1131198092Srdivacky { { "fr23" }, "f23" }, 1132198092Srdivacky { { "fr24" }, "f24" }, 1133198092Srdivacky { { "fr25" }, "f25" }, 1134198092Srdivacky { { "fr26" }, "f26" }, 1135198092Srdivacky { { "fr27" }, "f27" }, 1136198092Srdivacky { { "fr28" }, "f28" }, 1137198092Srdivacky { { "fr29" }, "f29" }, 1138198092Srdivacky { { "fr30" }, "f30" }, 1139198092Srdivacky { { "fr31" }, "f31" }, 1140198092Srdivacky { { "cc" }, "cr0" }, 1141193326Sed}; 1142193326Sed 1143193326Sedvoid PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1144193326Sed unsigned &NumAliases) const { 1145193326Sed Aliases = GCCRegAliases; 1146193326Sed NumAliases = llvm::array_lengthof(GCCRegAliases); 1147193326Sed} 1148193326Sed} // end anonymous namespace. 1149193326Sed 1150193326Sednamespace { 1151193326Sedclass PPC32TargetInfo : public PPCTargetInfo { 1152193326Sedpublic: 1153204643Srdivacky PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) { 1154193326Sed DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1155199482Srdivacky "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32"; 1156204643Srdivacky 1157224145Sdim switch (getTriple().getOS()) { 1158234353Sdim case llvm::Triple::Linux: 1159224145Sdim case llvm::Triple::FreeBSD: 1160224145Sdim case llvm::Triple::NetBSD: 1161224145Sdim SizeType = UnsignedInt; 1162234353Sdim PtrDiffType = SignedInt; 1163234353Sdim IntPtrType = SignedInt; 1164224145Sdim break; 1165224145Sdim default: 1166224145Sdim break; 1167224145Sdim } 1168234353Sdim 1169234353Sdim if (getTriple().getOS() == llvm::Triple::FreeBSD) { 1170234353Sdim LongDoubleWidth = LongDoubleAlign = 64; 1171234353Sdim LongDoubleFormat = &llvm::APFloat::IEEEdouble; 1172234353Sdim } 1173243830Sdim 1174243830Sdim // PPC32 supports atomics up to 4 bytes. 1175243830Sdim MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; 1176193326Sed } 1177218893Sdim 1178239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 1179218893Sdim // This is the ELF definition, and is overridden by the Darwin sub-target 1180239462Sdim return TargetInfo::PowerABIBuiltinVaList; 1181218893Sdim } 1182193326Sed}; 1183193326Sed} // end anonymous namespace. 1184193326Sed 1185193326Sednamespace { 1186193326Sedclass PPC64TargetInfo : public PPCTargetInfo { 1187193326Sedpublic: 1188193326Sed PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) { 1189193326Sed LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 1190195341Sed IntMaxType = SignedLong; 1191195341Sed UIntMaxType = UnsignedLong; 1192195341Sed Int64Type = SignedLong; 1193234353Sdim 1194234353Sdim if (getTriple().getOS() == llvm::Triple::FreeBSD) { 1195234353Sdim LongDoubleWidth = LongDoubleAlign = 64; 1196234353Sdim LongDoubleFormat = &llvm::APFloat::IEEEdouble; 1197243830Sdim DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1198243830Sdim "i64:64:64-f32:32:32-f64:64:64-f128:64:64-" 1199243830Sdim "v128:128:128-n32:64"; 1200243830Sdim } else 1201243830Sdim DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1202243830Sdim "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" 1203243830Sdim "v128:128:128-n32:64"; 1204243830Sdim 1205243830Sdim // PPC64 supports atomics up to 8 bytes. 1206243830Sdim MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 1207193326Sed } 1208239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 1209239462Sdim return TargetInfo::CharPtrBuiltinVaList; 1210218893Sdim } 1211193326Sed}; 1212193326Sed} // end anonymous namespace. 1213193326Sed 1214210299Sed 1215193326Sednamespace { 1216218893Sdimclass DarwinPPC32TargetInfo : 1217218893Sdim public DarwinTargetInfo<PPC32TargetInfo> { 1218210299Sedpublic: 1219218893Sdim DarwinPPC32TargetInfo(const std::string& triple) 1220218893Sdim : DarwinTargetInfo<PPC32TargetInfo>(triple) { 1221210299Sed HasAlignMac68kSupport = true; 1222218893Sdim BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool? 1223234353Sdim LongLongAlign = 32; 1224234353Sdim SuitableAlign = 128; 1225234353Sdim DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1226234353Sdim "i64:32:64-f32:32:32-f64:64:64-v128:128:128-n32"; 1227210299Sed } 1228239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 1229239462Sdim return TargetInfo::CharPtrBuiltinVaList; 1230218893Sdim } 1231210299Sed}; 1232210299Sed 1233210299Sedclass DarwinPPC64TargetInfo : 1234210299Sed public DarwinTargetInfo<PPC64TargetInfo> { 1235210299Sedpublic: 1236210299Sed DarwinPPC64TargetInfo(const std::string& triple) 1237210299Sed : DarwinTargetInfo<PPC64TargetInfo>(triple) { 1238210299Sed HasAlignMac68kSupport = true; 1239234353Sdim SuitableAlign = 128; 1240243830Sdim DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 1241243830Sdim "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"; 1242210299Sed } 1243210299Sed}; 1244210299Sed} // end anonymous namespace. 1245210299Sed 1246210299Sednamespace { 1247239462Sdim static const unsigned NVPTXAddrSpaceMap[] = { 1248239462Sdim 1, // opencl_global 1249239462Sdim 3, // opencl_local 1250239462Sdim 4, // opencl_constant 1251239462Sdim 1, // cuda_device 1252239462Sdim 4, // cuda_constant 1253239462Sdim 3, // cuda_shared 1254226633Sdim }; 1255239462Sdim class NVPTXTargetInfo : public TargetInfo { 1256221345Sdim static const char * const GCCRegNames[]; 1257221345Sdim static const Builtin::Info BuiltinInfo[]; 1258249423Sdim std::vector<StringRef> AvailableFeatures; 1259221345Sdim public: 1260239462Sdim NVPTXTargetInfo(const std::string& triple) : TargetInfo(triple) { 1261234353Sdim BigEndian = false; 1262221345Sdim TLSSupported = false; 1263221345Sdim LongWidth = LongAlign = 64; 1264239462Sdim AddrSpaceMap = &NVPTXAddrSpaceMap; 1265226633Sdim // Define available target features 1266239462Sdim // These must be defined in sorted order! 1267239462Sdim NoAsmVariants = true; 1268221345Sdim } 1269221345Sdim virtual void getTargetDefines(const LangOptions &Opts, 1270221345Sdim MacroBuilder &Builder) const { 1271221345Sdim Builder.defineMacro("__PTX__"); 1272239462Sdim Builder.defineMacro("__NVPTX__"); 1273221345Sdim } 1274221345Sdim virtual void getTargetBuiltins(const Builtin::Info *&Records, 1275221345Sdim unsigned &NumRecords) const { 1276221345Sdim Records = BuiltinInfo; 1277239462Sdim NumRecords = clang::NVPTX::LastTSBuiltin-Builtin::FirstTSBuiltin; 1278221345Sdim } 1279234353Sdim virtual bool hasFeature(StringRef Feature) const { 1280239462Sdim return Feature == "ptx" || Feature == "nvptx"; 1281234353Sdim } 1282234353Sdim 1283221345Sdim virtual void getGCCRegNames(const char * const *&Names, 1284221345Sdim unsigned &NumNames) const; 1285221345Sdim virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1286221345Sdim unsigned &NumAliases) const { 1287221345Sdim // No aliases. 1288221345Sdim Aliases = 0; 1289221345Sdim NumAliases = 0; 1290221345Sdim } 1291221345Sdim virtual bool validateAsmConstraint(const char *&Name, 1292221345Sdim TargetInfo::ConstraintInfo &info) const { 1293221345Sdim // FIXME: implement 1294221345Sdim return true; 1295221345Sdim } 1296221345Sdim virtual const char *getClobbers() const { 1297221345Sdim // FIXME: Is this really right? 1298221345Sdim return ""; 1299221345Sdim } 1300239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 1301221345Sdim // FIXME: implement 1302239462Sdim return TargetInfo::CharPtrBuiltinVaList; 1303221345Sdim } 1304239462Sdim virtual bool setCPU(const std::string &Name) { 1305249423Sdim bool Valid = llvm::StringSwitch<bool>(Name) 1306249423Sdim .Case("sm_20", true) 1307249423Sdim .Case("sm_21", true) 1308249423Sdim .Case("sm_30", true) 1309249423Sdim .Case("sm_35", true) 1310249423Sdim .Default(false); 1311249423Sdim 1312249423Sdim return Valid; 1313239462Sdim } 1314226633Sdim virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 1315234353Sdim StringRef Name, 1316226633Sdim bool Enabled) const; 1317221345Sdim }; 1318221345Sdim 1319239462Sdim const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = { 1320224145Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, 1321221345Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\ 1322224145Sdim ALL_LANGUAGES }, 1323239462Sdim#include "clang/Basic/BuiltinsNVPTX.def" 1324221345Sdim }; 1325221345Sdim 1326239462Sdim const char * const NVPTXTargetInfo::GCCRegNames[] = { 1327221345Sdim "r0" 1328221345Sdim }; 1329221345Sdim 1330239462Sdim void NVPTXTargetInfo::getGCCRegNames(const char * const *&Names, 1331221345Sdim unsigned &NumNames) const { 1332221345Sdim Names = GCCRegNames; 1333221345Sdim NumNames = llvm::array_lengthof(GCCRegNames); 1334221345Sdim } 1335221345Sdim 1336239462Sdim bool NVPTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, 1337239462Sdim StringRef Name, 1338239462Sdim bool Enabled) const { 1339226633Sdim if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(), 1340226633Sdim Name)) { 1341226633Sdim Features[Name] = Enabled; 1342226633Sdim return true; 1343226633Sdim } else { 1344226633Sdim return false; 1345226633Sdim } 1346226633Sdim } 1347221345Sdim 1348239462Sdim class NVPTX32TargetInfo : public NVPTXTargetInfo { 1349221345Sdim public: 1350239462Sdim NVPTX32TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) { 1351221345Sdim PointerWidth = PointerAlign = 32; 1352239462Sdim SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt; 1353221345Sdim DescriptionString 1354239462Sdim = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" 1355239462Sdim "f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-" 1356239462Sdim "n16:32:64"; 1357239462Sdim } 1358221345Sdim }; 1359221345Sdim 1360239462Sdim class NVPTX64TargetInfo : public NVPTXTargetInfo { 1361221345Sdim public: 1362239462Sdim NVPTX64TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) { 1363221345Sdim PointerWidth = PointerAlign = 64; 1364239462Sdim SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong; 1365221345Sdim DescriptionString 1366239462Sdim = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" 1367239462Sdim "f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-" 1368239462Sdim "n16:32:64"; 1369239462Sdim } 1370221345Sdim }; 1371221345Sdim} 1372221345Sdim 1373221345Sdimnamespace { 1374243830Sdim 1375243830Sdimstatic const unsigned R600AddrSpaceMap[] = { 1376243830Sdim 1, // opencl_global 1377243830Sdim 3, // opencl_local 1378243830Sdim 2, // opencl_constant 1379243830Sdim 1, // cuda_device 1380243830Sdim 2, // cuda_constant 1381243830Sdim 3 // cuda_shared 1382243830Sdim}; 1383243830Sdim 1384249423Sdimstatic const char *DescriptionStringR600 = 1385249423Sdim "e" 1386249423Sdim "-p:32:32:32" 1387249423Sdim "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32" 1388249423Sdim "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128" 1389249423Sdim "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048" 1390249423Sdim "-n32:64"; 1391249423Sdim 1392249423Sdimstatic const char *DescriptionStringR600DoubleOps = 1393249423Sdim "e" 1394249423Sdim "-p:32:32:32" 1395249423Sdim "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64" 1396249423Sdim "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128" 1397249423Sdim "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048" 1398249423Sdim "-n32:64"; 1399249423Sdim 1400249423Sdimstatic const char *DescriptionStringSI = 1401249423Sdim "e" 1402249423Sdim "-p:64:64:64" 1403249423Sdim "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64" 1404249423Sdim "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128" 1405249423Sdim "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048" 1406249423Sdim "-n32:64"; 1407249423Sdim 1408243830Sdimclass R600TargetInfo : public TargetInfo { 1409249423Sdim /// \brief The GPU profiles supported by the R600 target. 1410249423Sdim enum GPUKind { 1411249423Sdim GK_NONE, 1412249423Sdim GK_R600, 1413249423Sdim GK_R600_DOUBLE_OPS, 1414249423Sdim GK_R700, 1415249423Sdim GK_R700_DOUBLE_OPS, 1416249423Sdim GK_EVERGREEN, 1417249423Sdim GK_EVERGREEN_DOUBLE_OPS, 1418249423Sdim GK_NORTHERN_ISLANDS, 1419249423Sdim GK_CAYMAN, 1420249423Sdim GK_SOUTHERN_ISLANDS 1421249423Sdim } GPU; 1422249423Sdim 1423243830Sdimpublic: 1424249423Sdim R600TargetInfo(const std::string& triple) 1425249423Sdim : TargetInfo(triple), 1426249423Sdim GPU(GK_R600) { 1427249423Sdim DescriptionString = DescriptionStringR600; 1428243830Sdim AddrSpaceMap = &R600AddrSpaceMap; 1429243830Sdim } 1430243830Sdim 1431243830Sdim virtual const char * getClobbers() const { 1432243830Sdim return ""; 1433243830Sdim } 1434243830Sdim 1435243830Sdim virtual void getGCCRegNames(const char * const *&Names, 1436243830Sdim unsigned &numNames) const { 1437243830Sdim Names = NULL; 1438243830Sdim numNames = 0; 1439243830Sdim } 1440243830Sdim 1441243830Sdim virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1442243830Sdim unsigned &NumAliases) const { 1443243830Sdim Aliases = NULL; 1444243830Sdim NumAliases = 0; 1445243830Sdim } 1446243830Sdim 1447243830Sdim virtual bool validateAsmConstraint(const char *&Name, 1448243830Sdim TargetInfo::ConstraintInfo &info) const { 1449243830Sdim return true; 1450243830Sdim } 1451243830Sdim 1452243830Sdim virtual void getTargetBuiltins(const Builtin::Info *&Records, 1453243830Sdim unsigned &NumRecords) const { 1454243830Sdim Records = NULL; 1455243830Sdim NumRecords = 0; 1456243830Sdim } 1457243830Sdim 1458243830Sdim 1459243830Sdim virtual void getTargetDefines(const LangOptions &Opts, 1460243830Sdim MacroBuilder &Builder) const { 1461243830Sdim Builder.defineMacro("__R600__"); 1462243830Sdim } 1463243830Sdim 1464243830Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 1465243830Sdim return TargetInfo::CharPtrBuiltinVaList; 1466243830Sdim } 1467243830Sdim 1468249423Sdim virtual bool setCPU(const std::string &Name) { 1469249423Sdim GPU = llvm::StringSwitch<GPUKind>(Name) 1470249423Sdim .Case("r600" , GK_R600) 1471249423Sdim .Case("rv610", GK_R600) 1472249423Sdim .Case("rv620", GK_R600) 1473249423Sdim .Case("rv630", GK_R600) 1474249423Sdim .Case("rv635", GK_R600) 1475249423Sdim .Case("rs780", GK_R600) 1476249423Sdim .Case("rs880", GK_R600) 1477249423Sdim .Case("rv670", GK_R600_DOUBLE_OPS) 1478249423Sdim .Case("rv710", GK_R700) 1479249423Sdim .Case("rv730", GK_R700) 1480249423Sdim .Case("rv740", GK_R700_DOUBLE_OPS) 1481249423Sdim .Case("rv770", GK_R700_DOUBLE_OPS) 1482249423Sdim .Case("palm", GK_EVERGREEN) 1483249423Sdim .Case("cedar", GK_EVERGREEN) 1484249423Sdim .Case("sumo", GK_EVERGREEN) 1485249423Sdim .Case("sumo2", GK_EVERGREEN) 1486249423Sdim .Case("redwood", GK_EVERGREEN) 1487249423Sdim .Case("juniper", GK_EVERGREEN) 1488249423Sdim .Case("hemlock", GK_EVERGREEN_DOUBLE_OPS) 1489249423Sdim .Case("cypress", GK_EVERGREEN_DOUBLE_OPS) 1490249423Sdim .Case("barts", GK_NORTHERN_ISLANDS) 1491249423Sdim .Case("turks", GK_NORTHERN_ISLANDS) 1492249423Sdim .Case("caicos", GK_NORTHERN_ISLANDS) 1493249423Sdim .Case("cayman", GK_CAYMAN) 1494249423Sdim .Case("aruba", GK_CAYMAN) 1495249423Sdim .Case("tahiti", GK_SOUTHERN_ISLANDS) 1496249423Sdim .Case("pitcairn", GK_SOUTHERN_ISLANDS) 1497249423Sdim .Case("verde", GK_SOUTHERN_ISLANDS) 1498249423Sdim .Case("oland", GK_SOUTHERN_ISLANDS) 1499249423Sdim .Default(GK_NONE); 1500249423Sdim 1501249423Sdim if (GPU == GK_NONE) { 1502249423Sdim return false; 1503249423Sdim } 1504249423Sdim 1505249423Sdim // Set the correct data layout 1506249423Sdim switch (GPU) { 1507249423Sdim case GK_NONE: 1508249423Sdim case GK_R600: 1509249423Sdim case GK_R700: 1510249423Sdim case GK_EVERGREEN: 1511249423Sdim case GK_NORTHERN_ISLANDS: 1512249423Sdim DescriptionString = DescriptionStringR600; 1513249423Sdim break; 1514249423Sdim case GK_R600_DOUBLE_OPS: 1515249423Sdim case GK_R700_DOUBLE_OPS: 1516249423Sdim case GK_EVERGREEN_DOUBLE_OPS: 1517249423Sdim case GK_CAYMAN: 1518249423Sdim DescriptionString = DescriptionStringR600DoubleOps; 1519249423Sdim break; 1520249423Sdim case GK_SOUTHERN_ISLANDS: 1521249423Sdim DescriptionString = DescriptionStringSI; 1522249423Sdim break; 1523249423Sdim } 1524249423Sdim 1525249423Sdim return true; 1526249423Sdim } 1527243830Sdim}; 1528243830Sdim 1529243830Sdim} // end anonymous namespace 1530243830Sdim 1531243830Sdimnamespace { 1532204962Srdivacky// MBlaze abstract base class 1533204962Srdivackyclass MBlazeTargetInfo : public TargetInfo { 1534204962Srdivacky static const char * const GCCRegNames[]; 1535204962Srdivacky static const TargetInfo::GCCRegAlias GCCRegAliases[]; 1536204962Srdivacky 1537204962Srdivackypublic: 1538204962Srdivacky MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) { 1539218893Sdim DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16"; 1540204962Srdivacky } 1541204962Srdivacky 1542204962Srdivacky virtual void getTargetBuiltins(const Builtin::Info *&Records, 1543204962Srdivacky unsigned &NumRecords) const { 1544204962Srdivacky // FIXME: Implement. 1545204962Srdivacky Records = 0; 1546204962Srdivacky NumRecords = 0; 1547204962Srdivacky } 1548204962Srdivacky 1549204962Srdivacky virtual void getTargetDefines(const LangOptions &Opts, 1550204962Srdivacky MacroBuilder &Builder) const; 1551204962Srdivacky 1552234353Sdim virtual bool hasFeature(StringRef Feature) const { 1553234353Sdim return Feature == "mblaze"; 1554234353Sdim } 1555234353Sdim 1556239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 1557239462Sdim return TargetInfo::CharPtrBuiltinVaList; 1558204962Srdivacky } 1559204962Srdivacky virtual const char *getTargetPrefix() const { 1560204962Srdivacky return "mblaze"; 1561204962Srdivacky } 1562204962Srdivacky virtual void getGCCRegNames(const char * const *&Names, 1563204962Srdivacky unsigned &NumNames) const; 1564204962Srdivacky virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1565204962Srdivacky unsigned &NumAliases) const; 1566204962Srdivacky virtual bool validateAsmConstraint(const char *&Name, 1567204962Srdivacky TargetInfo::ConstraintInfo &Info) const { 1568204962Srdivacky switch (*Name) { 1569204962Srdivacky default: return false; 1570204962Srdivacky case 'O': // Zero 1571204962Srdivacky return true; 1572204962Srdivacky case 'b': // Base register 1573204962Srdivacky case 'f': // Floating point register 1574204962Srdivacky Info.setAllowsRegister(); 1575204962Srdivacky return true; 1576204962Srdivacky } 1577204962Srdivacky } 1578204962Srdivacky virtual const char *getClobbers() const { 1579204962Srdivacky return ""; 1580204962Srdivacky } 1581204962Srdivacky}; 1582204962Srdivacky 1583204962Srdivacky/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific 1584204962Srdivacky/// #defines that are not tied to a specific subtarget. 1585204962Srdivackyvoid MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts, 1586204962Srdivacky MacroBuilder &Builder) const { 1587204962Srdivacky // Target identification. 1588204962Srdivacky Builder.defineMacro("__microblaze__"); 1589204962Srdivacky Builder.defineMacro("_ARCH_MICROBLAZE"); 1590204962Srdivacky Builder.defineMacro("__MICROBLAZE__"); 1591204962Srdivacky 1592204962Srdivacky // Target properties. 1593204962Srdivacky Builder.defineMacro("_BIG_ENDIAN"); 1594204962Srdivacky Builder.defineMacro("__BIG_ENDIAN__"); 1595204962Srdivacky 1596204962Srdivacky // Subtarget options. 1597204962Srdivacky Builder.defineMacro("__REGISTER_PREFIX__", ""); 1598204962Srdivacky} 1599204962Srdivacky 1600204962Srdivacky 1601204962Srdivackyconst char * const MBlazeTargetInfo::GCCRegNames[] = { 1602204962Srdivacky "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 1603204962Srdivacky "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 1604204962Srdivacky "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 1605204962Srdivacky "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 1606204962Srdivacky "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", 1607204962Srdivacky "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", 1608204962Srdivacky "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", 1609204962Srdivacky "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", 1610204962Srdivacky "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4", 1611204962Srdivacky "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp" 1612204962Srdivacky}; 1613204962Srdivacky 1614204962Srdivackyvoid MBlazeTargetInfo::getGCCRegNames(const char * const *&Names, 1615204962Srdivacky unsigned &NumNames) const { 1616204962Srdivacky Names = GCCRegNames; 1617204962Srdivacky NumNames = llvm::array_lengthof(GCCRegNames); 1618204962Srdivacky} 1619204962Srdivacky 1620204962Srdivackyconst TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = { 1621204962Srdivacky { {"f0"}, "r0" }, 1622204962Srdivacky { {"f1"}, "r1" }, 1623204962Srdivacky { {"f2"}, "r2" }, 1624204962Srdivacky { {"f3"}, "r3" }, 1625204962Srdivacky { {"f4"}, "r4" }, 1626204962Srdivacky { {"f5"}, "r5" }, 1627204962Srdivacky { {"f6"}, "r6" }, 1628204962Srdivacky { {"f7"}, "r7" }, 1629204962Srdivacky { {"f8"}, "r8" }, 1630204962Srdivacky { {"f9"}, "r9" }, 1631204962Srdivacky { {"f10"}, "r10" }, 1632204962Srdivacky { {"f11"}, "r11" }, 1633204962Srdivacky { {"f12"}, "r12" }, 1634204962Srdivacky { {"f13"}, "r13" }, 1635204962Srdivacky { {"f14"}, "r14" }, 1636204962Srdivacky { {"f15"}, "r15" }, 1637204962Srdivacky { {"f16"}, "r16" }, 1638204962Srdivacky { {"f17"}, "r17" }, 1639204962Srdivacky { {"f18"}, "r18" }, 1640204962Srdivacky { {"f19"}, "r19" }, 1641204962Srdivacky { {"f20"}, "r20" }, 1642204962Srdivacky { {"f21"}, "r21" }, 1643204962Srdivacky { {"f22"}, "r22" }, 1644204962Srdivacky { {"f23"}, "r23" }, 1645204962Srdivacky { {"f24"}, "r24" }, 1646204962Srdivacky { {"f25"}, "r25" }, 1647204962Srdivacky { {"f26"}, "r26" }, 1648204962Srdivacky { {"f27"}, "r27" }, 1649204962Srdivacky { {"f28"}, "r28" }, 1650204962Srdivacky { {"f29"}, "r29" }, 1651204962Srdivacky { {"f30"}, "r30" }, 1652204962Srdivacky { {"f31"}, "r31" }, 1653204962Srdivacky}; 1654204962Srdivacky 1655204962Srdivackyvoid MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 1656204962Srdivacky unsigned &NumAliases) const { 1657204962Srdivacky Aliases = GCCRegAliases; 1658204962Srdivacky NumAliases = llvm::array_lengthof(GCCRegAliases); 1659204962Srdivacky} 1660204962Srdivacky} // end anonymous namespace. 1661204962Srdivacky 1662204962Srdivackynamespace { 1663193326Sed// Namespace for x86 abstract base class 1664193326Sedconst Builtin::Info BuiltinInfo[] = { 1665224145Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, 1666218893Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\ 1667224145Sdim ALL_LANGUAGES }, 1668194179Sed#include "clang/Basic/BuiltinsX86.def" 1669193326Sed}; 1670193326Sed 1671201361Srdivackystatic const char* const GCCRegNames[] = { 1672193326Sed "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", 1673193326Sed "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", 1674224145Sdim "argp", "flags", "fpcr", "fpsr", "dirflag", "frame", 1675193326Sed "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", 1676193326Sed "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", 1677193326Sed "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 1678224145Sdim "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", 1679234353Sdim "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", 1680234353Sdim "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", 1681193326Sed}; 1682193326Sed 1683224145Sdimconst TargetInfo::AddlRegName AddlRegNames[] = { 1684224145Sdim { { "al", "ah", "eax", "rax" }, 0 }, 1685224145Sdim { { "bl", "bh", "ebx", "rbx" }, 3 }, 1686224145Sdim { { "cl", "ch", "ecx", "rcx" }, 2 }, 1687224145Sdim { { "dl", "dh", "edx", "rdx" }, 1 }, 1688224145Sdim { { "esi", "rsi" }, 4 }, 1689224145Sdim { { "edi", "rdi" }, 5 }, 1690224145Sdim { { "esp", "rsp" }, 7 }, 1691224145Sdim { { "ebp", "rbp" }, 6 }, 1692193326Sed}; 1693193326Sed 1694193326Sed// X86 target abstract base class; x86-32 and x86-64 are very close, so 1695193326Sed// most of the implementation can be shared. 1696193326Sedclass X86TargetInfo : public TargetInfo { 1697193326Sed enum X86SSEEnum { 1698234353Sdim NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2 1699193326Sed } SSELevel; 1700224145Sdim enum MMX3DNowEnum { 1701224145Sdim NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon 1702224145Sdim } MMX3DNowLevel; 1703203955Srdivacky 1704206125Srdivacky bool HasAES; 1705239462Sdim bool HasPCLMUL; 1706234353Sdim bool HasLZCNT; 1707239462Sdim bool HasRDRND; 1708234353Sdim bool HasBMI; 1709234353Sdim bool HasBMI2; 1710234353Sdim bool HasPOPCNT; 1711243830Sdim bool HasRTM; 1712249423Sdim bool HasPRFCHW; 1713249423Sdim bool HasRDSEED; 1714239462Sdim bool HasSSE4a; 1715234353Sdim bool HasFMA4; 1716239462Sdim bool HasFMA; 1717239462Sdim bool HasXOP; 1718243830Sdim bool HasF16C; 1719212904Sdim 1720226633Sdim /// \brief Enumeration of all of the X86 CPUs supported by Clang. 1721226633Sdim /// 1722226633Sdim /// Each enumeration represents a particular CPU supported by Clang. These 1723226633Sdim /// loosely correspond to the options passed to '-march' or '-mtune' flags. 1724226633Sdim enum CPUKind { 1725226633Sdim CK_Generic, 1726226633Sdim 1727226633Sdim /// \name i386 1728226633Sdim /// i386-generation processors. 1729226633Sdim //@{ 1730226633Sdim CK_i386, 1731226633Sdim //@} 1732226633Sdim 1733226633Sdim /// \name i486 1734226633Sdim /// i486-generation processors. 1735226633Sdim //@{ 1736226633Sdim CK_i486, 1737226633Sdim CK_WinChipC6, 1738226633Sdim CK_WinChip2, 1739226633Sdim CK_C3, 1740226633Sdim //@} 1741226633Sdim 1742226633Sdim /// \name i586 1743226633Sdim /// i586-generation processors, P5 microarchitecture based. 1744226633Sdim //@{ 1745226633Sdim CK_i586, 1746226633Sdim CK_Pentium, 1747226633Sdim CK_PentiumMMX, 1748226633Sdim //@} 1749226633Sdim 1750226633Sdim /// \name i686 1751226633Sdim /// i686-generation processors, P6 / Pentium M microarchitecture based. 1752226633Sdim //@{ 1753226633Sdim CK_i686, 1754226633Sdim CK_PentiumPro, 1755226633Sdim CK_Pentium2, 1756226633Sdim CK_Pentium3, 1757226633Sdim CK_Pentium3M, 1758226633Sdim CK_PentiumM, 1759226633Sdim CK_C3_2, 1760226633Sdim 1761226633Sdim /// This enumerator is a bit odd, as GCC no longer accepts -march=yonah. 1762226633Sdim /// Clang however has some logic to suport this. 1763226633Sdim // FIXME: Warn, deprecate, and potentially remove this. 1764226633Sdim CK_Yonah, 1765226633Sdim //@} 1766226633Sdim 1767226633Sdim /// \name Netburst 1768226633Sdim /// Netburst microarchitecture based processors. 1769226633Sdim //@{ 1770226633Sdim CK_Pentium4, 1771226633Sdim CK_Pentium4M, 1772226633Sdim CK_Prescott, 1773226633Sdim CK_Nocona, 1774226633Sdim //@} 1775226633Sdim 1776226633Sdim /// \name Core 1777226633Sdim /// Core microarchitecture based processors. 1778226633Sdim //@{ 1779226633Sdim CK_Core2, 1780226633Sdim 1781226633Sdim /// This enumerator, like \see CK_Yonah, is a bit odd. It is another 1782226633Sdim /// codename which GCC no longer accepts as an option to -march, but Clang 1783226633Sdim /// has some logic for recognizing it. 1784226633Sdim // FIXME: Warn, deprecate, and potentially remove this. 1785226633Sdim CK_Penryn, 1786226633Sdim //@} 1787226633Sdim 1788226633Sdim /// \name Atom 1789226633Sdim /// Atom processors 1790226633Sdim //@{ 1791226633Sdim CK_Atom, 1792226633Sdim //@} 1793226633Sdim 1794226633Sdim /// \name Nehalem 1795226633Sdim /// Nehalem microarchitecture based processors. 1796226633Sdim //@{ 1797226633Sdim CK_Corei7, 1798226633Sdim CK_Corei7AVX, 1799226633Sdim CK_CoreAVXi, 1800234353Sdim CK_CoreAVX2, 1801226633Sdim //@} 1802226633Sdim 1803226633Sdim /// \name K6 1804226633Sdim /// K6 architecture processors. 1805226633Sdim //@{ 1806226633Sdim CK_K6, 1807226633Sdim CK_K6_2, 1808226633Sdim CK_K6_3, 1809226633Sdim //@} 1810226633Sdim 1811226633Sdim /// \name K7 1812226633Sdim /// K7 architecture processors. 1813226633Sdim //@{ 1814226633Sdim CK_Athlon, 1815226633Sdim CK_AthlonThunderbird, 1816226633Sdim CK_Athlon4, 1817226633Sdim CK_AthlonXP, 1818226633Sdim CK_AthlonMP, 1819226633Sdim //@} 1820226633Sdim 1821226633Sdim /// \name K8 1822226633Sdim /// K8 architecture processors. 1823226633Sdim //@{ 1824226633Sdim CK_Athlon64, 1825226633Sdim CK_Athlon64SSE3, 1826226633Sdim CK_AthlonFX, 1827226633Sdim CK_K8, 1828226633Sdim CK_K8SSE3, 1829226633Sdim CK_Opteron, 1830226633Sdim CK_OpteronSSE3, 1831226951Sdim CK_AMDFAM10, 1832234353Sdim //@} 1833226633Sdim 1834234353Sdim /// \name Bobcat 1835234353Sdim /// Bobcat architecture processors. 1836234353Sdim //@{ 1837234353Sdim CK_BTVER1, 1838251662Sdim CK_BTVER2, 1839234353Sdim //@} 1840234353Sdim 1841234353Sdim /// \name Bulldozer 1842234353Sdim /// Bulldozer architecture processors. 1843234353Sdim //@{ 1844234353Sdim CK_BDVER1, 1845234353Sdim CK_BDVER2, 1846234353Sdim //@} 1847234353Sdim 1848226633Sdim /// This specification is deprecated and will be removed in the future. 1849226633Sdim /// Users should prefer \see CK_K8. 1850226633Sdim // FIXME: Warn on this when the CPU is set to it. 1851226633Sdim CK_x86_64, 1852226633Sdim //@} 1853226633Sdim 1854226633Sdim /// \name Geode 1855226633Sdim /// Geode processors. 1856226633Sdim //@{ 1857226633Sdim CK_Geode 1858226633Sdim //@} 1859226633Sdim } CPU; 1860226633Sdim 1861193326Sedpublic: 1862193326Sed X86TargetInfo(const std::string& triple) 1863224145Sdim : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow), 1864239462Sdim HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasRDRND(false), 1865243830Sdim HasBMI(false), HasBMI2(false), HasPOPCNT(false), HasRTM(false), 1866249423Sdim HasPRFCHW(false), HasRDSEED(false), HasSSE4a(false), HasFMA4(false), 1867249423Sdim HasFMA(false), HasXOP(false), HasF16C(false), CPU(CK_Generic) { 1868234353Sdim BigEndian = false; 1869193326Sed LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; 1870193326Sed } 1871234353Sdim virtual unsigned getFloatEvalMethod() const { 1872234353Sdim // X87 evaluates with 80 bits "long double" precision. 1873234353Sdim return SSELevel == NoSSE ? 2 : 0; 1874234353Sdim } 1875193326Sed virtual void getTargetBuiltins(const Builtin::Info *&Records, 1876193326Sed unsigned &NumRecords) const { 1877193326Sed Records = BuiltinInfo; 1878193326Sed NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin; 1879193326Sed } 1880193326Sed virtual void getGCCRegNames(const char * const *&Names, 1881193326Sed unsigned &NumNames) const { 1882193326Sed Names = GCCRegNames; 1883193326Sed NumNames = llvm::array_lengthof(GCCRegNames); 1884193326Sed } 1885193326Sed virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 1886193326Sed unsigned &NumAliases) const { 1887224145Sdim Aliases = 0; 1888224145Sdim NumAliases = 0; 1889193326Sed } 1890224145Sdim virtual void getGCCAddlRegNames(const AddlRegName *&Names, 1891249423Sdim unsigned &NumNames) const { 1892224145Sdim Names = AddlRegNames; 1893224145Sdim NumNames = llvm::array_lengthof(AddlRegNames); 1894224145Sdim } 1895193326Sed virtual bool validateAsmConstraint(const char *&Name, 1896193326Sed TargetInfo::ConstraintInfo &info) const; 1897223017Sdim virtual std::string convertConstraint(const char *&Constraint) const; 1898193326Sed virtual const char *getClobbers() const { 1899193326Sed return "~{dirflag},~{fpsr},~{flags}"; 1900193326Sed } 1901193326Sed virtual void getTargetDefines(const LangOptions &Opts, 1902202379Srdivacky MacroBuilder &Builder) const; 1903193326Sed virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 1904234353Sdim StringRef Name, 1905193326Sed bool Enabled) const; 1906226633Sdim virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const; 1907234353Sdim virtual bool hasFeature(StringRef Feature) const; 1908201361Srdivacky virtual void HandleTargetFeatures(std::vector<std::string> &Features); 1909224145Sdim virtual const char* getABI() const { 1910243830Sdim if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX) 1911234353Sdim return "avx"; 1912243830Sdim else if (getTriple().getArch() == llvm::Triple::x86 && 1913243830Sdim MMX3DNowLevel == NoMMX3DNow) 1914234353Sdim return "no-mmx"; 1915234353Sdim return ""; 1916224145Sdim } 1917226633Sdim virtual bool setCPU(const std::string &Name) { 1918226633Sdim CPU = llvm::StringSwitch<CPUKind>(Name) 1919226633Sdim .Case("i386", CK_i386) 1920226633Sdim .Case("i486", CK_i486) 1921226633Sdim .Case("winchip-c6", CK_WinChipC6) 1922226633Sdim .Case("winchip2", CK_WinChip2) 1923226633Sdim .Case("c3", CK_C3) 1924226633Sdim .Case("i586", CK_i586) 1925226633Sdim .Case("pentium", CK_Pentium) 1926226633Sdim .Case("pentium-mmx", CK_PentiumMMX) 1927226633Sdim .Case("i686", CK_i686) 1928226633Sdim .Case("pentiumpro", CK_PentiumPro) 1929226633Sdim .Case("pentium2", CK_Pentium2) 1930226633Sdim .Case("pentium3", CK_Pentium3) 1931226633Sdim .Case("pentium3m", CK_Pentium3M) 1932226633Sdim .Case("pentium-m", CK_PentiumM) 1933226633Sdim .Case("c3-2", CK_C3_2) 1934226633Sdim .Case("yonah", CK_Yonah) 1935226633Sdim .Case("pentium4", CK_Pentium4) 1936226633Sdim .Case("pentium4m", CK_Pentium4M) 1937226633Sdim .Case("prescott", CK_Prescott) 1938226633Sdim .Case("nocona", CK_Nocona) 1939226633Sdim .Case("core2", CK_Core2) 1940226633Sdim .Case("penryn", CK_Penryn) 1941226633Sdim .Case("atom", CK_Atom) 1942226633Sdim .Case("corei7", CK_Corei7) 1943226633Sdim .Case("corei7-avx", CK_Corei7AVX) 1944226633Sdim .Case("core-avx-i", CK_CoreAVXi) 1945234353Sdim .Case("core-avx2", CK_CoreAVX2) 1946226633Sdim .Case("k6", CK_K6) 1947226633Sdim .Case("k6-2", CK_K6_2) 1948226633Sdim .Case("k6-3", CK_K6_3) 1949226633Sdim .Case("athlon", CK_Athlon) 1950226633Sdim .Case("athlon-tbird", CK_AthlonThunderbird) 1951226633Sdim .Case("athlon-4", CK_Athlon4) 1952226633Sdim .Case("athlon-xp", CK_AthlonXP) 1953226633Sdim .Case("athlon-mp", CK_AthlonMP) 1954226633Sdim .Case("athlon64", CK_Athlon64) 1955226633Sdim .Case("athlon64-sse3", CK_Athlon64SSE3) 1956226633Sdim .Case("athlon-fx", CK_AthlonFX) 1957226633Sdim .Case("k8", CK_K8) 1958226633Sdim .Case("k8-sse3", CK_K8SSE3) 1959226633Sdim .Case("opteron", CK_Opteron) 1960226633Sdim .Case("opteron-sse3", CK_OpteronSSE3) 1961226951Sdim .Case("amdfam10", CK_AMDFAM10) 1962234353Sdim .Case("btver1", CK_BTVER1) 1963251662Sdim .Case("btver2", CK_BTVER2) 1964234353Sdim .Case("bdver1", CK_BDVER1) 1965234353Sdim .Case("bdver2", CK_BDVER2) 1966226633Sdim .Case("x86-64", CK_x86_64) 1967226633Sdim .Case("geode", CK_Geode) 1968226633Sdim .Default(CK_Generic); 1969226633Sdim 1970226633Sdim // Perform any per-CPU checks necessary to determine if this CPU is 1971226633Sdim // acceptable. 1972226633Sdim // FIXME: This results in terrible diagnostics. Clang just says the CPU is 1973226633Sdim // invalid without explaining *why*. 1974226633Sdim switch (CPU) { 1975226633Sdim case CK_Generic: 1976226633Sdim // No processor selected! 1977226633Sdim return false; 1978226633Sdim 1979226633Sdim case CK_i386: 1980226633Sdim case CK_i486: 1981226633Sdim case CK_WinChipC6: 1982226633Sdim case CK_WinChip2: 1983226633Sdim case CK_C3: 1984226633Sdim case CK_i586: 1985226633Sdim case CK_Pentium: 1986226633Sdim case CK_PentiumMMX: 1987226633Sdim case CK_i686: 1988226633Sdim case CK_PentiumPro: 1989226633Sdim case CK_Pentium2: 1990226633Sdim case CK_Pentium3: 1991226633Sdim case CK_Pentium3M: 1992226633Sdim case CK_PentiumM: 1993226633Sdim case CK_Yonah: 1994226633Sdim case CK_C3_2: 1995226633Sdim case CK_Pentium4: 1996226633Sdim case CK_Pentium4M: 1997226633Sdim case CK_Prescott: 1998226633Sdim case CK_K6: 1999226633Sdim case CK_K6_2: 2000226633Sdim case CK_K6_3: 2001226633Sdim case CK_Athlon: 2002226633Sdim case CK_AthlonThunderbird: 2003226633Sdim case CK_Athlon4: 2004226633Sdim case CK_AthlonXP: 2005226633Sdim case CK_AthlonMP: 2006226633Sdim case CK_Geode: 2007226633Sdim // Only accept certain architectures when compiling in 32-bit mode. 2008243830Sdim if (getTriple().getArch() != llvm::Triple::x86) 2009226633Sdim return false; 2010226633Sdim 2011226633Sdim // Fallthrough 2012226633Sdim case CK_Nocona: 2013226633Sdim case CK_Core2: 2014226633Sdim case CK_Penryn: 2015226633Sdim case CK_Atom: 2016226633Sdim case CK_Corei7: 2017226633Sdim case CK_Corei7AVX: 2018226633Sdim case CK_CoreAVXi: 2019234353Sdim case CK_CoreAVX2: 2020226633Sdim case CK_Athlon64: 2021226633Sdim case CK_Athlon64SSE3: 2022226633Sdim case CK_AthlonFX: 2023226633Sdim case CK_K8: 2024226633Sdim case CK_K8SSE3: 2025226633Sdim case CK_Opteron: 2026226633Sdim case CK_OpteronSSE3: 2027226951Sdim case CK_AMDFAM10: 2028234353Sdim case CK_BTVER1: 2029251662Sdim case CK_BTVER2: 2030234353Sdim case CK_BDVER1: 2031234353Sdim case CK_BDVER2: 2032226633Sdim case CK_x86_64: 2033226633Sdim return true; 2034226633Sdim } 2035226633Sdim llvm_unreachable("Unhandled CPU kind"); 2036226633Sdim } 2037243830Sdim 2038243830Sdim virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { 2039243830Sdim // We accept all non-ARM calling conventions 2040243830Sdim return (CC == CC_X86ThisCall || 2041243830Sdim CC == CC_X86FastCall || 2042243830Sdim CC == CC_X86StdCall || 2043243830Sdim CC == CC_C || 2044249423Sdim CC == CC_X86Pascal || 2045249423Sdim CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning; 2046243830Sdim } 2047243830Sdim 2048249423Sdim virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const { 2049249423Sdim return MT == CCMT_Member ? CC_X86ThisCall : CC_C; 2050243830Sdim } 2051193326Sed}; 2052193326Sed 2053226633Sdimvoid X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { 2054193326Sed // FIXME: This should not be here. 2055193326Sed Features["3dnow"] = false; 2056193326Sed Features["3dnowa"] = false; 2057193326Sed Features["mmx"] = false; 2058193326Sed Features["sse"] = false; 2059193326Sed Features["sse2"] = false; 2060193326Sed Features["sse3"] = false; 2061193326Sed Features["ssse3"] = false; 2062193326Sed Features["sse41"] = false; 2063193326Sed Features["sse42"] = false; 2064226951Sdim Features["sse4a"] = false; 2065206125Srdivacky Features["aes"] = false; 2066239462Sdim Features["pclmul"] = false; 2067212904Sdim Features["avx"] = false; 2068234353Sdim Features["avx2"] = false; 2069234353Sdim Features["lzcnt"] = false; 2070239462Sdim Features["rdrand"] = false; 2071234353Sdim Features["bmi"] = false; 2072234353Sdim Features["bmi2"] = false; 2073234353Sdim Features["popcnt"] = false; 2074243830Sdim Features["rtm"] = false; 2075249423Sdim Features["prfchw"] = false; 2076249423Sdim Features["rdseed"] = false; 2077234353Sdim Features["fma4"] = false; 2078239462Sdim Features["fma"] = false; 2079239462Sdim Features["xop"] = false; 2080243830Sdim Features["f16c"] = false; 2081193326Sed 2082193326Sed // FIXME: This *really* should not be here. 2083193326Sed 2084193326Sed // X86_64 always has SSE2. 2085243830Sdim if (getTriple().getArch() == llvm::Triple::x86_64) 2086249423Sdim setFeatureEnabled(Features, "sse2", true); 2087193326Sed 2088226633Sdim switch (CPU) { 2089226633Sdim case CK_Generic: 2090226633Sdim case CK_i386: 2091226633Sdim case CK_i486: 2092226633Sdim case CK_i586: 2093226633Sdim case CK_Pentium: 2094226633Sdim case CK_i686: 2095226633Sdim case CK_PentiumPro: 2096226633Sdim break; 2097226633Sdim case CK_PentiumMMX: 2098226633Sdim case CK_Pentium2: 2099193326Sed setFeatureEnabled(Features, "mmx", true); 2100226633Sdim break; 2101226633Sdim case CK_Pentium3: 2102226633Sdim case CK_Pentium3M: 2103193326Sed setFeatureEnabled(Features, "sse", true); 2104226633Sdim break; 2105226633Sdim case CK_PentiumM: 2106226633Sdim case CK_Pentium4: 2107226633Sdim case CK_Pentium4M: 2108226633Sdim case CK_x86_64: 2109193326Sed setFeatureEnabled(Features, "sse2", true); 2110226633Sdim break; 2111226633Sdim case CK_Yonah: 2112226633Sdim case CK_Prescott: 2113226633Sdim case CK_Nocona: 2114193326Sed setFeatureEnabled(Features, "sse3", true); 2115226633Sdim break; 2116226633Sdim case CK_Core2: 2117193326Sed setFeatureEnabled(Features, "ssse3", true); 2118226633Sdim break; 2119226633Sdim case CK_Penryn: 2120234353Sdim setFeatureEnabled(Features, "sse4.1", true); 2121226633Sdim break; 2122226633Sdim case CK_Atom: 2123226633Sdim setFeatureEnabled(Features, "ssse3", true); 2124226633Sdim break; 2125226633Sdim case CK_Corei7: 2126193326Sed setFeatureEnabled(Features, "sse4", true); 2127239462Sdim break; 2128239462Sdim case CK_Corei7AVX: 2129239462Sdim setFeatureEnabled(Features, "avx", true); 2130206125Srdivacky setFeatureEnabled(Features, "aes", true); 2131239462Sdim setFeatureEnabled(Features, "pclmul", true); 2132226633Sdim break; 2133226633Sdim case CK_CoreAVXi: 2134239462Sdim setFeatureEnabled(Features, "avx", true); 2135221345Sdim setFeatureEnabled(Features, "aes", true); 2136239462Sdim setFeatureEnabled(Features, "pclmul", true); 2137239462Sdim setFeatureEnabled(Features, "rdrnd", true); 2138249423Sdim setFeatureEnabled(Features, "f16c", true); 2139226633Sdim break; 2140234353Sdim case CK_CoreAVX2: 2141239462Sdim setFeatureEnabled(Features, "avx2", true); 2142234353Sdim setFeatureEnabled(Features, "aes", true); 2143239462Sdim setFeatureEnabled(Features, "pclmul", true); 2144234353Sdim setFeatureEnabled(Features, "lzcnt", true); 2145239462Sdim setFeatureEnabled(Features, "rdrnd", true); 2146249423Sdim setFeatureEnabled(Features, "f16c", true); 2147234353Sdim setFeatureEnabled(Features, "bmi", true); 2148234353Sdim setFeatureEnabled(Features, "bmi2", true); 2149243830Sdim setFeatureEnabled(Features, "rtm", true); 2150239462Sdim setFeatureEnabled(Features, "fma", true); 2151234353Sdim break; 2152226633Sdim case CK_K6: 2153226633Sdim case CK_WinChipC6: 2154193326Sed setFeatureEnabled(Features, "mmx", true); 2155226633Sdim break; 2156226633Sdim case CK_K6_2: 2157226633Sdim case CK_K6_3: 2158226633Sdim case CK_WinChip2: 2159226633Sdim case CK_C3: 2160193326Sed setFeatureEnabled(Features, "3dnow", true); 2161226633Sdim break; 2162226633Sdim case CK_Athlon: 2163226633Sdim case CK_AthlonThunderbird: 2164226633Sdim case CK_Geode: 2165226633Sdim setFeatureEnabled(Features, "3dnowa", true); 2166226633Sdim break; 2167226633Sdim case CK_Athlon4: 2168226633Sdim case CK_AthlonXP: 2169226633Sdim case CK_AthlonMP: 2170193326Sed setFeatureEnabled(Features, "sse", true); 2171193326Sed setFeatureEnabled(Features, "3dnowa", true); 2172226633Sdim break; 2173226633Sdim case CK_K8: 2174226633Sdim case CK_Opteron: 2175226633Sdim case CK_Athlon64: 2176226633Sdim case CK_AthlonFX: 2177198092Srdivacky setFeatureEnabled(Features, "sse2", true); 2178193326Sed setFeatureEnabled(Features, "3dnowa", true); 2179226633Sdim break; 2180226633Sdim case CK_K8SSE3: 2181226633Sdim case CK_OpteronSSE3: 2182226633Sdim case CK_Athlon64SSE3: 2183218893Sdim setFeatureEnabled(Features, "sse3", true); 2184218893Sdim setFeatureEnabled(Features, "3dnowa", true); 2185226633Sdim break; 2186226951Sdim case CK_AMDFAM10: 2187226951Sdim setFeatureEnabled(Features, "sse3", true); 2188226951Sdim setFeatureEnabled(Features, "sse4a", true); 2189226951Sdim setFeatureEnabled(Features, "3dnowa", true); 2190249423Sdim setFeatureEnabled(Features, "lzcnt", true); 2191249423Sdim setFeatureEnabled(Features, "popcnt", true); 2192226951Sdim break; 2193234353Sdim case CK_BTVER1: 2194234353Sdim setFeatureEnabled(Features, "ssse3", true); 2195234353Sdim setFeatureEnabled(Features, "sse4a", true); 2196249423Sdim setFeatureEnabled(Features, "lzcnt", true); 2197249423Sdim setFeatureEnabled(Features, "popcnt", true); 2198239462Sdim break; 2199251662Sdim case CK_BTVER2: 2200251662Sdim setFeatureEnabled(Features, "avx", true); 2201251662Sdim setFeatureEnabled(Features, "sse4a", true); 2202251662Sdim setFeatureEnabled(Features, "lzcnt", true); 2203251662Sdim setFeatureEnabled(Features, "aes", true); 2204251662Sdim setFeatureEnabled(Features, "pclmul", true); 2205251662Sdim setFeatureEnabled(Features, "bmi", true); 2206251662Sdim setFeatureEnabled(Features, "f16c", true); 2207251662Sdim break; 2208234353Sdim case CK_BDVER1: 2209249423Sdim setFeatureEnabled(Features, "xop", true); 2210249423Sdim setFeatureEnabled(Features, "lzcnt", true); 2211249423Sdim setFeatureEnabled(Features, "aes", true); 2212249423Sdim setFeatureEnabled(Features, "pclmul", true); 2213249423Sdim break; 2214234353Sdim case CK_BDVER2: 2215239462Sdim setFeatureEnabled(Features, "xop", true); 2216249423Sdim setFeatureEnabled(Features, "lzcnt", true); 2217234353Sdim setFeatureEnabled(Features, "aes", true); 2218239462Sdim setFeatureEnabled(Features, "pclmul", true); 2219249423Sdim setFeatureEnabled(Features, "bmi", true); 2220249423Sdim setFeatureEnabled(Features, "fma", true); 2221249423Sdim setFeatureEnabled(Features, "f16c", true); 2222234353Sdim break; 2223226633Sdim case CK_C3_2: 2224193326Sed setFeatureEnabled(Features, "sse", true); 2225226633Sdim break; 2226224145Sdim } 2227193326Sed} 2228193326Sed 2229193326Sedbool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, 2230234353Sdim StringRef Name, 2231193326Sed bool Enabled) const { 2232204793Srdivacky // FIXME: This *really* should not be here. We need some way of translating 2233204793Srdivacky // options into llvm subtarget features. 2234204793Srdivacky if (!Features.count(Name) && 2235239462Sdim (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1" && 2236239462Sdim Name != "rdrnd")) 2237193326Sed return false; 2238193326Sed 2239232894Sdim // FIXME: this should probably use a switch with fall through. 2240232894Sdim 2241193326Sed if (Enabled) { 2242193326Sed if (Name == "mmx") 2243193326Sed Features["mmx"] = true; 2244193326Sed else if (Name == "sse") 2245232894Sdim Features["mmx"] = Features["sse"] = true; 2246193326Sed else if (Name == "sse2") 2247232894Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = true; 2248193326Sed else if (Name == "sse3") 2249232894Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 2250232894Sdim true; 2251193326Sed else if (Name == "ssse3") 2252232894Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 2253193326Sed Features["ssse3"] = true; 2254204793Srdivacky else if (Name == "sse4" || Name == "sse4.2") 2255232894Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 2256234353Sdim Features["ssse3"] = Features["sse41"] = Features["sse42"] = 2257234353Sdim Features["popcnt"] = true; 2258204793Srdivacky else if (Name == "sse4.1") 2259232894Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 2260204793Srdivacky Features["ssse3"] = Features["sse41"] = true; 2261193326Sed else if (Name == "3dnow") 2262224145Sdim Features["mmx"] = Features["3dnow"] = true; 2263193326Sed else if (Name == "3dnowa") 2264224145Sdim Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = true; 2265206125Srdivacky else if (Name == "aes") 2266239462Sdim Features["sse"] = Features["sse2"] = Features["aes"] = true; 2267239462Sdim else if (Name == "pclmul") 2268239462Sdim Features["sse"] = Features["sse2"] = Features["pclmul"] = true; 2269212904Sdim else if (Name == "avx") 2270232894Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 2271232894Sdim Features["ssse3"] = Features["sse41"] = Features["sse42"] = 2272234353Sdim Features["popcnt"] = Features["avx"] = true; 2273234353Sdim else if (Name == "avx2") 2274234353Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 2275234353Sdim Features["ssse3"] = Features["sse41"] = Features["sse42"] = 2276234353Sdim Features["popcnt"] = Features["avx"] = Features["avx2"] = true; 2277239462Sdim else if (Name == "fma") 2278239462Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 2279239462Sdim Features["ssse3"] = Features["sse41"] = Features["sse42"] = 2280239462Sdim Features["popcnt"] = Features["avx"] = Features["fma"] = true; 2281234353Sdim else if (Name == "fma4") 2282249423Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 2283234353Sdim Features["ssse3"] = Features["sse41"] = Features["sse42"] = 2284239462Sdim Features["popcnt"] = Features["avx"] = Features["sse4a"] = 2285239462Sdim Features["fma4"] = true; 2286239462Sdim else if (Name == "xop") 2287249423Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 2288239462Sdim Features["ssse3"] = Features["sse41"] = Features["sse42"] = 2289239462Sdim Features["popcnt"] = Features["avx"] = Features["sse4a"] = 2290239462Sdim Features["fma4"] = Features["xop"] = true; 2291226951Sdim else if (Name == "sse4a") 2292234353Sdim Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = 2293239462Sdim Features["sse4a"] = true; 2294234353Sdim else if (Name == "lzcnt") 2295234353Sdim Features["lzcnt"] = true; 2296239462Sdim else if (Name == "rdrnd") 2297239462Sdim Features["rdrand"] = true; 2298234353Sdim else if (Name == "bmi") 2299234353Sdim Features["bmi"] = true; 2300234353Sdim else if (Name == "bmi2") 2301234353Sdim Features["bmi2"] = true; 2302234353Sdim else if (Name == "popcnt") 2303234353Sdim Features["popcnt"] = true; 2304243830Sdim else if (Name == "f16c") 2305243830Sdim Features["f16c"] = true; 2306243830Sdim else if (Name == "rtm") 2307243830Sdim Features["rtm"] = true; 2308249423Sdim else if (Name == "prfchw") 2309249423Sdim Features["prfchw"] = true; 2310249423Sdim else if (Name == "rdseed") 2311249423Sdim Features["rdseed"] = true; 2312193326Sed } else { 2313193326Sed if (Name == "mmx") 2314224145Sdim Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false; 2315193326Sed else if (Name == "sse") 2316198092Srdivacky Features["sse"] = Features["sse2"] = Features["sse3"] = 2317234353Sdim Features["ssse3"] = Features["sse41"] = Features["sse42"] = 2318239462Sdim Features["sse4a"] = Features["avx"] = Features["avx2"] = 2319239462Sdim Features["fma"] = Features["fma4"] = Features["aes"] = 2320239462Sdim Features["pclmul"] = Features["xop"] = false; 2321193326Sed else if (Name == "sse2") 2322198092Srdivacky Features["sse2"] = Features["sse3"] = Features["ssse3"] = 2323239462Sdim Features["sse41"] = Features["sse42"] = Features["sse4a"] = 2324239462Sdim Features["avx"] = Features["avx2"] = Features["fma"] = 2325239462Sdim Features["fma4"] = Features["aes"] = Features["pclmul"] = 2326239462Sdim Features["xop"] = false; 2327193326Sed else if (Name == "sse3") 2328198092Srdivacky Features["sse3"] = Features["ssse3"] = Features["sse41"] = 2329239462Sdim Features["sse42"] = Features["sse4a"] = Features["avx"] = 2330239462Sdim Features["avx2"] = Features["fma"] = Features["fma4"] = 2331239462Sdim Features["xop"] = false; 2332193326Sed else if (Name == "ssse3") 2333239462Sdim Features["ssse3"] = Features["sse41"] = Features["sse42"] = 2334239462Sdim Features["avx"] = Features["avx2"] = Features["fma"] = false; 2335220754Sdim else if (Name == "sse4" || Name == "sse4.1") 2336239462Sdim Features["sse41"] = Features["sse42"] = Features["avx"] = 2337239462Sdim Features["avx2"] = Features["fma"] = false; 2338204793Srdivacky else if (Name == "sse4.2") 2339239462Sdim Features["sse42"] = Features["avx"] = Features["avx2"] = 2340239462Sdim Features["fma"] = false; 2341193326Sed else if (Name == "3dnow") 2342193326Sed Features["3dnow"] = Features["3dnowa"] = false; 2343193326Sed else if (Name == "3dnowa") 2344193326Sed Features["3dnowa"] = false; 2345206125Srdivacky else if (Name == "aes") 2346206125Srdivacky Features["aes"] = false; 2347239462Sdim else if (Name == "pclmul") 2348239462Sdim Features["pclmul"] = false; 2349212904Sdim else if (Name == "avx") 2350239462Sdim Features["avx"] = Features["avx2"] = Features["fma"] = 2351239462Sdim Features["fma4"] = Features["xop"] = false; 2352234353Sdim else if (Name == "avx2") 2353234353Sdim Features["avx2"] = false; 2354239462Sdim else if (Name == "fma") 2355239462Sdim Features["fma"] = false; 2356226951Sdim else if (Name == "sse4a") 2357239462Sdim Features["sse4a"] = Features["fma4"] = Features["xop"] = false; 2358234353Sdim else if (Name == "lzcnt") 2359234353Sdim Features["lzcnt"] = false; 2360239462Sdim else if (Name == "rdrnd") 2361239462Sdim Features["rdrand"] = false; 2362234353Sdim else if (Name == "bmi") 2363234353Sdim Features["bmi"] = false; 2364234353Sdim else if (Name == "bmi2") 2365234353Sdim Features["bmi2"] = false; 2366234353Sdim else if (Name == "popcnt") 2367234353Sdim Features["popcnt"] = false; 2368234353Sdim else if (Name == "fma4") 2369239462Sdim Features["fma4"] = Features["xop"] = false; 2370239462Sdim else if (Name == "xop") 2371239462Sdim Features["xop"] = false; 2372243830Sdim else if (Name == "f16c") 2373243830Sdim Features["f16c"] = false; 2374243830Sdim else if (Name == "rtm") 2375243830Sdim Features["rtm"] = false; 2376249423Sdim else if (Name == "prfchw") 2377249423Sdim Features["prfchw"] = false; 2378249423Sdim else if (Name == "rdseed") 2379249423Sdim Features["rdseed"] = false; 2380193326Sed } 2381193326Sed 2382193326Sed return true; 2383193326Sed} 2384193326Sed 2385193326Sed/// HandleTargetOptions - Perform initialization based on the user 2386193326Sed/// configured set of features. 2387201361Srdivackyvoid X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { 2388199482Srdivacky // Remember the maximum enabled sselevel. 2389199482Srdivacky for (unsigned i = 0, e = Features.size(); i !=e; ++i) { 2390199482Srdivacky // Ignore disabled features. 2391199482Srdivacky if (Features[i][0] == '-') 2392199482Srdivacky continue; 2393199482Srdivacky 2394234353Sdim StringRef Feature = StringRef(Features[i]).substr(1); 2395234353Sdim 2396234353Sdim if (Feature == "aes") { 2397206125Srdivacky HasAES = true; 2398206125Srdivacky continue; 2399206125Srdivacky } 2400206125Srdivacky 2401239462Sdim if (Feature == "pclmul") { 2402239462Sdim HasPCLMUL = true; 2403239462Sdim continue; 2404239462Sdim } 2405239462Sdim 2406234353Sdim if (Feature == "lzcnt") { 2407234353Sdim HasLZCNT = true; 2408212904Sdim continue; 2409212904Sdim } 2410212904Sdim 2411239462Sdim if (Feature == "rdrand") { 2412239462Sdim HasRDRND = true; 2413239462Sdim continue; 2414239462Sdim } 2415239462Sdim 2416234353Sdim if (Feature == "bmi") { 2417234353Sdim HasBMI = true; 2418234353Sdim continue; 2419234353Sdim } 2420234353Sdim 2421234353Sdim if (Feature == "bmi2") { 2422234353Sdim HasBMI2 = true; 2423234353Sdim continue; 2424234353Sdim } 2425234353Sdim 2426234353Sdim if (Feature == "popcnt") { 2427234353Sdim HasPOPCNT = true; 2428234353Sdim continue; 2429234353Sdim } 2430234353Sdim 2431243830Sdim if (Feature == "rtm") { 2432243830Sdim HasRTM = true; 2433243830Sdim continue; 2434243830Sdim } 2435243830Sdim 2436249423Sdim if (Feature == "prfchw") { 2437249423Sdim HasPRFCHW = true; 2438249423Sdim continue; 2439249423Sdim } 2440249423Sdim 2441249423Sdim if (Feature == "rdseed") { 2442249423Sdim HasRDSEED = true; 2443249423Sdim continue; 2444249423Sdim } 2445249423Sdim 2446239462Sdim if (Feature == "sse4a") { 2447239462Sdim HasSSE4a = true; 2448239462Sdim continue; 2449239462Sdim } 2450239462Sdim 2451234353Sdim if (Feature == "fma4") { 2452234353Sdim HasFMA4 = true; 2453234353Sdim continue; 2454234353Sdim } 2455234353Sdim 2456239462Sdim if (Feature == "fma") { 2457239462Sdim HasFMA = true; 2458239462Sdim continue; 2459239462Sdim } 2460239462Sdim 2461239462Sdim if (Feature == "xop") { 2462239462Sdim HasXOP = true; 2463239462Sdim continue; 2464239462Sdim } 2465239462Sdim 2466243830Sdim if (Feature == "f16c") { 2467243830Sdim HasF16C = true; 2468243830Sdim continue; 2469243830Sdim } 2470243830Sdim 2471199482Srdivacky assert(Features[i][0] == '+' && "Invalid target feature!"); 2472234353Sdim X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) 2473234353Sdim .Case("avx2", AVX2) 2474234353Sdim .Case("avx", AVX) 2475199482Srdivacky .Case("sse42", SSE42) 2476199482Srdivacky .Case("sse41", SSE41) 2477199482Srdivacky .Case("ssse3", SSSE3) 2478205219Srdivacky .Case("sse3", SSE3) 2479199482Srdivacky .Case("sse2", SSE2) 2480199482Srdivacky .Case("sse", SSE1) 2481224145Sdim .Default(NoSSE); 2482199482Srdivacky SSELevel = std::max(SSELevel, Level); 2483218893Sdim 2484224145Sdim MMX3DNowEnum ThreeDNowLevel = 2485234353Sdim llvm::StringSwitch<MMX3DNowEnum>(Feature) 2486203955Srdivacky .Case("3dnowa", AMD3DNowAthlon) 2487203955Srdivacky .Case("3dnow", AMD3DNow) 2488224145Sdim .Case("mmx", MMX) 2489224145Sdim .Default(NoMMX3DNow); 2490218893Sdim 2491224145Sdim MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel); 2492199482Srdivacky } 2493224145Sdim 2494224145Sdim // Don't tell the backend if we're turning off mmx; it will end up disabling 2495224145Sdim // SSE, which we don't want. 2496224145Sdim std::vector<std::string>::iterator it; 2497224145Sdim it = std::find(Features.begin(), Features.end(), "-mmx"); 2498224145Sdim if (it != Features.end()) 2499224145Sdim Features.erase(it); 2500193326Sed} 2501193326Sed 2502226633Sdim/// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro 2503226633Sdim/// definitions for this particular subtarget. 2504193326Sedvoid X86TargetInfo::getTargetDefines(const LangOptions &Opts, 2505202379Srdivacky MacroBuilder &Builder) const { 2506193326Sed // Target identification. 2507243830Sdim if (getTriple().getArch() == llvm::Triple::x86_64) { 2508202379Srdivacky Builder.defineMacro("__amd64__"); 2509202379Srdivacky Builder.defineMacro("__amd64"); 2510202379Srdivacky Builder.defineMacro("__x86_64"); 2511202379Srdivacky Builder.defineMacro("__x86_64__"); 2512193326Sed } else { 2513202379Srdivacky DefineStd(Builder, "i386", Opts); 2514193326Sed } 2515193326Sed 2516226633Sdim // Subtarget options. 2517226633Sdim // FIXME: We are hard-coding the tune parameters based on the CPU, but they 2518226633Sdim // truly should be based on -mtune options. 2519226633Sdim switch (CPU) { 2520226633Sdim case CK_Generic: 2521226633Sdim break; 2522226633Sdim case CK_i386: 2523226633Sdim // The rest are coming from the i386 define above. 2524226633Sdim Builder.defineMacro("__tune_i386__"); 2525226633Sdim break; 2526226633Sdim case CK_i486: 2527226633Sdim case CK_WinChipC6: 2528226633Sdim case CK_WinChip2: 2529226633Sdim case CK_C3: 2530234353Sdim defineCPUMacros(Builder, "i486"); 2531226633Sdim break; 2532226633Sdim case CK_PentiumMMX: 2533226633Sdim Builder.defineMacro("__pentium_mmx__"); 2534226633Sdim Builder.defineMacro("__tune_pentium_mmx__"); 2535226633Sdim // Fallthrough 2536226633Sdim case CK_i586: 2537226633Sdim case CK_Pentium: 2538234353Sdim defineCPUMacros(Builder, "i586"); 2539234353Sdim defineCPUMacros(Builder, "pentium"); 2540226633Sdim break; 2541226633Sdim case CK_Pentium3: 2542226633Sdim case CK_Pentium3M: 2543226633Sdim case CK_PentiumM: 2544226633Sdim Builder.defineMacro("__tune_pentium3__"); 2545226633Sdim // Fallthrough 2546226633Sdim case CK_Pentium2: 2547226633Sdim case CK_C3_2: 2548226633Sdim Builder.defineMacro("__tune_pentium2__"); 2549226633Sdim // Fallthrough 2550226633Sdim case CK_PentiumPro: 2551226633Sdim Builder.defineMacro("__tune_i686__"); 2552226633Sdim Builder.defineMacro("__tune_pentiumpro__"); 2553226633Sdim // Fallthrough 2554226633Sdim case CK_i686: 2555226633Sdim Builder.defineMacro("__i686"); 2556226633Sdim Builder.defineMacro("__i686__"); 2557226633Sdim // Strangely, __tune_i686__ isn't defined by GCC when CPU == i686. 2558226633Sdim Builder.defineMacro("__pentiumpro"); 2559226633Sdim Builder.defineMacro("__pentiumpro__"); 2560226633Sdim break; 2561226633Sdim case CK_Pentium4: 2562226633Sdim case CK_Pentium4M: 2563234353Sdim defineCPUMacros(Builder, "pentium4"); 2564226633Sdim break; 2565226633Sdim case CK_Yonah: 2566226633Sdim case CK_Prescott: 2567226633Sdim case CK_Nocona: 2568234353Sdim defineCPUMacros(Builder, "nocona"); 2569226633Sdim break; 2570226633Sdim case CK_Core2: 2571226633Sdim case CK_Penryn: 2572234353Sdim defineCPUMacros(Builder, "core2"); 2573226633Sdim break; 2574226633Sdim case CK_Atom: 2575234353Sdim defineCPUMacros(Builder, "atom"); 2576226633Sdim break; 2577226633Sdim case CK_Corei7: 2578226633Sdim case CK_Corei7AVX: 2579226633Sdim case CK_CoreAVXi: 2580234353Sdim case CK_CoreAVX2: 2581234353Sdim defineCPUMacros(Builder, "corei7"); 2582226633Sdim break; 2583226633Sdim case CK_K6_2: 2584226633Sdim Builder.defineMacro("__k6_2__"); 2585226633Sdim Builder.defineMacro("__tune_k6_2__"); 2586226633Sdim // Fallthrough 2587226633Sdim case CK_K6_3: 2588226633Sdim if (CPU != CK_K6_2) { // In case of fallthrough 2589226633Sdim // FIXME: GCC may be enabling these in cases where some other k6 2590226633Sdim // architecture is specified but -m3dnow is explicitly provided. The 2591226633Sdim // exact semantics need to be determined and emulated here. 2592226633Sdim Builder.defineMacro("__k6_3__"); 2593226633Sdim Builder.defineMacro("__tune_k6_3__"); 2594226633Sdim } 2595226633Sdim // Fallthrough 2596226633Sdim case CK_K6: 2597234353Sdim defineCPUMacros(Builder, "k6"); 2598226633Sdim break; 2599226633Sdim case CK_Athlon: 2600226633Sdim case CK_AthlonThunderbird: 2601226633Sdim case CK_Athlon4: 2602226633Sdim case CK_AthlonXP: 2603226633Sdim case CK_AthlonMP: 2604234353Sdim defineCPUMacros(Builder, "athlon"); 2605226633Sdim if (SSELevel != NoSSE) { 2606226633Sdim Builder.defineMacro("__athlon_sse__"); 2607226633Sdim Builder.defineMacro("__tune_athlon_sse__"); 2608226633Sdim } 2609226633Sdim break; 2610226633Sdim case CK_K8: 2611226633Sdim case CK_K8SSE3: 2612226633Sdim case CK_x86_64: 2613226633Sdim case CK_Opteron: 2614226633Sdim case CK_OpteronSSE3: 2615226633Sdim case CK_Athlon64: 2616226633Sdim case CK_Athlon64SSE3: 2617226633Sdim case CK_AthlonFX: 2618234353Sdim defineCPUMacros(Builder, "k8"); 2619226633Sdim break; 2620226951Sdim case CK_AMDFAM10: 2621234353Sdim defineCPUMacros(Builder, "amdfam10"); 2622226951Sdim break; 2623234353Sdim case CK_BTVER1: 2624234353Sdim defineCPUMacros(Builder, "btver1"); 2625234353Sdim break; 2626251662Sdim case CK_BTVER2: 2627251662Sdim defineCPUMacros(Builder, "btver2"); 2628251662Sdim break; 2629234353Sdim case CK_BDVER1: 2630234353Sdim defineCPUMacros(Builder, "bdver1"); 2631234353Sdim break; 2632234353Sdim case CK_BDVER2: 2633234353Sdim defineCPUMacros(Builder, "bdver2"); 2634234353Sdim break; 2635226633Sdim case CK_Geode: 2636234353Sdim defineCPUMacros(Builder, "geode"); 2637226633Sdim break; 2638226633Sdim } 2639206125Srdivacky 2640193326Sed // Target properties. 2641202379Srdivacky Builder.defineMacro("__LITTLE_ENDIAN__"); 2642202379Srdivacky Builder.defineMacro("__REGISTER_PREFIX__", ""); 2643193326Sed 2644193326Sed // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline 2645193326Sed // functions in glibc header files that use FP Stack inline asm which the 2646193326Sed // backend can't deal with (PR879). 2647202379Srdivacky Builder.defineMacro("__NO_MATH_INLINES"); 2648193326Sed 2649226633Sdim if (HasAES) 2650226633Sdim Builder.defineMacro("__AES__"); 2651226633Sdim 2652239462Sdim if (HasPCLMUL) 2653239462Sdim Builder.defineMacro("__PCLMUL__"); 2654239462Sdim 2655234353Sdim if (HasLZCNT) 2656234353Sdim Builder.defineMacro("__LZCNT__"); 2657226633Sdim 2658239462Sdim if (HasRDRND) 2659239462Sdim Builder.defineMacro("__RDRND__"); 2660239462Sdim 2661234353Sdim if (HasBMI) 2662234353Sdim Builder.defineMacro("__BMI__"); 2663234353Sdim 2664234353Sdim if (HasBMI2) 2665234353Sdim Builder.defineMacro("__BMI2__"); 2666234353Sdim 2667234353Sdim if (HasPOPCNT) 2668234353Sdim Builder.defineMacro("__POPCNT__"); 2669234353Sdim 2670243830Sdim if (HasRTM) 2671243830Sdim Builder.defineMacro("__RTM__"); 2672243830Sdim 2673249423Sdim if (HasPRFCHW) 2674249423Sdim Builder.defineMacro("__PRFCHW__"); 2675249423Sdim 2676249423Sdim if (HasRDSEED) 2677249423Sdim Builder.defineMacro("__RDSEED__"); 2678249423Sdim 2679239462Sdim if (HasSSE4a) 2680239462Sdim Builder.defineMacro("__SSE4A__"); 2681239462Sdim 2682234353Sdim if (HasFMA4) 2683234353Sdim Builder.defineMacro("__FMA4__"); 2684234353Sdim 2685239462Sdim if (HasFMA) 2686239462Sdim Builder.defineMacro("__FMA__"); 2687239462Sdim 2688239462Sdim if (HasXOP) 2689239462Sdim Builder.defineMacro("__XOP__"); 2690239462Sdim 2691243830Sdim if (HasF16C) 2692243830Sdim Builder.defineMacro("__F16C__"); 2693243830Sdim 2694193326Sed // Each case falls through to the previous one here. 2695193326Sed switch (SSELevel) { 2696234353Sdim case AVX2: 2697234353Sdim Builder.defineMacro("__AVX2__"); 2698234353Sdim case AVX: 2699234353Sdim Builder.defineMacro("__AVX__"); 2700193326Sed case SSE42: 2701202379Srdivacky Builder.defineMacro("__SSE4_2__"); 2702193326Sed case SSE41: 2703202379Srdivacky Builder.defineMacro("__SSE4_1__"); 2704193326Sed case SSSE3: 2705202379Srdivacky Builder.defineMacro("__SSSE3__"); 2706193326Sed case SSE3: 2707202379Srdivacky Builder.defineMacro("__SSE3__"); 2708193326Sed case SSE2: 2709202379Srdivacky Builder.defineMacro("__SSE2__"); 2710202379Srdivacky Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied. 2711193326Sed case SSE1: 2712202379Srdivacky Builder.defineMacro("__SSE__"); 2713202379Srdivacky Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied. 2714224145Sdim case NoSSE: 2715193326Sed break; 2716193326Sed } 2717218893Sdim 2718243830Sdim if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) { 2719218893Sdim switch (SSELevel) { 2720234353Sdim case AVX2: 2721234353Sdim case AVX: 2722218893Sdim case SSE42: 2723218893Sdim case SSE41: 2724218893Sdim case SSSE3: 2725218893Sdim case SSE3: 2726218893Sdim case SSE2: 2727226633Sdim Builder.defineMacro("_M_IX86_FP", Twine(2)); 2728218893Sdim break; 2729218893Sdim case SSE1: 2730226633Sdim Builder.defineMacro("_M_IX86_FP", Twine(1)); 2731218893Sdim break; 2732218893Sdim default: 2733226633Sdim Builder.defineMacro("_M_IX86_FP", Twine(0)); 2734218893Sdim } 2735218893Sdim } 2736218893Sdim 2737203955Srdivacky // Each case falls through to the previous one here. 2738224145Sdim switch (MMX3DNowLevel) { 2739203955Srdivacky case AMD3DNowAthlon: 2740203955Srdivacky Builder.defineMacro("__3dNOW_A__"); 2741203955Srdivacky case AMD3DNow: 2742203955Srdivacky Builder.defineMacro("__3dNOW__"); 2743224145Sdim case MMX: 2744224145Sdim Builder.defineMacro("__MMX__"); 2745224145Sdim case NoMMX3DNow: 2746203955Srdivacky break; 2747203955Srdivacky } 2748249423Sdim 2749249423Sdim if (CPU >= CK_i486) { 2750249423Sdim Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 2751249423Sdim Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 2752249423Sdim Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 2753249423Sdim } 2754249423Sdim if (CPU >= CK_i586) 2755249423Sdim Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 2756193326Sed} 2757193326Sed 2758234353Sdimbool X86TargetInfo::hasFeature(StringRef Feature) const { 2759234353Sdim return llvm::StringSwitch<bool>(Feature) 2760234353Sdim .Case("aes", HasAES) 2761234353Sdim .Case("avx", SSELevel >= AVX) 2762234353Sdim .Case("avx2", SSELevel >= AVX2) 2763234353Sdim .Case("bmi", HasBMI) 2764234353Sdim .Case("bmi2", HasBMI2) 2765239462Sdim .Case("fma", HasFMA) 2766234353Sdim .Case("fma4", HasFMA4) 2767234353Sdim .Case("lzcnt", HasLZCNT) 2768239462Sdim .Case("rdrnd", HasRDRND) 2769234353Sdim .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) 2770234353Sdim .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon) 2771234353Sdim .Case("mmx", MMX3DNowLevel >= MMX) 2772239462Sdim .Case("pclmul", HasPCLMUL) 2773234353Sdim .Case("popcnt", HasPOPCNT) 2774243830Sdim .Case("rtm", HasRTM) 2775249423Sdim .Case("prfchw", HasPRFCHW) 2776249423Sdim .Case("rdseed", HasRDSEED) 2777234353Sdim .Case("sse", SSELevel >= SSE1) 2778234353Sdim .Case("sse2", SSELevel >= SSE2) 2779234353Sdim .Case("sse3", SSELevel >= SSE3) 2780234353Sdim .Case("ssse3", SSELevel >= SSSE3) 2781234353Sdim .Case("sse41", SSELevel >= SSE41) 2782234353Sdim .Case("sse42", SSELevel >= SSE42) 2783239462Sdim .Case("sse4a", HasSSE4a) 2784234353Sdim .Case("x86", true) 2785243830Sdim .Case("x86_32", getTriple().getArch() == llvm::Triple::x86) 2786243830Sdim .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64) 2787239462Sdim .Case("xop", HasXOP) 2788243830Sdim .Case("f16c", HasF16C) 2789234353Sdim .Default(false); 2790234353Sdim} 2791193326Sed 2792193326Sedbool 2793193326SedX86TargetInfo::validateAsmConstraint(const char *&Name, 2794193326Sed TargetInfo::ConstraintInfo &Info) const { 2795193326Sed switch (*Name) { 2796193326Sed default: return false; 2797212904Sdim case 'Y': // first letter of a pair: 2798212904Sdim switch (*(Name+1)) { 2799212904Sdim default: return false; 2800212904Sdim case '0': // First SSE register. 2801212904Sdim case 't': // Any SSE register, when SSE2 is enabled. 2802212904Sdim case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled. 2803212904Sdim case 'm': // any MMX register, when inter-unit moves enabled. 2804212904Sdim break; // falls through to setAllowsRegister. 2805212904Sdim } 2806193326Sed case 'a': // eax. 2807193326Sed case 'b': // ebx. 2808193326Sed case 'c': // ecx. 2809193326Sed case 'd': // edx. 2810193326Sed case 'S': // esi. 2811193326Sed case 'D': // edi. 2812193326Sed case 'A': // edx:eax. 2813212904Sdim case 'f': // any x87 floating point stack register. 2814193326Sed case 't': // top of floating point stack. 2815193326Sed case 'u': // second from top of floating point stack. 2816193326Sed case 'q': // Any register accessible as [r]l: a, b, c, and d. 2817193326Sed case 'y': // Any MMX register. 2818193326Sed case 'x': // Any SSE register. 2819193326Sed case 'Q': // Any register accessible as [r]h: a, b, c, and d. 2820212904Sdim case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp. 2821212904Sdim case 'l': // "Index" registers: any general register that can be used as an 2822212904Sdim // index in a base+index memory access. 2823212904Sdim Info.setAllowsRegister(); 2824212904Sdim return true; 2825212904Sdim case 'C': // SSE floating point constant. 2826212904Sdim case 'G': // x87 floating point constant. 2827193326Sed case 'e': // 32-bit signed integer constant for use with zero-extending 2828193326Sed // x86_64 instructions. 2829193326Sed case 'Z': // 32-bit unsigned integer constant for use with zero-extending 2830193326Sed // x86_64 instructions. 2831193326Sed return true; 2832193326Sed } 2833193326Sed} 2834193326Sed 2835218893Sdim 2836193326Sedstd::string 2837223017SdimX86TargetInfo::convertConstraint(const char *&Constraint) const { 2838223017Sdim switch (*Constraint) { 2839193326Sed case 'a': return std::string("{ax}"); 2840193326Sed case 'b': return std::string("{bx}"); 2841193326Sed case 'c': return std::string("{cx}"); 2842193326Sed case 'd': return std::string("{dx}"); 2843193326Sed case 'S': return std::string("{si}"); 2844193326Sed case 'D': return std::string("{di}"); 2845218893Sdim case 'p': // address 2846218893Sdim return std::string("im"); 2847193326Sed case 't': // top of floating point stack. 2848193326Sed return std::string("{st}"); 2849193326Sed case 'u': // second from top of floating point stack. 2850193326Sed return std::string("{st(1)}"); // second from top of floating point stack. 2851193326Sed default: 2852223017Sdim return std::string(1, *Constraint); 2853193326Sed } 2854193326Sed} 2855193326Sed} // end anonymous namespace 2856193326Sed 2857193326Sednamespace { 2858193326Sed// X86-32 generic target 2859193326Sedclass X86_32TargetInfo : public X86TargetInfo { 2860193326Sedpublic: 2861193326Sed X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) { 2862193326Sed DoubleAlign = LongLongAlign = 32; 2863193326Sed LongDoubleWidth = 96; 2864193326Sed LongDoubleAlign = 32; 2865234353Sdim SuitableAlign = 128; 2866193326Sed DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 2867193326Sed "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 2868226633Sdim "a0:0:64-f80:32:32-n8:16:32-S128"; 2869193326Sed SizeType = UnsignedInt; 2870193326Sed PtrDiffType = SignedInt; 2871193326Sed IntPtrType = SignedInt; 2872193326Sed RegParmMax = 3; 2873210299Sed 2874210299Sed // Use fpret for all types. 2875210299Sed RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) | 2876210299Sed (1 << TargetInfo::Double) | 2877210299Sed (1 << TargetInfo::LongDouble)); 2878226633Sdim 2879226633Sdim // x86-32 has atomics up to 8 bytes 2880226633Sdim // FIXME: Check that we actually have cmpxchg8b before setting 2881226633Sdim // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.) 2882226633Sdim MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 2883193326Sed } 2884239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 2885239462Sdim return TargetInfo::CharPtrBuiltinVaList; 2886193326Sed } 2887218893Sdim 2888198092Srdivacky int getEHDataRegisterNumber(unsigned RegNo) const { 2889198092Srdivacky if (RegNo == 0) return 0; 2890198092Srdivacky if (RegNo == 1) return 2; 2891198092Srdivacky return -1; 2892198092Srdivacky } 2893249423Sdim virtual bool validateInputSize(StringRef Constraint, 2894249423Sdim unsigned Size) const { 2895249423Sdim switch (Constraint[0]) { 2896249423Sdim default: break; 2897249423Sdim case 'a': 2898249423Sdim case 'b': 2899249423Sdim case 'c': 2900249423Sdim case 'd': 2901249423Sdim return Size <= 32; 2902249423Sdim } 2903249423Sdim 2904249423Sdim return true; 2905249423Sdim } 2906193326Sed}; 2907193326Sed} // end anonymous namespace 2908193326Sed 2909193326Sednamespace { 2910234353Sdimclass NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> { 2911234353Sdimpublic: 2912234353Sdim NetBSDI386TargetInfo(const std::string &triple) : 2913234353Sdim NetBSDTargetInfo<X86_32TargetInfo>(triple) { 2914234353Sdim } 2915234353Sdim 2916234353Sdim virtual unsigned getFloatEvalMethod() const { 2917234353Sdim // NetBSD defaults to "double" rounding 2918234353Sdim return 1; 2919234353Sdim } 2920234353Sdim}; 2921234353Sdim} // end anonymous namespace 2922234353Sdim 2923234353Sdimnamespace { 2924198092Srdivackyclass OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> { 2925198092Srdivackypublic: 2926198092Srdivacky OpenBSDI386TargetInfo(const std::string& triple) : 2927198092Srdivacky OpenBSDTargetInfo<X86_32TargetInfo>(triple) { 2928198092Srdivacky SizeType = UnsignedLong; 2929198092Srdivacky IntPtrType = SignedLong; 2930198092Srdivacky PtrDiffType = SignedLong; 2931198092Srdivacky } 2932198092Srdivacky}; 2933198092Srdivacky} // end anonymous namespace 2934198092Srdivacky 2935198092Srdivackynamespace { 2936239462Sdimclass BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> { 2937239462Sdimpublic: 2938239462Sdim BitrigI386TargetInfo(const std::string& triple) : 2939239462Sdim BitrigTargetInfo<X86_32TargetInfo>(triple) { 2940239462Sdim SizeType = UnsignedLong; 2941239462Sdim IntPtrType = SignedLong; 2942239462Sdim PtrDiffType = SignedLong; 2943239462Sdim } 2944239462Sdim}; 2945239462Sdim} // end anonymous namespace 2946239462Sdim 2947239462Sdimnamespace { 2948195341Sedclass DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> { 2949193326Sedpublic: 2950195341Sed DarwinI386TargetInfo(const std::string& triple) : 2951195341Sed DarwinTargetInfo<X86_32TargetInfo>(triple) { 2952193326Sed LongDoubleWidth = 128; 2953193326Sed LongDoubleAlign = 128; 2954234353Sdim SuitableAlign = 128; 2955239462Sdim MaxVectorAlign = 256; 2956193326Sed SizeType = UnsignedLong; 2957193326Sed IntPtrType = SignedLong; 2958193326Sed DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 2959193326Sed "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" 2960226633Sdim "a0:0:64-f80:128:128-n8:16:32-S128"; 2961208600Srdivacky HasAlignMac68kSupport = true; 2962193326Sed } 2963193326Sed 2964193326Sed}; 2965193326Sed} // end anonymous namespace 2966193326Sed 2967193326Sednamespace { 2968193326Sed// x86-32 Windows target 2969218893Sdimclass WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> { 2970193326Sedpublic: 2971193326Sed WindowsX86_32TargetInfo(const std::string& triple) 2972218893Sdim : WindowsTargetInfo<X86_32TargetInfo>(triple) { 2973193326Sed TLSSupported = false; 2974195099Sed WCharType = UnsignedShort; 2975194179Sed DoubleAlign = LongLongAlign = 64; 2976194179Sed DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 2977201361Srdivacky "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-" 2978226633Sdim "v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"; 2979193326Sed } 2980193326Sed virtual void getTargetDefines(const LangOptions &Opts, 2981202379Srdivacky MacroBuilder &Builder) const { 2982218893Sdim WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder); 2983193326Sed } 2984198092Srdivacky}; 2985198092Srdivacky} // end anonymous namespace 2986193725Sed 2987198092Srdivackynamespace { 2988198092Srdivacky 2989198092Srdivacky// x86-32 Windows Visual Studio target 2990198092Srdivackyclass VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo { 2991198092Srdivackypublic: 2992198092Srdivacky VisualStudioWindowsX86_32TargetInfo(const std::string& triple) 2993198092Srdivacky : WindowsX86_32TargetInfo(triple) { 2994221345Sdim LongDoubleWidth = LongDoubleAlign = 64; 2995218893Sdim LongDoubleFormat = &llvm::APFloat::IEEEdouble; 2996198092Srdivacky } 2997198092Srdivacky virtual void getTargetDefines(const LangOptions &Opts, 2998202379Srdivacky MacroBuilder &Builder) const { 2999202379Srdivacky WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); 3000218893Sdim WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder); 3001198092Srdivacky // The value of the following reflects processor type. 3002198092Srdivacky // 300=386, 400=486, 500=Pentium, 600=Blend (default) 3003198092Srdivacky // We lost the original triple, so we use the default. 3004202379Srdivacky Builder.defineMacro("_M_IX86", "600"); 3005198092Srdivacky } 3006193326Sed}; 3007193326Sed} // end anonymous namespace 3008193326Sed 3009193326Sednamespace { 3010198092Srdivacky// x86-32 MinGW target 3011198092Srdivackyclass MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo { 3012198092Srdivackypublic: 3013198092Srdivacky MinGWX86_32TargetInfo(const std::string& triple) 3014198092Srdivacky : WindowsX86_32TargetInfo(triple) { 3015198092Srdivacky } 3016198092Srdivacky virtual void getTargetDefines(const LangOptions &Opts, 3017202379Srdivacky MacroBuilder &Builder) const { 3018202379Srdivacky WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); 3019218893Sdim DefineStd(Builder, "WIN32", Opts); 3020218893Sdim DefineStd(Builder, "WINNT", Opts); 3021218893Sdim Builder.defineMacro("_X86_"); 3022202379Srdivacky Builder.defineMacro("__MSVCRT__"); 3023202379Srdivacky Builder.defineMacro("__MINGW32__"); 3024221345Sdim 3025221345Sdim // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)). 3026221345Sdim // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions. 3027226633Sdim if (Opts.MicrosoftExt) 3028221345Sdim // Provide "as-is" __declspec. 3029221345Sdim Builder.defineMacro("__declspec", "__declspec"); 3030221345Sdim else 3031221345Sdim // Provide alias of __attribute__ like mingw32-gcc. 3032221345Sdim Builder.defineMacro("__declspec(a)", "__attribute__((a))"); 3033198092Srdivacky } 3034198092Srdivacky}; 3035198092Srdivacky} // end anonymous namespace 3036198092Srdivacky 3037198092Srdivackynamespace { 3038198092Srdivacky// x86-32 Cygwin target 3039198092Srdivackyclass CygwinX86_32TargetInfo : public X86_32TargetInfo { 3040198092Srdivackypublic: 3041198092Srdivacky CygwinX86_32TargetInfo(const std::string& triple) 3042198092Srdivacky : X86_32TargetInfo(triple) { 3043198092Srdivacky TLSSupported = false; 3044198092Srdivacky WCharType = UnsignedShort; 3045198092Srdivacky DoubleAlign = LongLongAlign = 64; 3046198092Srdivacky DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 3047198092Srdivacky "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 3048226633Sdim "a0:0:64-f80:32:32-n8:16:32-S32"; 3049198092Srdivacky } 3050198092Srdivacky virtual void getTargetDefines(const LangOptions &Opts, 3051202379Srdivacky MacroBuilder &Builder) const { 3052202379Srdivacky X86_32TargetInfo::getTargetDefines(Opts, Builder); 3053249423Sdim Builder.defineMacro("_X86_"); 3054202379Srdivacky Builder.defineMacro("__CYGWIN__"); 3055202379Srdivacky Builder.defineMacro("__CYGWIN32__"); 3056202379Srdivacky DefineStd(Builder, "unix", Opts); 3057207619Srdivacky if (Opts.CPlusPlus) 3058207619Srdivacky Builder.defineMacro("_GNU_SOURCE"); 3059198092Srdivacky } 3060198092Srdivacky}; 3061198092Srdivacky} // end anonymous namespace 3062198092Srdivacky 3063198092Srdivackynamespace { 3064207619Srdivacky// x86-32 Haiku target 3065207619Srdivackyclass HaikuX86_32TargetInfo : public X86_32TargetInfo { 3066207619Srdivackypublic: 3067207619Srdivacky HaikuX86_32TargetInfo(const std::string& triple) 3068207619Srdivacky : X86_32TargetInfo(triple) { 3069207619Srdivacky SizeType = UnsignedLong; 3070207619Srdivacky IntPtrType = SignedLong; 3071207619Srdivacky PtrDiffType = SignedLong; 3072243830Sdim ProcessIDType = SignedLong; 3073218893Sdim this->UserLabelPrefix = ""; 3074243830Sdim this->TLSSupported = false; 3075212904Sdim } 3076207619Srdivacky virtual void getTargetDefines(const LangOptions &Opts, 3077207619Srdivacky MacroBuilder &Builder) const { 3078207619Srdivacky X86_32TargetInfo::getTargetDefines(Opts, Builder); 3079207619Srdivacky Builder.defineMacro("__INTEL__"); 3080207619Srdivacky Builder.defineMacro("__HAIKU__"); 3081207619Srdivacky } 3082207619Srdivacky}; 3083207619Srdivacky} // end anonymous namespace 3084207619Srdivacky 3085224145Sdim// RTEMS Target 3086224145Sdimtemplate<typename Target> 3087224145Sdimclass RTEMSTargetInfo : public OSTargetInfo<Target> { 3088224145Sdimprotected: 3089224145Sdim virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 3090224145Sdim MacroBuilder &Builder) const { 3091224145Sdim // RTEMS defines; list based off of gcc output 3092224145Sdim 3093224145Sdim Builder.defineMacro("__rtems__"); 3094224145Sdim Builder.defineMacro("__ELF__"); 3095224145Sdim } 3096224145Sdimpublic: 3097224145Sdim RTEMSTargetInfo(const std::string &triple) 3098224145Sdim : OSTargetInfo<Target>(triple) { 3099224145Sdim this->UserLabelPrefix = ""; 3100224145Sdim 3101224145Sdim llvm::Triple Triple(triple); 3102224145Sdim switch (Triple.getArch()) { 3103224145Sdim default: 3104224145Sdim case llvm::Triple::x86: 3105224145Sdim // this->MCountName = ".mcount"; 3106224145Sdim break; 3107224145Sdim case llvm::Triple::mips: 3108224145Sdim case llvm::Triple::mipsel: 3109224145Sdim case llvm::Triple::ppc: 3110224145Sdim case llvm::Triple::ppc64: 3111224145Sdim // this->MCountName = "_mcount"; 3112224145Sdim break; 3113224145Sdim case llvm::Triple::arm: 3114224145Sdim // this->MCountName = "__mcount"; 3115224145Sdim break; 3116224145Sdim } 3117224145Sdim 3118224145Sdim } 3119224145Sdim}; 3120224145Sdim 3121207619Srdivackynamespace { 3122224145Sdim// x86-32 RTEMS target 3123224145Sdimclass RTEMSX86_32TargetInfo : public X86_32TargetInfo { 3124224145Sdimpublic: 3125224145Sdim RTEMSX86_32TargetInfo(const std::string& triple) 3126224145Sdim : X86_32TargetInfo(triple) { 3127224145Sdim SizeType = UnsignedLong; 3128224145Sdim IntPtrType = SignedLong; 3129224145Sdim PtrDiffType = SignedLong; 3130224145Sdim this->UserLabelPrefix = ""; 3131224145Sdim } 3132224145Sdim virtual void getTargetDefines(const LangOptions &Opts, 3133224145Sdim MacroBuilder &Builder) const { 3134224145Sdim X86_32TargetInfo::getTargetDefines(Opts, Builder); 3135224145Sdim Builder.defineMacro("__INTEL__"); 3136224145Sdim Builder.defineMacro("__rtems__"); 3137224145Sdim } 3138224145Sdim}; 3139224145Sdim} // end anonymous namespace 3140224145Sdim 3141224145Sdimnamespace { 3142193326Sed// x86-64 generic target 3143193326Sedclass X86_64TargetInfo : public X86TargetInfo { 3144193326Sedpublic: 3145193326Sed X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) { 3146193326Sed LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 3147193326Sed LongDoubleWidth = 128; 3148193326Sed LongDoubleAlign = 128; 3149210299Sed LargeArrayMinWidth = 128; 3150210299Sed LargeArrayAlign = 128; 3151234353Sdim SuitableAlign = 128; 3152193326Sed IntMaxType = SignedLong; 3153193326Sed UIntMaxType = UnsignedLong; 3154195341Sed Int64Type = SignedLong; 3155193326Sed RegParmMax = 6; 3156193326Sed 3157193326Sed DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 3158193326Sed "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 3159226633Sdim "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"; 3160210299Sed 3161210299Sed // Use fpret only for long double. 3162210299Sed RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble); 3163226633Sdim 3164234353Sdim // Use fp2ret for _Complex long double. 3165234353Sdim ComplexLongDoubleUsesFP2Ret = true; 3166234353Sdim 3167226633Sdim // x86-64 has atomics up to 16 bytes. 3168226633Sdim // FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128 3169226633Sdim // on CPUs with cmpxchg16b 3170226633Sdim MaxAtomicPromoteWidth = 128; 3171226633Sdim MaxAtomicInlineWidth = 64; 3172193326Sed } 3173239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 3174239462Sdim return TargetInfo::X86_64ABIBuiltinVaList; 3175193326Sed } 3176218893Sdim 3177198092Srdivacky int getEHDataRegisterNumber(unsigned RegNo) const { 3178198092Srdivacky if (RegNo == 0) return 0; 3179198092Srdivacky if (RegNo == 1) return 1; 3180198092Srdivacky return -1; 3181198092Srdivacky } 3182243830Sdim 3183243830Sdim virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { 3184249423Sdim return (CC == CC_Default || 3185256030Sdim CC == CC_C || 3186256030Sdim CC == CC_IntelOclBicc || 3187256030Sdim CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning; 3188243830Sdim } 3189243830Sdim 3190249423Sdim virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const { 3191249423Sdim return CC_C; 3192243830Sdim } 3193243830Sdim 3194193326Sed}; 3195193326Sed} // end anonymous namespace 3196193326Sed 3197193326Sednamespace { 3198198092Srdivacky// x86-64 Windows target 3199218893Sdimclass WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> { 3200198092Srdivackypublic: 3201198092Srdivacky WindowsX86_64TargetInfo(const std::string& triple) 3202218893Sdim : WindowsTargetInfo<X86_64TargetInfo>(triple) { 3203198092Srdivacky TLSSupported = false; 3204198092Srdivacky WCharType = UnsignedShort; 3205198092Srdivacky LongWidth = LongAlign = 32; 3206218893Sdim DoubleAlign = LongLongAlign = 64; 3207212904Sdim IntMaxType = SignedLongLong; 3208212904Sdim UIntMaxType = UnsignedLongLong; 3209212904Sdim Int64Type = SignedLongLong; 3210218893Sdim SizeType = UnsignedLongLong; 3211218893Sdim PtrDiffType = SignedLongLong; 3212218893Sdim IntPtrType = SignedLongLong; 3213218893Sdim this->UserLabelPrefix = ""; 3214198092Srdivacky } 3215198092Srdivacky virtual void getTargetDefines(const LangOptions &Opts, 3216202379Srdivacky MacroBuilder &Builder) const { 3217218893Sdim WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder); 3218202379Srdivacky Builder.defineMacro("_WIN64"); 3219198092Srdivacky } 3220239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 3221239462Sdim return TargetInfo::CharPtrBuiltinVaList; 3222218893Sdim } 3223256030Sdim virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { 3224256030Sdim return (CC == CC_C || 3225256030Sdim CC == CC_IntelOclBicc || 3226256030Sdim CC == CC_X86_64SysV) ? CCCR_OK : CCCR_Warning; 3227256030Sdim } 3228198092Srdivacky}; 3229198092Srdivacky} // end anonymous namespace 3230198092Srdivacky 3231198092Srdivackynamespace { 3232198092Srdivacky// x86-64 Windows Visual Studio target 3233198092Srdivackyclass VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo { 3234198092Srdivackypublic: 3235198092Srdivacky VisualStudioWindowsX86_64TargetInfo(const std::string& triple) 3236198092Srdivacky : WindowsX86_64TargetInfo(triple) { 3237221345Sdim LongDoubleWidth = LongDoubleAlign = 64; 3238221345Sdim LongDoubleFormat = &llvm::APFloat::IEEEdouble; 3239198092Srdivacky } 3240198092Srdivacky virtual void getTargetDefines(const LangOptions &Opts, 3241202379Srdivacky MacroBuilder &Builder) const { 3242202379Srdivacky WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder); 3243218893Sdim WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder); 3244202379Srdivacky Builder.defineMacro("_M_X64"); 3245218893Sdim Builder.defineMacro("_M_AMD64"); 3246198092Srdivacky } 3247198092Srdivacky}; 3248198092Srdivacky} // end anonymous namespace 3249198092Srdivacky 3250198092Srdivackynamespace { 3251198092Srdivacky// x86-64 MinGW target 3252198092Srdivackyclass MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo { 3253198092Srdivackypublic: 3254198092Srdivacky MinGWX86_64TargetInfo(const std::string& triple) 3255198092Srdivacky : WindowsX86_64TargetInfo(triple) { 3256198092Srdivacky } 3257198092Srdivacky virtual void getTargetDefines(const LangOptions &Opts, 3258202379Srdivacky MacroBuilder &Builder) const { 3259202379Srdivacky WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder); 3260218893Sdim DefineStd(Builder, "WIN64", Opts); 3261202379Srdivacky Builder.defineMacro("__MSVCRT__"); 3262221345Sdim Builder.defineMacro("__MINGW32__"); 3263202379Srdivacky Builder.defineMacro("__MINGW64__"); 3264221345Sdim 3265221345Sdim // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)). 3266221345Sdim // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions. 3267226633Sdim if (Opts.MicrosoftExt) 3268221345Sdim // Provide "as-is" __declspec. 3269221345Sdim Builder.defineMacro("__declspec", "__declspec"); 3270221345Sdim else 3271221345Sdim // Provide alias of __attribute__ like mingw32-gcc. 3272221345Sdim Builder.defineMacro("__declspec(a)", "__attribute__((a))"); 3273198092Srdivacky } 3274198092Srdivacky}; 3275198092Srdivacky} // end anonymous namespace 3276198092Srdivacky 3277198092Srdivackynamespace { 3278195341Sedclass DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> { 3279193326Sedpublic: 3280198092Srdivacky DarwinX86_64TargetInfo(const std::string& triple) 3281195341Sed : DarwinTargetInfo<X86_64TargetInfo>(triple) { 3282195341Sed Int64Type = SignedLongLong; 3283239462Sdim MaxVectorAlign = 256; 3284193326Sed } 3285193326Sed}; 3286193326Sed} // end anonymous namespace 3287193326Sed 3288193326Sednamespace { 3289198092Srdivackyclass OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> { 3290198092Srdivackypublic: 3291198092Srdivacky OpenBSDX86_64TargetInfo(const std::string& triple) 3292198092Srdivacky : OpenBSDTargetInfo<X86_64TargetInfo>(triple) { 3293198092Srdivacky IntMaxType = SignedLongLong; 3294198092Srdivacky UIntMaxType = UnsignedLongLong; 3295198092Srdivacky Int64Type = SignedLongLong; 3296198092Srdivacky } 3297198092Srdivacky}; 3298198092Srdivacky} // end anonymous namespace 3299198092Srdivacky 3300198092Srdivackynamespace { 3301239462Sdimclass BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> { 3302239462Sdimpublic: 3303239462Sdim BitrigX86_64TargetInfo(const std::string& triple) 3304239462Sdim : BitrigTargetInfo<X86_64TargetInfo>(triple) { 3305239462Sdim IntMaxType = SignedLongLong; 3306239462Sdim UIntMaxType = UnsignedLongLong; 3307239462Sdim Int64Type = SignedLongLong; 3308239462Sdim } 3309239462Sdim}; 3310249423Sdim} 3311249423Sdim 3312249423Sdimnamespace { 3313249423Sdimclass AArch64TargetInfo : public TargetInfo { 3314249423Sdim static const char * const GCCRegNames[]; 3315249423Sdim static const TargetInfo::GCCRegAlias GCCRegAliases[]; 3316251662Sdim 3317251662Sdim static const Builtin::Info BuiltinInfo[]; 3318249423Sdimpublic: 3319249423Sdim AArch64TargetInfo(const std::string& triple) : TargetInfo(triple) { 3320249423Sdim BigEndian = false; 3321249423Sdim LongWidth = LongAlign = 64; 3322249423Sdim LongDoubleWidth = LongDoubleAlign = 128; 3323249423Sdim PointerWidth = PointerAlign = 64; 3324249423Sdim SuitableAlign = 128; 3325249423Sdim DescriptionString = "e-p:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 3326249423Sdim "i64:64:64-i128:128:128-f32:32:32-f64:64:64-" 3327249423Sdim "f128:128:128-n32:64-S128"; 3328249423Sdim 3329249423Sdim WCharType = UnsignedInt; 3330249423Sdim LongDoubleFormat = &llvm::APFloat::IEEEquad; 3331249423Sdim 3332249423Sdim // AArch64 backend supports 64-bit operations at the moment. In principle 3333249423Sdim // 128-bit is possible if register-pairs are used. 3334249423Sdim MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 3335249423Sdim 3336249423Sdim TheCXXABI.set(TargetCXXABI::GenericAArch64); 3337249423Sdim } 3338249423Sdim virtual void getTargetDefines(const LangOptions &Opts, 3339249423Sdim MacroBuilder &Builder) const { 3340249423Sdim // GCC defines theses currently 3341249423Sdim Builder.defineMacro("__aarch64__"); 3342249423Sdim Builder.defineMacro("__AARCH64EL__"); 3343249423Sdim 3344249423Sdim // ACLE predefines. Many can only have one possible value on v8 AArch64. 3345249423Sdim 3346249423Sdim // FIXME: these were written based on an unreleased version of a 32-bit ACLE 3347249423Sdim // which was intended to be compatible with a 64-bit implementation. They 3348249423Sdim // will need updating when a real 64-bit ACLE exists. Particularly pressing 3349251662Sdim // instances are: __ARM_ARCH_ISA_ARM, __ARM_ARCH_ISA_THUMB, __ARM_PCS. 3350251662Sdim Builder.defineMacro("__ARM_ACLE", "101"); 3351251662Sdim Builder.defineMacro("__ARM_ARCH", "8"); 3352251662Sdim Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'"); 3353249423Sdim 3354251662Sdim Builder.defineMacro("__ARM_FEATURE_UNALIGNED"); 3355251662Sdim Builder.defineMacro("__ARM_FEATURE_CLZ"); 3356251662Sdim Builder.defineMacro("__ARM_FEATURE_FMA"); 3357249423Sdim 3358249423Sdim // FIXME: ACLE 1.1 reserves bit 4. Will almost certainly come to mean 3359249423Sdim // 128-bit LDXP present, at which point this becomes 0x1f. 3360251662Sdim Builder.defineMacro("__ARM_FEATURE_LDREX", "0xf"); 3361249423Sdim 3362249423Sdim // 0xe implies support for half, single and double precision operations. 3363251662Sdim Builder.defineMacro("__ARM_FP", "0xe"); 3364249423Sdim 3365249423Sdim // PCS specifies this for SysV variants, which is all we support. Other ABIs 3366251662Sdim // may choose __ARM_FP16_FORMAT_ALTERNATIVE. 3367251662Sdim Builder.defineMacro("__ARM_FP16_FORMAT_IEEE"); 3368249423Sdim 3369249423Sdim if (Opts.FastMath || Opts.FiniteMathOnly) 3370251662Sdim Builder.defineMacro("__ARM_FP_FAST"); 3371249423Sdim 3372249423Sdim if ((Opts.C99 || Opts.C11) && !Opts.Freestanding) 3373251662Sdim Builder.defineMacro("__ARM_FP_FENV_ROUNDING"); 3374249423Sdim 3375251662Sdim Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", 3376249423Sdim Opts.ShortWChar ? "2" : "4"); 3377249423Sdim 3378251662Sdim Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", 3379249423Sdim Opts.ShortEnums ? "1" : "4"); 3380249423Sdim 3381249423Sdim if (BigEndian) 3382251662Sdim Builder.defineMacro("__ARM_BIG_ENDIAN"); 3383249423Sdim } 3384249423Sdim virtual void getTargetBuiltins(const Builtin::Info *&Records, 3385249423Sdim unsigned &NumRecords) const { 3386251662Sdim Records = BuiltinInfo; 3387251662Sdim NumRecords = clang::AArch64::LastTSBuiltin-Builtin::FirstTSBuiltin; 3388249423Sdim } 3389249423Sdim virtual bool hasFeature(StringRef Feature) const { 3390249423Sdim return Feature == "aarch64"; 3391249423Sdim } 3392249423Sdim virtual void getGCCRegNames(const char * const *&Names, 3393249423Sdim unsigned &NumNames) const; 3394249423Sdim virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 3395249423Sdim unsigned &NumAliases) const; 3396249423Sdim 3397249423Sdim virtual bool isCLZForZeroUndef() const { return false; } 3398249423Sdim 3399249423Sdim virtual bool validateAsmConstraint(const char *&Name, 3400249423Sdim TargetInfo::ConstraintInfo &Info) const { 3401249423Sdim switch (*Name) { 3402249423Sdim default: return false; 3403249423Sdim case 'w': // An FP/SIMD vector register 3404249423Sdim Info.setAllowsRegister(); 3405249423Sdim return true; 3406249423Sdim case 'I': // Constant that can be used with an ADD instruction 3407249423Sdim case 'J': // Constant that can be used with a SUB instruction 3408249423Sdim case 'K': // Constant that can be used with a 32-bit logical instruction 3409249423Sdim case 'L': // Constant that can be used with a 64-bit logical instruction 3410249423Sdim case 'M': // Constant that can be used as a 32-bit MOV immediate 3411249423Sdim case 'N': // Constant that can be used as a 64-bit MOV immediate 3412249423Sdim case 'Y': // Floating point constant zero 3413249423Sdim case 'Z': // Integer constant zero 3414249423Sdim return true; 3415249423Sdim case 'Q': // A memory reference with base register and no offset 3416249423Sdim Info.setAllowsMemory(); 3417249423Sdim return true; 3418249423Sdim case 'S': // A symbolic address 3419249423Sdim Info.setAllowsRegister(); 3420249423Sdim return true; 3421249423Sdim case 'U': 3422249423Sdim // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes, whatever they may be 3423249423Sdim // Utf: A memory address suitable for ldp/stp in TF mode, whatever it may be 3424249423Sdim // Usa: An absolute symbolic address 3425249423Sdim // Ush: The high part (bits 32:12) of a pc-relative symbolic address 3426249423Sdim llvm_unreachable("FIXME: Unimplemented support for bizarre constraints"); 3427249423Sdim } 3428249423Sdim } 3429249423Sdim 3430249423Sdim virtual const char *getClobbers() const { 3431249423Sdim // There are no AArch64 clobbers shared by all asm statements. 3432249423Sdim return ""; 3433249423Sdim } 3434249423Sdim 3435249423Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 3436249423Sdim return TargetInfo::AArch64ABIBuiltinVaList; 3437249423Sdim } 3438249423Sdim}; 3439249423Sdim 3440249423Sdimconst char * const AArch64TargetInfo::GCCRegNames[] = { 3441249423Sdim "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", 3442249423Sdim "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", 3443249423Sdim "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23", 3444249423Sdim "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", "wzr", 3445249423Sdim 3446249423Sdim "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", 3447249423Sdim "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", 3448249423Sdim "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", 3449249423Sdim "x24", "x25", "x26", "x27", "x28", "x29", "x30", "sp", "xzr", 3450249423Sdim 3451249423Sdim "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", 3452249423Sdim "b8", "b9", "b10", "b11", "b12", "b13", "b14", "b15", 3453249423Sdim "b16", "b17", "b18", "b19", "b20", "b21", "b22", "b23", 3454249423Sdim "b24", "b25", "b26", "b27", "b28", "b29", "b30", "b31", 3455249423Sdim 3456249423Sdim "h0", "h1", "h2", "h3", "h4", "h5", "h6", "h7", 3457249423Sdim "h8", "h9", "h10", "h11", "h12", "h13", "h14", "h15", 3458249423Sdim "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23", 3459249423Sdim "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", 3460249423Sdim 3461249423Sdim "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 3462249423Sdim "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", 3463249423Sdim "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", 3464249423Sdim "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 3465249423Sdim 3466249423Sdim "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", 3467249423Sdim "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", 3468249423Sdim "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", 3469249423Sdim "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 3470249423Sdim 3471249423Sdim "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", 3472249423Sdim "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", 3473249423Sdim "q16", "q17", "q18", "q19", "q20", "q21", "q22", "q23", 3474249423Sdim "q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31" 3475249423Sdim}; 3476249423Sdim 3477249423Sdimvoid AArch64TargetInfo::getGCCRegNames(const char * const *&Names, 3478249423Sdim unsigned &NumNames) const { 3479249423Sdim Names = GCCRegNames; 3480249423Sdim NumNames = llvm::array_lengthof(GCCRegNames); 3481249423Sdim} 3482249423Sdim 3483249423Sdimconst TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { 3484249423Sdim { { "x16" }, "ip0"}, 3485249423Sdim { { "x17" }, "ip1"}, 3486249423Sdim { { "x29" }, "fp" }, 3487249423Sdim { { "x30" }, "lr" } 3488249423Sdim}; 3489249423Sdim 3490249423Sdimvoid AArch64TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 3491249423Sdim unsigned &NumAliases) const { 3492249423Sdim Aliases = GCCRegAliases; 3493249423Sdim NumAliases = llvm::array_lengthof(GCCRegAliases); 3494249423Sdim 3495249423Sdim} 3496251662Sdim 3497251662Sdimconst Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { 3498251662Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, 3499251662Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\ 3500251662Sdim ALL_LANGUAGES }, 3501251662Sdim#include "clang/Basic/BuiltinsAArch64.def" 3502251662Sdim}; 3503251662Sdim 3504239462Sdim} // end anonymous namespace 3505239462Sdim 3506239462Sdimnamespace { 3507193326Sedclass ARMTargetInfo : public TargetInfo { 3508201361Srdivacky // Possible FPU choices. 3509201361Srdivacky enum FPUMode { 3510243830Sdim VFP2FPU = (1 << 0), 3511243830Sdim VFP3FPU = (1 << 1), 3512243830Sdim VFP4FPU = (1 << 2), 3513243830Sdim NeonFPU = (1 << 3) 3514201361Srdivacky }; 3515198092Srdivacky 3516201361Srdivacky static bool FPUModeIsVFP(FPUMode Mode) { 3517243830Sdim return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU); 3518201361Srdivacky } 3519198092Srdivacky 3520201361Srdivacky static const TargetInfo::GCCRegAlias GCCRegAliases[]; 3521201361Srdivacky static const char * const GCCRegNames[]; 3522198092Srdivacky 3523201361Srdivacky std::string ABI, CPU; 3524201361Srdivacky 3525243830Sdim unsigned FPU : 4; 3526201361Srdivacky 3527243830Sdim unsigned IsAAPCS : 1; 3528201361Srdivacky unsigned IsThumb : 1; 3529201361Srdivacky 3530201361Srdivacky // Initialized via features. 3531201361Srdivacky unsigned SoftFloat : 1; 3532201361Srdivacky unsigned SoftFloatABI : 1; 3533201361Srdivacky 3534204793Srdivacky static const Builtin::Info BuiltinInfo[]; 3535204793Srdivacky 3536251662Sdim static bool shouldUseInlineAtomic(const llvm::Triple &T) { 3537251662Sdim // On linux, binaries targeting old cpus call functions in libgcc to 3538251662Sdim // perform atomic operations. The implementation in libgcc then calls into 3539251662Sdim // the kernel which on armv6 and newer uses ldrex and strex. The net result 3540251662Sdim // is that if we assume the kernel is at least as recent as the hardware, 3541251662Sdim // it is safe to use atomic instructions on armv6 and newer. 3542251785Sed if (T.getOS() != llvm::Triple::Linux && T.getOS() != llvm::Triple::FreeBSD) 3543251785Sed return false; 3544251662Sdim StringRef ArchName = T.getArchName(); 3545251662Sdim if (T.getArch() == llvm::Triple::arm) { 3546251662Sdim if (!ArchName.startswith("armv")) 3547251662Sdim return false; 3548251662Sdim StringRef VersionStr = ArchName.substr(4); 3549251662Sdim unsigned Version; 3550251662Sdim if (VersionStr.getAsInteger(10, Version)) 3551251662Sdim return false; 3552251662Sdim return Version >= 6; 3553251662Sdim } 3554251662Sdim assert(T.getArch() == llvm::Triple::thumb); 3555251662Sdim if (!ArchName.startswith("thumbv")) 3556251662Sdim return false; 3557251662Sdim StringRef VersionStr = ArchName.substr(6); 3558251662Sdim unsigned Version; 3559251662Sdim if (VersionStr.getAsInteger(10, Version)) 3560251662Sdim return false; 3561251662Sdim return Version >= 7; 3562251662Sdim } 3563251662Sdim 3564193326Sedpublic: 3565198092Srdivacky ARMTargetInfo(const std::string &TripleStr) 3566243830Sdim : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s"), IsAAPCS(true) 3567198092Srdivacky { 3568234353Sdim BigEndian = false; 3569198092Srdivacky SizeType = UnsignedInt; 3570198092Srdivacky PtrDiffType = SignedInt; 3571234353Sdim // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int. 3572234353Sdim WCharType = UnsignedInt; 3573198092Srdivacky 3574207619Srdivacky // {} in inline assembly are neon specifiers, not assembly variant 3575207619Srdivacky // specifiers. 3576207619Srdivacky NoAsmVariants = true; 3577218893Sdim 3578201361Srdivacky // FIXME: Should we just treat this as a feature? 3579201361Srdivacky IsThumb = getTriple().getArchName().startswith("thumb"); 3580198092Srdivacky if (IsThumb) { 3581221345Sdim // Thumb1 add sp, #imm requires the immediate value be multiple of 4, 3582221345Sdim // so set preferred for small types to 32. 3583198092Srdivacky DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" 3584198092Srdivacky "i64:64:64-f32:32:32-f64:64:64-" 3585226633Sdim "v64:64:64-v128:64:128-a0:0:32-n32-S64"); 3586198092Srdivacky } else { 3587198092Srdivacky DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 3588198092Srdivacky "i64:64:64-f32:32:32-f64:64:64-" 3589226633Sdim "v64:64:64-v128:64:128-a0:0:64-n32-S64"); 3590193326Sed } 3591212904Sdim 3592212904Sdim // ARM targets default to using the ARM C++ ABI. 3593249423Sdim TheCXXABI.set(TargetCXXABI::GenericARM); 3594226633Sdim 3595226633Sdim // ARM has atomics up to 8 bytes 3596226633Sdim MaxAtomicPromoteWidth = 64; 3597251662Sdim if (shouldUseInlineAtomic(getTriple())) 3598251662Sdim MaxAtomicInlineWidth = 64; 3599234353Sdim 3600234353Sdim // Do force alignment of members that follow zero length bitfields. If 3601234353Sdim // the alignment of the zero-length bitfield is greater than the member 3602234353Sdim // that follows it, `bar', `bar' will be aligned as the type of the 3603234353Sdim // zero length bitfield. 3604234353Sdim UseZeroLengthBitfieldAlignment = true; 3605193326Sed } 3606198092Srdivacky virtual const char *getABI() const { return ABI.c_str(); } 3607198092Srdivacky virtual bool setABI(const std::string &Name) { 3608198092Srdivacky ABI = Name; 3609198092Srdivacky 3610198092Srdivacky // The defaults (above) are for AAPCS, check if we need to change them. 3611198092Srdivacky // 3612198092Srdivacky // FIXME: We need support for -meabi... we could just mangle it into the 3613198092Srdivacky // name. 3614198092Srdivacky if (Name == "apcs-gnu") { 3615234353Sdim DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32; 3616244640Sandrew // size_t is unsigned int on FreeBSD. 3617244640Sandrew if (getTriple().getOS() != llvm::Triple::FreeBSD) 3618244640Sandrew SizeType = UnsignedLong; 3619198092Srdivacky 3620234353Sdim // Revert to using SignedInt on apcs-gnu to comply with existing behaviour. 3621234353Sdim WCharType = SignedInt; 3622234353Sdim 3623207619Srdivacky // Do not respect the alignment of bit-field types when laying out 3624207619Srdivacky // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc. 3625207619Srdivacky UseBitFieldTypeAlignment = false; 3626207619Srdivacky 3627226633Sdim /// gcc forces the alignment to 4 bytes, regardless of the type of the 3628226633Sdim /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in 3629226633Sdim /// gcc. 3630226633Sdim ZeroLengthBitfieldBoundary = 32; 3631226633Sdim 3632243830Sdim IsAAPCS = false; 3633243830Sdim 3634198092Srdivacky if (IsThumb) { 3635221345Sdim // Thumb1 add sp, #imm requires the immediate value be multiple of 4, 3636221345Sdim // so set preferred for small types to 32. 3637198092Srdivacky DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" 3638224145Sdim "i64:32:64-f32:32:32-f64:32:64-" 3639226633Sdim "v64:32:64-v128:32:128-a0:0:32-n32-S32"); 3640198092Srdivacky } else { 3641198092Srdivacky DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 3642221345Sdim "i64:32:64-f32:32:32-f64:32:64-" 3643226633Sdim "v64:32:64-v128:32:128-a0:0:32-n32-S32"); 3644198092Srdivacky } 3645198092Srdivacky 3646198092Srdivacky // FIXME: Override "preferred align" for double and long long. 3647243830Sdim } else if (Name == "aapcs" || Name == "aapcs-vfp") { 3648243830Sdim IsAAPCS = true; 3649198092Srdivacky // FIXME: Enumerated types are variable width in straight AAPCS. 3650198092Srdivacky } else if (Name == "aapcs-linux") { 3651243830Sdim IsAAPCS = true; 3652198092Srdivacky } else 3653198092Srdivacky return false; 3654198092Srdivacky 3655198092Srdivacky return true; 3656198092Srdivacky } 3657201361Srdivacky 3658226633Sdim void getDefaultFeatures(llvm::StringMap<bool> &Features) const { 3659201361Srdivacky if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore") 3660201361Srdivacky Features["vfp2"] = true; 3661243830Sdim else if (CPU == "cortex-a8" || CPU == "cortex-a15" || 3662243830Sdim CPU == "cortex-a9" || CPU == "cortex-a9-mp") 3663201361Srdivacky Features["neon"] = true; 3664249423Sdim else if (CPU == "swift" || CPU == "cortex-a7") { 3665243830Sdim Features["vfp4"] = true; 3666243830Sdim Features["neon"] = true; 3667243830Sdim } 3668201361Srdivacky } 3669218893Sdim 3670201361Srdivacky virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 3671234353Sdim StringRef Name, 3672201361Srdivacky bool Enabled) const { 3673224145Sdim if (Name == "soft-float" || Name == "soft-float-abi" || 3674243830Sdim Name == "vfp2" || Name == "vfp3" || Name == "vfp4" || Name == "neon" || 3675243830Sdim Name == "d16" || Name == "neonfp") { 3676201361Srdivacky Features[Name] = Enabled; 3677201361Srdivacky } else 3678201361Srdivacky return false; 3679201361Srdivacky 3680201361Srdivacky return true; 3681201361Srdivacky } 3682201361Srdivacky 3683201361Srdivacky virtual void HandleTargetFeatures(std::vector<std::string> &Features) { 3684243830Sdim FPU = 0; 3685201361Srdivacky SoftFloat = SoftFloatABI = false; 3686201361Srdivacky for (unsigned i = 0, e = Features.size(); i != e; ++i) { 3687201361Srdivacky if (Features[i] == "+soft-float") 3688201361Srdivacky SoftFloat = true; 3689201361Srdivacky else if (Features[i] == "+soft-float-abi") 3690201361Srdivacky SoftFloatABI = true; 3691201361Srdivacky else if (Features[i] == "+vfp2") 3692243830Sdim FPU |= VFP2FPU; 3693201361Srdivacky else if (Features[i] == "+vfp3") 3694243830Sdim FPU |= VFP3FPU; 3695243830Sdim else if (Features[i] == "+vfp4") 3696243830Sdim FPU |= VFP4FPU; 3697201361Srdivacky else if (Features[i] == "+neon") 3698243830Sdim FPU |= NeonFPU; 3699201361Srdivacky } 3700201361Srdivacky 3701201361Srdivacky // Remove front-end specific options which the backend handles differently. 3702201361Srdivacky std::vector<std::string>::iterator it; 3703201361Srdivacky it = std::find(Features.begin(), Features.end(), "+soft-float"); 3704201361Srdivacky if (it != Features.end()) 3705201361Srdivacky Features.erase(it); 3706201361Srdivacky it = std::find(Features.begin(), Features.end(), "+soft-float-abi"); 3707201361Srdivacky if (it != Features.end()) 3708201361Srdivacky Features.erase(it); 3709201361Srdivacky } 3710201361Srdivacky 3711234353Sdim virtual bool hasFeature(StringRef Feature) const { 3712234353Sdim return llvm::StringSwitch<bool>(Feature) 3713234353Sdim .Case("arm", true) 3714234353Sdim .Case("softfloat", SoftFloat) 3715234353Sdim .Case("thumb", IsThumb) 3716234353Sdim .Case("neon", FPU == NeonFPU && !SoftFloat && 3717234353Sdim StringRef(getCPUDefineSuffix(CPU)).startswith("7")) 3718234353Sdim .Default(false); 3719234353Sdim } 3720243830Sdim // FIXME: Should we actually have some table instead of these switches? 3721226633Sdim static const char *getCPUDefineSuffix(StringRef Name) { 3722201361Srdivacky return llvm::StringSwitch<const char*>(Name) 3723201361Srdivacky .Cases("arm8", "arm810", "4") 3724201361Srdivacky .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4") 3725201361Srdivacky .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T") 3726201361Srdivacky .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T") 3727201361Srdivacky .Case("ep9312", "4T") 3728201361Srdivacky .Cases("arm10tdmi", "arm1020t", "5T") 3729201361Srdivacky .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE") 3730201361Srdivacky .Case("arm926ej-s", "5TEJ") 3731201361Srdivacky .Cases("arm10e", "arm1020e", "arm1022e", "5TE") 3732201361Srdivacky .Cases("xscale", "iwmmxt", "5TE") 3733201361Srdivacky .Case("arm1136j-s", "6J") 3734201361Srdivacky .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK") 3735201361Srdivacky .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K") 3736201361Srdivacky .Cases("arm1156t2-s", "arm1156t2f-s", "6T2") 3737249423Sdim .Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A") 3738249423Sdim .Cases("cortex-a9", "cortex-a15", "7A") 3739249423Sdim .Case("cortex-r5", "7R") 3740243830Sdim .Case("cortex-a9-mp", "7F") 3741243830Sdim .Case("swift", "7S") 3742243830Sdim .Cases("cortex-m3", "cortex-m4", "7M") 3743221345Sdim .Case("cortex-m0", "6M") 3744201361Srdivacky .Default(0); 3745201361Srdivacky } 3746243830Sdim static const char *getCPUProfile(StringRef Name) { 3747243830Sdim return llvm::StringSwitch<const char*>(Name) 3748243830Sdim .Cases("cortex-a8", "cortex-a9", "A") 3749243830Sdim .Cases("cortex-m3", "cortex-m4", "cortex-m0", "M") 3750249423Sdim .Case("cortex-r5", "R") 3751243830Sdim .Default(""); 3752243830Sdim } 3753201361Srdivacky virtual bool setCPU(const std::string &Name) { 3754201361Srdivacky if (!getCPUDefineSuffix(Name)) 3755201361Srdivacky return false; 3756201361Srdivacky 3757201361Srdivacky CPU = Name; 3758201361Srdivacky return true; 3759201361Srdivacky } 3760193326Sed virtual void getTargetDefines(const LangOptions &Opts, 3761202379Srdivacky MacroBuilder &Builder) const { 3762193326Sed // Target identification. 3763202379Srdivacky Builder.defineMacro("__arm"); 3764202379Srdivacky Builder.defineMacro("__arm__"); 3765193326Sed 3766193326Sed // Target properties. 3767202379Srdivacky Builder.defineMacro("__ARMEL__"); 3768202379Srdivacky Builder.defineMacro("__LITTLE_ENDIAN__"); 3769202379Srdivacky Builder.defineMacro("__REGISTER_PREFIX__", ""); 3770193326Sed 3771226633Sdim StringRef CPUArch = getCPUDefineSuffix(CPU); 3772202379Srdivacky Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__"); 3773243830Sdim Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1)); 3774243830Sdim StringRef CPUProfile = getCPUProfile(CPU); 3775243830Sdim if (!CPUProfile.empty()) 3776243830Sdim Builder.defineMacro("__ARM_ARCH_PROFILE", CPUProfile); 3777243830Sdim 3778193326Sed // Subtarget options. 3779201361Srdivacky 3780201361Srdivacky // FIXME: It's more complicated than this and we don't really support 3781201361Srdivacky // interworking. 3782201361Srdivacky if ('5' <= CPUArch[0] && CPUArch[0] <= '7') 3783202379Srdivacky Builder.defineMacro("__THUMB_INTERWORK__"); 3784201361Srdivacky 3785243830Sdim if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") { 3786243830Sdim // M-class CPUs on Darwin follow AAPCS, but not EABI. 3787243830Sdim if (!(getTriple().isOSDarwin() && CPUProfile == "M")) 3788243830Sdim Builder.defineMacro("__ARM_EABI__"); 3789243830Sdim Builder.defineMacro("__ARM_PCS", "1"); 3790201361Srdivacky 3791243830Sdim if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp") 3792243830Sdim Builder.defineMacro("__ARM_PCS_VFP", "1"); 3793243830Sdim } 3794243830Sdim 3795201361Srdivacky if (SoftFloat) 3796202379Srdivacky Builder.defineMacro("__SOFTFP__"); 3797201361Srdivacky 3798201361Srdivacky if (CPU == "xscale") 3799202379Srdivacky Builder.defineMacro("__XSCALE__"); 3800198092Srdivacky 3801223017Sdim bool IsARMv7 = CPUArch.startswith("7"); 3802198092Srdivacky if (IsThumb) { 3803202379Srdivacky Builder.defineMacro("__THUMBEL__"); 3804202379Srdivacky Builder.defineMacro("__thumb__"); 3805223017Sdim if (CPUArch == "6T2" || IsARMv7) 3806202379Srdivacky Builder.defineMacro("__thumb2__"); 3807198092Srdivacky } 3808198092Srdivacky 3809198092Srdivacky // Note, this is always on in gcc, even though it doesn't make sense. 3810202379Srdivacky Builder.defineMacro("__APCS_32__"); 3811198092Srdivacky 3812243830Sdim if (FPUModeIsVFP((FPUMode) FPU)) { 3813202379Srdivacky Builder.defineMacro("__VFP_FP__"); 3814243830Sdim if (FPU & VFP2FPU) 3815243830Sdim Builder.defineMacro("__ARM_VFPV2__"); 3816243830Sdim if (FPU & VFP3FPU) 3817243830Sdim Builder.defineMacro("__ARM_VFPV3__"); 3818243830Sdim if (FPU & VFP4FPU) 3819243830Sdim Builder.defineMacro("__ARM_VFPV4__"); 3820243830Sdim } 3821243830Sdim 3822201361Srdivacky // This only gets set when Neon instructions are actually available, unlike 3823201361Srdivacky // the VFP define, hence the soft float and arch check. This is subtly 3824201361Srdivacky // different from gcc, we follow the intent which was that it should be set 3825201361Srdivacky // when Neon instructions are actually available. 3826243830Sdim if ((FPU & NeonFPU) && !SoftFloat && IsARMv7) 3827202379Srdivacky Builder.defineMacro("__ARM_NEON__"); 3828193326Sed } 3829193326Sed virtual void getTargetBuiltins(const Builtin::Info *&Records, 3830193326Sed unsigned &NumRecords) const { 3831204793Srdivacky Records = BuiltinInfo; 3832204793Srdivacky NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin; 3833193326Sed } 3834234353Sdim virtual bool isCLZForZeroUndef() const { return false; } 3835239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 3836243830Sdim return IsAAPCS ? AAPCSABIBuiltinVaList : TargetInfo::VoidPtrBuiltinVaList; 3837193326Sed } 3838193326Sed virtual void getGCCRegNames(const char * const *&Names, 3839198092Srdivacky unsigned &NumNames) const; 3840193326Sed virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 3841198092Srdivacky unsigned &NumAliases) const; 3842193326Sed virtual bool validateAsmConstraint(const char *&Name, 3843193326Sed TargetInfo::ConstraintInfo &Info) const { 3844193326Sed switch (*Name) { 3845239462Sdim default: break; 3846193326Sed case 'l': // r0-r7 3847193326Sed case 'h': // r8-r15 3848193326Sed case 'w': // VFP Floating point register single precision 3849193326Sed case 'P': // VFP Floating point register double precision 3850193326Sed Info.setAllowsRegister(); 3851193326Sed return true; 3852226633Sdim case 'Q': // A memory address that is a single base register. 3853226633Sdim Info.setAllowsMemory(); 3854226633Sdim return true; 3855223017Sdim case 'U': // a memory reference... 3856223017Sdim switch (Name[1]) { 3857223017Sdim case 'q': // ...ARMV4 ldrsb 3858223017Sdim case 'v': // ...VFP load/store (reg+constant offset) 3859223017Sdim case 'y': // ...iWMMXt load/store 3860224145Sdim case 't': // address valid for load/store opaque types wider 3861249423Sdim // than 128-bits 3862224145Sdim case 'n': // valid address for Neon doubleword vector load/store 3863224145Sdim case 'm': // valid address for Neon element and structure load/store 3864224145Sdim case 's': // valid address for non-offset loads/stores of quad-word 3865249423Sdim // values in four ARM registers 3866223017Sdim Info.setAllowsMemory(); 3867223017Sdim Name++; 3868223017Sdim return true; 3869223017Sdim } 3870193326Sed } 3871193326Sed return false; 3872193326Sed } 3873224145Sdim virtual std::string convertConstraint(const char *&Constraint) const { 3874223017Sdim std::string R; 3875223017Sdim switch (*Constraint) { 3876223017Sdim case 'U': // Two-character constraint; add "^" hint for later parsing. 3877223017Sdim R = std::string("^") + std::string(Constraint, 2); 3878223017Sdim Constraint++; 3879223017Sdim break; 3880224145Sdim case 'p': // 'p' should be translated to 'r' by default. 3881224145Sdim R = std::string("r"); 3882224145Sdim break; 3883223017Sdim default: 3884223017Sdim return std::string(1, *Constraint); 3885223017Sdim } 3886223017Sdim return R; 3887223017Sdim } 3888243830Sdim virtual bool validateConstraintModifier(StringRef Constraint, 3889243830Sdim const char Modifier, 3890243830Sdim unsigned Size) const { 3891249423Sdim bool isOutput = (Constraint[0] == '='); 3892249423Sdim bool isInOut = (Constraint[0] == '+'); 3893249423Sdim 3894243830Sdim // Strip off constraint modifiers. 3895243830Sdim while (Constraint[0] == '=' || 3896243830Sdim Constraint[0] == '+' || 3897243830Sdim Constraint[0] == '&') 3898243830Sdim Constraint = Constraint.substr(1); 3899243830Sdim 3900243830Sdim switch (Constraint[0]) { 3901243830Sdim default: break; 3902243830Sdim case 'r': { 3903243830Sdim switch (Modifier) { 3904243830Sdim default: 3905249423Sdim return isInOut || (isOutput && Size >= 32) || 3906249423Sdim (!isOutput && !isInOut && Size <= 32); 3907243830Sdim case 'q': 3908243830Sdim // A register of size 32 cannot fit a vector type. 3909243830Sdim return false; 3910243830Sdim } 3911243830Sdim } 3912243830Sdim } 3913243830Sdim 3914243830Sdim return true; 3915243830Sdim } 3916193326Sed virtual const char *getClobbers() const { 3917193326Sed // FIXME: Is this really right? 3918193326Sed return ""; 3919193326Sed } 3920243830Sdim 3921243830Sdim virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { 3922243830Sdim return (CC == CC_AAPCS || CC == CC_AAPCS_VFP) ? CCCR_OK : CCCR_Warning; 3923243830Sdim } 3924249423Sdim 3925249423Sdim virtual int getEHDataRegisterNumber(unsigned RegNo) const { 3926249423Sdim if (RegNo == 0) return 0; 3927249423Sdim if (RegNo == 1) return 1; 3928249423Sdim return -1; 3929249423Sdim } 3930193326Sed}; 3931198092Srdivacky 3932198092Srdivackyconst char * const ARMTargetInfo::GCCRegNames[] = { 3933212904Sdim // Integer registers 3934198092Srdivacky "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 3935212904Sdim "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", 3936212904Sdim 3937212904Sdim // Float registers 3938212904Sdim "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 3939212904Sdim "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", 3940212904Sdim "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", 3941218893Sdim "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 3942212904Sdim 3943218893Sdim // Double registers 3944218893Sdim "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", 3945218893Sdim "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", 3946218893Sdim "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", 3947218893Sdim "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 3948218893Sdim 3949218893Sdim // Quad registers 3950218893Sdim "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", 3951218893Sdim "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" 3952198092Srdivacky}; 3953198092Srdivacky 3954198092Srdivackyvoid ARMTargetInfo::getGCCRegNames(const char * const *&Names, 3955212904Sdim unsigned &NumNames) const { 3956198092Srdivacky Names = GCCRegNames; 3957198092Srdivacky NumNames = llvm::array_lengthof(GCCRegNames); 3958198092Srdivacky} 3959198092Srdivacky 3960198092Srdivackyconst TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 3961198092Srdivacky { { "a1" }, "r0" }, 3962198092Srdivacky { { "a2" }, "r1" }, 3963198092Srdivacky { { "a3" }, "r2" }, 3964198092Srdivacky { { "a4" }, "r3" }, 3965198092Srdivacky { { "v1" }, "r4" }, 3966198092Srdivacky { { "v2" }, "r5" }, 3967198092Srdivacky { { "v3" }, "r6" }, 3968198092Srdivacky { { "v4" }, "r7" }, 3969198092Srdivacky { { "v5" }, "r8" }, 3970198092Srdivacky { { "v6", "rfp" }, "r9" }, 3971198092Srdivacky { { "sl" }, "r10" }, 3972198092Srdivacky { { "fp" }, "r11" }, 3973198092Srdivacky { { "ip" }, "r12" }, 3974212904Sdim { { "r13" }, "sp" }, 3975212904Sdim { { "r14" }, "lr" }, 3976212904Sdim { { "r15" }, "pc" }, 3977218893Sdim // The S, D and Q registers overlap, but aren't really aliases; we 3978218893Sdim // don't want to substitute one of these for a different-sized one. 3979198092Srdivacky}; 3980198092Srdivacky 3981198092Srdivackyvoid ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 3982198092Srdivacky unsigned &NumAliases) const { 3983198092Srdivacky Aliases = GCCRegAliases; 3984198092Srdivacky NumAliases = llvm::array_lengthof(GCCRegAliases); 3985198092Srdivacky} 3986204793Srdivacky 3987204793Srdivackyconst Builtin::Info ARMTargetInfo::BuiltinInfo[] = { 3988224145Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, 3989218893Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\ 3990224145Sdim ALL_LANGUAGES }, 3991204793Srdivacky#include "clang/Basic/BuiltinsARM.def" 3992204793Srdivacky}; 3993193326Sed} // end anonymous namespace. 3994193326Sed 3995193326Sednamespace { 3996198092Srdivackyclass DarwinARMTargetInfo : 3997195341Sed public DarwinTargetInfo<ARMTargetInfo> { 3998195341Sedprotected: 3999198092Srdivacky virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 4000202379Srdivacky MacroBuilder &Builder) const { 4001221345Sdim getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 4002193326Sed } 4003193326Sed 4004193326Sedpublic: 4005198092Srdivacky DarwinARMTargetInfo(const std::string& triple) 4006208600Srdivacky : DarwinTargetInfo<ARMTargetInfo>(triple) { 4007208600Srdivacky HasAlignMac68kSupport = true; 4008226633Sdim // iOS always has 64-bit atomic instructions. 4009226633Sdim // FIXME: This should be based off of the target features in ARMTargetInfo. 4010226633Sdim MaxAtomicInlineWidth = 64; 4011249423Sdim 4012249423Sdim // Darwin on iOS uses a variant of the ARM C++ ABI. 4013249423Sdim TheCXXABI.set(TargetCXXABI::iOS); 4014208600Srdivacky } 4015193326Sed}; 4016195341Sed} // end anonymous namespace. 4017193326Sed 4018234353Sdim 4019193326Sednamespace { 4020234353Sdim// Hexagon abstract base class 4021234353Sdimclass HexagonTargetInfo : public TargetInfo { 4022234353Sdim static const Builtin::Info BuiltinInfo[]; 4023234353Sdim static const char * const GCCRegNames[]; 4024234353Sdim static const TargetInfo::GCCRegAlias GCCRegAliases[]; 4025234353Sdim std::string CPU; 4026234353Sdimpublic: 4027234353Sdim HexagonTargetInfo(const std::string& triple) : TargetInfo(triple) { 4028234353Sdim BigEndian = false; 4029234353Sdim DescriptionString = ("e-p:32:32:32-" 4030249423Sdim "i64:64:64-i32:32:32-i16:16:16-i1:32:32-" 4031239462Sdim "f64:64:64-f32:32:32-a0:0-n32"); 4032234353Sdim 4033234353Sdim // {} in inline assembly are packet specifiers, not assembly variant 4034234353Sdim // specifiers. 4035234353Sdim NoAsmVariants = true; 4036234353Sdim } 4037234353Sdim 4038234353Sdim virtual void getTargetBuiltins(const Builtin::Info *&Records, 4039234353Sdim unsigned &NumRecords) const { 4040234353Sdim Records = BuiltinInfo; 4041234353Sdim NumRecords = clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin; 4042234353Sdim } 4043234353Sdim 4044234353Sdim virtual bool validateAsmConstraint(const char *&Name, 4045234353Sdim TargetInfo::ConstraintInfo &Info) const { 4046234353Sdim return true; 4047234353Sdim } 4048234353Sdim 4049234353Sdim virtual void getTargetDefines(const LangOptions &Opts, 4050234353Sdim MacroBuilder &Builder) const; 4051234353Sdim 4052234353Sdim virtual bool hasFeature(StringRef Feature) const { 4053234353Sdim return Feature == "hexagon"; 4054234353Sdim } 4055234353Sdim 4056239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 4057239462Sdim return TargetInfo::CharPtrBuiltinVaList; 4058234353Sdim } 4059234353Sdim virtual void getGCCRegNames(const char * const *&Names, 4060234353Sdim unsigned &NumNames) const; 4061234353Sdim virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 4062234353Sdim unsigned &NumAliases) const; 4063234353Sdim virtual const char *getClobbers() const { 4064234353Sdim return ""; 4065234353Sdim } 4066234353Sdim 4067234353Sdim static const char *getHexagonCPUSuffix(StringRef Name) { 4068234353Sdim return llvm::StringSwitch<const char*>(Name) 4069234353Sdim .Case("hexagonv4", "4") 4070239462Sdim .Case("hexagonv5", "5") 4071234353Sdim .Default(0); 4072234353Sdim } 4073234353Sdim 4074234353Sdim virtual bool setCPU(const std::string &Name) { 4075234353Sdim if (!getHexagonCPUSuffix(Name)) 4076234353Sdim return false; 4077234353Sdim 4078234353Sdim CPU = Name; 4079234353Sdim return true; 4080234353Sdim } 4081234353Sdim}; 4082234353Sdim 4083234353Sdimvoid HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, 4084234353Sdim MacroBuilder &Builder) const { 4085234353Sdim Builder.defineMacro("qdsp6"); 4086234353Sdim Builder.defineMacro("__qdsp6", "1"); 4087234353Sdim Builder.defineMacro("__qdsp6__", "1"); 4088234353Sdim 4089234353Sdim Builder.defineMacro("hexagon"); 4090234353Sdim Builder.defineMacro("__hexagon", "1"); 4091234353Sdim Builder.defineMacro("__hexagon__", "1"); 4092234353Sdim 4093234353Sdim if(CPU == "hexagonv1") { 4094234353Sdim Builder.defineMacro("__HEXAGON_V1__"); 4095234353Sdim Builder.defineMacro("__HEXAGON_ARCH__", "1"); 4096234353Sdim if(Opts.HexagonQdsp6Compat) { 4097234353Sdim Builder.defineMacro("__QDSP6_V1__"); 4098234353Sdim Builder.defineMacro("__QDSP6_ARCH__", "1"); 4099234353Sdim } 4100234353Sdim } 4101234353Sdim else if(CPU == "hexagonv2") { 4102234353Sdim Builder.defineMacro("__HEXAGON_V2__"); 4103234353Sdim Builder.defineMacro("__HEXAGON_ARCH__", "2"); 4104234353Sdim if(Opts.HexagonQdsp6Compat) { 4105234353Sdim Builder.defineMacro("__QDSP6_V2__"); 4106234353Sdim Builder.defineMacro("__QDSP6_ARCH__", "2"); 4107234353Sdim } 4108234353Sdim } 4109234353Sdim else if(CPU == "hexagonv3") { 4110234353Sdim Builder.defineMacro("__HEXAGON_V3__"); 4111234353Sdim Builder.defineMacro("__HEXAGON_ARCH__", "3"); 4112234353Sdim if(Opts.HexagonQdsp6Compat) { 4113234353Sdim Builder.defineMacro("__QDSP6_V3__"); 4114234353Sdim Builder.defineMacro("__QDSP6_ARCH__", "3"); 4115234353Sdim } 4116234353Sdim } 4117234353Sdim else if(CPU == "hexagonv4") { 4118234353Sdim Builder.defineMacro("__HEXAGON_V4__"); 4119234353Sdim Builder.defineMacro("__HEXAGON_ARCH__", "4"); 4120234353Sdim if(Opts.HexagonQdsp6Compat) { 4121234353Sdim Builder.defineMacro("__QDSP6_V4__"); 4122234353Sdim Builder.defineMacro("__QDSP6_ARCH__", "4"); 4123234353Sdim } 4124234353Sdim } 4125239462Sdim else if(CPU == "hexagonv5") { 4126239462Sdim Builder.defineMacro("__HEXAGON_V5__"); 4127239462Sdim Builder.defineMacro("__HEXAGON_ARCH__", "5"); 4128239462Sdim if(Opts.HexagonQdsp6Compat) { 4129239462Sdim Builder.defineMacro("__QDSP6_V5__"); 4130239462Sdim Builder.defineMacro("__QDSP6_ARCH__", "5"); 4131239462Sdim } 4132239462Sdim } 4133234353Sdim} 4134234353Sdim 4135234353Sdimconst char * const HexagonTargetInfo::GCCRegNames[] = { 4136234353Sdim "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 4137234353Sdim "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 4138234353Sdim "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 4139234353Sdim "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 4140234353Sdim "p0", "p1", "p2", "p3", 4141234353Sdim "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp" 4142234353Sdim}; 4143234353Sdim 4144234353Sdimvoid HexagonTargetInfo::getGCCRegNames(const char * const *&Names, 4145234353Sdim unsigned &NumNames) const { 4146234353Sdim Names = GCCRegNames; 4147234353Sdim NumNames = llvm::array_lengthof(GCCRegNames); 4148234353Sdim} 4149234353Sdim 4150234353Sdim 4151234353Sdimconst TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { 4152234353Sdim { { "sp" }, "r29" }, 4153234353Sdim { { "fp" }, "r30" }, 4154234353Sdim { { "lr" }, "r31" }, 4155234353Sdim }; 4156234353Sdim 4157234353Sdimvoid HexagonTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 4158234353Sdim unsigned &NumAliases) const { 4159234353Sdim Aliases = GCCRegAliases; 4160234353Sdim NumAliases = llvm::array_lengthof(GCCRegAliases); 4161234353Sdim} 4162234353Sdim 4163234353Sdim 4164234353Sdimconst Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { 4165234353Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, 4166234353Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\ 4167234353Sdim ALL_LANGUAGES }, 4168234353Sdim#include "clang/Basic/BuiltinsHexagon.def" 4169234353Sdim}; 4170234353Sdim} 4171234353Sdim 4172234353Sdim 4173234353Sdimnamespace { 4174251662Sdim// Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit). 4175251662Sdimclass SparcTargetInfo : public TargetInfo { 4176193326Sed static const TargetInfo::GCCRegAlias GCCRegAliases[]; 4177193326Sed static const char * const GCCRegNames[]; 4178218893Sdim bool SoftFloat; 4179193326Sedpublic: 4180251662Sdim SparcTargetInfo(const std::string &triple) : TargetInfo(triple) {} 4181251662Sdim 4182218893Sdim virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 4183234353Sdim StringRef Name, 4184218893Sdim bool Enabled) const { 4185218893Sdim if (Name == "soft-float") 4186218893Sdim Features[Name] = Enabled; 4187218893Sdim else 4188218893Sdim return false; 4189218893Sdim 4190218893Sdim return true; 4191218893Sdim } 4192218893Sdim virtual void HandleTargetFeatures(std::vector<std::string> &Features) { 4193218893Sdim SoftFloat = false; 4194218893Sdim for (unsigned i = 0, e = Features.size(); i != e; ++i) 4195218893Sdim if (Features[i] == "+soft-float") 4196218893Sdim SoftFloat = true; 4197218893Sdim } 4198193326Sed virtual void getTargetDefines(const LangOptions &Opts, 4199202379Srdivacky MacroBuilder &Builder) const { 4200202379Srdivacky DefineStd(Builder, "sparc", Opts); 4201202379Srdivacky Builder.defineMacro("__REGISTER_PREFIX__", ""); 4202218893Sdim 4203218893Sdim if (SoftFloat) 4204218893Sdim Builder.defineMacro("SOFT_FLOAT", "1"); 4205193326Sed } 4206234353Sdim 4207234353Sdim virtual bool hasFeature(StringRef Feature) const { 4208234353Sdim return llvm::StringSwitch<bool>(Feature) 4209234353Sdim .Case("softfloat", SoftFloat) 4210234353Sdim .Case("sparc", true) 4211234353Sdim .Default(false); 4212234353Sdim } 4213234353Sdim 4214193326Sed virtual void getTargetBuiltins(const Builtin::Info *&Records, 4215193326Sed unsigned &NumRecords) const { 4216193326Sed // FIXME: Implement! 4217193326Sed } 4218239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 4219239462Sdim return TargetInfo::VoidPtrBuiltinVaList; 4220193326Sed } 4221193326Sed virtual void getGCCRegNames(const char * const *&Names, 4222193326Sed unsigned &NumNames) const; 4223193326Sed virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 4224193326Sed unsigned &NumAliases) const; 4225193326Sed virtual bool validateAsmConstraint(const char *&Name, 4226193326Sed TargetInfo::ConstraintInfo &info) const { 4227193326Sed // FIXME: Implement! 4228193326Sed return false; 4229193326Sed } 4230193326Sed virtual const char *getClobbers() const { 4231193326Sed // FIXME: Implement! 4232193326Sed return ""; 4233193326Sed } 4234193326Sed}; 4235193326Sed 4236251662Sdimconst char * const SparcTargetInfo::GCCRegNames[] = { 4237193326Sed "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 4238193326Sed "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 4239193326Sed "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 4240193326Sed "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" 4241193326Sed}; 4242193326Sed 4243251662Sdimvoid SparcTargetInfo::getGCCRegNames(const char * const *&Names, 4244251662Sdim unsigned &NumNames) const { 4245193326Sed Names = GCCRegNames; 4246193326Sed NumNames = llvm::array_lengthof(GCCRegNames); 4247193326Sed} 4248193326Sed 4249251662Sdimconst TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = { 4250193326Sed { { "g0" }, "r0" }, 4251193326Sed { { "g1" }, "r1" }, 4252193326Sed { { "g2" }, "r2" }, 4253193326Sed { { "g3" }, "r3" }, 4254193326Sed { { "g4" }, "r4" }, 4255193326Sed { { "g5" }, "r5" }, 4256193326Sed { { "g6" }, "r6" }, 4257193326Sed { { "g7" }, "r7" }, 4258193326Sed { { "o0" }, "r8" }, 4259193326Sed { { "o1" }, "r9" }, 4260193326Sed { { "o2" }, "r10" }, 4261193326Sed { { "o3" }, "r11" }, 4262193326Sed { { "o4" }, "r12" }, 4263193326Sed { { "o5" }, "r13" }, 4264193326Sed { { "o6", "sp" }, "r14" }, 4265193326Sed { { "o7" }, "r15" }, 4266193326Sed { { "l0" }, "r16" }, 4267193326Sed { { "l1" }, "r17" }, 4268193326Sed { { "l2" }, "r18" }, 4269193326Sed { { "l3" }, "r19" }, 4270193326Sed { { "l4" }, "r20" }, 4271193326Sed { { "l5" }, "r21" }, 4272193326Sed { { "l6" }, "r22" }, 4273193326Sed { { "l7" }, "r23" }, 4274193326Sed { { "i0" }, "r24" }, 4275193326Sed { { "i1" }, "r25" }, 4276193326Sed { { "i2" }, "r26" }, 4277193326Sed { { "i3" }, "r27" }, 4278193326Sed { { "i4" }, "r28" }, 4279193326Sed { { "i5" }, "r29" }, 4280193326Sed { { "i6", "fp" }, "r30" }, 4281193326Sed { { "i7" }, "r31" }, 4282193326Sed}; 4283193326Sed 4284251662Sdimvoid SparcTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 4285251662Sdim unsigned &NumAliases) const { 4286193326Sed Aliases = GCCRegAliases; 4287193326Sed NumAliases = llvm::array_lengthof(GCCRegAliases); 4288193326Sed} 4289251662Sdim 4290251662Sdim// SPARC v8 is the 32-bit mode selected by Triple::sparc. 4291251662Sdimclass SparcV8TargetInfo : public SparcTargetInfo { 4292251662Sdimpublic: 4293251662Sdim SparcV8TargetInfo(const std::string& triple) : SparcTargetInfo(triple) { 4294251662Sdim // FIXME: Support Sparc quad-precision long double? 4295251662Sdim DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 4296251662Sdim "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64"; 4297251662Sdim } 4298251662Sdim 4299251662Sdim virtual void getTargetDefines(const LangOptions &Opts, 4300251662Sdim MacroBuilder &Builder) const { 4301251662Sdim SparcTargetInfo::getTargetDefines(Opts, Builder); 4302251662Sdim Builder.defineMacro("__sparcv8"); 4303251662Sdim } 4304251662Sdim}; 4305251662Sdim 4306251662Sdim// SPARC v9 is the 64-bit mode selected by Triple::sparcv9. 4307251662Sdimclass SparcV9TargetInfo : public SparcTargetInfo { 4308251662Sdimpublic: 4309251662Sdim SparcV9TargetInfo(const std::string& triple) : SparcTargetInfo(triple) { 4310251662Sdim // FIXME: Support Sparc quad-precision long double? 4311251662Sdim DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 4312251662Sdim "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32:64-S128"; 4313251662Sdim } 4314251662Sdim 4315251662Sdim virtual void getTargetDefines(const LangOptions &Opts, 4316251662Sdim MacroBuilder &Builder) const { 4317251662Sdim SparcTargetInfo::getTargetDefines(Opts, Builder); 4318251662Sdim Builder.defineMacro("__sparcv9"); 4319251662Sdim Builder.defineMacro("__arch64__"); 4320251662Sdim // Solaris and its derivative AuroraUX don't need these variants, but the 4321251662Sdim // BSDs do. 4322251662Sdim if (getTriple().getOS() != llvm::Triple::Solaris && 4323251662Sdim getTriple().getOS() != llvm::Triple::AuroraUX) { 4324251662Sdim Builder.defineMacro("__sparc64__"); 4325251662Sdim Builder.defineMacro("__sparc_v9__"); 4326251662Sdim Builder.defineMacro("__sparcv9__"); 4327251662Sdim } 4328251662Sdim } 4329251662Sdim}; 4330251662Sdim 4331193326Sed} // end anonymous namespace. 4332193326Sed 4333193326Sednamespace { 4334198398Srdivackyclass AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> { 4335198398Srdivackypublic: 4336198398Srdivacky AuroraUXSparcV8TargetInfo(const std::string& triple) : 4337198398Srdivacky AuroraUXTargetInfo<SparcV8TargetInfo>(triple) { 4338198398Srdivacky SizeType = UnsignedInt; 4339198398Srdivacky PtrDiffType = SignedInt; 4340198398Srdivacky } 4341198398Srdivacky}; 4342195341Sedclass SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> { 4343193326Sedpublic: 4344193326Sed SolarisSparcV8TargetInfo(const std::string& triple) : 4345195341Sed SolarisTargetInfo<SparcV8TargetInfo>(triple) { 4346193326Sed SizeType = UnsignedInt; 4347193326Sed PtrDiffType = SignedInt; 4348193326Sed } 4349193326Sed}; 4350193326Sed} // end anonymous namespace. 4351193326Sed 4352193326Sednamespace { 4353251662Sdim class SystemZTargetInfo : public TargetInfo { 4354251662Sdim static const char *const GCCRegNames[]; 4355251662Sdim 4356251662Sdim public: 4357251662Sdim SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) { 4358251662Sdim TLSSupported = true; 4359251662Sdim IntWidth = IntAlign = 32; 4360251662Sdim LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; 4361251662Sdim PointerWidth = PointerAlign = 64; 4362251662Sdim LongDoubleWidth = 128; 4363251662Sdim LongDoubleAlign = 64; 4364251662Sdim LongDoubleFormat = &llvm::APFloat::IEEEquad; 4365251662Sdim MinGlobalAlign = 16; 4366251662Sdim DescriptionString = "E-p:64:64:64-i1:8:16-i8:8:16-i16:16-i32:32-i64:64" 4367251662Sdim "-f32:32-f64:64-f128:64-a0:8:16-n32:64"; 4368251662Sdim MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 4369251662Sdim } 4370251662Sdim virtual void getTargetDefines(const LangOptions &Opts, 4371251662Sdim MacroBuilder &Builder) const { 4372251662Sdim Builder.defineMacro("__s390__"); 4373251662Sdim Builder.defineMacro("__s390x__"); 4374251662Sdim Builder.defineMacro("__zarch__"); 4375251662Sdim Builder.defineMacro("__LONG_DOUBLE_128__"); 4376251662Sdim } 4377251662Sdim virtual void getTargetBuiltins(const Builtin::Info *&Records, 4378251662Sdim unsigned &NumRecords) const { 4379251662Sdim // FIXME: Implement. 4380251662Sdim Records = 0; 4381251662Sdim NumRecords = 0; 4382251662Sdim } 4383251662Sdim 4384251662Sdim virtual void getGCCRegNames(const char *const *&Names, 4385251662Sdim unsigned &NumNames) const; 4386251662Sdim virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 4387251662Sdim unsigned &NumAliases) const { 4388251662Sdim // No aliases. 4389251662Sdim Aliases = 0; 4390251662Sdim NumAliases = 0; 4391251662Sdim } 4392251662Sdim virtual bool validateAsmConstraint(const char *&Name, 4393251662Sdim TargetInfo::ConstraintInfo &info) const; 4394251662Sdim virtual const char *getClobbers() const { 4395251662Sdim // FIXME: Is this really right? 4396251662Sdim return ""; 4397251662Sdim } 4398251662Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 4399251662Sdim return TargetInfo::SystemZBuiltinVaList; 4400251662Sdim } 4401251662Sdim }; 4402251662Sdim 4403251662Sdim const char *const SystemZTargetInfo::GCCRegNames[] = { 4404251662Sdim "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 4405251662Sdim "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 4406251662Sdim "f0", "f2", "f4", "f6", "f1", "f3", "f5", "f7", 4407251662Sdim "f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15" 4408251662Sdim }; 4409251662Sdim 4410251662Sdim void SystemZTargetInfo::getGCCRegNames(const char *const *&Names, 4411251662Sdim unsigned &NumNames) const { 4412251662Sdim Names = GCCRegNames; 4413251662Sdim NumNames = llvm::array_lengthof(GCCRegNames); 4414251662Sdim } 4415251662Sdim 4416251662Sdim bool SystemZTargetInfo:: 4417251662Sdim validateAsmConstraint(const char *&Name, 4418251662Sdim TargetInfo::ConstraintInfo &Info) const { 4419251662Sdim switch (*Name) { 4420251662Sdim default: 4421251662Sdim return false; 4422251662Sdim 4423251662Sdim case 'a': // Address register 4424251662Sdim case 'd': // Data register (equivalent to 'r') 4425251662Sdim case 'f': // Floating-point register 4426251662Sdim Info.setAllowsRegister(); 4427251662Sdim return true; 4428251662Sdim 4429251662Sdim case 'I': // Unsigned 8-bit constant 4430251662Sdim case 'J': // Unsigned 12-bit constant 4431251662Sdim case 'K': // Signed 16-bit constant 4432251662Sdim case 'L': // Signed 20-bit displacement (on all targets we support) 4433251662Sdim case 'M': // 0x7fffffff 4434251662Sdim return true; 4435251662Sdim 4436251662Sdim case 'Q': // Memory with base and unsigned 12-bit displacement 4437251662Sdim case 'R': // Likewise, plus an index 4438251662Sdim case 'S': // Memory with base and signed 20-bit displacement 4439251662Sdim case 'T': // Likewise, plus an index 4440251662Sdim Info.setAllowsMemory(); 4441251662Sdim return true; 4442251662Sdim } 4443251662Sdim } 4444251662Sdim} 4445251662Sdim 4446251662Sdimnamespace { 4447193326Sed class MSP430TargetInfo : public TargetInfo { 4448193326Sed static const char * const GCCRegNames[]; 4449193326Sed public: 4450193326Sed MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { 4451234353Sdim BigEndian = false; 4452193326Sed TLSSupported = false; 4453203955Srdivacky IntWidth = 16; IntAlign = 16; 4454203955Srdivacky LongWidth = 32; LongLongWidth = 64; 4455203955Srdivacky LongAlign = LongLongAlign = 16; 4456203955Srdivacky PointerWidth = 16; PointerAlign = 16; 4457234353Sdim SuitableAlign = 16; 4458193326Sed SizeType = UnsignedInt; 4459193326Sed IntMaxType = SignedLong; 4460193326Sed UIntMaxType = UnsignedLong; 4461193326Sed IntPtrType = SignedShort; 4462193326Sed PtrDiffType = SignedInt; 4463199990Srdivacky SigAtomicType = SignedLong; 4464201361Srdivacky DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"; 4465193326Sed } 4466193326Sed virtual void getTargetDefines(const LangOptions &Opts, 4467202379Srdivacky MacroBuilder &Builder) const { 4468202379Srdivacky Builder.defineMacro("MSP430"); 4469202379Srdivacky Builder.defineMacro("__MSP430__"); 4470193326Sed // FIXME: defines for different 'flavours' of MCU 4471193326Sed } 4472193326Sed virtual void getTargetBuiltins(const Builtin::Info *&Records, 4473193326Sed unsigned &NumRecords) const { 4474193326Sed // FIXME: Implement. 4475193326Sed Records = 0; 4476193326Sed NumRecords = 0; 4477193326Sed } 4478234353Sdim virtual bool hasFeature(StringRef Feature) const { 4479234353Sdim return Feature == "msp430"; 4480234353Sdim } 4481193326Sed virtual void getGCCRegNames(const char * const *&Names, 4482193326Sed unsigned &NumNames) const; 4483193326Sed virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 4484193326Sed unsigned &NumAliases) const { 4485193326Sed // No aliases. 4486193326Sed Aliases = 0; 4487193326Sed NumAliases = 0; 4488193326Sed } 4489193326Sed virtual bool validateAsmConstraint(const char *&Name, 4490193326Sed TargetInfo::ConstraintInfo &info) const { 4491198398Srdivacky // No target constraints for now. 4492198398Srdivacky return false; 4493193326Sed } 4494193326Sed virtual const char *getClobbers() const { 4495193326Sed // FIXME: Is this really right? 4496193326Sed return ""; 4497193326Sed } 4498239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 4499193326Sed // FIXME: implement 4500239462Sdim return TargetInfo::CharPtrBuiltinVaList; 4501193326Sed } 4502193326Sed }; 4503193326Sed 4504193326Sed const char * const MSP430TargetInfo::GCCRegNames[] = { 4505193326Sed "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 4506193326Sed "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 4507193326Sed }; 4508193326Sed 4509193326Sed void MSP430TargetInfo::getGCCRegNames(const char * const *&Names, 4510193326Sed unsigned &NumNames) const { 4511193326Sed Names = GCCRegNames; 4512193326Sed NumNames = llvm::array_lengthof(GCCRegNames); 4513193326Sed } 4514193326Sed} 4515193326Sed 4516198092Srdivackynamespace { 4517198092Srdivacky 4518198092Srdivacky // LLVM and Clang cannot be used directly to output native binaries for 4519198092Srdivacky // target, but is used to compile C code to llvm bitcode with correct 4520198092Srdivacky // type and alignment information. 4521198092Srdivacky // 4522198092Srdivacky // TCE uses the llvm bitcode as input and uses it for generating customized 4523198092Srdivacky // target processor and program binary. TCE co-design environment is 4524198092Srdivacky // publicly available in http://tce.cs.tut.fi 4525198092Srdivacky 4526226633Sdim static const unsigned TCEOpenCLAddrSpaceMap[] = { 4527226633Sdim 3, // opencl_global 4528226633Sdim 4, // opencl_local 4529239462Sdim 5, // opencl_constant 4530239462Sdim 0, // cuda_device 4531239462Sdim 0, // cuda_constant 4532239462Sdim 0 // cuda_shared 4533226633Sdim }; 4534226633Sdim 4535198092Srdivacky class TCETargetInfo : public TargetInfo{ 4536198092Srdivacky public: 4537198092Srdivacky TCETargetInfo(const std::string& triple) : TargetInfo(triple) { 4538198092Srdivacky TLSSupported = false; 4539198092Srdivacky IntWidth = 32; 4540198092Srdivacky LongWidth = LongLongWidth = 32; 4541198092Srdivacky PointerWidth = 32; 4542198092Srdivacky IntAlign = 32; 4543198092Srdivacky LongAlign = LongLongAlign = 32; 4544198092Srdivacky PointerAlign = 32; 4545234353Sdim SuitableAlign = 32; 4546198092Srdivacky SizeType = UnsignedInt; 4547198092Srdivacky IntMaxType = SignedLong; 4548198092Srdivacky UIntMaxType = UnsignedLong; 4549198092Srdivacky IntPtrType = SignedInt; 4550198092Srdivacky PtrDiffType = SignedInt; 4551198092Srdivacky FloatWidth = 32; 4552198092Srdivacky FloatAlign = 32; 4553198092Srdivacky DoubleWidth = 32; 4554198092Srdivacky DoubleAlign = 32; 4555198092Srdivacky LongDoubleWidth = 32; 4556198092Srdivacky LongDoubleAlign = 32; 4557198092Srdivacky FloatFormat = &llvm::APFloat::IEEEsingle; 4558198092Srdivacky DoubleFormat = &llvm::APFloat::IEEEsingle; 4559198092Srdivacky LongDoubleFormat = &llvm::APFloat::IEEEsingle; 4560204793Srdivacky DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-" 4561204793Srdivacky "i16:16:32-i32:32:32-i64:32:32-" 4562218893Sdim "f32:32:32-f64:32:32-v64:32:32-" 4563218893Sdim "v128:32:32-a0:0:32-n32"; 4564226633Sdim AddrSpaceMap = &TCEOpenCLAddrSpaceMap; 4565198092Srdivacky } 4566198092Srdivacky 4567198092Srdivacky virtual void getTargetDefines(const LangOptions &Opts, 4568202379Srdivacky MacroBuilder &Builder) const { 4569202379Srdivacky DefineStd(Builder, "tce", Opts); 4570202379Srdivacky Builder.defineMacro("__TCE__"); 4571202379Srdivacky Builder.defineMacro("__TCE_V1__"); 4572198092Srdivacky } 4573234353Sdim virtual bool hasFeature(StringRef Feature) const { 4574234353Sdim return Feature == "tce"; 4575234353Sdim } 4576234353Sdim 4577198092Srdivacky virtual void getTargetBuiltins(const Builtin::Info *&Records, 4578198092Srdivacky unsigned &NumRecords) const {} 4579198092Srdivacky virtual const char *getClobbers() const { 4580198092Srdivacky return ""; 4581198092Srdivacky } 4582239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 4583239462Sdim return TargetInfo::VoidPtrBuiltinVaList; 4584198092Srdivacky } 4585198092Srdivacky virtual void getGCCRegNames(const char * const *&Names, 4586198092Srdivacky unsigned &NumNames) const {} 4587198092Srdivacky virtual bool validateAsmConstraint(const char *&Name, 4588198092Srdivacky TargetInfo::ConstraintInfo &info) const { 4589198092Srdivacky return true; 4590198092Srdivacky } 4591198092Srdivacky virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 4592198092Srdivacky unsigned &NumAliases) const {} 4593198092Srdivacky }; 4594198092Srdivacky} 4595198092Srdivacky 4596199482Srdivackynamespace { 4597226633Sdimclass MipsTargetInfoBase : public TargetInfo { 4598239462Sdim static const Builtin::Info BuiltinInfo[]; 4599226633Sdim std::string CPU; 4600239462Sdim bool IsMips16; 4601251662Sdim bool IsMicromips; 4602251662Sdim bool IsSingleFloat; 4603239462Sdim enum MipsFloatABI { 4604251662Sdim HardFloat, SoftFloat 4605239462Sdim } FloatABI; 4606239462Sdim enum DspRevEnum { 4607239462Sdim NoDSP, DSP1, DSP2 4608239462Sdim } DspRev; 4609234353Sdim 4610226633Sdimprotected: 4611226633Sdim std::string ABI; 4612234353Sdim 4613199482Srdivackypublic: 4614234353Sdim MipsTargetInfoBase(const std::string& triple, 4615234353Sdim const std::string& ABIStr, 4616234353Sdim const std::string& CPUStr) 4617234353Sdim : TargetInfo(triple), 4618234353Sdim CPU(CPUStr), 4619239462Sdim IsMips16(false), 4620251662Sdim IsMicromips(false), 4621251662Sdim IsSingleFloat(false), 4622239462Sdim FloatABI(HardFloat), 4623239462Sdim DspRev(NoDSP), 4624234353Sdim ABI(ABIStr) 4625234353Sdim {} 4626234353Sdim 4627204643Srdivacky virtual const char *getABI() const { return ABI.c_str(); } 4628226633Sdim virtual bool setABI(const std::string &Name) = 0; 4629204643Srdivacky virtual bool setCPU(const std::string &Name) { 4630204643Srdivacky CPU = Name; 4631204643Srdivacky return true; 4632204643Srdivacky } 4633226633Sdim void getDefaultFeatures(llvm::StringMap<bool> &Features) const { 4634204643Srdivacky Features[ABI] = true; 4635204643Srdivacky Features[CPU] = true; 4636204643Srdivacky } 4637234353Sdim 4638243830Sdim virtual void getTargetDefines(const LangOptions &Opts, 4639243830Sdim MacroBuilder &Builder) const { 4640243830Sdim DefineStd(Builder, "mips", Opts); 4641243830Sdim Builder.defineMacro("_mips"); 4642243830Sdim Builder.defineMacro("__REGISTER_PREFIX__", ""); 4643243830Sdim 4644239462Sdim switch (FloatABI) { 4645239462Sdim case HardFloat: 4646239462Sdim Builder.defineMacro("__mips_hard_float", Twine(1)); 4647239462Sdim break; 4648239462Sdim case SoftFloat: 4649234353Sdim Builder.defineMacro("__mips_soft_float", Twine(1)); 4650239462Sdim break; 4651239462Sdim } 4652234353Sdim 4653251662Sdim if (IsSingleFloat) 4654251662Sdim Builder.defineMacro("__mips_single_float", Twine(1)); 4655251662Sdim 4656239462Sdim if (IsMips16) 4657239462Sdim Builder.defineMacro("__mips16", Twine(1)); 4658239462Sdim 4659251662Sdim if (IsMicromips) 4660251662Sdim Builder.defineMacro("__mips_micromips", Twine(1)); 4661251662Sdim 4662239462Sdim switch (DspRev) { 4663239462Sdim default: 4664239462Sdim break; 4665239462Sdim case DSP1: 4666239462Sdim Builder.defineMacro("__mips_dsp_rev", Twine(1)); 4667239462Sdim Builder.defineMacro("__mips_dsp", Twine(1)); 4668239462Sdim break; 4669239462Sdim case DSP2: 4670239462Sdim Builder.defineMacro("__mips_dsp_rev", Twine(2)); 4671239462Sdim Builder.defineMacro("__mips_dspr2", Twine(1)); 4672239462Sdim Builder.defineMacro("__mips_dsp", Twine(1)); 4673239462Sdim break; 4674239462Sdim } 4675239462Sdim 4676234353Sdim Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0))); 4677234353Sdim Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth())); 4678234353Sdim Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth())); 4679243830Sdim 4680243830Sdim Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\""); 4681243830Sdim Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper()); 4682234353Sdim } 4683234353Sdim 4684199482Srdivacky virtual void getTargetBuiltins(const Builtin::Info *&Records, 4685199482Srdivacky unsigned &NumRecords) const { 4686239462Sdim Records = BuiltinInfo; 4687239462Sdim NumRecords = clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin; 4688199482Srdivacky } 4689234353Sdim virtual bool hasFeature(StringRef Feature) const { 4690234353Sdim return Feature == "mips"; 4691234353Sdim } 4692239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 4693239462Sdim return TargetInfo::VoidPtrBuiltinVaList; 4694199482Srdivacky } 4695199482Srdivacky virtual void getGCCRegNames(const char * const *&Names, 4696226633Sdim unsigned &NumNames) const { 4697226633Sdim static const char * const GCCRegNames[] = { 4698234353Sdim // CPU register names 4699234353Sdim // Must match second column of GCCRegAliases 4700226633Sdim "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 4701226633Sdim "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 4702226633Sdim "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 4703234353Sdim "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", 4704234353Sdim // Floating point register names 4705226633Sdim "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", 4706226633Sdim "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", 4707226633Sdim "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", 4708226633Sdim "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", 4709234353Sdim // Hi/lo and condition register names 4710226633Sdim "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", 4711226633Sdim "$fcc5","$fcc6","$fcc7" 4712226633Sdim }; 4713226633Sdim Names = GCCRegNames; 4714226633Sdim NumNames = llvm::array_lengthof(GCCRegNames); 4715226633Sdim } 4716199482Srdivacky virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 4717226633Sdim unsigned &NumAliases) const = 0; 4718199482Srdivacky virtual bool validateAsmConstraint(const char *&Name, 4719199482Srdivacky TargetInfo::ConstraintInfo &Info) const { 4720199482Srdivacky switch (*Name) { 4721199482Srdivacky default: 4722234353Sdim return false; 4723234353Sdim 4724199482Srdivacky case 'r': // CPU registers. 4725199482Srdivacky case 'd': // Equivalent to "r" unless generating MIPS16 code. 4726199482Srdivacky case 'y': // Equivalent to "r", backwards compatibility only. 4727199482Srdivacky case 'f': // floating-point registers. 4728234353Sdim case 'c': // $25 for indirect jumps 4729234353Sdim case 'l': // lo register 4730234353Sdim case 'x': // hilo register pair 4731199482Srdivacky Info.setAllowsRegister(); 4732199482Srdivacky return true; 4733249423Sdim case 'R': // An address that can be used in a non-macro load or store 4734249423Sdim Info.setAllowsMemory(); 4735249423Sdim return true; 4736199482Srdivacky } 4737199482Srdivacky } 4738199482Srdivacky 4739199482Srdivacky virtual const char *getClobbers() const { 4740199482Srdivacky // FIXME: Implement! 4741199482Srdivacky return ""; 4742199482Srdivacky } 4743234353Sdim 4744234353Sdim virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, 4745234353Sdim StringRef Name, 4746234353Sdim bool Enabled) const { 4747234982Sdim if (Name == "soft-float" || Name == "single-float" || 4748234982Sdim Name == "o32" || Name == "n32" || Name == "n64" || Name == "eabi" || 4749234982Sdim Name == "mips32" || Name == "mips32r2" || 4750239462Sdim Name == "mips64" || Name == "mips64r2" || 4751251662Sdim Name == "mips16" || Name == "micromips" || 4752251662Sdim Name == "dsp" || Name == "dspr2") { 4753234353Sdim Features[Name] = Enabled; 4754234353Sdim return true; 4755249423Sdim } else if (Name == "32") { 4756249423Sdim Features["o32"] = Enabled; 4757249423Sdim return true; 4758249423Sdim } else if (Name == "64") { 4759249423Sdim Features["n64"] = Enabled; 4760249423Sdim return true; 4761234353Sdim } 4762234353Sdim return false; 4763234353Sdim } 4764234353Sdim 4765234353Sdim virtual void HandleTargetFeatures(std::vector<std::string> &Features) { 4766239462Sdim IsMips16 = false; 4767251662Sdim IsMicromips = false; 4768251662Sdim IsSingleFloat = false; 4769239462Sdim FloatABI = HardFloat; 4770239462Sdim DspRev = NoDSP; 4771234353Sdim 4772234353Sdim for (std::vector<std::string>::iterator it = Features.begin(), 4773234353Sdim ie = Features.end(); it != ie; ++it) { 4774239462Sdim if (*it == "+single-float") 4775251662Sdim IsSingleFloat = true; 4776239462Sdim else if (*it == "+soft-float") 4777239462Sdim FloatABI = SoftFloat; 4778239462Sdim else if (*it == "+mips16") 4779239462Sdim IsMips16 = true; 4780251662Sdim else if (*it == "+micromips") 4781251662Sdim IsMicromips = true; 4782239462Sdim else if (*it == "+dsp") 4783239462Sdim DspRev = std::max(DspRev, DSP1); 4784239462Sdim else if (*it == "+dspr2") 4785239462Sdim DspRev = std::max(DspRev, DSP2); 4786239462Sdim } 4787234353Sdim 4788239462Sdim // Remove front-end specific option. 4789239462Sdim std::vector<std::string>::iterator it = 4790239462Sdim std::find(Features.begin(), Features.end(), "+soft-float"); 4791239462Sdim if (it != Features.end()) 4792239462Sdim Features.erase(it); 4793234353Sdim } 4794249423Sdim 4795249423Sdim virtual int getEHDataRegisterNumber(unsigned RegNo) const { 4796249423Sdim if (RegNo == 0) return 4; 4797249423Sdim if (RegNo == 1) return 5; 4798249423Sdim return -1; 4799249423Sdim } 4800199482Srdivacky}; 4801199482Srdivacky 4802239462Sdimconst Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = { 4803239462Sdim#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, 4804239462Sdim#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\ 4805239462Sdim ALL_LANGUAGES }, 4806239462Sdim#include "clang/Basic/BuiltinsMips.def" 4807239462Sdim}; 4808239462Sdim 4809226633Sdimclass Mips32TargetInfoBase : public MipsTargetInfoBase { 4810226633Sdimpublic: 4811226633Sdim Mips32TargetInfoBase(const std::string& triple) : 4812234353Sdim MipsTargetInfoBase(triple, "o32", "mips32") { 4813234353Sdim SizeType = UnsignedInt; 4814234353Sdim PtrDiffType = SignedInt; 4815249423Sdim MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; 4816234353Sdim } 4817226633Sdim virtual bool setABI(const std::string &Name) { 4818226633Sdim if ((Name == "o32") || (Name == "eabi")) { 4819226633Sdim ABI = Name; 4820226633Sdim return true; 4821249423Sdim } else if (Name == "32") { 4822249423Sdim ABI = "o32"; 4823249423Sdim return true; 4824226633Sdim } else 4825226633Sdim return false; 4826226633Sdim } 4827243830Sdim virtual void getTargetDefines(const LangOptions &Opts, 4828243830Sdim MacroBuilder &Builder) const { 4829243830Sdim MipsTargetInfoBase::getTargetDefines(Opts, Builder); 4830234353Sdim 4831226633Sdim if (ABI == "o32") { 4832226633Sdim Builder.defineMacro("__mips_o32"); 4833226633Sdim Builder.defineMacro("_ABIO32", "1"); 4834226633Sdim Builder.defineMacro("_MIPS_SIM", "_ABIO32"); 4835226633Sdim } 4836226633Sdim else if (ABI == "eabi") 4837226633Sdim Builder.defineMacro("__mips_eabi"); 4838226633Sdim else 4839226633Sdim llvm_unreachable("Invalid ABI for Mips32."); 4840226633Sdim } 4841226633Sdim virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 4842226633Sdim unsigned &NumAliases) const { 4843226633Sdim static const TargetInfo::GCCRegAlias GCCRegAliases[] = { 4844226633Sdim { { "at" }, "$1" }, 4845226633Sdim { { "v0" }, "$2" }, 4846226633Sdim { { "v1" }, "$3" }, 4847226633Sdim { { "a0" }, "$4" }, 4848226633Sdim { { "a1" }, "$5" }, 4849226633Sdim { { "a2" }, "$6" }, 4850226633Sdim { { "a3" }, "$7" }, 4851226633Sdim { { "t0" }, "$8" }, 4852226633Sdim { { "t1" }, "$9" }, 4853226633Sdim { { "t2" }, "$10" }, 4854226633Sdim { { "t3" }, "$11" }, 4855226633Sdim { { "t4" }, "$12" }, 4856226633Sdim { { "t5" }, "$13" }, 4857226633Sdim { { "t6" }, "$14" }, 4858226633Sdim { { "t7" }, "$15" }, 4859226633Sdim { { "s0" }, "$16" }, 4860226633Sdim { { "s1" }, "$17" }, 4861226633Sdim { { "s2" }, "$18" }, 4862226633Sdim { { "s3" }, "$19" }, 4863226633Sdim { { "s4" }, "$20" }, 4864226633Sdim { { "s5" }, "$21" }, 4865226633Sdim { { "s6" }, "$22" }, 4866226633Sdim { { "s7" }, "$23" }, 4867226633Sdim { { "t8" }, "$24" }, 4868226633Sdim { { "t9" }, "$25" }, 4869226633Sdim { { "k0" }, "$26" }, 4870226633Sdim { { "k1" }, "$27" }, 4871226633Sdim { { "gp" }, "$28" }, 4872234353Sdim { { "sp","$sp" }, "$29" }, 4873234353Sdim { { "fp","$fp" }, "$30" }, 4874226633Sdim { { "ra" }, "$31" } 4875226633Sdim }; 4876226633Sdim Aliases = GCCRegAliases; 4877226633Sdim NumAliases = llvm::array_lengthof(GCCRegAliases); 4878226633Sdim } 4879199482Srdivacky}; 4880199482Srdivacky 4881226633Sdimclass Mips32EBTargetInfo : public Mips32TargetInfoBase { 4882226633Sdimpublic: 4883226633Sdim Mips32EBTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) { 4884226633Sdim DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 4885249423Sdim "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64"; 4886226633Sdim } 4887226633Sdim virtual void getTargetDefines(const LangOptions &Opts, 4888226633Sdim MacroBuilder &Builder) const { 4889226633Sdim DefineStd(Builder, "MIPSEB", Opts); 4890226633Sdim Builder.defineMacro("_MIPSEB"); 4891243830Sdim Mips32TargetInfoBase::getTargetDefines(Opts, Builder); 4892226633Sdim } 4893226633Sdim}; 4894199482Srdivacky 4895226633Sdimclass Mips32ELTargetInfo : public Mips32TargetInfoBase { 4896226633Sdimpublic: 4897226633Sdim Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) { 4898234353Sdim BigEndian = false; 4899226633Sdim DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 4900249423Sdim "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64"; 4901226633Sdim } 4902226633Sdim virtual void getTargetDefines(const LangOptions &Opts, 4903226633Sdim MacroBuilder &Builder) const { 4904226633Sdim DefineStd(Builder, "MIPSEL", Opts); 4905226633Sdim Builder.defineMacro("_MIPSEL"); 4906243830Sdim Mips32TargetInfoBase::getTargetDefines(Opts, Builder); 4907226633Sdim } 4908199482Srdivacky}; 4909199482Srdivacky 4910226633Sdimclass Mips64TargetInfoBase : public MipsTargetInfoBase { 4911226633Sdim virtual void SetDescriptionString(const std::string &Name) = 0; 4912226633Sdimpublic: 4913226633Sdim Mips64TargetInfoBase(const std::string& triple) : 4914234353Sdim MipsTargetInfoBase(triple, "n64", "mips64") { 4915234353Sdim LongWidth = LongAlign = 64; 4916234353Sdim PointerWidth = PointerAlign = 64; 4917234353Sdim LongDoubleWidth = LongDoubleAlign = 128; 4918234353Sdim LongDoubleFormat = &llvm::APFloat::IEEEquad; 4919249423Sdim if (getTriple().getOS() == llvm::Triple::FreeBSD) { 4920249423Sdim LongDoubleWidth = LongDoubleAlign = 64; 4921249423Sdim LongDoubleFormat = &llvm::APFloat::IEEEdouble; 4922249423Sdim } 4923234353Sdim SuitableAlign = 128; 4924249423Sdim MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 4925234353Sdim } 4926226633Sdim virtual bool setABI(const std::string &Name) { 4927226633Sdim SetDescriptionString(Name); 4928234353Sdim if (Name == "n32") { 4929234353Sdim LongWidth = LongAlign = 32; 4930234353Sdim PointerWidth = PointerAlign = 32; 4931249423Sdim ABI = Name; 4932249423Sdim return true; 4933249423Sdim } else if (Name == "n64") { 4934249423Sdim ABI = Name; 4935249423Sdim return true; 4936249423Sdim } else if (Name == "64") { 4937249423Sdim ABI = "n64"; 4938249423Sdim return true; 4939249423Sdim } else 4940249423Sdim return false; 4941226633Sdim } 4942243830Sdim virtual void getTargetDefines(const LangOptions &Opts, 4943243830Sdim MacroBuilder &Builder) const { 4944243830Sdim MipsTargetInfoBase::getTargetDefines(Opts, Builder); 4945234353Sdim 4946243830Sdim Builder.defineMacro("__mips64"); 4947243830Sdim Builder.defineMacro("__mips64__"); 4948243830Sdim 4949226633Sdim if (ABI == "n32") { 4950226633Sdim Builder.defineMacro("__mips_n32"); 4951226633Sdim Builder.defineMacro("_ABIN32", "2"); 4952226633Sdim Builder.defineMacro("_MIPS_SIM", "_ABIN32"); 4953226633Sdim } 4954226633Sdim else if (ABI == "n64") { 4955226633Sdim Builder.defineMacro("__mips_n64"); 4956226633Sdim Builder.defineMacro("_ABI64", "3"); 4957226633Sdim Builder.defineMacro("_MIPS_SIM", "_ABI64"); 4958226633Sdim } 4959226633Sdim else 4960226633Sdim llvm_unreachable("Invalid ABI for Mips64."); 4961226633Sdim } 4962226633Sdim virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 4963226633Sdim unsigned &NumAliases) const { 4964226633Sdim static const TargetInfo::GCCRegAlias GCCRegAliases[] = { 4965226633Sdim { { "at" }, "$1" }, 4966226633Sdim { { "v0" }, "$2" }, 4967226633Sdim { { "v1" }, "$3" }, 4968226633Sdim { { "a0" }, "$4" }, 4969226633Sdim { { "a1" }, "$5" }, 4970226633Sdim { { "a2" }, "$6" }, 4971226633Sdim { { "a3" }, "$7" }, 4972226633Sdim { { "a4" }, "$8" }, 4973226633Sdim { { "a5" }, "$9" }, 4974226633Sdim { { "a6" }, "$10" }, 4975226633Sdim { { "a7" }, "$11" }, 4976226633Sdim { { "t0" }, "$12" }, 4977226633Sdim { { "t1" }, "$13" }, 4978226633Sdim { { "t2" }, "$14" }, 4979226633Sdim { { "t3" }, "$15" }, 4980226633Sdim { { "s0" }, "$16" }, 4981226633Sdim { { "s1" }, "$17" }, 4982226633Sdim { { "s2" }, "$18" }, 4983226633Sdim { { "s3" }, "$19" }, 4984226633Sdim { { "s4" }, "$20" }, 4985226633Sdim { { "s5" }, "$21" }, 4986226633Sdim { { "s6" }, "$22" }, 4987226633Sdim { { "s7" }, "$23" }, 4988226633Sdim { { "t8" }, "$24" }, 4989226633Sdim { { "t9" }, "$25" }, 4990226633Sdim { { "k0" }, "$26" }, 4991226633Sdim { { "k1" }, "$27" }, 4992226633Sdim { { "gp" }, "$28" }, 4993234353Sdim { { "sp","$sp" }, "$29" }, 4994234353Sdim { { "fp","$fp" }, "$30" }, 4995226633Sdim { { "ra" }, "$31" } 4996226633Sdim }; 4997226633Sdim Aliases = GCCRegAliases; 4998226633Sdim NumAliases = llvm::array_lengthof(GCCRegAliases); 4999226633Sdim } 5000226633Sdim}; 5001226633Sdim 5002226633Sdimclass Mips64EBTargetInfo : public Mips64TargetInfoBase { 5003226633Sdim virtual void SetDescriptionString(const std::string &Name) { 5004226633Sdim // Change DescriptionString only if ABI is n32. 5005226633Sdim if (Name == "n32") 5006226633Sdim DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 5007234353Sdim "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" 5008249423Sdim "v64:64:64-n32:64-S128"; 5009226633Sdim } 5010226633Sdimpublic: 5011226633Sdim Mips64EBTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) { 5012226633Sdim // Default ABI is n64. 5013226633Sdim DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 5014234353Sdim "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" 5015249423Sdim "v64:64:64-n32:64-S128"; 5016226633Sdim } 5017226633Sdim virtual void getTargetDefines(const LangOptions &Opts, 5018226633Sdim MacroBuilder &Builder) const { 5019226633Sdim DefineStd(Builder, "MIPSEB", Opts); 5020226633Sdim Builder.defineMacro("_MIPSEB"); 5021243830Sdim Mips64TargetInfoBase::getTargetDefines(Opts, Builder); 5022226633Sdim } 5023226633Sdim}; 5024226633Sdim 5025226633Sdimclass Mips64ELTargetInfo : public Mips64TargetInfoBase { 5026226633Sdim virtual void SetDescriptionString(const std::string &Name) { 5027226633Sdim // Change DescriptionString only if ABI is n32. 5028226633Sdim if (Name == "n32") 5029226633Sdim DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 5030234353Sdim "i64:64:64-f32:32:32-f64:64:64-f128:128:128" 5031249423Sdim "-v64:64:64-n32:64-S128"; 5032226633Sdim } 5033226633Sdimpublic: 5034226633Sdim Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) { 5035234353Sdim // Default ABI is n64. 5036234353Sdim BigEndian = false; 5037226633Sdim DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" 5038234353Sdim "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" 5039249423Sdim "v64:64:64-n32:64-S128"; 5040226633Sdim } 5041226633Sdim virtual void getTargetDefines(const LangOptions &Opts, 5042226633Sdim MacroBuilder &Builder) const { 5043226633Sdim DefineStd(Builder, "MIPSEL", Opts); 5044226633Sdim Builder.defineMacro("_MIPSEL"); 5045243830Sdim Mips64TargetInfoBase::getTargetDefines(Opts, Builder); 5046226633Sdim } 5047226633Sdim}; 5048199482Srdivacky} // end anonymous namespace. 5049199482Srdivacky 5050199482Srdivackynamespace { 5051226633Sdimclass PNaClTargetInfo : public TargetInfo { 5052199482Srdivackypublic: 5053226633Sdim PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) { 5054234353Sdim BigEndian = false; 5055226633Sdim this->UserLabelPrefix = ""; 5056226633Sdim this->LongAlign = 32; 5057226633Sdim this->LongWidth = 32; 5058226633Sdim this->PointerAlign = 32; 5059226633Sdim this->PointerWidth = 32; 5060226633Sdim this->IntMaxType = TargetInfo::SignedLongLong; 5061226633Sdim this->UIntMaxType = TargetInfo::UnsignedLongLong; 5062226633Sdim this->Int64Type = TargetInfo::SignedLongLong; 5063226633Sdim this->DoubleAlign = 64; 5064226633Sdim this->LongDoubleWidth = 64; 5065226633Sdim this->LongDoubleAlign = 64; 5066226633Sdim this->SizeType = TargetInfo::UnsignedInt; 5067226633Sdim this->PtrDiffType = TargetInfo::SignedInt; 5068226633Sdim this->IntPtrType = TargetInfo::SignedInt; 5069251662Sdim this->RegParmMax = 0; // Disallow regparm 5070226633Sdim DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" 5071226633Sdim "f32:32:32-f64:64:64-p:32:32:32-v128:32:32"; 5072199482Srdivacky } 5073199482Srdivacky 5074226633Sdim void getDefaultFeatures(llvm::StringMap<bool> &Features) const { 5075226633Sdim } 5076226633Sdim virtual void getArchDefines(const LangOptions &Opts, 5077226633Sdim MacroBuilder &Builder) const { 5078226633Sdim Builder.defineMacro("__le32__"); 5079226633Sdim Builder.defineMacro("__pnacl__"); 5080226633Sdim } 5081199482Srdivacky virtual void getTargetDefines(const LangOptions &Opts, 5082226633Sdim MacroBuilder &Builder) const { 5083234353Sdim Builder.defineMacro("__LITTLE_ENDIAN__"); 5084226633Sdim getArchDefines(Opts, Builder); 5085226633Sdim } 5086234353Sdim virtual bool hasFeature(StringRef Feature) const { 5087234353Sdim return Feature == "pnacl"; 5088234353Sdim } 5089226633Sdim virtual void getTargetBuiltins(const Builtin::Info *&Records, 5090226633Sdim unsigned &NumRecords) const { 5091226633Sdim } 5092239462Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 5093239462Sdim return TargetInfo::PNaClABIBuiltinVaList; 5094226633Sdim } 5095226633Sdim virtual void getGCCRegNames(const char * const *&Names, 5096226633Sdim unsigned &NumNames) const; 5097226633Sdim virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 5098226633Sdim unsigned &NumAliases) const; 5099226633Sdim virtual bool validateAsmConstraint(const char *&Name, 5100226633Sdim TargetInfo::ConstraintInfo &Info) const { 5101226633Sdim return false; 5102226633Sdim } 5103226633Sdim 5104226633Sdim virtual const char *getClobbers() const { 5105226633Sdim return ""; 5106226633Sdim } 5107199482Srdivacky}; 5108199482Srdivacky 5109226633Sdimvoid PNaClTargetInfo::getGCCRegNames(const char * const *&Names, 5110226633Sdim unsigned &NumNames) const { 5111226633Sdim Names = NULL; 5112226633Sdim NumNames = 0; 5113199482Srdivacky} 5114226633Sdim 5115226633Sdimvoid PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, 5116226633Sdim unsigned &NumAliases) const { 5117226633Sdim Aliases = NULL; 5118226633Sdim NumAliases = 0; 5119226633Sdim} 5120199482Srdivacky} // end anonymous namespace. 5121199482Srdivacky 5122249423Sdimnamespace { 5123249423Sdim static const unsigned SPIRAddrSpaceMap[] = { 5124249423Sdim 1, // opencl_global 5125249423Sdim 3, // opencl_local 5126249423Sdim 2, // opencl_constant 5127249423Sdim 0, // cuda_device 5128249423Sdim 0, // cuda_constant 5129249423Sdim 0 // cuda_shared 5130249423Sdim }; 5131249423Sdim class SPIRTargetInfo : public TargetInfo { 5132249423Sdim static const char * const GCCRegNames[]; 5133249423Sdim static const Builtin::Info BuiltinInfo[]; 5134249423Sdim std::vector<StringRef> AvailableFeatures; 5135249423Sdim public: 5136249423Sdim SPIRTargetInfo(const std::string& triple) : TargetInfo(triple) { 5137249423Sdim assert(getTriple().getOS() == llvm::Triple::UnknownOS && 5138249423Sdim "SPIR target must use unknown OS"); 5139249423Sdim assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && 5140249423Sdim "SPIR target must use unknown environment type"); 5141249423Sdim BigEndian = false; 5142249423Sdim TLSSupported = false; 5143249423Sdim LongWidth = LongAlign = 64; 5144249423Sdim AddrSpaceMap = &SPIRAddrSpaceMap; 5145249423Sdim // Define available target features 5146249423Sdim // These must be defined in sorted order! 5147249423Sdim NoAsmVariants = true; 5148249423Sdim } 5149249423Sdim virtual void getTargetDefines(const LangOptions &Opts, 5150249423Sdim MacroBuilder &Builder) const { 5151249423Sdim DefineStd(Builder, "SPIR", Opts); 5152249423Sdim } 5153249423Sdim virtual bool hasFeature(StringRef Feature) const { 5154249423Sdim return Feature == "spir"; 5155249423Sdim } 5156249423Sdim 5157249423Sdim virtual void getTargetBuiltins(const Builtin::Info *&Records, 5158249423Sdim unsigned &NumRecords) const {} 5159249423Sdim virtual const char *getClobbers() const { 5160249423Sdim return ""; 5161249423Sdim } 5162249423Sdim virtual void getGCCRegNames(const char * const *&Names, 5163249423Sdim unsigned &NumNames) const {} 5164249423Sdim virtual bool validateAsmConstraint(const char *&Name, 5165249423Sdim TargetInfo::ConstraintInfo &info) const { 5166249423Sdim return true; 5167249423Sdim } 5168249423Sdim virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, 5169249423Sdim unsigned &NumAliases) const {} 5170249423Sdim virtual BuiltinVaListKind getBuiltinVaListKind() const { 5171249423Sdim return TargetInfo::VoidPtrBuiltinVaList; 5172249423Sdim } 5173249423Sdim }; 5174226633Sdim 5175249423Sdim 5176249423Sdim class SPIR32TargetInfo : public SPIRTargetInfo { 5177249423Sdim public: 5178249423Sdim SPIR32TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) { 5179249423Sdim PointerWidth = PointerAlign = 32; 5180249423Sdim SizeType = TargetInfo::UnsignedInt; 5181249423Sdim PtrDiffType = IntPtrType = TargetInfo::SignedInt; 5182249423Sdim DescriptionString 5183249423Sdim = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" 5184249423Sdim "f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-" 5185249423Sdim "v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-" 5186249423Sdim "v512:512:512-v1024:1024:1024"; 5187249423Sdim } 5188249423Sdim virtual void getTargetDefines(const LangOptions &Opts, 5189249423Sdim MacroBuilder &Builder) const { 5190249423Sdim DefineStd(Builder, "SPIR32", Opts); 5191249423Sdim } 5192249423Sdim }; 5193249423Sdim 5194249423Sdim class SPIR64TargetInfo : public SPIRTargetInfo { 5195249423Sdim public: 5196249423Sdim SPIR64TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) { 5197249423Sdim PointerWidth = PointerAlign = 64; 5198249423Sdim SizeType = TargetInfo::UnsignedLong; 5199249423Sdim PtrDiffType = IntPtrType = TargetInfo::SignedLong; 5200249423Sdim DescriptionString 5201249423Sdim = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" 5202249423Sdim "f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-" 5203249423Sdim "v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-" 5204249423Sdim "v512:512:512-v1024:1024:1024"; 5205249423Sdim } 5206249423Sdim virtual void getTargetDefines(const LangOptions &Opts, 5207249423Sdim MacroBuilder &Builder) const { 5208249423Sdim DefineStd(Builder, "SPIR64", Opts); 5209249423Sdim } 5210249423Sdim }; 5211249423Sdim} 5212249423Sdim 5213249423Sdim 5214193326Sed//===----------------------------------------------------------------------===// 5215193326Sed// Driver code 5216193326Sed//===----------------------------------------------------------------------===// 5217193326Sed 5218199482Srdivackystatic TargetInfo *AllocateTarget(const std::string &T) { 5219198092Srdivacky llvm::Triple Triple(T); 5220198092Srdivacky llvm::Triple::OSType os = Triple.getOS(); 5221193326Sed 5222198092Srdivacky switch (Triple.getArch()) { 5223198092Srdivacky default: 5224198092Srdivacky return NULL; 5225198092Srdivacky 5226234353Sdim case llvm::Triple::hexagon: 5227234353Sdim return new HexagonTargetInfo(T); 5228234353Sdim 5229249423Sdim case llvm::Triple::aarch64: 5230249423Sdim switch (os) { 5231249423Sdim case llvm::Triple::Linux: 5232249423Sdim return new LinuxTargetInfo<AArch64TargetInfo>(T); 5233249423Sdim default: 5234249423Sdim return new AArch64TargetInfo(T); 5235249423Sdim } 5236249423Sdim 5237198092Srdivacky case llvm::Triple::arm: 5238198092Srdivacky case llvm::Triple::thumb: 5239221345Sdim if (Triple.isOSDarwin()) 5240221345Sdim return new DarwinARMTargetInfo(T); 5241221345Sdim 5242198092Srdivacky switch (os) { 5243210299Sed case llvm::Triple::Linux: 5244210299Sed return new LinuxTargetInfo<ARMTargetInfo>(T); 5245198092Srdivacky case llvm::Triple::FreeBSD: 5246198092Srdivacky return new FreeBSDTargetInfo<ARMTargetInfo>(T); 5247224145Sdim case llvm::Triple::NetBSD: 5248224145Sdim return new NetBSDTargetInfo<ARMTargetInfo>(T); 5249239462Sdim case llvm::Triple::OpenBSD: 5250239462Sdim return new OpenBSDTargetInfo<ARMTargetInfo>(T); 5251239462Sdim case llvm::Triple::Bitrig: 5252239462Sdim return new BitrigTargetInfo<ARMTargetInfo>(T); 5253224145Sdim case llvm::Triple::RTEMS: 5254224145Sdim return new RTEMSTargetInfo<ARMTargetInfo>(T); 5255249423Sdim case llvm::Triple::NaCl: 5256243830Sdim return new NaClTargetInfo<ARMTargetInfo>(T); 5257198092Srdivacky default: 5258198092Srdivacky return new ARMTargetInfo(T); 5259198092Srdivacky } 5260198092Srdivacky 5261198092Srdivacky case llvm::Triple::msp430: 5262198092Srdivacky return new MSP430TargetInfo(T); 5263198092Srdivacky 5264199482Srdivacky case llvm::Triple::mips: 5265224145Sdim switch (os) { 5266224145Sdim case llvm::Triple::Linux: 5267226633Sdim return new LinuxTargetInfo<Mips32EBTargetInfo>(T); 5268224145Sdim case llvm::Triple::RTEMS: 5269226633Sdim return new RTEMSTargetInfo<Mips32EBTargetInfo>(T); 5270224145Sdim case llvm::Triple::FreeBSD: 5271226633Sdim return new FreeBSDTargetInfo<Mips32EBTargetInfo>(T); 5272224145Sdim case llvm::Triple::NetBSD: 5273226633Sdim return new NetBSDTargetInfo<Mips32EBTargetInfo>(T); 5274224145Sdim default: 5275226633Sdim return new Mips32EBTargetInfo(T); 5276224145Sdim } 5277199482Srdivacky 5278199482Srdivacky case llvm::Triple::mipsel: 5279224145Sdim switch (os) { 5280224145Sdim case llvm::Triple::Linux: 5281226633Sdim return new LinuxTargetInfo<Mips32ELTargetInfo>(T); 5282224145Sdim case llvm::Triple::RTEMS: 5283226633Sdim return new RTEMSTargetInfo<Mips32ELTargetInfo>(T); 5284224145Sdim case llvm::Triple::FreeBSD: 5285226633Sdim return new FreeBSDTargetInfo<Mips32ELTargetInfo>(T); 5286224145Sdim case llvm::Triple::NetBSD: 5287226633Sdim return new NetBSDTargetInfo<Mips32ELTargetInfo>(T); 5288224145Sdim default: 5289226633Sdim return new Mips32ELTargetInfo(T); 5290224145Sdim } 5291199482Srdivacky 5292226633Sdim case llvm::Triple::mips64: 5293226633Sdim switch (os) { 5294226633Sdim case llvm::Triple::Linux: 5295226633Sdim return new LinuxTargetInfo<Mips64EBTargetInfo>(T); 5296226633Sdim case llvm::Triple::RTEMS: 5297226633Sdim return new RTEMSTargetInfo<Mips64EBTargetInfo>(T); 5298226633Sdim case llvm::Triple::FreeBSD: 5299226633Sdim return new FreeBSDTargetInfo<Mips64EBTargetInfo>(T); 5300226633Sdim case llvm::Triple::NetBSD: 5301226633Sdim return new NetBSDTargetInfo<Mips64EBTargetInfo>(T); 5302239462Sdim case llvm::Triple::OpenBSD: 5303239462Sdim return new OpenBSDTargetInfo<Mips64EBTargetInfo>(T); 5304226633Sdim default: 5305226633Sdim return new Mips64EBTargetInfo(T); 5306226633Sdim } 5307226633Sdim 5308226633Sdim case llvm::Triple::mips64el: 5309226633Sdim switch (os) { 5310226633Sdim case llvm::Triple::Linux: 5311226633Sdim return new LinuxTargetInfo<Mips64ELTargetInfo>(T); 5312226633Sdim case llvm::Triple::RTEMS: 5313226633Sdim return new RTEMSTargetInfo<Mips64ELTargetInfo>(T); 5314226633Sdim case llvm::Triple::FreeBSD: 5315226633Sdim return new FreeBSDTargetInfo<Mips64ELTargetInfo>(T); 5316226633Sdim case llvm::Triple::NetBSD: 5317226633Sdim return new NetBSDTargetInfo<Mips64ELTargetInfo>(T); 5318239462Sdim case llvm::Triple::OpenBSD: 5319239462Sdim return new OpenBSDTargetInfo<Mips64ELTargetInfo>(T); 5320226633Sdim default: 5321226633Sdim return new Mips64ELTargetInfo(T); 5322226633Sdim } 5323226633Sdim 5324226633Sdim case llvm::Triple::le32: 5325226633Sdim switch (os) { 5326249423Sdim case llvm::Triple::NaCl: 5327243830Sdim return new NaClTargetInfo<PNaClTargetInfo>(T); 5328226633Sdim default: 5329226633Sdim return NULL; 5330226633Sdim } 5331226633Sdim 5332198092Srdivacky case llvm::Triple::ppc: 5333221345Sdim if (Triple.isOSDarwin()) 5334218893Sdim return new DarwinPPC32TargetInfo(T); 5335224145Sdim switch (os) { 5336226633Sdim case llvm::Triple::Linux: 5337226633Sdim return new LinuxTargetInfo<PPC32TargetInfo>(T); 5338224145Sdim case llvm::Triple::FreeBSD: 5339204643Srdivacky return new FreeBSDTargetInfo<PPC32TargetInfo>(T); 5340224145Sdim case llvm::Triple::NetBSD: 5341224145Sdim return new NetBSDTargetInfo<PPC32TargetInfo>(T); 5342239462Sdim case llvm::Triple::OpenBSD: 5343239462Sdim return new OpenBSDTargetInfo<PPC32TargetInfo>(T); 5344224145Sdim case llvm::Triple::RTEMS: 5345224145Sdim return new RTEMSTargetInfo<PPC32TargetInfo>(T); 5346224145Sdim default: 5347224145Sdim return new PPC32TargetInfo(T); 5348224145Sdim } 5349193326Sed 5350198092Srdivacky case llvm::Triple::ppc64: 5351221345Sdim if (Triple.isOSDarwin()) 5352210299Sed return new DarwinPPC64TargetInfo(T); 5353224145Sdim switch (os) { 5354226633Sdim case llvm::Triple::Linux: 5355226633Sdim return new LinuxTargetInfo<PPC64TargetInfo>(T); 5356224145Sdim case llvm::Triple::Lv2: 5357199990Srdivacky return new PS3PPUTargetInfo<PPC64TargetInfo>(T); 5358224145Sdim case llvm::Triple::FreeBSD: 5359204643Srdivacky return new FreeBSDTargetInfo<PPC64TargetInfo>(T); 5360224145Sdim case llvm::Triple::NetBSD: 5361224145Sdim return new NetBSDTargetInfo<PPC64TargetInfo>(T); 5362224145Sdim default: 5363224145Sdim return new PPC64TargetInfo(T); 5364224145Sdim } 5365193326Sed 5366239462Sdim case llvm::Triple::nvptx: 5367239462Sdim return new NVPTX32TargetInfo(T); 5368239462Sdim case llvm::Triple::nvptx64: 5369239462Sdim return new NVPTX64TargetInfo(T); 5370221345Sdim 5371204962Srdivacky case llvm::Triple::mblaze: 5372204962Srdivacky return new MBlazeTargetInfo(T); 5373204962Srdivacky 5374243830Sdim case llvm::Triple::r600: 5375243830Sdim return new R600TargetInfo(T); 5376243830Sdim 5377198092Srdivacky case llvm::Triple::sparc: 5378224145Sdim switch (os) { 5379226633Sdim case llvm::Triple::Linux: 5380226633Sdim return new LinuxTargetInfo<SparcV8TargetInfo>(T); 5381224145Sdim case llvm::Triple::AuroraUX: 5382198398Srdivacky return new AuroraUXSparcV8TargetInfo(T); 5383224145Sdim case llvm::Triple::Solaris: 5384193326Sed return new SolarisSparcV8TargetInfo(T); 5385224145Sdim case llvm::Triple::NetBSD: 5386224145Sdim return new NetBSDTargetInfo<SparcV8TargetInfo>(T); 5387239462Sdim case llvm::Triple::OpenBSD: 5388239462Sdim return new OpenBSDTargetInfo<SparcV8TargetInfo>(T); 5389224145Sdim case llvm::Triple::RTEMS: 5390224145Sdim return new RTEMSTargetInfo<SparcV8TargetInfo>(T); 5391224145Sdim default: 5392224145Sdim return new SparcV8TargetInfo(T); 5393224145Sdim } 5394193326Sed 5395251662Sdim case llvm::Triple::sparcv9: 5396251662Sdim switch (os) { 5397251662Sdim case llvm::Triple::Linux: 5398251662Sdim return new LinuxTargetInfo<SparcV9TargetInfo>(T); 5399251662Sdim case llvm::Triple::AuroraUX: 5400251662Sdim return new AuroraUXTargetInfo<SparcV9TargetInfo>(T); 5401251662Sdim case llvm::Triple::Solaris: 5402251662Sdim return new SolarisTargetInfo<SparcV9TargetInfo>(T); 5403251662Sdim case llvm::Triple::NetBSD: 5404251662Sdim return new NetBSDTargetInfo<SparcV9TargetInfo>(T); 5405251662Sdim case llvm::Triple::OpenBSD: 5406251662Sdim return new OpenBSDTargetInfo<SparcV9TargetInfo>(T); 5407251662Sdim case llvm::Triple::FreeBSD: 5408251662Sdim return new FreeBSDTargetInfo<SparcV9TargetInfo>(T); 5409251662Sdim default: 5410251662Sdim return new SparcV9TargetInfo(T); 5411251662Sdim } 5412251662Sdim 5413251662Sdim case llvm::Triple::systemz: 5414251662Sdim switch (os) { 5415251662Sdim case llvm::Triple::Linux: 5416251662Sdim return new LinuxTargetInfo<SystemZTargetInfo>(T); 5417251662Sdim default: 5418251662Sdim return new SystemZTargetInfo(T); 5419251662Sdim } 5420251662Sdim 5421198092Srdivacky case llvm::Triple::tce: 5422198092Srdivacky return new TCETargetInfo(T); 5423193326Sed 5424198092Srdivacky case llvm::Triple::x86: 5425221345Sdim if (Triple.isOSDarwin()) 5426221345Sdim return new DarwinI386TargetInfo(T); 5427221345Sdim 5428198092Srdivacky switch (os) { 5429198398Srdivacky case llvm::Triple::AuroraUX: 5430198398Srdivacky return new AuroraUXTargetInfo<X86_32TargetInfo>(T); 5431198092Srdivacky case llvm::Triple::Linux: 5432195341Sed return new LinuxTargetInfo<X86_32TargetInfo>(T); 5433198092Srdivacky case llvm::Triple::DragonFly: 5434195341Sed return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T); 5435198092Srdivacky case llvm::Triple::NetBSD: 5436234353Sdim return new NetBSDI386TargetInfo(T); 5437198092Srdivacky case llvm::Triple::OpenBSD: 5438198092Srdivacky return new OpenBSDI386TargetInfo(T); 5439239462Sdim case llvm::Triple::Bitrig: 5440239462Sdim return new BitrigI386TargetInfo(T); 5441198092Srdivacky case llvm::Triple::FreeBSD: 5442195341Sed return new FreeBSDTargetInfo<X86_32TargetInfo>(T); 5443210299Sed case llvm::Triple::Minix: 5444210299Sed return new MinixTargetInfo<X86_32TargetInfo>(T); 5445198092Srdivacky case llvm::Triple::Solaris: 5446195341Sed return new SolarisTargetInfo<X86_32TargetInfo>(T); 5447198092Srdivacky case llvm::Triple::Cygwin: 5448198092Srdivacky return new CygwinX86_32TargetInfo(T); 5449198092Srdivacky case llvm::Triple::MinGW32: 5450198092Srdivacky return new MinGWX86_32TargetInfo(T); 5451198092Srdivacky case llvm::Triple::Win32: 5452198092Srdivacky return new VisualStudioWindowsX86_32TargetInfo(T); 5453207619Srdivacky case llvm::Triple::Haiku: 5454207619Srdivacky return new HaikuX86_32TargetInfo(T); 5455224145Sdim case llvm::Triple::RTEMS: 5456224145Sdim return new RTEMSX86_32TargetInfo(T); 5457249423Sdim case llvm::Triple::NaCl: 5458243830Sdim return new NaClTargetInfo<X86_32TargetInfo>(T); 5459198092Srdivacky default: 5460198092Srdivacky return new X86_32TargetInfo(T); 5461198092Srdivacky } 5462198092Srdivacky 5463198092Srdivacky case llvm::Triple::x86_64: 5464221345Sdim if (Triple.isOSDarwin() || Triple.getEnvironment() == llvm::Triple::MachO) 5465221345Sdim return new DarwinX86_64TargetInfo(T); 5466221345Sdim 5467198092Srdivacky switch (os) { 5468198398Srdivacky case llvm::Triple::AuroraUX: 5469198398Srdivacky return new AuroraUXTargetInfo<X86_64TargetInfo>(T); 5470198092Srdivacky case llvm::Triple::Linux: 5471198092Srdivacky return new LinuxTargetInfo<X86_64TargetInfo>(T); 5472202379Srdivacky case llvm::Triple::DragonFly: 5473202379Srdivacky return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T); 5474198092Srdivacky case llvm::Triple::NetBSD: 5475198092Srdivacky return new NetBSDTargetInfo<X86_64TargetInfo>(T); 5476198092Srdivacky case llvm::Triple::OpenBSD: 5477198092Srdivacky return new OpenBSDX86_64TargetInfo(T); 5478239462Sdim case llvm::Triple::Bitrig: 5479239462Sdim return new BitrigX86_64TargetInfo(T); 5480198092Srdivacky case llvm::Triple::FreeBSD: 5481198092Srdivacky return new FreeBSDTargetInfo<X86_64TargetInfo>(T); 5482198092Srdivacky case llvm::Triple::Solaris: 5483198092Srdivacky return new SolarisTargetInfo<X86_64TargetInfo>(T); 5484218893Sdim case llvm::Triple::MinGW32: 5485198092Srdivacky return new MinGWX86_64TargetInfo(T); 5486198092Srdivacky case llvm::Triple::Win32: // This is what Triple.h supports now. 5487221345Sdim return new VisualStudioWindowsX86_64TargetInfo(T); 5488249423Sdim case llvm::Triple::NaCl: 5489243830Sdim return new NaClTargetInfo<X86_64TargetInfo>(T); 5490198092Srdivacky default: 5491198092Srdivacky return new X86_64TargetInfo(T); 5492198092Srdivacky } 5493249423Sdim 5494249423Sdim case llvm::Triple::spir: { 5495249423Sdim llvm::Triple Triple(T); 5496249423Sdim if (Triple.getOS() != llvm::Triple::UnknownOS || 5497249423Sdim Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) 5498249423Sdim return NULL; 5499249423Sdim return new SPIR32TargetInfo(T); 5500249423Sdim } 5501249423Sdim case llvm::Triple::spir64: { 5502249423Sdim llvm::Triple Triple(T); 5503249423Sdim if (Triple.getOS() != llvm::Triple::UnknownOS || 5504249423Sdim Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) 5505249423Sdim return NULL; 5506249423Sdim return new SPIR64TargetInfo(T); 5507249423Sdim } 5508193326Sed } 5509193326Sed} 5510199482Srdivacky 5511199482Srdivacky/// CreateTargetInfo - Return the target info object for the specified target 5512199482Srdivacky/// triple. 5513226633SdimTargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, 5514249423Sdim TargetOptions *Opts) { 5515249423Sdim llvm::Triple Triple(Opts->Triple); 5516199482Srdivacky 5517199482Srdivacky // Construct the target 5518234353Sdim OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str())); 5519199482Srdivacky if (!Target) { 5520199482Srdivacky Diags.Report(diag::err_target_unknown_triple) << Triple.str(); 5521199482Srdivacky return 0; 5522199482Srdivacky } 5523243830Sdim Target->setTargetOpts(Opts); 5524199482Srdivacky 5525201361Srdivacky // Set the target CPU if specified. 5526249423Sdim if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) { 5527249423Sdim Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU; 5528201361Srdivacky return 0; 5529201361Srdivacky } 5530201361Srdivacky 5531199482Srdivacky // Set the target ABI if specified. 5532249423Sdim if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) { 5533249423Sdim Diags.Report(diag::err_target_unknown_abi) << Opts->ABI; 5534199482Srdivacky return 0; 5535199482Srdivacky } 5536199482Srdivacky 5537210299Sed // Set the target C++ ABI. 5538249423Sdim if (!Opts->CXXABI.empty() && !Target->setCXXABI(Opts->CXXABI)) { 5539249423Sdim Diags.Report(diag::err_target_unknown_cxxabi) << Opts->CXXABI; 5540210299Sed return 0; 5541210299Sed } 5542210299Sed 5543199482Srdivacky // Compute the default target features, we need the target to handle this 5544199482Srdivacky // because features may have dependencies on one another. 5545199482Srdivacky llvm::StringMap<bool> Features; 5546226633Sdim Target->getDefaultFeatures(Features); 5547199482Srdivacky 5548199482Srdivacky // Apply the user specified deltas. 5549232894Sdim // First the enables. 5550243830Sdim for (std::vector<std::string>::const_iterator 5551249423Sdim it = Opts->FeaturesAsWritten.begin(), 5552249423Sdim ie = Opts->FeaturesAsWritten.end(); 5553243830Sdim it != ie; ++it) { 5554199482Srdivacky const char *Name = it->c_str(); 5555199482Srdivacky 5556232894Sdim if (Name[0] != '+') 5557232894Sdim continue; 5558232894Sdim 5559199482Srdivacky // Apply the feature via the target. 5560232894Sdim if (!Target->setFeatureEnabled(Features, Name + 1, true)) { 5561199482Srdivacky Diags.Report(diag::err_target_invalid_feature) << Name; 5562199482Srdivacky return 0; 5563199482Srdivacky } 5564199482Srdivacky } 5565199482Srdivacky 5566232894Sdim // Then the disables. 5567243830Sdim for (std::vector<std::string>::const_iterator 5568249423Sdim it = Opts->FeaturesAsWritten.begin(), 5569249423Sdim ie = Opts->FeaturesAsWritten.end(); 5570243830Sdim it != ie; ++it) { 5571232894Sdim const char *Name = it->c_str(); 5572232894Sdim 5573232894Sdim if (Name[0] == '+') 5574232894Sdim continue; 5575232894Sdim 5576232894Sdim // Apply the feature via the target. 5577232894Sdim if (Name[0] != '-' || 5578232894Sdim !Target->setFeatureEnabled(Features, Name + 1, false)) { 5579232894Sdim Diags.Report(diag::err_target_invalid_feature) << Name; 5580232894Sdim return 0; 5581232894Sdim } 5582232894Sdim } 5583232894Sdim 5584199482Srdivacky // Add the features to the compile options. 5585199482Srdivacky // 5586199482Srdivacky // FIXME: If we are completely confident that we have the right set, we only 5587199482Srdivacky // need to pass the minuses. 5588249423Sdim Opts->Features.clear(); 5589199482Srdivacky for (llvm::StringMap<bool>::const_iterator it = Features.begin(), 5590199482Srdivacky ie = Features.end(); it != ie; ++it) 5591249423Sdim Opts->Features.push_back((it->second ? "+" : "-") + it->first().str()); 5592249423Sdim Target->HandleTargetFeatures(Opts->Features); 5593199482Srdivacky 5594199482Srdivacky return Target.take(); 5595199482Srdivacky} 5596