diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:01:22 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:01:22 +0000 | 
| commit | 71d5a2540a98c81f5bcaeb48805e0e2881f530ef (patch) | |
| tree | 5343938942df402b49ec7300a1c25a2d4ccd5821 /lib/Object/ELFObjectFile.cpp | |
| parent | 31bbf64f3a4974a2d6c8b3b27ad2f519caf74057 (diff) | |
Diffstat (limited to 'lib/Object/ELFObjectFile.cpp')
| -rw-r--r-- | lib/Object/ELFObjectFile.cpp | 262 | 
1 files changed, 220 insertions, 42 deletions
diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index 4bd69e34e3c3..3f8c81c8e911 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -12,6 +12,8 @@  //===----------------------------------------------------------------------===//  #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Support/ARMBuildAttributes.h" +#include "llvm/Support/ARMAttributeParser.h"  #include "llvm/Support/MathExtras.h"  namespace llvm { @@ -55,71 +57,247 @@ ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {    return std::move(R);  } -SubtargetFeatures ELFObjectFileBase::getFeatures() const { -  switch (getEMachine()) { -  case ELF::EM_MIPS: { -    SubtargetFeatures Features; -    unsigned PlatformFlags; -    getPlatformFlags(PlatformFlags); +SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const { +  SubtargetFeatures Features; +  unsigned PlatformFlags; +  getPlatformFlags(PlatformFlags); + +  switch (PlatformFlags & ELF::EF_MIPS_ARCH) { +  case ELF::EF_MIPS_ARCH_1: +    break; +  case ELF::EF_MIPS_ARCH_2: +    Features.AddFeature("mips2"); +    break; +  case ELF::EF_MIPS_ARCH_3: +    Features.AddFeature("mips3"); +    break; +  case ELF::EF_MIPS_ARCH_4: +    Features.AddFeature("mips4"); +    break; +  case ELF::EF_MIPS_ARCH_5: +    Features.AddFeature("mips5"); +    break; +  case ELF::EF_MIPS_ARCH_32: +    Features.AddFeature("mips32"); +    break; +  case ELF::EF_MIPS_ARCH_64: +    Features.AddFeature("mips64"); +    break; +  case ELF::EF_MIPS_ARCH_32R2: +    Features.AddFeature("mips32r2"); +    break; +  case ELF::EF_MIPS_ARCH_64R2: +    Features.AddFeature("mips64r2"); +    break; +  case ELF::EF_MIPS_ARCH_32R6: +    Features.AddFeature("mips32r6"); +    break; +  case ELF::EF_MIPS_ARCH_64R6: +    Features.AddFeature("mips64r6"); +    break; +  default: +    llvm_unreachable("Unknown EF_MIPS_ARCH value"); +  } + +  switch (PlatformFlags & ELF::EF_MIPS_MACH) { +  case ELF::EF_MIPS_MACH_NONE: +    // No feature associated with this value. +    break; +  case ELF::EF_MIPS_MACH_OCTEON: +    Features.AddFeature("cnmips"); +    break; +  default: +    llvm_unreachable("Unknown EF_MIPS_ARCH value"); +  } -    switch (PlatformFlags & ELF::EF_MIPS_ARCH) { -    case ELF::EF_MIPS_ARCH_1: +  if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16) +    Features.AddFeature("mips16"); +  if (PlatformFlags & ELF::EF_MIPS_MICROMIPS) +    Features.AddFeature("micromips"); + +  return Features; +} + +SubtargetFeatures ELFObjectFileBase::getARMFeatures() const { +  SubtargetFeatures Features; +  ARMAttributeParser Attributes; +  std::error_code EC = getBuildAttributes(Attributes); +  if (EC) +    return SubtargetFeatures(); + +  // both ARMv7-M and R have to support thumb hardware div +  bool isV7 = false; +  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) +    isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch) +      == ARMBuildAttrs::v7; + +  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch_profile)) { +    switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile)) { +    case ARMBuildAttrs::ApplicationProfile: +      Features.AddFeature("aclass");        break; -    case ELF::EF_MIPS_ARCH_2: -      Features.AddFeature("mips2"); +    case ARMBuildAttrs::RealTimeProfile: +      Features.AddFeature("rclass"); +      if (isV7) +        Features.AddFeature("hwdiv");        break; -    case ELF::EF_MIPS_ARCH_3: -      Features.AddFeature("mips3"); +    case ARMBuildAttrs::MicroControllerProfile: +      Features.AddFeature("mclass"); +      if (isV7) +        Features.AddFeature("hwdiv");        break; -    case ELF::EF_MIPS_ARCH_4: -      Features.AddFeature("mips4"); +    } +  } + +  if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) { +    switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) { +    default:        break; -    case ELF::EF_MIPS_ARCH_5: -      Features.AddFeature("mips5"); +    case ARMBuildAttrs::Not_Allowed: +      Features.AddFeature("thumb", false); +      Features.AddFeature("thumb2", false);        break; -    case ELF::EF_MIPS_ARCH_32: -      Features.AddFeature("mips32"); +    case ARMBuildAttrs::AllowThumb32: +      Features.AddFeature("thumb2");        break; -    case ELF::EF_MIPS_ARCH_64: -      Features.AddFeature("mips64"); +    } +  } + +  if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) { +    switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) { +    default:        break; -    case ELF::EF_MIPS_ARCH_32R2: -      Features.AddFeature("mips32r2"); +    case ARMBuildAttrs::Not_Allowed: +      Features.AddFeature("vfp2", false); +      Features.AddFeature("vfp3", false); +      Features.AddFeature("vfp4", false);        break; -    case ELF::EF_MIPS_ARCH_64R2: -      Features.AddFeature("mips64r2"); +    case ARMBuildAttrs::AllowFPv2: +      Features.AddFeature("vfp2");        break; -    case ELF::EF_MIPS_ARCH_32R6: -      Features.AddFeature("mips32r6"); +    case ARMBuildAttrs::AllowFPv3A: +    case ARMBuildAttrs::AllowFPv3B: +      Features.AddFeature("vfp3");        break; -    case ELF::EF_MIPS_ARCH_64R6: -      Features.AddFeature("mips64r6"); +    case ARMBuildAttrs::AllowFPv4A: +    case ARMBuildAttrs::AllowFPv4B: +      Features.AddFeature("vfp4");        break; -    default: -      llvm_unreachable("Unknown EF_MIPS_ARCH value");      } +  } -    switch (PlatformFlags & ELF::EF_MIPS_MACH) { -    case ELF::EF_MIPS_MACH_NONE: -      // No feature associated with this value. +  if (Attributes.hasAttribute(ARMBuildAttrs::Advanced_SIMD_arch)) { +    switch(Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch)) { +    default: +      break; +    case ARMBuildAttrs::Not_Allowed: +      Features.AddFeature("neon", false); +      Features.AddFeature("fp16", false); +      break; +    case ARMBuildAttrs::AllowNeon: +      Features.AddFeature("neon");        break; -    case ELF::EF_MIPS_MACH_OCTEON: -      Features.AddFeature("cnmips"); +    case ARMBuildAttrs::AllowNeon2: +      Features.AddFeature("neon"); +      Features.AddFeature("fp16");        break; +    } +  } + +  if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) { +    switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {      default: -      llvm_unreachable("Unknown EF_MIPS_ARCH value"); +      break; +    case ARMBuildAttrs::DisallowDIV: +      Features.AddFeature("hwdiv", false); +      Features.AddFeature("hwdiv-arm", false); +      break; +    case ARMBuildAttrs::AllowDIVExt: +      Features.AddFeature("hwdiv"); +      Features.AddFeature("hwdiv-arm"); +      break;      } +  } -    if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16) -      Features.AddFeature("mips16"); -    if (PlatformFlags & ELF::EF_MIPS_MICROMIPS) -      Features.AddFeature("micromips"); +  return Features; +} -    return Features; -  } +SubtargetFeatures ELFObjectFileBase::getFeatures() const { +  switch (getEMachine()) { +  case ELF::EM_MIPS: +    return getMIPSFeatures(); +  case ELF::EM_ARM: +    return getARMFeatures();    default:      return SubtargetFeatures();    }  } +// FIXME Encode from a tablegen description or target parser. +void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { +  if (TheTriple.getSubArch() != Triple::NoSubArch) +    return; + +  ARMAttributeParser Attributes; +  std::error_code EC = getBuildAttributes(Attributes); +  if (EC) +    return; + +  std::string Triple; +  // Default to ARM, but use the triple if it's been set. +  if (TheTriple.getArch() == Triple::thumb || +      TheTriple.getArch() == Triple::thumbeb) +    Triple = "thumb"; +  else +    Triple = "arm"; + +  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) { +    switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) { +    case ARMBuildAttrs::v4: +      Triple += "v4"; +      break; +    case ARMBuildAttrs::v4T: +      Triple += "v4t"; +      break; +    case ARMBuildAttrs::v5T: +      Triple += "v5t"; +      break; +    case ARMBuildAttrs::v5TE: +      Triple += "v5te"; +      break; +    case ARMBuildAttrs::v5TEJ: +      Triple += "v5tej"; +      break; +    case ARMBuildAttrs::v6: +      Triple += "v6"; +      break; +    case ARMBuildAttrs::v6KZ: +      Triple += "v6kz"; +      break; +    case ARMBuildAttrs::v6T2: +      Triple += "v6t2"; +      break; +    case ARMBuildAttrs::v6K: +      Triple += "v6k"; +      break; +    case ARMBuildAttrs::v7: +      Triple += "v7"; +      break; +    case ARMBuildAttrs::v6_M: +      Triple += "v6m"; +      break; +    case ARMBuildAttrs::v6S_M: +      Triple += "v6sm"; +      break; +    case ARMBuildAttrs::v7E_M: +      Triple += "v7em"; +      break; +    } +  } +  if (!isLittleEndian()) +    Triple += "eb"; + +  TheTriple.setArchName(Triple); +} +  } // end namespace llvm  | 
