diff options
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 13 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 30 | ||||
-rw-r--r-- | test/MC/ARM/thumb-types.s | 82 | ||||
-rw-r--r-- | test/MC/ARM/thumb_set.s | 3 |
4 files changed, 126 insertions, 2 deletions
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 759058efcb..85d4dd79b3 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/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/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index ccb1c641ef..1a15352279 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/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; } } diff --git a/test/MC/ARM/thumb-types.s b/test/MC/ARM/thumb-types.s new file mode 100644 index 0000000000..2fd71525ba --- /dev/null +++ b/test/MC/ARM/thumb-types.s @@ -0,0 +1,82 @@ +@ RUN: llvm-mc -triple armv7-elf -filetype obj -o - %s | llvm-readobj -t \ +@ RUN: | FileCheck %s + + .syntax unified + + .thumb + + .type implicit_function,%function +implicit_function: + nop + + .type implicit_data,%object +implicit_data: + .long 0 + + .arm + .type arm_function,%function +arm_function: + nop + + .thumb + + .text + +untyped_text_label: + nop + + .type explicit_function,%function +explicit_function: + nop + + .data + +untyped_data_label: + nop + + .type explicit_data,%object +explicit_data: + .long 0 + +@ CHECK: Symbol { +@ CHECK: Name: arm_function +@ CHECK: Value: 0x6 +@ CHECK: Type: Function +@ CHECK: } + +@ CHECK: Symbol { +@ CHECK: Name: explicit_data +@ CHECK: Value: 0x2 +@ CHECK: Type: Object +@ CHECK: } + +@ CHECK: Symbol { +@ CHECK: Name: explicit_function +@ CHECK: Value: 0xD +@ CHECK: Type: Function +@ CHECK: } + +@ CHECK: Symbol { +@ CHECK: Name: implicit_data +@ CHECK: Value: 0x2 +@ CHECK: Type: Object +@ CHECK: } + +@ CHECK: Symbol { +@ CHECK: Name: implicit_function +@ CHECK: Value: 0x1 +@ CHECK: Type: Function +@ CHECK: } + +@ CHECK: Symbol { +@ CHECK: Name: untyped_data_label +@ CHECK: Value: 0x0 +@ CHECK: Type: None +@ CHECK: } + +@ CHECK: Symbol { +@ CHECK: Name: untyped_text_label +@ CHECK: Value: 0xA +@ CHECK: Type: None +@ CHECK: } + diff --git a/test/MC/ARM/thumb_set.s b/test/MC/ARM/thumb_set.s index 7381a98134..d0bc9858dd 100644 --- a/test/MC/ARM/thumb_set.s +++ b/test/MC/ARM/thumb_set.s @@ -79,8 +79,7 @@ beta: @ CHECK: Symbol { @ CHECK: Name: alpha -@ CHECK: Value: 0x6 -@ XFAIL-CHECK: Value: 0x7 +@ CHECK: Value: 0x7 @ CHECK: Type: Function @ CHECK: } |