diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-10-25 17:50:35 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-10-25 17:50:35 +0000 |
commit | 0ed1543d4ea758a040288eeba7e72f1dcffea45a (patch) | |
tree | 6701090fefa727b8ac7265d865dcfa0b1d5fb3ac /llvm/lib/Target/ARM | |
parent | e5d0677173aa041f09b0d963eaf7c9ce10c4bc8d (diff) | |
download | bcm5719-llvm-0ed1543d4ea758a040288eeba7e72f1dcffea45a.tar.gz bcm5719-llvm-0ed1543d4ea758a040288eeba7e72f1dcffea45a.zip |
Add support for emitting ARM file attributes.
llvm-svn: 117275
Diffstat (limited to 'llvm/lib/Target/ARM')
-rw-r--r-- | llvm/lib/Target/ARM/ARMAsmBackend.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 160 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMBuildAttrs.h | 25 |
3 files changed, 147 insertions, 41 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/ARMAsmBackend.cpp index 72f6e2b4ce7..4be02424752 100644 --- a/llvm/lib/Target/ARM/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/ARMAsmBackend.cpp @@ -55,12 +55,11 @@ void ARMAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const { } bool ARMAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const { - assert(0 && "ARMAsmBackend::WriteNopData() unimplemented"); if ((Count % 4) != 0) { // Fixme: % 2 for Thumb? return false; } - return false; + return true; } } // end anonymous namespace diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index dab549110dd..7790484c58d 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -32,10 +32,12 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSectionMachO.h" +#include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Target/Mangler.h" @@ -63,6 +65,91 @@ 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 Finish() = 0; + }; + + 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 Finish() { } + }; + + class ObjectAttributeEmitter : public AttributeEmitter { + MCObjectStreamer &Streamer; + size_t SectionStart; + size_t TagStart; + StringRef CurrentVendor; + SmallString<64> Contents; + + public: + ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : + Streamer(Streamer_), CurrentVendor("") { } + + 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; + + SectionStart = Contents.size(); + + // Length of the data for this vendor. + Contents.append(4, (char)0); + + Contents.append(Vendor.begin(), Vendor.end()); + Contents += 0; + + Contents += ARMBuildAttrs::File; + + TagStart = Contents.size(); + + // Length of the data for this tag. + Contents.append(4, (char)0); + } + + void EmitAttribute(unsigned Attribute, unsigned Value) { + // FIXME: should be ULEB + Contents += Attribute; + Contents += Value; + } + + void Finish() { + size_t EndPos = Contents.size(); + + // FIXME: endian. + *((uint32_t*)&Contents[SectionStart]) = EndPos - SectionStart; + + // +1 since it includes the tag that came before it. + *((uint32_t*)&Contents[TagStart]) = EndPos - TagStart + 1; + + Streamer.EmitBytes(Contents, 0); + } + }; + class ARMAsmPrinter : public AsmPrinter { /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can @@ -110,8 +197,6 @@ namespace { private: // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile() void emitAttributes(); - void emitTextAttribute(ARMBuildAttrs::SpecialAttr attr, StringRef v); - void emitAttribute(ARMBuildAttrs::AttrType attr, int v); // Helper for ELF .o only void emitARMAttributeSection(); @@ -502,34 +587,58 @@ void ARMAsmPrinter::emitAttributes() { emitARMAttributeSection(); + AttributeEmitter *AttrEmitter; + if (OutStreamer.hasRawTextSupport()) + AttrEmitter = new AsmAttributeEmitter(OutStreamer); + else { + MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer); + AttrEmitter = new ObjectAttributeEmitter(O); + } + + AttrEmitter->MaybeSwitchVendor("aeabi"); + std::string CPUString = Subtarget->getCPUString(); - emitTextAttribute(ARMBuildAttrs::SEL_CPU, CPUString); + if (OutStreamer.hasRawTextSupport()) { + if (CPUString != "generic") + OutStreamer.EmitRawText(StringRef("\t.cpu ") + CPUString); + } else { + assert(CPUString == "generic" && "Unsupported .cpu attribute for ELF/.o"); + // FIXME: Why these defaults? + AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T); + AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 1); + AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 1); + } // FIXME: Emit FPU type if (Subtarget->hasVFP2()) - emitAttribute(ARMBuildAttrs::VFP_arch, 2); + AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 2); // Signal various FP modes. if (!UnsafeFPMath) { - emitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1); - emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1); + AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1); + AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1); } if (NoInfsFPMath && NoNaNsFPMath) - emitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1); + AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1); else - emitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3); + AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3); // 8-bytes alignment stuff. - emitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); - emitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); + AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); + AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); // Hard float. Use both S and D registers and conform to AAPCS-VFP. if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { - emitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); - emitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); + AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); + AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); } // FIXME: Should we signal R9 usage? + + AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1); + + AttrEmitter->Finish(); + delete AttrEmitter; } void ARMAsmPrinter::emitARMAttributeSection() { @@ -549,32 +658,9 @@ void ARMAsmPrinter::emitARMAttributeSection() { (getObjFileLowering()); OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); - // Fixme: Still more to do here. -} -void ARMAsmPrinter::emitAttribute(ARMBuildAttrs::AttrType attr, int v) { - if (OutStreamer.hasRawTextSupport()) { - OutStreamer.EmitRawText("\t.eabi_attribute " + - Twine(attr) + ", " + Twine(v)); - - } else { - assert(0 && "ELF .ARM.attributes unimplemented"); - } -} - -void ARMAsmPrinter::emitTextAttribute(ARMBuildAttrs::SpecialAttr attr, - StringRef val) { - switch (attr) { - default: assert(0 && "Unimplemented ARMBuildAttrs::SpecialAttr"); break; - case ARMBuildAttrs::SEL_CPU: - if (OutStreamer.hasRawTextSupport()) { - if (val != "generic") { - OutStreamer.EmitRawText("\t.cpu " + val); - } - } else { - // FIXME: ELF - } - } + // Format version + OutStreamer.EmitIntValue(0x41, 1); } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/ARM/ARMBuildAttrs.h b/llvm/lib/Target/ARM/ARMBuildAttrs.h index 8c54298ceb4..c0444982d47 100644 --- a/llvm/lib/Target/ARM/ARMBuildAttrs.h +++ b/llvm/lib/Target/ARM/ARMBuildAttrs.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file contains enumerations and support routines for ARM build attributes -// as defined in ARM ABI addenda document (ABI release 2.07). +// as defined in ARM ABI addenda document (ABI release 2.08). // //===----------------------------------------------------------------------===// @@ -59,18 +59,39 @@ namespace ARMBuildAttrs { CPU_unaligned_access = 34, VFP_HP_extension = 36, ABI_FP_16bit_format = 38, + MPextension_use = 42, // was 70, 2.08 ABI + DIV_use = 44, nodefaults = 64, also_compatible_with = 65, T2EE_use = 66, conformance = 67, Virtualization_use = 68, - MPextension_use = 70 + MPextension_use_old = 70 }; // Magic numbers for .ARM.attributes enum AttrMagic { Format_Version = 0x41 }; + + // Legal Values for CPU_arch, (=6), uleb128 + enum CPUArch { + Pre_v4 = 0, + v4 = 1, // e.g. SA110 + v4T = 2, // e.g. ARM7TDMI + v5T = 3, // e.g. ARM9TDMI + v5TE = 4, // e.g. ARM946E_S + v5TEJ = 5, // e.g. ARM926EJ_S + v6 = 6, // e.g. ARM1136J_S + v6KZ = 7, // e.g. ARM1176JZ_S + v6T2 = 8, // e.g. ARM1156T2F_S + v6K = 9, // e.g. ARM1136J_S + v7 = 10, // e.g. Cortex A8, Cortex M3 + v6_M = 11, // e.g. Cortex M1 + v6S_M = 12, // v6_M with the System extensions + v7E_M = 13 // v7_M with DSP extensions + }; + } #endif // __TARGET_ARMBUILDATTRS_H__ |