diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-07-13 17:21:42 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-07-13 17:21:42 +0000 | 
| commit | 4ba675006b5a8edfc48b6a9bd3dcf54a70cc08f2 (patch) | |
| tree | 48b44512b5db8ced345df4a1a56b5065cf2a14d9 /lib/Basic/Targets.cpp | |
| parent | d7279c4c177bca357ef96ff1379fd9bc420bfe83 (diff) | |
Notes
Diffstat (limited to 'lib/Basic/Targets.cpp')
| -rw-r--r-- | lib/Basic/Targets.cpp | 166 | 
1 files changed, 161 insertions, 5 deletions
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 92fd417173bd..8d793163bc0b 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -150,7 +150,7 @@ protected:  public:    DarwinTargetInfo(const std::string& triple) :      OSTargetInfo<Target>(triple) { -      this->TLSSupported = false; +      this->TLSSupported = llvm::Triple(triple).getDarwinMajorNumber() > 10;      }    virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const { @@ -160,6 +160,12 @@ public:      return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,                                                         TAA, StubSize);    } +   +  virtual const char *getStaticInitSectionSpecifier() const { +    // FIXME: We should return 0 when building kexts. +    return "__TEXT,__StaticInit,regular,pure_instructions"; +  } +    }; @@ -206,6 +212,30 @@ public:      }  }; +// Minix Target +template<typename Target> +class MinixTargetInfo : public OSTargetInfo<Target> { +protected: +  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, +                            MacroBuilder &Builder) const { +    // Minix defines + +    Builder.defineMacro("__minix", "3"); +    Builder.defineMacro("_EM_WSIZE", "4"); +    Builder.defineMacro("_EM_PSIZE", "4"); +    Builder.defineMacro("_EM_SSIZE", "2"); +    Builder.defineMacro("_EM_LSIZE", "4"); +    Builder.defineMacro("_EM_FSIZE", "4"); +    Builder.defineMacro("_EM_DSIZE", "8"); +    DefineStd(Builder, "unix", Opts); +  } +public: +  MinixTargetInfo(const std::string &triple) +    : OSTargetInfo<Target>(triple) { +      this->UserLabelPrefix = ""; +    } +}; +  // Linux target  template<typename Target>  class LinuxTargetInfo : public OSTargetInfo<Target> { @@ -299,13 +329,20 @@ protected:      Builder.defineMacro("__CELLOS_LV2__");      Builder.defineMacro("__ELF__");      Builder.defineMacro("__LP32__"); +    Builder.defineMacro("_ARCH_PPC64"); +    Builder.defineMacro("__powerpc64__");    }  public:    PS3PPUTargetInfo(const std::string& triple)      : OSTargetInfo<Target>(triple) {      this->UserLabelPrefix = "";      this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32; +    this->IntMaxType = TargetInfo::SignedLongLong; +    this->UIntMaxType = TargetInfo::UnsignedLongLong; +    this->Int64Type = TargetInfo::SignedLongLong;      this->SizeType = TargetInfo::UnsignedInt; +    this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" +                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";    }  }; @@ -413,12 +450,98 @@ public:      switch (*Name) {      default: return false;      case 'O': // Zero -      return true; +      break;      case 'b': // Base register      case 'f': // Floating point register        Info.setAllowsRegister(); -      return true; +      break; +    // FIXME: The following are added to allow parsing. +    // I just took a guess at what the actions should be. +    // Also, is more specific checking needed?  I.e. specific registers? +    case 'd': // Floating point register (containing 64-bit value)  +    case 'v': // Altivec vector register +      Info.setAllowsRegister(); +      break; +    case 'w': +      switch (Name[1]) { +        case 'd':// VSX vector register to hold vector double data  +        case 'f':// VSX vector register to hold vector float data  +        case 's':// VSX vector register to hold scalar float data  +        case 'a':// Any VSX register  +          break; +        default: +          return false; +      } +      Info.setAllowsRegister(); +      Name++; // Skip over 'w'. +      break; +    case 'h': // `MQ', `CTR', or `LINK' register  +    case 'q': // `MQ' register  +    case 'c': // `CTR' register  +    case 'l': // `LINK' register  +    case 'x': // `CR' register (condition register) number 0  +    case 'y': // `CR' register (condition register)  +    case 'z': // `XER[CA]' carry bit (part of the XER register)  +      Info.setAllowsRegister(); +      break; +    case 'I': // Signed 16-bit constant  +    case 'J': // Unsigned 16-bit constant shifted left 16 bits +              //  (use `L' instead for SImode constants)  +    case 'K': // Unsigned 16-bit constant  +    case 'L': // Signed 16-bit constant shifted left 16 bits  +    case 'M': // Constant larger than 31  +    case 'N': // Exact power of 2  +    case 'P': // Constant whose negation is a signed 16-bit constant  +    case 'G': // Floating point constant that can be loaded into a +              // register with one instruction per word  +    case 'H': // Integer/Floating point constant that can be loaded +              // into a register using three instructions  +      break; +    case 'm': // Memory operand. Note that on PowerPC targets, m can +              // include addresses that update the base register. It +              // is therefore only safe to use `m' in an asm statement +              // if that asm statement accesses the operand exactly once. +              // The asm statement must also use `%U<opno>' as a +              // placeholder for the “update” flag in the corresponding +              // load or store instruction. For example:  +              // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val)); +              // is correct but:  +              // asm ("st %1,%0" : "=m" (mem) : "r" (val)); +              // is not. Use es rather than m if you don't want the base +              // register to be updated.  +    case 'e':  +      if (Name[1] != 's') +          return false; +              // es: A “stable” memory operand; that is, one which does not +              // include any automodification of the base register. Unlike +              // `m', this constraint can be used in asm statements that +              // might access the operand several times, or that might not +              // access it at all. +      Info.setAllowsMemory(); +      Name++; // Skip over 'e'. +      break; +    case 'Q': // Memory operand that is an offset from a register (it is +              // usually better to use `m' or `es' in asm statements)  +    case 'Z': // Memory operand that is an indexed or indirect from a +              // register (it is usually better to use `m' or `es' in +              // asm statements)  +      Info.setAllowsMemory(); +      Info.setAllowsRegister(); +      break; +    case 'R': // AIX TOC entry  +    case 'a': // Address operand that is an indexed or indirect from a +              // register (`p' is preferable for asm statements)  +    case 'S': // Constant suitable as a 64-bit mask operand  +    case 'T': // Constant suitable as a 32-bit mask operand  +    case 'U': // System V Release 4 small data area reference  +    case 't': // AND masks that can be performed by two rldic{l, r} +              // instructions  +    case 'W': // Vector constant that does not require memory  +    case 'j': // Vector constant that is all zeros.  +      break; +    // End FIXME.      } +    return true;    }    virtual const char *getClobbers() const {      return ""; @@ -600,6 +723,27 @@ public:  };  } // end anonymous namespace. + +namespace { +class DarwinPPCTargetInfo : +  public DarwinTargetInfo<PPCTargetInfo> { +public: +  DarwinPPCTargetInfo(const std::string& triple) +    : DarwinTargetInfo<PPCTargetInfo>(triple) { +    HasAlignMac68kSupport = true; +  } +}; + +class DarwinPPC64TargetInfo : +  public DarwinTargetInfo<PPC64TargetInfo> { +public: +  DarwinPPC64TargetInfo(const std::string& triple) +    : DarwinTargetInfo<PPC64TargetInfo>(triple) { +    HasAlignMac68kSupport = true; +  } +}; +} // end anonymous namespace. +  namespace {  // MBlaze abstract base class  class MBlazeTargetInfo : public TargetInfo { @@ -1257,6 +1401,8 @@ public:      LongWidth = LongAlign = PointerWidth = PointerAlign = 64;      LongDoubleWidth = 128;      LongDoubleAlign = 128; +    LargeArrayMinWidth = 128; +    LargeArrayAlign = 128;      IntMaxType = SignedLong;      UIntMaxType = UnsignedLong;      Int64Type = SignedLong; @@ -2294,6 +2440,8 @@ static TargetInfo *AllocateTarget(const std::string &T) {    case llvm::Triple::arm:    case llvm::Triple::thumb:      switch (os) { +    case llvm::Triple::Linux: +      return new LinuxTargetInfo<ARMTargetInfo>(T);      case llvm::Triple::Darwin:        return new DarwinARMTargetInfo(T);      case llvm::Triple::FreeBSD: @@ -2327,14 +2475,14 @@ static TargetInfo *AllocateTarget(const std::string &T) {    case llvm::Triple::ppc:      if (os == llvm::Triple::Darwin) -      return new DarwinTargetInfo<PPCTargetInfo>(T); +      return new DarwinPPCTargetInfo(T);      else if (os == llvm::Triple::FreeBSD)        return new FreeBSDTargetInfo<PPC32TargetInfo>(T);      return new PPC32TargetInfo(T);    case llvm::Triple::ppc64:      if (os == llvm::Triple::Darwin) -      return new DarwinTargetInfo<PPC64TargetInfo>(T); +      return new DarwinPPC64TargetInfo(T);      else if (os == llvm::Triple::Lv2)        return new PS3PPUTargetInfo<PPC64TargetInfo>(T);      else if (os == llvm::Triple::FreeBSD) @@ -2377,6 +2525,8 @@ static TargetInfo *AllocateTarget(const std::string &T) {        return new OpenBSDI386TargetInfo(T);      case llvm::Triple::FreeBSD:        return new FreeBSDTargetInfo<X86_32TargetInfo>(T); +    case llvm::Triple::Minix: +      return new MinixTargetInfo<X86_32TargetInfo>(T);      case llvm::Triple::Solaris:        return new SolarisTargetInfo<X86_32TargetInfo>(T);      case llvm::Triple::Cygwin: @@ -2444,6 +2594,12 @@ TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,      return 0;    } +  // Set the target C++ ABI. +  if (!Target->setCXXABI(Opts.CXXABI)) { +    Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI; +    return 0; +  } +    // Compute the default target features, we need the target to handle this    // because features may have dependencies on one another.    llvm::StringMap<bool> Features;  | 
