Keep the MCSubtargetInfo in the MCRelxableFragment class.
authorDavid Woodhouse <dwmw2@infradead.org>
Tue, 28 Jan 2014 23:12:53 +0000 (23:12 +0000)
committerDavid Woodhouse <dwmw2@infradead.org>
Tue, 28 Jan 2014 23:12:53 +0000 (23:12 +0000)
Needed to fix PR18303 to correctly re-encode the instruction if it
is relaxed.

We keep a copy of the MCSubtargetInfo to make sure that we are not
effected by future changes to the subtarget info coming from the
assembler (e.g. when parsing .code 16 directived).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200347 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCAssembler.h
lib/MC/MCObjectStreamer.cpp
lib/MC/MCPureStreamer.cpp

index 8735a55ce044e59cf5963065e41e5ef46c50fd64..e1cf66d3f9ec84023209f32383649ce461aa2464 100644 (file)
@@ -17,6 +17,7 @@
 #include "llvm/ADT/ilist_node.h"
 #include "llvm/MC/MCFixup.h"
 #include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/DataTypes.h"
 #include <algorithm>
@@ -33,6 +34,7 @@ class MCFragment;
 class MCObjectWriter;
 class MCSection;
 class MCSectionData;
+class MCSubtargetInfo;
 class MCSymbol;
 class MCSymbolData;
 class MCValue;
@@ -288,6 +290,11 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
   /// Inst - The instruction this is a fragment for.
   MCInst Inst;
 
+  /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
+  /// Keep a copy instead of a reference to make sure that updates to STI
+  /// in the assembler are not seen here.
+  const MCSubtargetInfo STI;
+
   /// Contents - Binary data for the currently encoded instruction.
   SmallVector<char, 8> Contents;
 
@@ -295,8 +302,10 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
   SmallVector<MCFixup, 1> Fixups;
 
 public:
-  MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
-    : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {
+  MCRelaxableFragment(const MCInst &_Inst,
+                      const MCSubtargetInfo &_STI,
+                      MCSectionData *SD = 0)
+    : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) {
   }
 
   virtual SmallVectorImpl<char> &getContents() { return Contents; }
@@ -305,6 +314,8 @@ public:
   const MCInst &getInst() const { return Inst; }
   void setInst(const MCInst& Value) { Inst = Value; }
 
+  const MCSubtargetInfo &getSubtargetInfo() { return STI; }
+
   SmallVectorImpl<MCFixup> &getFixups() {
     return Fixups;
   }
index d46f9d6f903201cfaac2e70abf16fa1252f7b82d..689c4230aac14bc7e8802a2e3af87f6c89a521aa 100644 (file)
@@ -230,7 +230,7 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
                                           const MCSubtargetInfo &STI) {
   // Always create a new, separate fragment here, because its size can change
   // during relaxation.
-  MCRelaxableFragment *IF = new MCRelaxableFragment(Inst);
+  MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
   insert(IF);
 
   SmallString<128> Code;
index 6d93596676b9e39f46551b7b1b6abb8aa50a23a9..26d0765e15d997ed225b5b1dd1d48fd31296f736 100644 (file)
@@ -181,7 +181,7 @@ bool MCPureStreamer::EmitValueToOffset(const MCExpr *Offset,
 
 void MCPureStreamer::EmitInstToFragment(const MCInst &Inst,
                                         const MCSubtargetInfo &STI) {
-  MCRelaxableFragment *IF = new MCRelaxableFragment(Inst);
+  MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
   insert(IF);
 
   // Add the fixups and data.