diff options
| author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-03-17 17:13:54 +0000 |
|---|---|---|
| committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-03-17 17:13:54 +0000 |
| commit | 11543a9953111cd29623653d5f9ca5749f05b8d6 (patch) | |
| tree | ccd76e775f53a933c0aa6310f7530cdd402406c7 /llvm/lib/Target/ARM | |
| parent | 24381f1cb74d230d029e4804f8eaf46b7ff5deb2 (diff) | |
| download | bcm5719-llvm-11543a9953111cd29623653d5f9ca5749f05b8d6.tar.gz bcm5719-llvm-11543a9953111cd29623653d5f9ca5749f05b8d6.zip | |
ARM IAS: support .thumb_set
This performs the equivalent of a .set directive in that it creates a symbol
which is an alias for another symbol or value which may possibly be yet
undefined. This directive also has the added property in that it marks the
aliased symbol as being a thumb function entry point, in the same way that the
.thumb_func directive does.
The current implementation fails one test due to an unrelated issue. Functions
within .thumb sections are not marked as thumb_func. The result is that
the aliasee function is not valued correctly.
llvm-svn: 204059
Diffstat (limited to 'llvm/lib/Target/ARM')
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index b361bb70fa6..403e147a6ab 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -30,6 +30,7 @@ #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" @@ -41,6 +42,7 @@ #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/Support/ARMBuildAttributes.h" #include "llvm/Support/ARMEHABI.h" +#include "llvm/Support/COFF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" #include "llvm/Support/MathExtras.h" @@ -229,6 +231,7 @@ class ARMAsmParser : public MCTargetAsmParser { bool parseDirectiveObjectArch(SMLoc L); bool parseDirectiveArchExtension(SMLoc L); bool parseDirectiveAlign(SMLoc L); + bool parseDirectiveThumbSet(SMLoc L); StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, bool &CarrySetting, unsigned &ProcessorIMod, @@ -8030,6 +8033,8 @@ bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { return parseDirectiveArchExtension(DirectiveID.getLoc()); else if (IDVal == ".align") return parseDirectiveAlign(DirectiveID.getLoc()); + else if (IDVal == ".thumb_set") + return parseDirectiveThumbSet(DirectiveID.getLoc()); return true; } @@ -9086,6 +9091,71 @@ bool ARMAsmParser::parseDirectiveAlign(SMLoc L) { return false; } +/// parseDirectiveThumbSet +/// ::= .thumb_set name, value +bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) { + StringRef Name; + if (Parser.parseIdentifier(Name)) { + TokError("expected identifier after '.thumb_set'"); + Parser.eatToEndOfStatement(); + return false; + } + + if (getLexer().isNot(AsmToken::Comma)) { + TokError("expected comma after name '" + Name + "'"); + Parser.eatToEndOfStatement(); + return false; + } + Lex(); + + const MCExpr *Value; + if (Parser.parseExpression(Value)) { + TokError("missing expression"); + Parser.eatToEndOfStatement(); + return false; + } + + if (getLexer().isNot(AsmToken::EndOfStatement)) { + TokError("unexpected token"); + Parser.eatToEndOfStatement(); + return false; + } + Lex(); + + MCSymbol *Alias = getContext().GetOrCreateSymbol(Name); + if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) { + MCSymbol *Sym = getContext().LookupSymbol(SRE->getSymbol().getName()); + if (!Sym->isDefined()) { + getStreamer().EmitSymbolAttribute(Sym, MCSA_Global); + getStreamer().EmitAssignment(Alias, Value); + return false; + } + + const MCObjectFileInfo::Environment Format = + getContext().getObjectFileInfo()->getObjectFileType(); + switch (Format) { + case MCObjectFileInfo::IsCOFF: { + char Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT; + getStreamer().EmitCOFFSymbolType(Type); + // .set values are always local in COFF + getStreamer().EmitSymbolAttribute(Alias, MCSA_Local); + break; + } + case MCObjectFileInfo::IsELF: + getStreamer().EmitSymbolAttribute(Alias, MCSA_ELF_TypeFunction); + break; + case MCObjectFileInfo::IsMachO: + break; + } + } + + // FIXME: set the function as being a thumb function via the assembler + getStreamer().EmitThumbFunc(Alias); + getStreamer().EmitAssignment(Alias, Value); + + return false; +} + /// Force static initialization. extern "C" void LLVMInitializeARMAsmParser() { RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); |

