Thanks !<span></span><br><br>On Monday, October 28, 2013, Logan Chien  wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: logan<br>
Date: Mon Oct 28 12:51:12 2013<br>
New Revision: 193524<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=193524&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=193524&view=rev</a><br>
Log:<br>
[arm] Implement eabi_attribute, cpu, and fpu directives.<br>
<br>
This commit allows the ARM integrated assembler to parse<br>
and assemble the code with .eabi_attribute, .cpu, and<br>
.fpu directives.<br>
<br>
To implement the feature, this commit moves the code from<br>
AttrEmitter to ARMTargetStreamers, and several new test<br>
cases related to cortex-m4, cortex-r5, and cortex-a15 are<br>
added.<br>
<br>
Besides, this commit also change the Subtarget->isFPOnlySP()<br>
to Subtarget->hasD16() to match the usage of .fpu directive.<br>
<br>
This commit changes the test cases:<br>
<br>
* Several .eabi_attribute directives in<br>
  2010-09-29-mc-asm-header-test.ll are removed because the .fpu<br>
  directive already cover the functionality.<br>
<br>
* In the Cortex-A15 test case, the value for<br>
  Tag_Advanced_SIMD_arch has be changed from 1 to 2,<br>
  which is more precise.<br>
<br>
<br>
Added:<br>
    llvm/trunk/lib/Target/ARM/ARMFPUName.def<br>
    llvm/trunk/lib/Target/ARM/ARMFPUName.h<br>
    llvm/trunk/test/MC/ARM/directive-cpu.s<br>
    llvm/trunk/test/MC/ARM/directive-eabi_attribute.s<br>
    llvm/trunk/test/MC/ARM/directive-fpu-multiple.s<br>
    llvm/trunk/test/MC/ARM/directive-fpu.s<br>
Modified:<br>
    llvm/trunk/include/llvm/MC/MCStreamer.h<br>
    llvm/trunk/lib/Target/ARM/ARM.td<br>
    llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp<br>
    llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h<br>
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp<br>
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp<br>
    llvm/trunk/test/CodeGen/ARM/2010-09-29-mc-asm-header-test.ll<br>
    llvm/trunk/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCStreamer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=193524&r1=193523&r2=193524&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=193524&r1=193523&r2=193524&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Mon Oct 28 12:51:12 2013<br>
@@ -87,6 +87,12 @@ public:<br>
   virtual void emitPad(int64_t Offset) = 0;<br>
   virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,<br>
                            bool isVector) = 0;<br>
+<br>
+  virtual void switchVendor(StringRef Vendor) = 0;<br>
+  virtual void emitAttribute(unsigned Attribute, unsigned Value) = 0;<br>
+  virtual void emitTextAttribute(unsigned Attribute, StringRef String) = 0;<br>
+  virtual void emitFPU(unsigned FPU) = 0;<br>
+  virtual void finishAttributeSection() = 0;<br>
 };<br>
<br>
 /// MCStreamer - Streaming machine code generation interface.  This interface<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARM.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.td?rev=193524&r1=193523&r2=193524&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARM.td?rev=193524&r1=193523&r2=193524&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARM.td (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARM.td Mon Oct 28 12:51:12 2013<br>
@@ -309,7 +309,7 @@ def : ProcessorModel<"cortex-r5",   Cort<br>
                                     [ProcR5, HasV7Ops, FeatureDB,<br>
                                      FeatureVFP3, FeatureDSPThumb2,<br>
                                      FeatureHasRAS, FeatureVFPOnlySP,<br>
-                                     FeatureRClass]>;<br>
+                                     FeatureD16, FeatureRClass]>;<br>
<br>
 // V7M Processors.<br>
 def : ProcNoItin<"cortex-m3",       [HasV7Ops,<br>
@@ -321,7 +321,8 @@ def : ProcNoItin<"cortex-m4",       [Has<br>
                                      FeatureThumb2, FeatureNoARM, FeatureDB,<br>
                                      FeatureHWDiv, FeatureDSPThumb2,<br>
                                      FeatureT2XtPk, FeatureVFP4,<br>
-                                     FeatureVFPOnlySP, FeatureMClass]>;<br>
+                                     FeatureVFPOnlySP, FeatureD16,<br>
+                                     FeatureMClass]>;<br>
<br>
 // Swift uArch Processors.<br>
 def : ProcessorModel<"swift",       SwiftModel,<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=193524&r1=193523&r2=193524&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=193524&r1=193523&r2=193524&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Mon Oct 28 12:51:12 2013<br>
@@ -17,6 +17,7 @@<br>
 #include "ARM.h"<br>
 #include "ARMBuildAttrs.h"<br>
 #include "ARMConstantPoolValue.h"<br>
