[llvm] r193524 - [arm] Implement eabi_attribute, cpu, and fpu directives.

David Peixotto dpeixott at codeaurora.org
Tue Nov 19 14:30:32 PST 2013


Is there any plan to support parsing named eabi_attributes in assembly to
match gnu as (https://sourceware.org/binutils/docs/as/ARM-Directives.html)?

For example,
.eabi_attribute Tag_ABI_align_needed, 1

instead of
.eabi_attribute 24, 1


> -----Original Message-----
> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-
> bounces at cs.uiuc.edu] On Behalf Of Logan Chien
> Sent: Monday, October 28, 2013 10:51 AM
> To: llvm-commits at cs.uiuc.edu
> Subject: [llvm] r193524 - [arm] Implement eabi_attribute, cpu, and fpu
> directives.
> 
> Author: logan
> Date: Mon Oct 28 12:51:12 2013
> New Revision: 193524
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=193524&view=rev
> Log:
> [arm] Implement eabi_attribute, cpu, and fpu directives.
> 
> This commit allows the ARM integrated assembler to parse
> and assemble the code with .eabi_attribute, .cpu, and
> .fpu directives.
> 
> To implement the feature, this commit moves the code from
> AttrEmitter to ARMTargetStreamers, and several new test
> cases related to cortex-m4, cortex-r5, and cortex-a15 are
> added.
> 
> Besides, this commit also change the Subtarget->isFPOnlySP()
> to Subtarget->hasD16() to match the usage of .fpu directive.
> 
> This commit changes the test cases:
> 
> * Several .eabi_attribute directives in
>   2010-09-29-mc-asm-header-test.ll are removed because the .fpu
>   directive already cover the functionality.
> 
> * In the Cortex-A15 test case, the value for
>   Tag_Advanced_SIMD_arch has be changed from 1 to 2,
>   which is more precise.
> 
> 
> Added:
>     llvm/trunk/lib/Target/ARM/ARMFPUName.def
>     llvm/trunk/lib/Target/ARM/ARMFPUName.h
>     llvm/trunk/test/MC/ARM/directive-cpu.s
>     llvm/trunk/test/MC/ARM/directive-eabi_attribute.s
>     llvm/trunk/test/MC/ARM/directive-fpu-multiple.s
>     llvm/trunk/test/MC/ARM/directive-fpu.s
> Modified:
>     llvm/trunk/include/llvm/MC/MCStreamer.h
>     llvm/trunk/lib/Target/ARM/ARM.td
>     llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
>     llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h
>     llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
>     llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
>     llvm/trunk/test/CodeGen/ARM/2010-09-29-mc-asm-header-test.ll
>     llvm/trunk/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll
> 
> Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=193524&r1=193523&r2=19
> 3524&view=diff
> ==========================================================================
> ====
> --- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
> +++ llvm/trunk/include/llvm/MC/MCStreamer.h Mon Oct 28 12:51:12 2013
> @@ -87,6 +87,12 @@ public:
>    virtual void emitPad(int64_t Offset) = 0;
>    virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
>                             bool isVector) = 0;
> +
> +  virtual void switchVendor(StringRef Vendor) = 0;
> +  virtual void emitAttribute(unsigned Attribute, unsigned Value) = 0;
> +  virtual void emitTextAttribute(unsigned Attribute, StringRef String) =
> 0;
> +  virtual void emitFPU(unsigned FPU) = 0;
> +  virtual void finishAttributeSection() = 0;
>  };
> 
>  /// MCStreamer - Streaming machine code generation interface.  This
> interface
> 
> Modified: llvm/trunk/lib/Target/ARM/ARM.td
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/ARM/ARM.td?rev=193524&r1=193523&r2=193524&vi
> ew=diff
> ==========================================================================
> ====
> --- llvm/trunk/lib/Target/ARM/ARM.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARM.td Mon Oct 28 12:51:12 2013
> @@ -309,7 +309,7 @@ def : ProcessorModel<"cortex-r5",   Cort
>                                      [ProcR5, HasV7Ops, FeatureDB,
>                                       FeatureVFP3, FeatureDSPThumb2,
>                                       FeatureHasRAS, FeatureVFPOnlySP,
> -                                     FeatureRClass]>;
> +                                     FeatureD16, FeatureRClass]>;
> 
>  // V7M Processors.
>  def : ProcNoItin<"cortex-m3",       [HasV7Ops,
> @@ -321,7 +321,8 @@ def : ProcNoItin<"cortex-m4",       [Has
>                                       FeatureThumb2, FeatureNoARM,
> FeatureDB,
>                                       FeatureHWDiv, FeatureDSPThumb2,
>                                       FeatureT2XtPk, FeatureVFP4,
> -                                     FeatureVFPOnlySP, FeatureMClass]>;
> +                                     FeatureVFPOnlySP, FeatureD16,
> +                                     FeatureMClass]>;
> 
>  // Swift uArch Processors.
>  def : ProcessorModel<"swift",       SwiftModel,
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=193524&r1=193523&r
> 2=193524&view=diff
> ==========================================================================
> ====
> --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Mon Oct 28 12:51:12 2013
> @@ -17,6 +17,7 @@
>  #include "ARM.h"
>  #include "ARMBuildAttrs.h"
>  #include "ARMConstantPoolValue.h"
> +#include "ARMFPUName.h"
>  #include "ARMMachineFunctionInfo.h"
>  #include "ARMTargetMachine.h"
>  #include "ARMTargetObjectFile.h"
> @@ -55,164 +56,6 @@
>  #include <cctype>
>  using namespace llvm;
> 
> -namespace {
> -
> -  // Per section and per symbol attributes are not supported.
> -  // To implement them we would need the ability to delay this emission
> -  // until the assembly file is fully parsed/generated as only then do we
> -  // know the symbol and section numbers.
> -  class AttributeEmitter {
> -  public:
> -    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
> -    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
> -    virtual void EmitTextAttribute(unsigned Attribute, StringRef String)
> = 0;
> -    virtual void Finish() = 0;
> -    virtual ~AttributeEmitter() {}
> -  };
> -
> -  class AsmAttributeEmitter : public AttributeEmitter {
> -    MCStreamer &Streamer;
> -
> -  public:
> -    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
> -    void MaybeSwitchVendor(StringRef Vendor) { }
> -
> -    void EmitAttribute(unsigned Attribute, unsigned Value) {
> -      Streamer.EmitRawText("\t.eabi_attribute " +
> -                           Twine(Attribute) + ", " + Twine(Value));
> -    }
> -
> -    void EmitTextAttribute(unsigned Attribute, StringRef String) {
> -      switch (Attribute) {
> -      default: llvm_unreachable("Unsupported Text attribute in ASM
> Mode");
> -      case ARMBuildAttrs::CPU_name:
> -        Streamer.EmitRawText(StringRef("\t.cpu ") + String.lower());
> -        break;
> -      /* GAS requires .fpu to be emitted regardless of EABI attribute */
> -      case ARMBuildAttrs::Advanced_SIMD_arch:
> -      case ARMBuildAttrs::VFP_arch:
> -        Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower());
> -        break;
> -      }
> -    }
> -    void Finish() { }
> -  };
> -
> -  class ObjectAttributeEmitter : public AttributeEmitter {
> -    // This structure holds all attributes, accounting for
> -    // their string/numeric value, so we can later emmit them
> -    // in declaration order, keeping all in the same vector
> -    struct AttributeItemType {
> -      enum {
> -        HiddenAttribute = 0,
> -        NumericAttribute,
> -        TextAttribute
> -      } Type;
> -      unsigned Tag;
> -      unsigned IntValue;
> -      StringRef StringValue;
> -    };
> -
> -    MCObjectStreamer &Streamer;
> -    StringRef CurrentVendor;
> -    SmallVector<AttributeItemType, 64> Contents;
> -
> -    // Account for the ULEB/String size of each item,
> -    // not just the number of items
> -    size_t ContentsSize;
> -    // FIXME: this should be in a more generic place, but
> -    // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf
> -    size_t getULEBSize(int Value) {
> -      size_t Size = 0;
> -      do {
> -        Value >>= 7;
> -        Size += sizeof(int8_t); // Is this really necessary?
> -      } while (Value);
> -      return Size;
> -    }
> -
> -  public:
> -    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
> -      Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { }
> -
> -    void MaybeSwitchVendor(StringRef Vendor) {
> -      assert(!Vendor.empty() && "Vendor cannot be empty.");
> -
> -      if (CurrentVendor.empty())
> -        CurrentVendor = Vendor;
> -      else if (CurrentVendor == Vendor)
> -        return;
> -      else
> -        Finish();
> -
> -      CurrentVendor = Vendor;
> -
> -      assert(Contents.size() == 0);
> -    }
> -
> -    void EmitAttribute(unsigned Attribute, unsigned Value) {
> -      AttributeItemType attr = {
> -        AttributeItemType::NumericAttribute,
> -        Attribute,
> -        Value,
> -        StringRef("")
> -      };
> -      ContentsSize += getULEBSize(Attribute);
> -      ContentsSize += getULEBSize(Value);
> -      Contents.push_back(attr);
> -    }
> -
> -    void EmitTextAttribute(unsigned Attribute, StringRef String) {
> -      AttributeItemType attr = {
> -        AttributeItemType::TextAttribute,
> -        Attribute,
> -        0,
> -        String
> -      };
> -      ContentsSize += getULEBSize(Attribute);
> -      // String + \0
> -      ContentsSize += String.size()+1;
> -
> -      Contents.push_back(attr);
> -    }
> -
> -    void Finish() {
> -      // Vendor size + Vendor name + '\0'
> -      const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
> -
> -      // Tag + Tag Size
> -      const size_t TagHeaderSize = 1 + 4;
> -
> -      Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize +
> ContentsSize, 4);
> -      Streamer.EmitBytes(CurrentVendor);
> -      Streamer.EmitIntValue(0, 1); // '\0'
> -
> -      Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
> -      Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
> -
> -      // Size should have been accounted for already, now
> -      // emit each field as its type (ULEB or String)
> -      for (unsigned int i=0; i<Contents.size(); ++i) {
> -        AttributeItemType item = Contents[i];
> -        Streamer.EmitULEB128IntValue(item.Tag);
> -        switch (item.Type) {
> -        default: llvm_unreachable("Invalid attribute type");
> -        case AttributeItemType::NumericAttribute:
> -          Streamer.EmitULEB128IntValue(item.IntValue);
> -          break;
> -        case AttributeItemType::TextAttribute:
> -          Streamer.EmitBytes(item.StringValue.upper());
> -          Streamer.EmitIntValue(0, 1); // '\0'
> -          break;
> -        }
> -      }
> -
> -      Contents.clear();
> -    }
> -  };
> -
> -} // end of anonymous namespace
> -
>  /// EmitDwarfRegOp - Emit dwarf register operation.
>  void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
>                                     bool Indirect) const {
> @@ -768,149 +611,102 @@ static ARMBuildAttrs::CPUArch getArchFor
>  }
> 
>  void ARMAsmPrinter::emitAttributes() {
> +  MCTargetStreamer &TS = OutStreamer.getTargetStreamer();
> +  ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
> 
> -  emitARMAttributeSection();
> -
> -  /* GAS expect .fpu to be emitted, regardless of VFP build attribute */
> -  bool emitFPU = false;
> -  AttributeEmitter *AttrEmitter;
> -  if (OutStreamer.hasRawTextSupport()) {
> -    AttrEmitter = new AsmAttributeEmitter(OutStreamer);
> -    emitFPU = true;
> -  } else {
> -    MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);
> -    AttrEmitter = new ObjectAttributeEmitter(O);
> -  }
> -
> -  AttrEmitter->MaybeSwitchVendor("aeabi");
> +  ATS.switchVendor("aeabi");
> 
>    std::string CPUString = Subtarget->getCPUString();
> 
>    if (CPUString != "generic")
> -    AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);
> +    ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);
> 
> -  AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch,
> -                             getArchForCPU(CPUString, Subtarget));
> +  ATS.emitAttribute(ARMBuildAttrs::CPU_arch,
> +                    getArchForCPU(CPUString, Subtarget));
> 
>    if (Subtarget->isAClass()) {
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
> -                               ARMBuildAttrs::ApplicationProfile);
> +    ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
> +                      ARMBuildAttrs::ApplicationProfile);
>    } else if (Subtarget->isRClass()) {
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
> -                               ARMBuildAttrs::RealTimeProfile);
> +    ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
> +                      ARMBuildAttrs::RealTimeProfile);
>    } else if (Subtarget->isMClass()){
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,
> -                               ARMBuildAttrs::MicroControllerProfile);
> +    ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
> +                      ARMBuildAttrs::MicroControllerProfile);
>    }
> 
> -  AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, Subtarget-
> >hasARMOps() ?
> -                           ARMBuildAttrs::Allowed :
> ARMBuildAttrs::Not_Allowed);
> +  ATS.emitAttribute(ARMBuildAttrs::ARM_ISA_use, Subtarget->hasARMOps() ?
> +                      ARMBuildAttrs::Allowed :
> ARMBuildAttrs::Not_Allowed);
>    if (Subtarget->isThumb1Only()) {
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
> -                               ARMBuildAttrs::Allowed);
> +    ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
> +                      ARMBuildAttrs::Allowed);
>    } else if (Subtarget->hasThumb2()) {
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,
> -                               ARMBuildAttrs::AllowThumb32);
> +    ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
> +                      ARMBuildAttrs::AllowThumb32);
>    }
> 
> -  if (Subtarget->hasNEON() && emitFPU) {
> +  if (Subtarget->hasNEON()) {
>      /* NEON is not exactly a VFP architecture, but GAS emit one of
>       * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
>      if (Subtarget->hasFPARMv8()) {
>        if (Subtarget->hasCrypto())
> -        AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
> -                                       "crypto-neon-fp-armv8");
> +        ATS.emitFPU(ARM::CRYPTO_NEON_FP_ARMV8);
>        else
> -        AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
> -                                       "neon-fp-armv8");
> +        ATS.emitFPU(ARM::NEON_FP_ARMV8);
>      }
>      else if (Subtarget->hasVFP4())
> -      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
> -                                     "neon-vfpv4");
> +      ATS.emitFPU(ARM::NEON_VFPV4);
>      else
> -      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
> "neon");
> -    /* If emitted for NEON, omit from VFP below, since you can have both
> -     * NEON and VFP in build attributes but only one .fpu */
> -    emitFPU = false;
> -  }
> -
> -  /* FPARMv8 + .fpu */
> -  if (Subtarget->hasFPARMv8()) {
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
> -                               ARMBuildAttrs::AllowFPARMv8A);
> -    if (emitFPU)
> -      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "fp-
> armv8");
> -    /* VFPv4 + .fpu */
> -  } else if (Subtarget->hasVFP4()) {
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
> -      Subtarget->isFPOnlySP() ? ARMBuildAttrs::AllowFPv4B :
> -                                ARMBuildAttrs::AllowFPv4A);
> -    if (emitFPU)
> -      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv4");
> -
> -  /* VFPv3 + .fpu */
> -  } else if (Subtarget->hasVFP3()) {
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
> -      Subtarget->isFPOnlySP() ? ARMBuildAttrs::AllowFPv3B :
> -                                ARMBuildAttrs::AllowFPv3A);
> -    if (emitFPU)
> -      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv3");
> -
> -  /* VFPv2 + .fpu */
> -  } else if (Subtarget->hasVFP2()) {
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch,
> -                               ARMBuildAttrs::AllowFPv2);
> -    if (emitFPU)
> -      AttrEmitter->EmitTextAttribute(ARMBuildAttrs::VFP_arch, "vfpv2");
> -  }
> -
> -  /* TODO: ARMBuildAttrs::Allowed is not completely accurate,
> -   * since NEON can have 1 (allowed) or 2 (MAC operations) */
> -  if (Subtarget->hasNEON()) {
> +      ATS.emitFPU(ARM::NEON);
> +    // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
>      if (Subtarget->hasV8Ops())
> -      AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
> -                                 ARMBuildAttrs::AllowedNeonV8);
> -    else
> -      AttrEmitter->EmitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
> -                                 ARMBuildAttrs::Allowed);
> +      ATS.emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
> +                        ARMBuildAttrs::AllowNeonARMv8);
> +  } else {
> +    if (Subtarget->hasFPARMv8())
> +      ATS.emitFPU(ARM::FP_ARMV8);
> +    else if (Subtarget->hasVFP4())
> +      ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV4_D16 : ARM::VFPV4);
> +    else if (Subtarget->hasVFP3())
> +      ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV3_D16 : ARM::VFPV3);
> +    else if (Subtarget->hasVFP2())
> +      ATS.emitFPU(ARM::VFPV2);
>    }
> 
>    // Signal various FP modes.
>    if (!TM.Options.UnsafeFPMath) {
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal,
> -                               ARMBuildAttrs::Allowed);
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
> -                               ARMBuildAttrs::Allowed);
> +    ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
> ARMBuildAttrs::Allowed);
> +    ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
> +                      ARMBuildAttrs::Allowed);
>    }
> 
>    if (TM.Options.NoInfsFPMath && TM.Options.NoNaNsFPMath)
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
> -                               ARMBuildAttrs::Allowed);
> +    ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
> +                      ARMBuildAttrs::Allowed);
>    else
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model,
> -                               ARMBuildAttrs::AllowIEE754);
> +    ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
> +                      ARMBuildAttrs::AllowIEE754);
> 
>    // FIXME: add more flags to ARMBuildAttrs.h
>    // 8-bytes alignment stuff.
> -  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
> -  AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
> +  ATS.emitAttribute(ARMBuildAttrs::ABI_align8_needed, 1);
> +  ATS.emitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1);
> 
>    // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
>    if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType ==
> FloatABI::Hard) {
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
> +    ATS.emitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3);
> +    ATS.emitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
>    }
>    // FIXME: Should we signal R9 usage?
> 
>    if (Subtarget->hasDivide()) {
>      // Check if hardware divide is only available in thumb2 or ARM as
> well.
> -    AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use,
> +    ATS.emitAttribute(ARMBuildAttrs::DIV_use,
>        Subtarget->hasDivideInARMMode() ? ARMBuildAttrs::AllowDIVExt :
>                                          ARMBuildAttrs::AllowDIVIfExists);
>    }
> 
> -  AttrEmitter->Finish();
> -  delete AttrEmitter;
> +  ATS.finishAttributeSection();
>  }
> 
>  void ARMAsmPrinter::emitARMAttributeSection() {
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h?rev=193524&r1=193523&r2=
> 193524&view=diff
> ==========================================================================
> ====
> --- llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h Mon Oct 28 12:51:12 2013
> @@ -15,11 +15,13 @@
>  #ifndef __TARGET_ARMBUILDATTRS_H__
>  #define __TARGET_ARMBUILDATTRS_H__
> 
> +namespace llvm {
>  namespace ARMBuildAttrs {
> +
>    enum SpecialAttr {
>      // This is for the .cpu asm attr. It translates into one or more
>      // AttrType (below) entries in the .ARM.attributes section in the
> ELF.
> -    SEL_CPU
> +    SEL_CPU
>    };
> 
>    enum AttrType {
> @@ -93,7 +95,7 @@ namespace ARMBuildAttrs {
>      v8       = 14   // v8, AArch32
>    };
> 
> -  enum CPUArchProfile { // (=7), uleb128
> +  enum CPUArchProfile { // (=7), uleb128
>      Not_Applicable = 0, // pre v7, or cross-profile code
>      ApplicationProfile = (0x41), // 'A' (e.g. for Cortex A8)
>      RealTimeProfile = (0x52), // 'R' (e.g. for Cortex R4)
> @@ -102,40 +104,50 @@ namespace ARMBuildAttrs {
>    };
> 
>    // The following have a lot of common use cases
> -  enum {
> +  enum {
>      //ARMISAUse (=8), uleb128  and THUMBISAUse (=9), uleb128
>      Not_Allowed = 0,
>      Allowed = 1,
> -    AllowedNeonV8 = 3,
> 
>      // FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10)
>      AllowFPv2  = 2, // v2 FP ISA permitted (implies use of the v1 FP ISA)
>      AllowFPv3A = 3, // v3 FP ISA permitted (implies use of the v2 FP ISA)
> -    AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31
> -    AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA)
> +    AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31
> +    AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA)
>      AllowFPv4B = 6, // v4 FP ISA was permitted, but only D0-D15, S0-S31
>      AllowFPARMv8A = 7, // Use of the ARM v8-A FP ISA was permitted
>      AllowFPARMv8B = 8, // Use of the ARM v8-A FP ISA was permitted, but
> only D0-D15, S0-S31
> 
>      // Tag_WMMX_arch, (=11), uleb128
>      AllowThumb32 = 2, // 32-bit Thumb (implies 16-bit instructions)
> -
> +
>      // Tag_WMMX_arch, (=11), uleb128
>      AllowWMMXv1 = 2,  // The user permitted this entity to use WMMX v2
> 
> -    // Tag_ABI_FP_denormal, (=20), uleb128
> +    // Tag_Advanced_SIMD_arch, (=12), uleb128
> +    AllowNeon = 1, // SIMDv1 was permitted
> +    AllowNeon2 = 2, // SIMDv2 was permitted (Half-precision FP, MAC
> operations)
> +    AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted
> +
> +    // Tag_ABI_FP_denormal, (=20), uleb128
>      PreserveFPSign = 2, // sign when flushed-to-zero is preserved
> 
>      // Tag_ABI_FP_number_model, (=23), uleb128
>      AllowRTABI = 2,  // numbers, infinities, and one quiet NaN (see
> [RTABI])
>      AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP
> encodings
> 
> +    // Tag_ABI_HardFP_use, (=27), uleb128
> +    HardFPSinglePrecision = 1, // Single-precision only
> +    HardFPImplied = 3, // FP use should be implied by Tag_FP_arch
> +
>      // Tag_DIV_use, (=44), uleb128
>      AllowDIVIfExists = 0, // Allow hardware divide if available in arch,
> or no info exists.
>      DisallowDIV = 1, // Hardware divide explicitly disallowed
>      AllowDIVExt = 2  // Allow hardware divide as optional architecture
> extension above
>                       // the base arch specified by Tag_CPU_arch and
> Tag_CPU_arch_profile.
>    };
> -}
> +
> +} // namespace ARMBuildAttrs
> +} // namespace llvm
> 
>  #endif // __TARGET_ARMBUILDATTRS_H__
> 
> Added: llvm/trunk/lib/Target/ARM/ARMFPUName.def
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/ARM/ARMFPUName.def?rev=193524&view=auto
> ==========================================================================
> ====
> --- llvm/trunk/lib/Target/ARM/ARMFPUName.def (added)
> +++ llvm/trunk/lib/Target/ARM/ARMFPUName.def Mon Oct 28 12:51:12 2013
> @@ -0,0 +1,32 @@
> +//===-- ARMFPUName.def - List of the ARM FPU names --------------*- C++ -
> *-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===--------------------------------------------------------------------
> --===//
> +//
> +// This file contains the list of the supported ARM FPU names.
> +//
> +//===--------------------------------------------------------------------
> --===//
> +
> +// NOTE: NO INCLUDE GUARD DESIRED!
> +
> +#ifndef ARM_FPU_NAME
> +#error "You must define ARM_FPU_NAME(NAME, ID) before including
> ARMFPUName.h"
> +#endif
> +
> +ARM_FPU_NAME("vfp", VFP)
> +ARM_FPU_NAME("vfpv2", VFPV2)
> +ARM_FPU_NAME("vfpv3", VFPV3)
> +ARM_FPU_NAME("vfpv3-d16", VFPV3_D16)
> +ARM_FPU_NAME("vfpv4", VFPV4)
> +ARM_FPU_NAME("vfpv4-d16", VFPV4_D16)
> +ARM_FPU_NAME("fp-armv8", FP_ARMV8)
> +ARM_FPU_NAME("neon", NEON)
> +ARM_FPU_NAME("neon-vfpv4", NEON_VFPV4)
> +ARM_FPU_NAME("neon-fp-armv8", NEON_FP_ARMV8)
> +ARM_FPU_NAME("crypto-neon-fp-armv8", CRYPTO_NEON_FP_ARMV8)
> +
> +#undef ARM_FPU_NAME
> 
> Added: llvm/trunk/lib/Target/ARM/ARMFPUName.h
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/ARM/ARMFPUName.h?rev=193524&view=auto
> ==========================================================================
> ====
> --- llvm/trunk/lib/Target/ARM/ARMFPUName.h (added)
> +++ llvm/trunk/lib/Target/ARM/ARMFPUName.h Mon Oct 28 12:51:12 2013
> @@ -0,0 +1,26 @@
> +//===-- ARMFPUName.h - List of the ARM FPU names ----------------*- C++ -
> *-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===--------------------------------------------------------------------
> --===//
> +
> +#ifndef ARMFPUNAME_H
> +#define ARMFPUNAME_H
> +
> +namespace llvm {
> +namespace ARM {
> +
> +enum FPUKind {
> +  INVALID_FPU = 0
> +
> +#define ARM_FPU_NAME(NAME, ID) , ID
> +#include "ARMFPUName.def"
> +};
> +
> +} // namespace ARM
> +} // namespace llvm
> +
> +#endif // ARMFPUNAME_H
> 
> Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=193524&r1
> =193523&r2=193524&view=diff
> ==========================================================================
> ====
> --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Mon Oct 28
> 12:51:12 2013
> @@ -7,6 +7,8 @@
>  //
>  //===--------------------------------------------------------------------
> --===//
> 
> +#include "ARMBuildAttrs.h"
> +#include "ARMFPUName.h"
>  #include "ARMFeatures.h"
>  #include "llvm/MC/MCTargetAsmParser.h"
>  #include "MCTargetDesc/ARMAddressingModes.h"
> @@ -137,6 +139,8 @@ class ARMAsmParser : public MCTargetAsmP
>    bool parseDirectiveUnreq(SMLoc L);
>    bool parseDirectiveArch(SMLoc L);
>    bool parseDirectiveEabiAttr(SMLoc L);
> +  bool parseDirectiveCPU(SMLoc L);
> +  bool parseDirectiveFPU(SMLoc L);
>    bool parseDirectiveFnStart(SMLoc L);
>    bool parseDirectiveFnEnd(SMLoc L);
>    bool parseDirectiveCantUnwind(SMLoc L);
> @@ -7765,6 +7769,10 @@ bool ARMAsmParser::ParseDirective(AsmTok
>      return parseDirectiveArch(DirectiveID.getLoc());
>    else if (IDVal == ".eabi_attribute")
>      return parseDirectiveEabiAttr(DirectiveID.getLoc());
> +  else if (IDVal == ".cpu")
> +    return parseDirectiveCPU(DirectiveID.getLoc());
> +  else if (IDVal == ".fpu")
> +    return parseDirectiveFPU(DirectiveID.getLoc());
>    else if (IDVal == ".fnstart")
>      return parseDirectiveFnStart(DirectiveID.getLoc());
>    else if (IDVal == ".fnend")
> @@ -7987,7 +7995,48 @@ bool ARMAsmParser::parseDirectiveArch(SM
>  /// parseDirectiveEabiAttr
>  ///  ::= .eabi_attribute int, int
>  bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
> -  return true;
> +  if (Parser.getTok().isNot(AsmToken::Integer))
> +    return Error(L, "integer expected");
> +  int64_t Tag = Parser.getTok().getIntVal();
> +  Parser.Lex(); // eat tag integer
> +
> +  if (Parser.getTok().isNot(AsmToken::Comma))
> +    return Error(L, "comma expected");
> +  Parser.Lex(); // skip comma
> +
> +  L = Parser.getTok().getLoc();
> +  if (Parser.getTok().isNot(AsmToken::Integer))
> +    return Error(L, "integer expected");
> +  int64_t Value = Parser.getTok().getIntVal();
> +  Parser.Lex(); // eat value integer
> +
> +  getTargetStreamer().emitAttribute(Tag, Value);
> +  return false;
> +}
> +
> +/// parseDirectiveCPU
> +///  ::= .cpu str
> +bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
> +  StringRef CPU = getParser().parseStringToEndOfStatement().trim();
> +  getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU);
> +  return false;
> +}
> +
> +/// parseDirectiveFPU
> +///  ::= .fpu str
> +bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
> +  StringRef FPU = getParser().parseStringToEndOfStatement().trim();
> +
> +  unsigned ID = StringSwitch<unsigned>(FPU)
> +#define ARM_FPU_NAME(NAME, ID) .Case(NAME, ARM::ID)
> +#include "ARMFPUName.def"
> +    .Default(ARM::INVALID_FPU);
> +
> +  if (ID == ARM::INVALID_FPU)
> +    return Error(L, "Unknown FPU name");
> +
> +  getTargetStreamer().emitFPU(ID);
> +  return false;
>  }
> 
>  /// parseDirectiveFnStart
> 
> Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp?rev=1935
> 24&r1=193523&r2=193524&view=diff
> ==========================================================================
> ====
> --- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp Mon Oct 28
> 12:51:12 2013
> @@ -13,6 +13,8 @@
>  //
>  //===--------------------------------------------------------------------
> --===//
> 
> +#include "ARMBuildAttrs.h"
> +#include "ARMFPUName.h"
>  #include "ARMRegisterInfo.h"
>  #include "ARMUnwindOp.h"
>  #include "ARMUnwindOpAsm.h"
> @@ -39,6 +41,7 @@
>  #include "llvm/Support/ELF.h"
>  #include "llvm/Support/FormattedStream.h"
>  #include "llvm/Support/raw_ostream.h"
> +#include <algorithm>
> 
>  using namespace llvm;
> 
> @@ -47,6 +50,17 @@ static std::string GetAEABIUnwindPersona
>    return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
>  }
> 
> +static const char *GetFPUName(unsigned ID) {
> +  switch (ID) {
> +  default:
> +    llvm_unreachable("Unknown FPU kind");
> +    break;
> +#define ARM_FPU_NAME(NAME, ID) case ARM::ID: return NAME;
> +#include "ARMFPUName.def"
> +  }
> +  return NULL;
> +}
> +
>  namespace {
> 
>  class ARMELFStreamer;
> @@ -65,6 +79,12 @@ class ARMTargetAsmStreamer : public ARMT
>    virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
>                             bool isVector);
> 
> +  virtual void switchVendor(StringRef Vendor);
> +  virtual void emitAttribute(unsigned Attribute, unsigned Value);
> +  virtual void emitTextAttribute(unsigned Attribute, StringRef String);
> +  virtual void emitFPU(unsigned FPU);
> +  virtual void finishAttributeSection();
> +
>  public:
>    ARMTargetAsmStreamer(formatted_raw_ostream &OS, MCInstPrinter
> &InstPrinter);
>  };
> @@ -109,9 +129,114 @@ void ARMTargetAsmStreamer::emitRegSave(c
> 
>    OS << "}\n";
>  }
> +void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {
> +}
> +void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned
> Value) {
> +  OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value) <<
> "\n";
> +}
> +void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
> +                                             StringRef String) {
> +  switch (Attribute) {
> +  default: llvm_unreachable("Unsupported Text attribute in ASM Mode");
> +  case ARMBuildAttrs::CPU_name:
> +    OS << "\t.cpu\t" << String.lower() << "\n";
> +    break;
> +  }
> +}
> +void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
> +  OS << "\t.fpu\t" << GetFPUName(FPU) << "\n";
> +}
> +void ARMTargetAsmStreamer::finishAttributeSection() {
> +}
> 
>  class ARMTargetELFStreamer : public ARMTargetStreamer {
> +private:
> +  // This structure holds all attributes, accounting for
> +  // their string/numeric value, so we can later emmit them
> +  // in declaration order, keeping all in the same vector
> +  struct AttributeItem {
> +    enum {
> +      HiddenAttribute = 0,
> +      NumericAttribute,
> +      TextAttribute
> +    } Type;
> +    unsigned Tag;
> +    unsigned IntValue;
> +    StringRef StringValue;
> +
> +    static bool LessTag(const AttributeItem &LHS, const AttributeItem
> &RHS) {
> +      return (LHS.Tag < RHS.Tag);
> +    }
> +  };
> +
> +  StringRef CurrentVendor;
> +  unsigned FPU;
> +  SmallVector<AttributeItem, 64> Contents;
> +
> +  const MCSection *AttributeSection;
> +
> +  // FIXME: this should be in a more generic place, but
> +  // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf
> +  static size_t getULEBSize(int Value) {
> +    size_t Size = 0;
> +    do {
> +      Value >>= 7;
> +      Size += sizeof(int8_t); // Is this really necessary?
> +    } while (Value);
> +    return Size;
> +  }
> +
> +  AttributeItem *getAttributeItem(unsigned Attribute) {
> +    for (size_t i = 0; i < Contents.size(); ++i)
> +      if (Contents[i].Tag == Attribute)
> +        return &Contents[i];
> +    return 0;
> +  }
> +
> +  void setAttributeItem(unsigned Attribute, unsigned Value,
> +                        bool OverwriteExisting) {
> +    // Look for existing attribute item
> +    if (AttributeItem *Item = getAttributeItem(Attribute)) {
> +      if (!OverwriteExisting)
> +        return;
> +      Item->IntValue = Value;
> +      return;
> +    }
> +
> +    // Create new attribute item
> +    AttributeItem Item = {
> +      AttributeItem::NumericAttribute,
> +      Attribute,
> +      Value,
> +      StringRef("")
> +    };
> +    Contents.push_back(Item);
> +  }
> +
> +  void setAttributeItem(unsigned Attribute, StringRef Value,
> +                        bool OverwriteExisting) {
> +    // Look for existing attribute item
> +    if (AttributeItem *Item = getAttributeItem(Attribute)) {
> +      if (!OverwriteExisting)
> +        return;
> +      Item->StringValue = Value;
> +      return;
> +    }
> +
> +    // Create new attribute item
> +    AttributeItem Item = {
> +      AttributeItem::TextAttribute,
> +      Attribute,
> +      0,
> +      Value
> +    };
> +    Contents.push_back(Item);
> +  }
> +
> +  void emitFPUDefaultAttributes();
> +
>    ARMELFStreamer &getStreamer();
> +
>    virtual void emitFnStart();
>    virtual void emitFnEnd();
>    virtual void emitCantUnwind();
> @@ -121,6 +246,20 @@ class ARMTargetELFStreamer : public ARMT
>    virtual void emitPad(int64_t Offset);
>    virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
>                             bool isVector);
> +
> +  virtual void switchVendor(StringRef Vendor);
> +  virtual void emitAttribute(unsigned Attribute, unsigned Value);
> +  virtual void emitTextAttribute(unsigned Attribute, StringRef String);
> +  virtual void emitFPU(unsigned FPU);
> +  virtual void finishAttributeSection();
> +
> +  size_t calculateContentSize() const;
> +
> +public:
> +  ARMTargetELFStreamer()
> +    : ARMTargetStreamer(), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU),
> +      AttributeSection(0) {
> +  }
>  };
> 
>  /// Extend the generic ELFStreamer class so that it can emit mapping
> symbols at
> @@ -149,6 +288,8 @@ public:
> 
>    ~ARMELFStreamer() {}
> 
> +  virtual void FinishImpl();
> +
>    // ARM exception handling directives
>    void emitFnStart();
>    void emitFnEnd();
> @@ -329,6 +470,198 @@ void ARMTargetELFStreamer::emitRegSave(c
>                                         bool isVector) {
>    getStreamer().emitRegSave(RegList, isVector);
>  }
> +void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
> +  assert(!Vendor.empty() && "Vendor cannot be empty.");
> +
> +  if (CurrentVendor == Vendor)
> +    return;
> +
> +  if (!CurrentVendor.empty())
> +    finishAttributeSection();
> +
> +  assert(Contents.empty() &&
> +         ".ARM.attributes should be flushed before changing vendor");
> +  CurrentVendor = Vendor;
> +
> +}
> +void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned
> Value) {
> +  setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
> +}
> +void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
> +                                             StringRef Value) {
> +  setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
> +}
> +void ARMTargetELFStreamer::emitFPU(unsigned Value) {
> +  FPU = Value;
> +}
> +void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
> +  switch (FPU) {
> +  case ARM::VFP:
> +  case ARM::VFPV2:
> +    setAttributeItem(ARMBuildAttrs::VFP_arch,
> +                     ARMBuildAttrs::AllowFPv2,
> +                     /* OverwriteExisting= */ false);
> +    break;
> +
> +  case ARM::VFPV3:
> +    setAttributeItem(ARMBuildAttrs::VFP_arch,
> +                     ARMBuildAttrs::AllowFPv3A,
> +                     /* OverwriteExisting= */ false);
> +    break;
> +
> +  case ARM::VFPV3_D16:
> +    setAttributeItem(ARMBuildAttrs::VFP_arch,
> +                     ARMBuildAttrs::AllowFPv3B,
> +                     /* OverwriteExisting= */ false);
> +    break;
> +
> +  case ARM::VFPV4:
> +    setAttributeItem(ARMBuildAttrs::VFP_arch,
> +                     ARMBuildAttrs::AllowFPv4A,
> +                     /* OverwriteExisting= */ false);
> +    break;
> +
> +  case ARM::VFPV4_D16:
> +    setAttributeItem(ARMBuildAttrs::VFP_arch,
> +                     ARMBuildAttrs::AllowFPv4B,
> +                     /* OverwriteExisting= */ false);
> +    break;
> +
> +  case ARM::FP_ARMV8:
> +    setAttributeItem(ARMBuildAttrs::VFP_arch,
> +                     ARMBuildAttrs::AllowFPARMv8A,
> +                     /* OverwriteExisting= */ false);
> +    break;
> +
> +  case ARM::NEON:
> +    setAttributeItem(ARMBuildAttrs::VFP_arch,
> +                     ARMBuildAttrs::AllowFPv3A,
> +                     /* OverwriteExisting= */ false);
> +    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
> +                     ARMBuildAttrs::AllowNeon,
> +                     /* OverwriteExisting= */ false);
> +    break;
> +
> +  case ARM::NEON_VFPV4:
> +    setAttributeItem(ARMBuildAttrs::VFP_arch,
> +                     ARMBuildAttrs::AllowFPv4A,
> +                     /* OverwriteExisting= */ false);
> +    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
> +                     ARMBuildAttrs::AllowNeon2,
> +                     /* OverwriteExisting= */ false);
> +    break;
> +
> +  case ARM::NEON_FP_ARMV8:
> +  case ARM::CRYPTO_NEON_FP_ARMV8:
> +    setAttributeItem(ARMBuildAttrs::VFP_arch,
> +                     ARMBuildAttrs::AllowFPARMv8A,
> +                     /* OverwriteExisting= */ false);
> +    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
> +                     ARMBuildAttrs::AllowNeonARMv8,
> +                     /* OverwriteExisting= */ false);
> +    break;
> +
> +  default:
> +    report_fatal_error("Unknown FPU: " + Twine(FPU));
> +    break;
> +  }
> +}
> +size_t ARMTargetELFStreamer::calculateContentSize() const {
> +  size_t Result = 0;
> +  for (size_t i = 0; i < Contents.size(); ++i) {
> +    AttributeItem item = Contents[i];
> +    switch (item.Type) {
> +    case AttributeItem::HiddenAttribute:
> +      break;
> +    case AttributeItem::NumericAttribute:
> +      Result += getULEBSize(item.Tag);
> +      Result += getULEBSize(item.IntValue);
> +      break;
> +    case AttributeItem::TextAttribute:
> +      Result += getULEBSize(item.Tag);
> +      Result += item.StringValue.size() + 1; // string + '\0'
> +      break;
> +    }
> +  }
> +  return Result;
> +}
> +void ARMTargetELFStreamer::finishAttributeSection() {
> +  // <format-version>
> +  // [ <section-length> "vendor-name"
> +  // [ <file-tag> <size> <attribute>*
> +  //   | <section-tag> <size> <section-number>* 0 <attribute>*
> +  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
> +  //   ]+
> +  // ]*
> +
> +  if (FPU != ARM::INVALID_FPU)
> +    emitFPUDefaultAttributes();
> +
> +  if (Contents.empty())
> +    return;
> +
> +  std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag);
> +
> +  ARMELFStreamer &Streamer = getStreamer();
> +
> +  // Switch to .ARM.attributes section
> +  if (AttributeSection) {
> +    Streamer.SwitchSection(AttributeSection);
> +  } else {
> +    AttributeSection =
> +      Streamer.getContext().getELFSection(".ARM.attributes",
> +                                          ELF::SHT_ARM_ATTRIBUTES,
> +                                          0,
> +                                          SectionKind::getMetadata());
> +    Streamer.SwitchSection(AttributeSection);
> +
> +    // Format version
> +    Streamer.EmitIntValue(0x41, 1);
> +  }
> +
> +  // Vendor size + Vendor name + '\0'
> +  const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
> +
> +  // Tag + Tag Size
> +  const size_t TagHeaderSize = 1 + 4;
> +
> +  const size_t ContentsSize = calculateContentSize();
> +
> +  Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize,
> 4);
> +  Streamer.EmitBytes(CurrentVendor);
> +  Streamer.EmitIntValue(0, 1); // '\0'
> +
> +  Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
> +  Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
> +
> +  // Size should have been accounted for already, now
> +  // emit each field as its type (ULEB or String)
> +  for (size_t i = 0; i < Contents.size(); ++i) {
> +    AttributeItem item = Contents[i];
> +    Streamer.EmitULEB128IntValue(item.Tag);
> +    switch (item.Type) {
> +    default: llvm_unreachable("Invalid attribute type");
> +    case AttributeItem::NumericAttribute:
> +      Streamer.EmitULEB128IntValue(item.IntValue);
> +      break;
> +    case AttributeItem::TextAttribute:
> +      Streamer.EmitBytes(item.StringValue.upper());
> +      Streamer.EmitIntValue(0, 1); // '\0'
> +      break;
> +    }
> +  }
> +
> +  Contents.clear();
> +  FPU = ARM::INVALID_FPU;
> +}
> +
> +void ARMELFStreamer::FinishImpl() {
> +  MCTargetStreamer &TS = getTargetStreamer();
> +  ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
> +  ATS.finishAttributeSection();
> +
> +  MCELFStreamer::FinishImpl();
> +}
> 
>  inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
>                                                unsigned Type,
> 
> Modified: llvm/trunk/test/CodeGen/ARM/2010-09-29-mc-asm-header-test.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2010-
> 09-29-mc-asm-header-test.ll?rev=193524&r1=193523&r2=193524&view=diff
> ==========================================================================
> ====
> --- llvm/trunk/test/CodeGen/ARM/2010-09-29-mc-asm-header-test.ll
> (original)
> +++ llvm/trunk/test/CodeGen/ARM/2010-09-29-mc-asm-header-test.ll Mon Oct
> 28 12:51:12 2013
> @@ -1,3 +1,6 @@
> +; This tests that MC/asm header conversion is smooth and that the
> +; build attributes are correct
> +
>  ; RUN: llc < %s -mtriple=armv6-linux-gnueabi | FileCheck %s --check-
> prefix=V6
>  ; RUN: llc < %s -mtriple=thumbv6m-linux-gnueabi | FileCheck %s --check-
> prefix=V6M
>  ; RUN: llc < %s -mtriple=armv6-linux-gnueabi -mcpu=arm1156t2f-s |
> FileCheck %s --check-prefix=ARM1156T2F-S
> @@ -10,13 +13,12 @@
>  ; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mattr=-crypto | FileCheck
> %s --check-prefix=V8-FPARMv8-NEON
>  ; RUN: llc < %s -mtriple=armv8-linux-gnueabi | FileCheck %s --check-
> prefix=V8-FPARMv8-NEON-CRYPTO
>  ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a9 | FileCheck
> %s --check-prefix=CORTEX-A9
> +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 | FileCheck
> %s --check-prefix=CORTEX-A15
>  ; RUN: llc < %s -mtriple=thumbv6m-linux-gnueabi -mcpu=cortex-m0 |
> FileCheck %s --check-prefix=CORTEX-M0
>  ; RUN: llc < %s -mtriple=thumbv7m-linux-gnueabi -mcpu=cortex-m4 |
> FileCheck %s --check-prefix=CORTEX-M4
>  ; RUN: llc < %s -mtriple=armv7r-linux-gnueabi -mcpu=cortex-r5 | FileCheck
> %s --check-prefix=CORTEX-R5
>  ; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a53 | FileCheck
> %s --check-prefix=CORTEX-A53
>  ; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a57 | FileCheck
> %s --check-prefix=CORTEX-A57
> -; This tests that MC/asm header conversion is smooth and that build
> attributes are correct
> -;
> 
>  ; V6:   .eabi_attribute 6, 6
>  ; V6:   .eabi_attribute 8, 1
> @@ -34,7 +36,6 @@
>  ; ARM1156T2F-S: .eabi_attribute 6, 8
>  ; ARM1156T2F-S: .eabi_attribute 8, 1
>  ; ARM1156T2F-S: .eabi_attribute 9, 2
> -; ARM1156T2F-S: .eabi_attribute 10, 2
>  ; ARM1156T2F-S: .fpu vfpv2
>  ; ARM1156T2F-S: .eabi_attribute 20, 1
>  ; ARM1156T2F-S: .eabi_attribute 21, 1
> @@ -66,7 +67,6 @@
> 
>  ; V8-FPARMv8:      .syntax unified
>  ; V8-FPARMv8: .eabi_attribute 6, 14
> -; V8-FPARMv8: .eabi_attribute 10, 7
>  ; V8-FPARMv8: .fpu fp-armv8
> 
>  ; V8-NEON:      .syntax unified
> @@ -77,13 +77,11 @@
>  ; V8-FPARMv8-NEON:      .syntax unified
>  ; V8-FPARMv8-NEON: .eabi_attribute 6, 14
>  ; V8-FPARMv8-NEON: .fpu neon-fp-armv8
> -; V8-FPARMv8-NEON: .eabi_attribute 10, 7
>  ; V8-FPARMv8-NEON: .eabi_attribute 12, 3
> 
>  ; V8-FPARMv8-NEON-CRYPTO:      .syntax unified
>  ; V8-FPARMv8-NEON-CRYPTO: .eabi_attribute 6, 14
>  ; V8-FPARMv8-NEON-CRYPTO: .fpu crypto-neon-fp-armv8
> -; V8-FPARMv8-NEON-CRYPTO: .eabi_attribute 10, 7
>  ; V8-FPARMv8-NEON-CRYPTO: .eabi_attribute 12, 3
> 
>  ; CORTEX-A9:  .cpu cortex-a9
> @@ -92,14 +90,25 @@
>  ; CORTEX-A9:  .eabi_attribute 8, 1
>  ; CORTEX-A9:  .eabi_attribute 9, 2
>  ; CORTEX-A9:  .fpu neon
> -; CORTEX-A9:  .eabi_attribute 10, 3
> -; CORTEX-A9:  .eabi_attribute 12, 1
>  ; CORTEX-A9:  .eabi_attribute 20, 1
>  ; CORTEX-A9:  .eabi_attribute 21, 1
>  ; CORTEX-A9:  .eabi_attribute 23, 3
>  ; CORTEX-A9:  .eabi_attribute 24, 1
>  ; CORTEX-A9:  .eabi_attribute 25, 1
> 
> +; CORTEX-A15: .cpu cortex-a15
> +; CORTEX-A15: .eabi_attribute 6, 10
> +; CORTEX-A15: .eabi_attribute 7, 65
> +; CORTEX-A15: .eabi_attribute 8, 1
> +; CORTEX-A15: .eabi_attribute 9, 2
> +; CORTEX-A15: .fpu neon-vfpv4
> +; CORTEX-A15: .eabi_attribute 20, 1
> +; CORTEX-A15: .eabi_attribute 21, 1
> +; CORTEX-A15: .eabi_attribute 23, 3
> +; CORTEX-A15: .eabi_attribute 24, 1
> +; CORTEX-A15: .eabi_attribute 25, 1
> +; CORTEX-A15: .eabi_attribute 44, 2
> +
>  ; CORTEX-M0:  .cpu cortex-m0
>  ; CORTEX-M0:  .eabi_attribute 6, 12
>  ; CORTEX-M0:  .eabi_attribute 7, 77
> @@ -113,8 +122,7 @@
>  ; CORTEX-M4:  .eabi_attribute 7, 77
>  ; CORTEX-M4:  .eabi_attribute 8, 0
>  ; CORTEX-M4:  .eabi_attribute 9, 2
> -; CORTEX-M4:  .eabi_attribute 10, 6
> -; CORTEX-M4:  .fpu vfpv4
> +; CORTEX-M4:  .fpu vfpv4-d16
>  ; CORTEX-M4:  .eabi_attribute 20, 1
>  ; CORTEX-M4:  .eabi_attribute 21, 1
>  ; CORTEX-M4:  .eabi_attribute 23, 3
> @@ -127,8 +135,7 @@
>  ; CORTEX-R5:  .eabi_attribute 7, 82
>  ; CORTEX-R5:   .eabi_attribute 8, 1
>  ; CORTEX-R5:  .eabi_attribute 9, 2
> -; CORTEX-R5:  .eabi_attribute 10, 4
> -; CORTEX-R5:  .fpu vfpv3
> +; CORTEX-R5:  .fpu vfpv3-d16
>  ; CORTEX-R5:  .eabi_attribute 20, 1
>  ; CORTEX-R5:  .eabi_attribute 21, 1
>  ; CORTEX-R5:  .eabi_attribute 23, 3
> @@ -142,7 +149,6 @@
>  ; CORTEX-A53:  .eabi_attribute 8, 1
>  ; CORTEX-A53:  .eabi_attribute 9, 2
>  ; CORTEX-A53:  .fpu crypto-neon-fp-armv8
> -; CORTEX-A53:  .eabi_attribute 10, 7
>  ; CORTEX-A53:  .eabi_attribute 12, 3
>  ; CORTEX-A53:  .eabi_attribute 24, 1
>  ; CORTEX-A53:  .eabi_attribute 25, 1
> @@ -154,7 +160,6 @@
>  ; CORTEX-A57:  .eabi_attribute 8, 1
>  ; CORTEX-A57:  .eabi_attribute 9, 2
>  ; CORTEX-A57:  .fpu crypto-neon-fp-armv8
> -; CORTEX-A57:  .eabi_attribute 10, 7
>  ; CORTEX-A57:  .eabi_attribute 12, 3
>  ; CORTEX-A57:  .eabi_attribute 24, 1
>  ; CORTEX-A57:  .eabi_attribute 25, 1
> 
> Modified: llvm/trunk/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2010-
> 10-19-mc-elf-objheader.ll?rev=193524&r1=193523&r2=193524&view=diff
> ==========================================================================
> ====
> --- llvm/trunk/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll Mon Oct 28
> 12:51:12 2013
> @@ -1,13 +1,36 @@
> -; RUN: llc  %s -mtriple=arm-linux-gnueabi -filetype=obj -o - | \
> -; RUN:    llvm-readobj -s -sd | FileCheck  -check-prefix=BASIC %s
> -; RUN: llc  %s -mtriple=armv7-linux-gnueabi -march=arm -mcpu=cortex-a8 \
> -; RUN:    -mattr=-neon,-vfp3,+vfp2 \
> -; RUN:    -arm-reserve-r9 -filetype=obj -o - | \
> -; RUN:    llvm-readobj -s -sd | FileCheck  -check-prefix=CORTEXA8 %s
> +; This tests that the expected ARM attributes are emitted.
> 
> +; RUN: llc < %s -mtriple=arm-linux-gnueabi -filetype=obj -o - \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=BASIC
> +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -march=arm -mcpu=cortex-a8 \
> +; RUN:          -mattr=-neon,-vfp3,+vfp2 -arm-reserve-r9 -filetype=obj -o
> - \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-A8
> +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=V7
> +; RUN: llc < %s -mtriple=armv8-linux-gnueabi -filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=V8
> +; RUN: llc < %s -mtriple=thumbv8-linux-gnueabi -filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=Vt8
> +; RUN: llc < %s -mtriple=armv8-linux-gnueabi \
> +; RUN:          -mattr=-neon,-crypto -filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=V8-FPARMv8
> +; RUN: llc < %s -mtriple=armv8-linux-gnueabi \
> +; RUN:          -mattr=-fp-armv8,-crypto -filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=V8-NEON
> +; RUN: llc < %s -mtriple=armv8-linux-gnueabi \
> +; RUN:          -mattr=-crypto -filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=V8-FPARMv8-
> NEON
> +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a9 -
> filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-A9
> +; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -
> filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-A15
> +; RUN: llc < %s -mtriple=thumbv6m-linux-gnueabi -mcpu=cortex-m0 -
> filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-M0
> +; RUN: llc < %s -mtriple=thumbv7m-linux-gnueabi -mcpu=cortex-m4 -
> filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-M4
> +; RUN: llc < %s -mtriple=armv7r-linux-gnueabi -mcpu=cortex-r5 -
> filetype=obj \
> +; RUN:   | llvm-readobj -s -sd | FileCheck %s --check-prefix=CORTEX-R5
> 
> -; This tests that the extpected ARM attributes are emitted.
> -;
>  ; BASIC:        Section {
>  ; BASIC:          Name: .ARM.attributes
>  ; BASIC-NEXT:     Type: SHT_ARM_ATTRIBUTES
> @@ -25,22 +48,215 @@
>  ; BASIC-NEXT:       0010: 06010801 14011501 17031801 1901
>  ; BASIC-NEXT:     )
> 
> -; CORTEXA8:        Name: .ARM.attributes
> -; CORTEXA8-NEXT:     Type: SHT_ARM_ATTRIBUTES
> -; CORTEXA8-NEXT:     Flags [ (0x0)
> -; CORTEXA8-NEXT:     ]
> -; CORTEXA8-NEXT:     Address: 0x0
> -; CORTEXA8-NEXT:     Offset: 0x3C
> -; CORTEXA8-NEXT:     Size: 47
> -; CORTEXA8-NEXT:     Link: 0
> -; CORTEXA8-NEXT:     Info: 0
> -; CORTEXA8-NEXT:     AddressAlignment: 1
> -; CORTEXA8-NEXT:     EntrySize: 0
> -; CORTEXA8-NEXT:     SectionData (
> -; CORTEXA8-NEXT:       0000: 412E0000 00616561 62690001 24000000
> -; CORTEXA8-NEXT:       0010: 05434F52 5445582D 41380006 0A074108
> -; CORTEXA8-NEXT:       0020: 0109020A 02140115 01170318 011901
> -; CORTEXA8-NEXT:     )
> +; CORTEX-A8:      Name: .ARM.attributes
> +; CORTEX-A8-NEXT: Type: SHT_ARM_ATTRIBUTES
> +; CORTEX-A8-NEXT: Flags [ (0x0)
> +; CORTEX-A8-NEXT: ]
> +; CORTEX-A8-NEXT: Address: 0x0
> +; CORTEX-A8-NEXT: Offset: 0x3C
> +; CORTEX-A8-NEXT: Size: 47
> +; CORTEX-A8-NEXT: Link: 0
> +; CORTEX-A8-NEXT: Info: 0
> +; CORTEX-A8-NEXT: AddressAlignment: 1
> +; CORTEX-A8-NEXT: EntrySize: 0
> +; CORTEX-A8-NEXT: SectionData (
> +; CORTEX-A8-NEXT:   0000: 412E0000 00616561 62690001 24000000
> +; CORTEX-A8-NEXT:   0010: 05434F52 5445582D 41380006 0A074108
> +; CORTEX-A8-NEXT:   0020: 0109020A 02140115 01170318 011901
> +; CORTEX-A8-NEXT: )
> +
> +; V7:      Name: .ARM.attributes
> +; V7-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; V7-NEXT: Flags [ (0x0)
> +; V7-NEXT: ]
> +; V7-NEXT: Address: 0x0
> +; V7-NEXT: Offset: 0x3C
> +; V7-NEXT: Size: 36
> +; V7-NEXT: Link: 0
> +; V7-NEXT: Info: 0
> +; V7-NEXT: AddressAlignment: 1
> +; V7-NEXT: EntrySize: 0
> +; V7-NEXT: SectionData (
> +; V7-NEXT:   0000: 41230000 00616561 62690001 19000000
> +; V7-NEXT:   0010: 060A0801 09020A03 0C011401 15011703
> +; V7-NEXT:   0020: 18011901
> +; V7-NEXT: )
> +
> +; V8:      Name: .ARM.attributes
> +; V8-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; V8-NEXT: Flags [ (0x0)
> +; V8-NEXT: ]
> +; V8-NEXT: Address: 0x0
> +; V8-NEXT: Offset: 0x3C
> +; V8-NEXT: Size: 38
> +; V8-NEXT: Link: 0
> +; V8-NEXT: Info: 0
> +; V8-NEXT: AddressAlignment: 1
> +; V8-NEXT: EntrySize: 0
> +; V8-NEXT: SectionData (
> +; V8-NEXT:   0000: 41250000 00616561 62690001 1B000000
> +; V8-NEXT:   0010: 060E0801 09020A07 0C031401 15011703
> +; V8-NEXT:   0020: 18011901 2C02
> +; V8-NEXT: )
> +
> +; Vt8:      Name: .ARM.attributes
> +; Vt8-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; Vt8-NEXT: Flags [ (0x0)
> +; Vt8-NEXT: ]
> +; Vt8-NEXT: Address: 0x0
> +; Vt8-NEXT: Offset: 0x38
> +; Vt8-NEXT: Size: 38
> +; Vt8-NEXT: Link: 0
> +; Vt8-NEXT: Info: 0
> +; Vt8-NEXT: AddressAlignment: 1
> +; Vt8-NEXT: EntrySize: 0
> +; Vt8-NEXT: SectionData (
> +; Vt8-NEXT:   0000: 41250000 00616561 62690001 1B000000
> +; Vt8-NEXT:   0010: 060E0801 09020A07 0C031401 15011703
> +; Vt8-NEXT:   0020: 18011901 2C02
> +; Vt8-NEXT: )
> +
> +
> +; V8-FPARMv8:      Name: .ARM.attributes
> +; V8-FPARMv8-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; V8-FPARMv8-NEXT: Flags [ (0x0)
> +; V8-FPARMv8-NEXT: ]
> +; V8-FPARMv8-NEXT: Address: 0x0
> +; V8-FPARMv8-NEXT: Offset: 0x3C
> +; V8-FPARMv8-NEXT: Size: 36
> +; V8-FPARMv8-NEXT: Link: 0
> +; V8-FPARMv8-NEXT: Info: 0
> +; V8-FPARMv8-NEXT: AddressAlignment: 1
> +; V8-FPARMv8-NEXT: EntrySize: 0
> +; V8-FPARMv8-NEXT: SectionData (
> +; V8-FPARMv8-NEXT:   0000: 41230000 00616561 62690001 19000000
> +; V8-FPARMv8-NEXT:   0010: 060E0801 09020A07 14011501 17031801
> +; V8-FPARMv8-NEXT:   0020: 19012C02
> +; V8-FPARMv8-NEXT: )
> +
> +
> +; V8-NEON:      Name: .ARM.attributes
> +; V8-NEON-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; V8-NEON-NEXT: Flags [ (0x0)
> +; V8-NEON-NEXT: ]
> +; V8-NEON-NEXT: Address: 0x0
> +; V8-NEON-NEXT: Offset: 0x3C
> +; V8-NEON-NEXT: Size: 38
> +; V8-NEON-NEXT: Link: 0
> +; V8-NEON-NEXT: Info: 0
> +; V8-NEON-NEXT: AddressAlignment: 1
> +; V8-NEON-NEXT: EntrySize: 0
> +; V8-NEON-NEXT: SectionData (
> +; V8-NEON-NEXT:   0000: 41250000 00616561 62690001 1B000000
> +; V8-NEON-NEXT:   0010: 060E0801 09020A05 0C031401 15011703
> +; V8-NEON-NEXT:   0020: 18011901 2C02
> +; V8-NEON-NEXT: )
> +
> +; V8-FPARMv8-NEON:      Name: .ARM.attributes
> +; V8-FPARMv8-NEON-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; V8-FPARMv8-NEON-NEXT: Flags [ (0x0)
> +; V8-FPARMv8-NEON-NEXT: ]
> +; V8-FPARMv8-NEON-NEXT: Address: 0x0
> +; V8-FPARMv8-NEON-NEXT: Offset: 0x3C
> +; V8-FPARMv8-NEON-NEXT: Size: 38
> +; V8-FPARMv8-NEON-NEXT: Link: 0
> +; V8-FPARMv8-NEON-NEXT: Info: 0
> +; V8-FPARMv8-NEON-NEXT: AddressAlignment: 1
> +; V8-FPARMv8-NEON-NEXT: EntrySize: 0
> +; V8-FPARMv8-NEON-NEXT: SectionData (
> +; V8-FPARMv8-NEON-NEXT:   0000: 41250000 00616561 62690001 1B000000
> +; V8-FPARMv8-NEON-NEXT:   0010: 060E0801 09020A07 0C031401 15011703
> +; V8-FPARMv8-NEON-NEXT:   0020: 18011901 2C02
> +; V8-FPARMv8-NEON-NEXT: )
> +
> +; CORTEX-A9:      Name: .ARM.attributes
> +; CORTEX-A9-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; CORTEX-A9-NEXT: Flags [ (0x0)
> +; CORTEX-A9-NEXT: ]
> +; CORTEX-A9-NEXT: Address: 0x0
> +; CORTEX-A9-NEXT: Offset: 0x3C
> +; CORTEX-A9-NEXT: Size: 49
> +; CORTEX-A9-NEXT: Link: 0
> +; CORTEX-A9-NEXT: Info: 0
> +; CORTEX-A9-NEXT: AddressAlignment: 1
> +; CORTEX-A9-NEXT: EntrySize: 0
> +; CORTEX-A9-NEXT: SectionData (
> +; CORTEX-A9-NEXT:   0000: 41300000 00616561 62690001 26000000
> +; CORTEX-A9-NEXT:   0010: 05434F52 5445582D 41390006 0A074108
> +; CORTEX-A9-NEXT:   0020: 0109020A 030C0114 01150117 03180119
> +; CORTEX-A9-NEXT:   0030: 01
> +; CORTEX-A9-NEXT: )
> +
> +; CORTEX-A15:      Name: .ARM.attributes
> +; CORTEX-A15-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; CORTEX-A15-NEXT: Flags [ (0x0)
> +; CORTEX-A15-NEXT: ]
> +; CORTEX-A15-NEXT: Address: 0x0
> +; CORTEX-A15-NEXT: Offset: 0x3C
> +; CORTEX-A15-NEXT: Size: 52
> +; CORTEX-A15-NEXT: Link: 0
> +; CORTEX-A15-NEXT: Info: 0
> +; CORTEX-A15-NEXT: AddressAlignment: 1
> +; CORTEX-A15-NEXT: EntrySize: 0
> +; CORTEX-A15-NEXT: SectionData (
> +; CORTEX-A15-NEXT:   0000: 41330000 00616561 62690001 29000000
> +; CORTEX-A15-NEXT:   0010: 05434F52 5445582D 41313500 060A0741
> +; CORTEX-A15-NEXT:   0020: 08010902 0A050C02 14011501 17031801
> +; CORTEX-A15-NEXT:   0030: 19012C02
> +; CORTEX-A15-NEXT: )
> +
> +; CORTEX-M0:      Name: .ARM.attributes
> +; CORTEX-M0-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; CORTEX-M0-NEXT: Flags [ (0x0)
> +; CORTEX-M0-NEXT: ]
> +; CORTEX-M0-NEXT: Address: 0x0
> +; CORTEX-M0-NEXT: Offset: 0x38
> +; CORTEX-M0-NEXT: Size: 45
> +; CORTEX-M0-NEXT: Link: 0
> +; CORTEX-M0-NEXT: Info: 0
> +; CORTEX-M0-NEXT: AddressAlignment: 1
> +; CORTEX-M0-NEXT: EntrySize: 0
> +; CORTEX-M0-NEXT: SectionData (
> +; CORTEX-M0-NEXT:   0000: 412C0000 00616561 62690001 22000000
> +; CORTEX-M0-NEXT:   0010: 05434F52 5445582D 4D300006 0C074D08
> +; CORTEX-M0-NEXT:   0020: 00090114 01150117 03180119 01
> +; CORTEX-M0-NEXT: )
> +
> +; CORTEX-M4:      Name: .ARM.attributes
> +; CORTEX-M4-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; CORTEX-M4-NEXT: Flags [ (0x0)
> +; CORTEX-M4-NEXT: ]
> +; CORTEX-M4-NEXT: Address: 0x0
> +; CORTEX-M4-NEXT: Offset: 0x38
> +; CORTEX-M4-NEXT: Size: 49
> +; CORTEX-M4-NEXT: Link: 0
> +; CORTEX-M4-NEXT: Info: 0
> +; CORTEX-M4-NEXT: AddressAlignment: 1
> +; CORTEX-M4-NEXT: EntrySize: 0
> +; CORTEX-M4-NEXT: SectionData (
> +; CORTEX-M4-NEXT:   0000: 41300000 00616561 62690001 26000000
> +; CORTEX-M4-NEXT:   0010: 05434F52 5445582D 4D340006 0D074D08
> +; CORTEX-M4-NEXT:   0020: 0009020A 06140115 01170318 0119012C
> +; CORTEX-M4-NEXT:   0030: 00
> +; CORTEX-M4-NEXT: )
> +
> +; CORTEX-R5:      Name: .ARM.attributes
> +; CORTEX-R5-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +; CORTEX-R5-NEXT: Flags [ (0x0)
> +; CORTEX-R5-NEXT: ]
> +; CORTEX-R5-NEXT: Address: 0x0
> +; CORTEX-R5-NEXT: Offset: 0x3C
> +; CORTEX-R5-NEXT: Size: 49
> +; CORTEX-R5-NEXT: Link: 0
> +; CORTEX-R5-NEXT: Info: 0
> +; CORTEX-R5-NEXT: AddressAlignment: 1
> +; CORTEX-R5-NEXT: EntrySize: 0
> +; CORTEX-R5-NEXT: SectionData (
> +; CORTEX-R5-NEXT:   0000: 41300000 00616561 62690001 26000000
> +; CORTEX-R5-NEXT:   0010: 05434F52 5445582D 52350006 0A075208
> +; CORTEX-R5-NEXT:   0020: 0109020A 04140115 01170318 0119012C
> +; CORTEX-R5-NEXT:   0030: 02
> +; CORTEX-R5-NEXT: )
> 
>  define i32 @f(i64 %z) {
>         ret i32 0
> 
> Added: llvm/trunk/test/MC/ARM/directive-cpu.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/directive-
> cpu.s?rev=193524&view=auto
> ==========================================================================
> ====
> --- llvm/trunk/test/MC/ARM/directive-cpu.s (added)
> +++ llvm/trunk/test/MC/ARM/directive-cpu.s Mon Oct 28 12:51:12 2013
> @@ -0,0 +1,26 @@
> +@ RUN: llvm-mc < %s -triple armv7-unknown-linux-gnueabi -filetype=obj -o
> - \
> +@ RUN:   | llvm-readobj -s -sd | FileCheck %s
> +
> +@ CHECK: Name: .ARM.attribute
> +@ CHECK: SectionData (
> +
> +@ <format-version>
> +@ CHECK: 41
> +
> +@ <section-length>
> +@ CHECK: 1A0000 00
> +
> +@ <vendor-name> "aeabi\0"
> +@ CHECK: 616561 626900
> +
> +@ <file-tag>
> +@ CHECK: 01
> +
> +@ <size>
> +@ CHECK: 10000000
> +
> +	.cpu	cortex-a8
> +@ CHECK: 05
> +@ CHECK: 434F52 5445582D 413800
> +
> +@ CHECK: )
> 
> Added: llvm/trunk/test/MC/ARM/directive-eabi_attribute.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/directive-
> eabi_attribute.s?rev=193524&view=auto
> ==========================================================================
> ====
> --- llvm/trunk/test/MC/ARM/directive-eabi_attribute.s (added)
> +++ llvm/trunk/test/MC/ARM/directive-eabi_attribute.s Mon Oct 28 12:51:12
> 2013
> @@ -0,0 +1,56 @@
> +@ RUN: llvm-mc < %s -triple armv7-unknown-linux-gnueabi -filetype=obj -o
> - \
> +@ RUN:   | llvm-readobj -s -sd | FileCheck %s
> +
> +@ CHECK: Name: .ARM.attribute
> +@ CHECK: SectionData (
> +
> +@ <format-version>
> +@ CHECK: 41
> +
> +@ <section-length>
> +@ CHECK: 250000 00
> +
> +@ <vendor-name> "aeabi\0"
> +@ CHECK: 616561 626900
> +
> +@ <file-tag>
> +@ CHECK: 01
> +
> +@ <size>
> +@ CHECK: 1B000000
> +
> +@ <attribute>*
> +
> +	.eabi_attribute 6, 10
> +@ CHECK: 060A
> +
> +	.eabi_attribute 7, 65
> +@ CHECK: 0741
> +
> +	.eabi_attribute 8, 1
> +@ CHECK: 0801
> +
> +	.eabi_attribute 9, 2
> +@ CHECK: 0902
> +
> +	.eabi_attribute 10, 3
> +@ CHECK: 0A03
> +
> +	.eabi_attribute 12, 1
> +@ CHECK: 0C01
> +
> +	.eabi_attribute 20, 1
> +@ CHECK: 1401
> +
> +	.eabi_attribute 21, 1
> +@ CHECK: 1501
> +
> +	.eabi_attribute 23, 3
> +@ CHECK: 1703
> +
> +	.eabi_attribute 24, 1
> +@ CHECK: 1801
> +
> +	.eabi_attribute 25, 1
> +@ CHECK: 1901
> +@ CHECK: )
> 
> Added: llvm/trunk/test/MC/ARM/directive-fpu-multiple.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/directive-
> fpu-multiple.s?rev=193524&view=auto
> ==========================================================================
> ====
> --- llvm/trunk/test/MC/ARM/directive-fpu-multiple.s (added)
> +++ llvm/trunk/test/MC/ARM/directive-fpu-multiple.s Mon Oct 28 12:51:12
> 2013
> @@ -0,0 +1,26 @@
> +@ Check multiple .fpu directives.
> +
> +@ The later .fpu directive should overwrite the earlier one.
> +@ See also: directive-fpu-multiple2.s.
> +
> +@ RUN: llvm-mc < %s -triple arm-unknown-linux-gnueabi -filetype=obj \
> +@ RUN:   | llvm-readobj -s -sd | FileCheck %s
> +
> +	.fpu neon
> +	.fpu vfpv4
> +
> +@ CHECK:      Name: .ARM.attributes
> +@ CHECK-NEXT: Type: SHT_ARM_ATTRIBUTES (0x70000003)
> +@ CHECK-NEXT: Flags [ (0x0)
> +@ CHECK-NEXT: ]
> +@ CHECK-NEXT: Address: 0x0
> +@ CHECK-NEXT: Offset: 0x34
> +@ CHECK-NEXT: Size: 18
> +@ CHECK-NEXT: Link: 0
> +@ CHECK-NEXT: Info: 0
> +@ CHECK-NEXT: AddressAlignment: 1
> +@ CHECK-NEXT: EntrySize: 0
> +@ CHECK-NEXT: SectionData (
> +@ CHECK-NEXT:   0000: 41110000 00616561 62690001 07000000
> +@ CHECK-NEXT:   0010: 0A05
> +@ CHECK-NEXT: )
> 
> Added: llvm/trunk/test/MC/ARM/directive-fpu.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/directive-
> fpu.s?rev=193524&view=auto
> ==========================================================================
> ====
> --- llvm/trunk/test/MC/ARM/directive-fpu.s (added)
> +++ llvm/trunk/test/MC/ARM/directive-fpu.s Mon Oct 28 12:51:12 2013
> @@ -0,0 +1,26 @@
> +@ RUN: llvm-mc < %s -triple armv7-unknown-linux-gnueabi -filetype=obj -o
> - \
> +@ RUN:   | llvm-readobj -s -sd | FileCheck %s
> +
> +@ CHECK: Name: .ARM.attribute
> +@ CHECK: SectionData (
> +
> +@ <format-version>
> +@ CHECK: 41
> +
> +@ <section-length>
> +@ CHECK: 130000 00
> +
> +@ <vendor-name> "aeabi\0"
> +@ CHECK: 616561 626900
> +
> +@ <file-tag>
> +@ CHECK: 01
> +
> +@ <size>
> +@ CHECK: 09000000
> +
> +	.fpu	neon
> +@ CHECK: 0A03
> +@ CHECK: 0C01
> +
> +@ CHECK: )
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list