Mark alias symbols as microMIPS if necessary. Differential Revision: http://llvm...
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Thu, 20 Mar 2014 09:44:49 +0000 (09:44 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Thu, 20 Mar 2014 09:44:49 +0000 (09:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204323 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCELFStreamer.h
include/llvm/MC/MCStreamer.h
lib/MC/MCAsmStreamer.cpp
lib/MC/MCELFStreamer.cpp
lib/MC/MCObjectStreamer.cpp
lib/MC/MCStreamer.cpp
lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
lib/Target/Mips/MipsTargetStreamer.h
test/MC/Mips/micromips-alias.s [new file with mode: 0644]

index 23cc2e36a1a0c08cff06e36c61c9d5a062a4cc2e..ebd5d57651180beae465c9dbc6da05d215bbff4c 100644 (file)
@@ -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;
 
index 37d18fbe43a6121d09e3838d5762a167009e9555..37d586b8f18b485c3726c47b91f91c88fe63b944 100644 (file)
@@ -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.
   ///
index e28c56e7d31263f95938d4809f04ebe072438062..759058efcba700b4655e21796685964f36dabb45 100644 (file)
@@ -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) {
index d07ef9e698ec1f4cf44ee7a97d247be89015e66a..f710c3e1ea7811164c0d78a8521f6855ffa5c964 100644 (file)
@@ -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);
 }
 
index 6b2234eeb3769b505c1e89dc8d963b481cb90b0a..809cb11e36d2d771423d24af02ffe5330b605dc4 100644 (file)
@@ -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) {
index ec3b5f9be41e29b05da48f362610df4e9bd037c5..6638fdeb486601c44821d54dbfb60471dd233119 100644 (file)
@@ -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<MCSymbolData*>(0));
 }
+
+void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
+  Symbol->setVariableValue(Value);
+
+  MCTargetStreamer *TS = getTargetStreamer();
+  if (TS)
+    TS->emitAssignment(Symbol, Value);
+}
index e9ce4b8bf25a281508892fe018390894a2627f54..f31743a2eae3028272cb51b1511ffbfcdcd8de6c 100644 (file)
@@ -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<const MCSymbolRefExpr *>(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<MCELFStreamer &>(Streamer);
 }
index 7917b77ced1ece05769df897bbfaa466c62de767..5550e7d56020b3ed7c2f9cb8463283e5a897eba5 100644 (file)
@@ -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 (file)
index 0000000..c0bf4b3
--- /dev/null
@@ -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