From b71fd20f2d38e7e1a6f41bdc575196dd23ab716b Mon Sep 17 00:00:00 2001 From: Zoran Jovanovic Date: Thu, 20 Mar 2014 09:44:49 +0000 Subject: [PATCH] Mark alias symbols as microMIPS if necessary. Differential Revision: http://llvm-reviews.chandlerc.com/D3080 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204323 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCELFStreamer.h | 2 +- include/llvm/MC/MCStreamer.h | 6 ++++-- lib/MC/MCAsmStreamer.cpp | 3 +-- lib/MC/MCELFStreamer.cpp | 2 +- lib/MC/MCObjectStreamer.cpp | 3 ++- lib/MC/MCStreamer.cpp | 12 ++++++++++- .../Mips/MCTargetDesc/MipsTargetStreamer.cpp | 20 +++++++++++++++++++ lib/Target/Mips/MipsTargetStreamer.h | 1 + test/MC/Mips/micromips-alias.s | 16 +++++++++++++++ 9 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 test/MC/Mips/micromips-alias.s diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 23cc2e36a1a..ebd5d576511 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -61,7 +61,7 @@ public: void EmitCOFFSymbolType(int Type) override; void EndCOFFSymbolDef() override; - MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol) override; + MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) override; void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 37d18fbe43a..37d586b8f18 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -79,6 +79,8 @@ public: // Allow a target to add behavior to the EmitLabel of MCStreamer. virtual void emitLabel(MCSymbol *Symbol); + // Allow a target to add behavior to the emitAssignment of MCStreamer. + virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value); virtual void finish(); }; @@ -395,7 +397,7 @@ public: virtual void EmitThumbFunc(MCSymbol *Func) = 0; /// getOrCreateSymbolData - Get symbol data for given symbol. - virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol); + virtual MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol); /// EmitAssignment - Emit an assignment of @p Value to @p Symbol. /// @@ -408,7 +410,7 @@ public: /// /// @param Symbol - The symbol being assigned to. /// @param Value - The value for the symbol. - virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) = 0; + virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); /// EmitWeakReference - Emit an weak reference from @p Alias to @p Symbol. /// diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index e28c56e7d31..759058efcba 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -408,8 +408,7 @@ void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { OS << *Symbol << " = " << *Value; EmitEOL(); - // FIXME: Lift context changes into super class. - Symbol->setVariableValue(Value); + MCStreamer::EmitAssignment(Symbol, Value); } void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index d07ef9e698e..f710c3e1ea7 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -559,7 +559,7 @@ void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { llvm_unreachable("Generic ELF doesn't support this directive"); } -MCSymbolData &MCELFStreamer::getOrCreateSymbolData(MCSymbol *Symbol) { +MCSymbolData &MCELFStreamer::getOrCreateSymbolData(const MCSymbol *Symbol) { return getAssembler().getOrCreateSymbolData(*Symbol); } diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index 6b2234eeb37..809cb11e36d 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -184,7 +184,8 @@ void MCObjectStreamer::ChangeSection(const MCSection *Section, void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { getAssembler().getOrCreateSymbolData(*Symbol); - Symbol->setVariableValue(AddValueSymbols(Value)); + AddValueSymbols(Value); + MCStreamer::EmitAssignment(Symbol, Value); } void MCObjectStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index ec3b5f9be41..6638fdeb486 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -34,6 +34,8 @@ void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {} void MCTargetStreamer::finish() {} +void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {} + MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false), CurrentW64UnwindInfo(0), LastSymbol(0) { @@ -627,7 +629,15 @@ void MCStreamer::Finish() { FinishImpl(); } -MCSymbolData &MCStreamer::getOrCreateSymbolData(MCSymbol *Symbol) { +MCSymbolData &MCStreamer::getOrCreateSymbolData(const MCSymbol *Symbol) { report_fatal_error("Not supported!"); return *(static_cast(0)); } + +void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { + Symbol->setVariableValue(Value); + + MCTargetStreamer *TS = getTargetStreamer(); + if (TS) + TS->emitAssignment(Symbol, Value); +} diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index e9ce4b8bf25..f31743a2eae 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -219,6 +219,26 @@ void MipsTargetELFStreamer::finish() { } } +void MipsTargetELFStreamer::emitAssignment(MCSymbol *Symbol, + const MCExpr *Value) { + // If on rhs is micromips symbol then mark Symbol as microMips. + if (Value->getKind() != MCExpr::SymbolRef) + return; + const MCSymbol &RhsSym = + static_cast(Value)->getSymbol(); + MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym); + uint8_t Type = MCELF::GetType(Data); + if ((Type != ELF::STT_FUNC) + || !(MCELF::getOther(Data) & (ELF::STO_MIPS_MICROMIPS >> 2))) + return; + + MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol); + // The "other" values are stored in the last 6 bits of the second byte. + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + MCELF::setOther(SymbolData, ELF::STO_MIPS_MICROMIPS >> 2); +} + MCELFStreamer &MipsTargetELFStreamer::getStreamer() { return static_cast(Streamer); } diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h index 7917b77ced1..5550e7d5602 100644 --- a/lib/Target/Mips/MipsTargetStreamer.h +++ b/lib/Target/Mips/MipsTargetStreamer.h @@ -86,6 +86,7 @@ public: MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); virtual void emitLabel(MCSymbol *Symbol) override; + virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void finish() override; virtual void emitDirectiveSetMicroMips(); diff --git a/test/MC/Mips/micromips-alias.s b/test/MC/Mips/micromips-alias.s new file mode 100644 index 00000000000..c0bf4b3a8e3 --- /dev/null +++ b/test/MC/Mips/micromips-alias.s @@ -0,0 +1,16 @@ +# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 %s -o - \ +# RUN: | llvm-readobj -t | FileCheck %s + +# Symbol bar must be marked as micromips. +# CHECK: Name: bar +# CHECK: Other: 128 + .align 2 + .type f,@function + .set nomips16 + .set micromips +f: + nop + .set nomicromips + nop + .globl bar +bar = f -- 2.34.1