Keep the MCSubtargetInfo in the MCRelxableFragment class.

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
This commit is contained in:
David Woodhouse 2014-01-28 23:12:53 +00:00
parent d5d381b762
commit 41c8ba9d61
3 changed files with 15 additions and 4 deletions

View File

@ -17,6 +17,7 @@
#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ilist_node.h"
#include "llvm/MC/MCFixup.h" #include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h" #include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include <algorithm> #include <algorithm>
@ -33,6 +34,7 @@ class MCFragment;
class MCObjectWriter; class MCObjectWriter;
class MCSection; class MCSection;
class MCSectionData; class MCSectionData;
class MCSubtargetInfo;
class MCSymbol; class MCSymbol;
class MCSymbolData; class MCSymbolData;
class MCValue; class MCValue;
@ -288,6 +290,11 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
/// Inst - The instruction this is a fragment for. /// Inst - The instruction this is a fragment for.
MCInst Inst; 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. /// Contents - Binary data for the currently encoded instruction.
SmallVector<char, 8> Contents; SmallVector<char, 8> Contents;
@ -295,8 +302,10 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
SmallVector<MCFixup, 1> Fixups; SmallVector<MCFixup, 1> Fixups;
public: public:
MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0) MCRelaxableFragment(const MCInst &_Inst,
: MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) { const MCSubtargetInfo &_STI,
MCSectionData *SD = 0)
: MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) {
} }
virtual SmallVectorImpl<char> &getContents() { return Contents; } virtual SmallVectorImpl<char> &getContents() { return Contents; }
@ -305,6 +314,8 @@ public:
const MCInst &getInst() const { return Inst; } const MCInst &getInst() const { return Inst; }
void setInst(const MCInst& Value) { Inst = Value; } void setInst(const MCInst& Value) { Inst = Value; }
const MCSubtargetInfo &getSubtargetInfo() { return STI; }
SmallVectorImpl<MCFixup> &getFixups() { SmallVectorImpl<MCFixup> &getFixups() {
return Fixups; return Fixups;
} }

View File

@ -230,7 +230,7 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
const MCSubtargetInfo &STI) { const MCSubtargetInfo &STI) {
// Always create a new, separate fragment here, because its size can change // Always create a new, separate fragment here, because its size can change
// during relaxation. // during relaxation.
MCRelaxableFragment *IF = new MCRelaxableFragment(Inst); MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
insert(IF); insert(IF);
SmallString<128> Code; SmallString<128> Code;

View File

@ -181,7 +181,7 @@ bool MCPureStreamer::EmitValueToOffset(const MCExpr *Offset,
void MCPureStreamer::EmitInstToFragment(const MCInst &Inst, void MCPureStreamer::EmitInstToFragment(const MCInst &Inst,
const MCSubtargetInfo &STI) { const MCSubtargetInfo &STI) {
MCRelaxableFragment *IF = new MCRelaxableFragment(Inst); MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
insert(IF); insert(IF);
// Add the fixups and data. // Add the fixups and data.