[llvm-commits] [llvm] r117275 - in /llvm/trunk: include/llvm/Support/ELF.h lib/MC/ELFObjectWriter.cpp lib/Target/ARM/ARMAsmBackend.cpp lib/Target/ARM/ARMAsmPrinter.cpp lib/Target/ARM/ARMBuildAttrs.h test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll
Rafael Espíndola
rafael.espindola at gmail.com
Mon Oct 25 10:58:14 PDT 2010
Patch by Jason, refactoring into a class by me.
On 25 October 2010 13:50, Rafael Espindola <rafael.espindola at gmail.com> wrote:
> Author: rafael
> Date: Mon Oct 25 12:50:35 2010
> New Revision: 117275
>
> URL: http://llvm.org/viewvc/llvm-project?rev=117275&view=rev
> Log:
> Add support for emitting ARM file attributes.
>
> Added:
> llvm/trunk/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll
> Modified:
> llvm/trunk/include/llvm/Support/ELF.h
> llvm/trunk/lib/MC/ELFObjectWriter.cpp
> llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp
> llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
> llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h
>
> Modified: llvm/trunk/include/llvm/Support/ELF.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ELF.h?rev=117275&r1=117274&r2=117275&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/ELF.h (original)
> +++ llvm/trunk/include/llvm/Support/ELF.h Mon Oct 25 12:50:35 2010
> @@ -299,6 +299,16 @@
> SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
> SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
> SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type.
> + // Fixme: All this is duplicated in MCSectionELF. Why??
> + // Exception Index table
> + SHT_ARM_EXIDX = 0x70000001U,
> + // BPABI DLL dynamic linking pre-emption map
> + SHT_ARM_PREEMPTMAP = 0x70000002U,
> + // Object file compatibility attributes
> + SHT_ARM_ATTRIBUTES = 0x70000003U,
> + SHT_ARM_DEBUGOVERLAY = 0x70000004U,
> + SHT_ARM_OVERLAYSECTION = 0x70000005U,
> +
> SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type.
> SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
> SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
>
> Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=117275&r1=117274&r2=117275&view=diff
> ==============================================================================
> --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
> +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Mon Oct 25 12:50:35 2010
> @@ -1200,12 +1200,10 @@
> case ELF::SHT_STRTAB:
> case ELF::SHT_NOBITS:
> case ELF::SHT_NULL:
> + case ELF::SHT_ARM_ATTRIBUTES:
> // Nothing to do.
> break;
>
> - case ELF::SHT_HASH:
> - case ELF::SHT_GROUP:
> - case ELF::SHT_SYMTAB_SHNDX:
> default:
> assert(0 && "FIXME: sh_type value not supported!");
> break;
>
> Modified: llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp?rev=117275&r1=117274&r2=117275&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMAsmBackend.cpp Mon Oct 25 12:50:35 2010
> @@ -55,12 +55,11 @@
> }
>
> 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
>
>
> Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=117275&r1=117274&r2=117275&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Mon Oct 25 12:50:35 2010
> @@ -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 {
> +
> + // 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 @@
> 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 @@
>
> 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 @@
> (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);
> }
>
> //===----------------------------------------------------------------------===//
>
> Modified: llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h?rev=117275&r1=117274&r2=117275&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMBuildAttrs.h Mon Oct 25 12:50:35 2010
> @@ -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 @@
> 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__
>
> Added: 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=117275&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll (added)
> +++ llvm/trunk/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll Mon Oct 25 12:50:35 2010
> @@ -0,0 +1,19 @@
> +; RUN: llc %s -mtriple=arm-linux-gnueabi -filetype=obj -o - | \
> +; RUN: elf-dump --dump-section-data | FileCheck %s
> +; This tests that the extpected ARM attributes are emitted.
> +;
> +; CHECK: .ARM.attributes
> +; CHECK-NEXT: 0x70000003
> +; CHECK-NEXT: 0x00000000
> +; CHECK-NEXT: 0x00000000
> +; CHECK-NEXT: 0x0000003c
> +; CHECK-NEXT: 0x00000022
> +; CHECK-NEXT: 0x00000000
> +; CHECK-NEXT: 0x00000000
> +; CHECK-NEXT: 0x00000001
> +; CHECK-NEXT: 0x00000000
> +; CHECK-NEXT: '41210000 00616561 62690001 17000000 06020801 09011401 15011703 18011901 2c01'
> +
> +define i32 @f(i64 %z) {
> + ret i32 0
> +}
>
>
> _______________________________________________
> 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