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>