summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp13
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp30
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;
}
}
OpenPOWER on IntegriCloud