+#include "ARMFPUName.h"<br>
 #include "ARMMachineFunctionInfo.h"<br>
 #include "ARMTargetMachine.h"<br>
 #include "ARMTargetObjectFile.h"<br>
@@ -55,164 +56,6 @@<br>
 #include <cctype><br>
 using namespace llvm;<br>
<br>
-namespace {<br>
-<br>
-  // Per section and per symbol attributes are not supported.<br>
-  // To implement them we would need the ability to delay this emission<br>
-  // until the assembly file is fully parsed/generated as only then do we<br>
-  // know the symbol and section numbers.<br>
-  class AttributeEmitter {<br>
-  public:<br>
-    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;<br>
-    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;<br>
-    virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0;<br>
-    virtual void Finish() = 0;<br>
-    virtual ~AttributeEmitter() {}<br>
-  };<br>
-<br>
-  class AsmAttributeEmitter : public AttributeEmitter {<br>
-    MCStreamer &Streamer;<br>
-<br>
-  public:<br>
-    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}<br>
-    void MaybeSwitchVendor(StringRef Vendor) { }<br>
-<br>
-    void EmitAttribute(unsigned Attribute, unsigned Value) {<br>
-      Streamer.EmitRawText("\t.eabi_attribute " +<br>
-                           Twine(Attribute) + ", " + Twine(Value));<br>
-    }<br>
-<br>
-    void EmitTextAttribute(unsigned Attribute, StringRef String) {<br>
-      switch (Attribute) {<br>
-      default: llvm_unreachable("Unsupported Text attribute in ASM Mode");<br>
-      case ARMBuildAttrs::CPU_name:<br>
-        Streamer.EmitRawText(StringRef("\t.cpu ") + String.lower());<br>
-        break;<br>
-      /* GAS requires .fpu to be emitted regardless of EABI attribute */<br>
-      case ARMBuildAttrs::Advanced_SIMD_arch:<br>
-      case ARMBuildAttrs::VFP_arch:<br>
-        Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower());<br>
-        break;<br>
-      }<br>
-    }<br>
-    void Finish() { }<br>
-  };<br>
-<br>
-  class ObjectAttributeEmitter : public AttributeEmitter {<br>
-    // This structure holds all attributes, accounting for<br>
-    // their string/numeric value, so we can later emmit them<br>
-    // in declaration order, keeping all in the same vector<br>
-    struct AttributeItemType {<br>
-      enum {<br>
-        HiddenAttribute = 0,<br>
-        NumericAttribute,<br>
-        TextAttribute<br>
-      } Type;<br>
-      unsigned Tag;<br>
-      unsigned IntValue;<br>
-      StringRef StringValue;<br>
-    };<br>
-<br>
-    MCObjectStreamer &Streamer;<br>
-    StringRef CurrentVendor;<br>
-    SmallVector<AttributeItemType, 64> Contents;<br>
-<br>
-    // Account for the ULEB/String size of each item,<br>
-    // not just the number of items<br>
-    size_t ContentsSize;<br>
-    // FIXME: this should be in a more generic place, but<br>
-    // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf<br>
-    size_t getULEBSize(int Value) {<br>
-      size_t Size = 0;<br>
-      do {<br>
-        Value >>= 7;<br>
-        Size += sizeof(int8_t); // Is this really necessary?<br>
-      } while (Value);<br>
-      return Size;<br>
-    }<br>
-<br>
-  public:<br>
-    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :<br>
-      Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { }<br>
-<br>
-    void MaybeSwitchVendor(StringRef Vendor) {<br>
-      assert(!Vendor.empty() && "Vendor cannot be empty.");<br>
-<br>
-      if (CurrentVendor.empty())<br>
-        CurrentVendor = Vendor;<br>
-      else if (CurrentVendor == Vendor)<br>
-        return;<br>
-      else<br>
-        Finish();<br>
-<br>
-      CurrentVendor = Vendor;<br>
-<br>
-      assert(Contents.size() == 0);<br>
-    }<br>
-<br>
-    void EmitAttribute(unsigned Attribute, unsigned Value) {<br>
-      AttributeItemType attr = {<br>
-        AttributeItemType::NumericAttribute,<br>
-        Attribute,<br>
-        Value,<br>
-        StringRef("")<br>
-      };<br>
-      ContentsSize += getULEBSize(Attribute);<br>
-      ContentsSize += getULEBSize(Value);<br>
-      Contents.push_back(attr);<br>
-    }<br>
-<br>
-    void EmitTextAttribute(unsigned Attribute, StringRef String) {<br>
-      AttributeItemType attr = {<br>
-        AttributeItemType::TextAttribute,<br>
-        Attribute,<br>
-        0,<br>
-        String<br>
-      };<br>
-      ContentsSize += getULEBSize(Attribute);<br>
-      // String + \0<br>
-      ContentsSize += String.size()+1;<br>
-<br>
-      Contents.push_back(attr);<br>
-    }<br>
-<br>
-    void Finish() {<br>
-      // Vendor size + Vendor name + '\0'<br>
-      const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;<br>
-<br>
-      // Tag + Tag Size<br>
-      const size_t TagHeaderSize = 1 + 4;<br>
-<br>
-      Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);<br>
-      Streamer.EmitBytes(CurrentVendor);<br>
-      Streamer.EmitIntValue(0, 1); // '\0'<br>
-<br>
-      Streamer.EmitIntValue(ARMBuildAttrs::File, 1);<br>
-      Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);<br>
-<br>
-      // Size should have been accounted for already, now<br>
-      // emit each field as its type (ULEB or String)<br>
-      for (unsigned int i=0; i<Contents.size(); ++i) {<br>
-        AttributeItemType item = Contents[i];<br>
-        Streamer.EmitULEB128IntValue(item.Tag);<br>
-        switch (item.Type) {<br>
-        default: llvm_unreachable("Invalid attribute type");<br>
-        case AttributeItemType::NumericAttribute:<br>
-          Streamer.EmitULEB128IntValue(item.IntValue);<br>
-          break;<br>
-        case AttributeItemType::TextAttribute:<br>
-          Streamer.EmitBytes(item.StringValue.upper());<br>
-          Streamer.EmitIntValue(0, 1); // '\0'<br>
-          break;<br>
-        }<br>
-      }<br>
-<br>
-      Contents.clear();<br>
-    }<br>
-  };<br>
-<br>
-} // end of anonymous namespace<br>
-<br>
 /// EmitDwarfRegOp - Emit dwarf register operation.<br>
 void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,<br>
                                    bool Indirect) const {<br>
@@ -768,149 +611,102 @@ static ARMBuildAttrs::CPUArch getArchFor<br>
 }<br>
