diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 30 |
2 files changed, 43 insertions, 0 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 759058efcba..85d4dd79b30 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -57,6 +57,8 @@ private: EHPrivateExtern = 1 << 2 }; DenseMap<const MCSymbol*, unsigned> FlagMap; + DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; + bool needsSet(const MCExpr *Value); void EmitRegisterName(int64_t Register); @@ -252,6 +254,8 @@ public: void EmitRawTextImpl(StringRef String) override; void FinishImpl() override; + + virtual MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) override; }; } // end anonymous namespace. @@ -1417,6 +1421,15 @@ void MCAsmStreamer::FinishImpl() { EmitFrames(AsmBackend.get(), false); } +MCSymbolData &MCAsmStreamer::getOrCreateSymbolData(const MCSymbol *Symbol) { + MCSymbolData *&Entry = SymbolMap[Symbol]; + + if (!Entry) + Entry = new MCSymbolData(*Symbol, 0, 0, 0); + + return *Entry; +} + MCStreamer *llvm::createAsmStreamer(MCContext &Context, formatted_raw_ostream &OS, bool isVerboseAsm, bool useCFI, diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index ccb1c641efe..1a153522796 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -25,7 +25,9 @@ #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCELF.h" #include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrDesc.h" @@ -8085,6 +8087,7 @@ bool ARMAsmParser::parseDirectiveThumb(SMLoc L) { if (!isThumb()) SwitchMode(); + getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); return false; } @@ -8105,6 +8108,7 @@ bool ARMAsmParser::parseDirectiveARM(SMLoc L) { if (isThumb()) SwitchMode(); + getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); return false; } @@ -8113,6 +8117,32 @@ void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) { if (NextSymbolIsThumb) { getParser().getStreamer().EmitThumbFunc(Symbol); NextSymbolIsThumb = false; + return; + } + + if (!isThumb()) + return; + + const MCObjectFileInfo::Environment Format = + getContext().getObjectFileInfo()->getObjectFileType(); + switch (Format) { + case MCObjectFileInfo::IsCOFF: { + const MCSymbolData &SD = + getParser().getStreamer().getOrCreateSymbolData(Symbol); + char Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT; + if (SD.getFlags() & (Type << COFF::SF_TypeShift)) + getParser().getStreamer().EmitThumbFunc(Symbol); + break; + } + case MCObjectFileInfo::IsELF: { + const MCSymbolData &SD = + getParser().getStreamer().getOrCreateSymbolData(Symbol); + if (MCELF::GetType(SD) & (ELF::STT_FUNC << ELF_STT_Shift)) + getParser().getStreamer().EmitThumbFunc(Symbol); + break; + } + case MCObjectFileInfo::IsMachO: + break; } } |