| Index: lib/Target/ARM/ARMAsmPrinter.cpp
|
| ===================================================================
|
| --- lib/Target/ARM/ARMAsmPrinter.cpp (revision 116749)
|
| +++ lib/Target/ARM/ARMAsmPrinter.cpp (working copy)
|
| @@ -38,6 +38,7 @@
|
| #include "llvm/MC/MCSectionMachO.h"
|
| #include "llvm/MC/MCStreamer.h"
|
| #include "llvm/MC/MCSymbol.h"
|
| +#include "llvm/MC/MCAssembler.h"
|
| #include "llvm/Target/Mangler.h"
|
| #include "llvm/Target/TargetData.h"
|
| #include "llvm/Target/TargetMachine.h"
|
| @@ -48,6 +49,7 @@
|
| #include "llvm/ADT/StringExtras.h"
|
| #include "llvm/Support/CommandLine.h"
|
| #include "llvm/Support/Debug.h"
|
| +#include "llvm/Support/ELF.h"
|
| #include "llvm/Support/ErrorHandling.h"
|
| #include "llvm/Support/raw_ostream.h"
|
| #include <cctype>
|
| @@ -79,7 +81,9 @@
|
|
|
| public:
|
| explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
|
| - : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) {
|
| + : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL),
|
| + headFragment(NULL), currFileFragment(NULL),
|
| + currSectionFragment(NULL), currSymbolFragment(NULL) {
|
| Subtarget = &TM.getSubtarget<ARMSubtarget>();
|
| }
|
|
|
| @@ -108,14 +112,33 @@
|
| void EmitEndOfAsmFile(Module &M);
|
|
|
| private:
|
| +
|
| // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
|
| + // Helper for ELF .s/.o only
|
| void emitAttributes();
|
| void emitTextAttribute(ARMBuildAttrs::SpecialAttr attr, StringRef v);
|
| void emitAttribute(ARMBuildAttrs::AttrType attr, int v);
|
|
|
| - // Helper for ELF .o only
|
| void emitARMAttributeSection();
|
|
|
| + // Slots for keeping state for above member funcs.
|
| + MCDataFragment *headFragment;
|
| +
|
| + // Fixme: do we ever need more than one of each?
|
| + MCDataFragment *currFileFragment,
|
| + *currSectionFragment, *currSymbolFragment;
|
| +
|
| + // Section-global offset counters
|
| + int currOffset;
|
| + int attrDataStartOffset;
|
| +
|
| + // Helper routine for the emit*() functions above
|
| + MCDataFragment *addAttrSubsec(MCSectionData *AttrSecData,
|
| + ARMBuildAttrs::AttrType attr,
|
| + int SecOrSym=0);
|
| +
|
| + int fixupAttrSizes();
|
| + int fixupAttrSize(MCDataFragment *F, int secLenOffset, int lenAdjust);
|
| public:
|
| void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
|
|
|
| @@ -530,6 +553,14 @@
|
| emitAttribute(ARMBuildAttrs::ABI_VFP_args, 1);
|
| }
|
| // FIXME: Should we signal R9 usage?
|
| +
|
| + // FIXME: This is just a freebie set by GNU/ARM as for ELF/.o only.
|
| + // LLVM never emitted this explicitly for .s
|
| + if (!OutStreamer.hasRawTextSupport()) {
|
| + emitAttribute(ARMBuildAttrs::DIV_use, 1);
|
| + }
|
| +
|
| + (void) fixupAttrSizes();
|
| }
|
|
|
| void ARMAsmPrinter::emitARMAttributeSection() {
|
| @@ -549,16 +580,52 @@
|
| (getObjFileLowering());
|
|
|
| OutStreamer.SwitchSection(TLOFELF.getAttributesSection());
|
| - // Fixme: Still more to do here.
|
| +
|
| + MCObjectStreamer *ELFStreamer = static_cast<MCObjectStreamer*>(&OutStreamer);
|
| + MCAssembler *Asm = &ELFStreamer->getAssembler();
|
| +
|
| + bool newSec = false;
|
| + MCSectionData *AttrSecData =
|
| + &(Asm->getOrCreateSectionData(*TLOFELF.getAttributesSection(), &newSec));
|
| +
|
| + headFragment = new MCDataFragment(AttrSecData);
|
| + SmallString<32> *FC = &headFragment->getContents();
|
| +
|
| + (*FC) += ((char)ARMBuildAttrs::Format_Version);
|
| +
|
| + FC->append(sizeof(ELF::Elf32_Word), 0);
|
| +
|
| + FC->append(ARMBuildAttrs::Vendor_Name,
|
| + ARMBuildAttrs::Vendor_Name_End);
|
| +
|
| + currFileFragment =
|
| + addAttrSubsec(AttrSecData, ARMBuildAttrs::File);
|
| }
|
|
|
| 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");
|
| + switch (attr) {
|
| + // These all go into the File subsection
|
| + case ARMBuildAttrs::VFP_arch:
|
| + case ARMBuildAttrs::ABI_FP_denormal:
|
| + case ARMBuildAttrs::ABI_FP_exceptions:
|
| + case ARMBuildAttrs::ABI_FP_number_model:
|
| + case ARMBuildAttrs::ABI_align8_needed:
|
| + case ARMBuildAttrs::ABI_align8_preserved:
|
| + case ARMBuildAttrs::ABI_HardFP_use:
|
| + case ARMBuildAttrs::ABI_VFP_args:
|
| + case ARMBuildAttrs::DIV_use: {
|
| + assert(currFileFragment && "No File subsection found");
|
| + SmallString<32> *FC = &currFileFragment->getContents();
|
| + (*FC) += static_cast<char>(attr);
|
| + (*FC) += static_cast<char>(0xFF & v);
|
| + }; break;
|
| + default: assert(0 && "Unsupported ARMBuildAttrs::AttrType"); break;
|
| + }
|
| }
|
| }
|
|
|
| @@ -572,11 +639,75 @@
|
| OutStreamer.EmitRawText("\t.cpu " + val);
|
| }
|
| } else {
|
| - // FIXME: ELF
|
| + // .o
|
| + if (val == "generic") {
|
| + assert(currFileFragment && "No File subsection found");
|
| + SmallString<32> *FC = &currFileFragment->getContents();
|
| + (*FC) += static_cast<char>(ARMBuildAttrs::CPU_arch);
|
| + (*FC) += static_cast<char>(ARMBuildAttrs::v4T);
|
| +
|
| + (*FC) += static_cast<char>(ARMBuildAttrs::ARM_ISA_use);
|
| + (*FC) += static_cast<char>(1);
|
| +
|
| + (*FC) += static_cast<char>(ARMBuildAttrs::THUMB_ISA_use);
|
| + (*FC) += static_cast<char>(1);
|
| + } else {
|
| + assert(0 && "unsupported .cpu attribute for ELF/.o");
|
| + }
|
| }
|
| }
|
| }
|
|
|
| +MCDataFragment *ARMAsmPrinter::addAttrSubsec(MCSectionData *AttrSecData,
|
| + ARMBuildAttrs::AttrType attr,
|
| + int SecOrSym) {
|
| + MCDataFragment *rtn = new MCDataFragment(AttrSecData);
|
| + SmallString<32> *FC = &rtn->getContents();
|
| +
|
| + (*FC) += static_cast<char>(ARMBuildAttrs::File);
|
| + FC->append(sizeof(ELF::Elf32_Word), 0);
|
| +
|
| + switch (attr) {
|
| + case ARMBuildAttrs::File: break;
|
| + case ARMBuildAttrs::Section:
|
| + case ARMBuildAttrs::Symbol: {
|
| + (*FC) += (0xFF & SecOrSym);
|
| + (*FC) += (0xFF & (SecOrSym >> 8));
|
| + (*FC) += (0xFF & (SecOrSym >> 16));
|
| + (*FC) += (0xFF & (SecOrSym >> 24));
|
| +
|
| + (*FC) += 0;
|
| + } break;
|
| + default: assert(0 && "Unknown .ARM.attributes subsection"); break;
|
| + }
|
| +
|
| + return rtn;
|
| +}
|
| +
|
| +int ARMAsmPrinter::fixupAttrSizes() {
|
| + int SFileAttr = fixupAttrSize(currFileFragment, 1, 0);
|
| + int SSecAttr = fixupAttrSize(currSectionFragment, 1, 0);
|
| + int SSymAttr = fixupAttrSize(currSymbolFragment, 1, 0);
|
| + int Shead = fixupAttrSize(headFragment, 1,
|
| + (SFileAttr + SSecAttr + SSymAttr - 1));
|
| + return Shead;
|
| +}
|
| +
|
| +int ARMAsmPrinter::fixupAttrSize(MCDataFragment *F,
|
| + int secLenOffset, int lenAdjust) {
|
| + if (F) {
|
| + SmallString<32> *FC = &F->getContents();
|
| +
|
| + int S = (int)(FC->size() + lenAdjust);
|
| + (*FC)[secLenOffset+0] = 0xFF & S;
|
| + (*FC)[secLenOffset+1] = 0xFF & (S>>8);
|
| + (*FC)[secLenOffset+2] = 0xFF & (S>>16);
|
| + (*FC)[secLenOffset+3] = 0xFF & (S>>24);
|
| + return S + lenAdjust;
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| //===----------------------------------------------------------------------===//
|
|
|
| static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
|
|
|