<br>
 void ARMAsmPrinter::emitAttributes() {<br>
+  MCTargetStreamer &TS = OutStreamer.getTargetStreamer();<br>
+  ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);<br>
<br>
-  emitARMAttributeSection();<br>
-<br>
-  /* GAS expect .fpu to be emitted, regardless of VFP build attribute */<br>
-  bool emitFPU = false;<br>
-  AttributeEmitter *AttrEmitter;<br>
-  if (OutStreamer.hasRawTextSupport()) {<br>
-    AttrEmitter = new AsmAttributeEmitter(OutStreamer);<br>
-    emitFPU = true;<br>
-  } else {<br>
-    MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer);<br>
-    AttrEmitter = new ObjectAttributeEmitter(O);<br>
-  }<br>
-<br>
-  AttrEmitter->MaybeSwitchVendor("aeabi");<br>
+  ATS.switchVendor("aeabi");<br>
<br>
   std::string CPUString = Subtarget->getCPUString();<br>
<br>
   if (CPUString != "generic")<br>
-    AttrEmitter->EmitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);<br>
+    ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);<br>
<br>
-  AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch,<br>
-                             getArchForCPU(CPUString, Subtarget));<br>
+  ATS.emitAttribute(ARMBuildAttrs::CPU_arch,<br>
+                    getArchForCPU(CPUString, Subtarget));<br>
<br>
   if (Subtarget->isAClass()) {<br>
-    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,<br>
-                               ARMBuildAttrs::ApplicationProfile);<br>
+    ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,<br>
+                      ARMBuildAttrs::ApplicationProfile);<br>
   } else if (Subtarget->isRClass()) {<br>
-    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,<br>
-                               ARMBuildAttrs::RealTimeProfile);<br>
+    ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,<br>
+                      ARMBuildAttrs::RealTimeProfile);<br>
   } else if (Subtarget->isMClass()){<br>
-    AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch_profile,<br>
-                               ARMBuildAttrs::MicroControllerProfile);<br>
+    ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,<br>
+                      ARMBuildAttrs::MicroControllerProfile);<br>
   }<br>
<br>
-  AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, Subtarget->hasARMOps() ?<br>
-                           ARMBuildAttrs::Allowed : ARMBuildAttrs::Not_Allowed);<br>
+  ATS.emitAttribute(ARMBuildAttrs::ARM_ISA_use, Subtarget->hasARMOps() ?<br>
+                      ARMBuildAttrs::Allowed : ARMBuildAttrs::Not_Allowed);<br>
   if (Subtarget->isThumb1Only()) {<br>
-    AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use,<br>
-                               ARMBuildAttrs::Allowed);<br>
+    ATS.emitAttribute(ARMBuildAttrs::</blockquote>