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

Kristof Beyls kristof.beyls at arm.com
Mon Dec 16 00:27:46 PST 2013


I agree that support for parsing (and printing?) named eabi_attributes
should be implemented. AFAIK, no-one is currently actively working on
this.

I would have thought the implementation would be pretty straightforward.
I imagine the only contentious issue would be whether the 
ARMTargetAsmStreamer should start printing the symbolic names instead of
the integer values. If the gnu assembler already supports the symbolic
eabi_attributes for a number of releases, I think the ARMTargetAsmStreamer
should print the symbolic names, as it is much easier to understand e.g. 
what "Tag_ABI_align_needed" means rather than what "24" means in this
context.

Kristof

> -----Original Message-----
> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-
> bounces at cs.uiuc.edu] On Behalf Of David Peixotto
> Sent: 19 November 2013 22:31
> To: 'Logan Chien'; llvm-commits at cs.uiuc.edu
> Subject: RE: [llvm] r193524 - [arm] Implement eabi_attribute, cpu, and fpu
> directives.
> 
> 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
> 
> _______________________________________________
> 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