diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-01-30 04:46:41 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-01-30 04:46:41 +0000 |
commit | 09f38a0ef13bf542f7b3f1862d718e33e7de587b (patch) | |
tree | c82a746a55e2173bda6e65335d953fcaf7d13eab /lib | |
parent | 459c9497772f7d4e8567233a99f126198ec93b68 (diff) | |
download | llvm-09f38a0ef13bf542f7b3f1862d718e33e7de587b.tar.gz llvm-09f38a0ef13bf542f7b3f1862d718e33e7de587b.tar.bz2 llvm-09f38a0ef13bf542f7b3f1862d718e33e7de587b.tar.xz |
ARM IAS: support .object_arch
The .object_arch directive indicates an alternative architecture to be specified
in the object file. The directive does *not* effect the enabled feature bits
for the object file generation. This is particularly useful when the code
performs runtime detection and would like to indicate a lower architecture as
the requirements than the actual instructions used.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200451 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 42 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 20 |
2 files changed, 59 insertions, 3 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 531e2cc906..74e4e66c6e 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -298,6 +298,7 @@ class ARMAsmParser : public MCTargetAsmParser { bool parseDirectiveUnwindRaw(SMLoc L); bool parseDirectiveTLSDescSeq(SMLoc L); bool parseDirectiveMovSP(SMLoc L); + bool parseDirectiveObjectArch(SMLoc L); StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, bool &CarrySetting, unsigned &ProcessorIMod, @@ -8090,6 +8091,8 @@ bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { return parseDirectiveTLSDescSeq(DirectiveID.getLoc()); else if (IDVal == ".movsp") return parseDirectiveMovSP(DirectiveID.getLoc()); + else if (IDVal == ".object_arch") + return parseDirectiveObjectArch(DirectiveID.getLoc()); return true; } @@ -9094,6 +9097,45 @@ bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) { return false; } +/// parseDirectiveObjectArch +/// ::= .object_arch name +bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) { + if (getLexer().isNot(AsmToken::Identifier)) { + Error(getLexer().getLoc(), "unexpected token"); + Parser.eatToEndOfStatement(); + return false; + } + + StringRef Arch = Parser.getTok().getString(); + SMLoc ArchLoc = Parser.getTok().getLoc(); + getLexer().Lex(); + + unsigned ID = StringSwitch<unsigned>(Arch) +#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \ + .Case(NAME, ARM::ID) +#define ARM_ARCH_ALIAS(NAME, ID) \ + .Case(NAME, ARM::ID) +#include "MCTargetDesc/ARMArchName.def" +#undef ARM_ARCH_NAME +#undef ARM_ARCH_ALIAS + .Default(ARM::INVALID_ARCH); + + if (ID == ARM::INVALID_ARCH) { + Error(ArchLoc, "unknown architecture '" + Arch + "'"); + Parser.eatToEndOfStatement(); + return false; + } + + getTargetStreamer().emitObjectArch(ID); + + if (getLexer().isNot(AsmToken::EndOfStatement)) { + Error(getLexer().getLoc(), "unexpected token"); + Parser.eatToEndOfStatement(); + } + + return false; +} + /// Force static initialization. extern "C" void LLVMInitializeARMAsmParser() { RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 151d48df63..44b56fbe19 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -136,6 +136,7 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer { virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StrinValue); virtual void emitArch(unsigned Arch); + virtual void emitObjectArch(unsigned Arch); virtual void emitFPU(unsigned FPU); virtual void emitInst(uint32_t Inst, char Suffix = '\0'); virtual void finishAttributeSection(); @@ -249,6 +250,9 @@ void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute, void ARMTargetAsmStreamer::emitArch(unsigned Arch) { OS << "\t.arch\t" << GetArchName(Arch) << "\n"; } +void ARMTargetAsmStreamer::emitObjectArch(unsigned Arch) { + OS << "\t.object_arch\t" << GetArchName(Arch) << '\n'; +} void ARMTargetAsmStreamer::emitFPU(unsigned FPU) { OS << "\t.fpu\t" << GetFPUName(FPU) << "\n"; } @@ -300,6 +304,7 @@ private: StringRef CurrentVendor; unsigned FPU; unsigned Arch; + unsigned EmittedArch; SmallVector<AttributeItem, 64> Contents; const MCSection *AttributeSection; @@ -411,6 +416,7 @@ private: virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue); virtual void emitArch(unsigned Arch); + virtual void emitObjectArch(unsigned Arch); virtual void emitFPU(unsigned FPU); virtual void emitInst(uint32_t Inst, char Suffix = '\0'); virtual void finishAttributeSection(); @@ -421,8 +427,9 @@ private: public: ARMTargetELFStreamer(MCStreamer &S) - : ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU), - Arch(ARM::INVALID_ARCH), AttributeSection(0) {} + : ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU), + Arch(ARM::INVALID_ARCH), EmittedArch(ARM::INVALID_ARCH), + AttributeSection(0) {} }; /// Extend the generic ELFStreamer class so that it can emit mapping symbols at @@ -714,10 +721,17 @@ void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, void ARMTargetELFStreamer::emitArch(unsigned Value) { Arch = Value; } +void ARMTargetELFStreamer::emitObjectArch(unsigned Value) { + EmittedArch = Value; +} void ARMTargetELFStreamer::emitArchDefaultAttributes() { using namespace ARMBuildAttrs; + setAttributeItem(CPU_name, GetArchDefaultCPUName(Arch), false); - setAttributeItem(CPU_arch, GetArchDefaultCPUArch(Arch), false); + if (EmittedArch == ARM::INVALID_ARCH) + setAttributeItem(CPU_arch, GetArchDefaultCPUArch(Arch), false); + else + setAttributeItem(CPU_arch, GetArchDefaultCPUArch(EmittedArch), false); switch (Arch) { case ARM::ARMV2: |