mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-17 04:24:00 +00:00
Add support for expressions in .sleb/.uleb directives.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118023 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -50,7 +50,8 @@ public:
|
|||||||
FT_Fill,
|
FT_Fill,
|
||||||
FT_Inst,
|
FT_Inst,
|
||||||
FT_Org,
|
FT_Org,
|
||||||
FT_Dwarf
|
FT_Dwarf,
|
||||||
|
FT_LEB
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -338,6 +339,40 @@ public:
|
|||||||
static bool classof(const MCOrgFragment *) { return true; }
|
static bool classof(const MCOrgFragment *) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MCLEBFragment : public MCFragment {
|
||||||
|
/// Value - The value this fragment should contain.
|
||||||
|
const MCExpr *Value;
|
||||||
|
|
||||||
|
/// IsSigned - True if this is a sleb128, false if uleb128.
|
||||||
|
bool IsSigned;
|
||||||
|
|
||||||
|
/// Size - The current size estimate.
|
||||||
|
uint64_t Size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
|
||||||
|
: MCFragment(FT_LEB, SD),
|
||||||
|
Value(&Value_), IsSigned(IsSigned_), Size(1) {}
|
||||||
|
|
||||||
|
/// @name Accessors
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
const MCExpr &getValue() const { return *Value; }
|
||||||
|
|
||||||
|
bool isSigned() const { return IsSigned; }
|
||||||
|
|
||||||
|
uint64_t getSize() const { return Size; }
|
||||||
|
|
||||||
|
void setSize(uint64_t Size_) { Size = Size_; }
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
static bool classof(const MCFragment *F) {
|
||||||
|
return F->getKind() == MCFragment::FT_LEB;
|
||||||
|
}
|
||||||
|
static bool classof(const MCLEBFragment *) { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
class MCDwarfLineAddrFragment : public MCFragment {
|
class MCDwarfLineAddrFragment : public MCFragment {
|
||||||
/// LineDelta - the value of the difference between the two line numbers
|
/// LineDelta - the value of the difference between the two line numbers
|
||||||
/// between two .loc dwarf directives.
|
/// between two .loc dwarf directives.
|
||||||
@ -677,6 +712,12 @@ private:
|
|||||||
/// were adjusted.
|
/// were adjusted.
|
||||||
bool LayoutOnce(const MCObjectWriter &Writer, MCAsmLayout &Layout);
|
bool LayoutOnce(const MCObjectWriter &Writer, MCAsmLayout &Layout);
|
||||||
|
|
||||||
|
bool RelaxInstruction(const MCObjectWriter &Writer, MCAsmLayout &Layout,
|
||||||
|
MCInstFragment &IF);
|
||||||
|
|
||||||
|
bool RelaxLEB(const MCObjectWriter &Writer, MCAsmLayout &Layout,
|
||||||
|
MCLEBFragment &IF);
|
||||||
|
|
||||||
/// FinishLayout - Finalize a layout, including fragment lowering.
|
/// FinishLayout - Finalize a layout, including fragment lowering.
|
||||||
void FinishLayout(MCAsmLayout &Layout);
|
void FinishLayout(MCAsmLayout &Layout);
|
||||||
|
|
||||||
|
@ -60,6 +60,8 @@ public:
|
|||||||
/// @name MCStreamer Interface
|
/// @name MCStreamer Interface
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
|
||||||
|
virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
|
||||||
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
|
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
|
||||||
virtual void SwitchSection(const MCSection *Section);
|
virtual void SwitchSection(const MCSection *Section);
|
||||||
virtual void EmitInstruction(const MCInst &Inst);
|
virtual void EmitInstruction(const MCInst &Inst);
|
||||||
|
@ -244,13 +244,20 @@ namespace llvm {
|
|||||||
virtual void EmitIntValue(uint64_t Value, unsigned Size,
|
virtual void EmitIntValue(uint64_t Value, unsigned Size,
|
||||||
unsigned AddrSpace = 0);
|
unsigned AddrSpace = 0);
|
||||||
|
|
||||||
/// EmitULEB128Value - Special case of EmitValue that takes an ULEB128 and
|
|
||||||
/// emits the needed bytes for the encoded value.
|
|
||||||
virtual void EmitULEB128Value(uint64_t Value, unsigned AddrSpace = 0);
|
|
||||||
|
|
||||||
/// EmitSLEB128Value - Special case of EmitValue that takes an SLEB128 and
|
virtual void EmitULEB128Value(const MCExpr *Value,
|
||||||
/// emits the needed bytes for the encoded value.
|
unsigned AddrSpace = 0) = 0;
|
||||||
virtual void EmitSLEB128Value(int64_t Value, unsigned AddrSpace = 0);
|
|
||||||
|
virtual void EmitSLEB128Value(const MCExpr *Value,
|
||||||
|
unsigned AddrSpace = 0) = 0;
|
||||||
|
|
||||||
|
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
|
||||||
|
/// client having to pass in a MCExpr for constant integers.
|
||||||
|
virtual void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0);
|
||||||
|
|
||||||
|
/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
|
||||||
|
/// client having to pass in a MCExpr for constant integers.
|
||||||
|
virtual void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0);
|
||||||
|
|
||||||
/// EmitSymbolValue - Special case of EmitValue that avoids the client
|
/// EmitSymbolValue - Special case of EmitValue that avoids the client
|
||||||
/// having to pass in a MCExpr for MCSymbols.
|
/// having to pass in a MCExpr for MCSymbols.
|
||||||
|
@ -141,7 +141,13 @@ public:
|
|||||||
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
|
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
|
||||||
|
|
||||||
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
|
virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
|
||||||
|
|
||||||
virtual void EmitIntValue(uint64_t Value, unsigned Size, unsigned AddrSpace);
|
virtual void EmitIntValue(uint64_t Value, unsigned Size, unsigned AddrSpace);
|
||||||
|
|
||||||
|
virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
|
||||||
|
|
||||||
|
virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0);
|
||||||
|
|
||||||
virtual void EmitGPRel32Value(const MCExpr *Value);
|
virtual void EmitGPRel32Value(const MCExpr *Value);
|
||||||
|
|
||||||
|
|
||||||
@ -505,6 +511,16 @@ void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
|
|||||||
EmitEOL();
|
EmitEOL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace) {
|
||||||
|
OS << ".uleb " << *Value;
|
||||||
|
EmitEOL();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace) {
|
||||||
|
OS << ".sleb " << *Value;
|
||||||
|
EmitEOL();
|
||||||
|
}
|
||||||
|
|
||||||
void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
|
void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
|
||||||
assert(MAI.getGPRel32Directive() != 0);
|
assert(MAI.getGPRel32Directive() != 0);
|
||||||
OS << MAI.getGPRel32Directive() << *Value;
|
OS << MAI.getGPRel32Directive() << *Value;
|
||||||
|
@ -318,6 +318,9 @@ uint64_t MCAssembler::ComputeFragmentSize(MCAsmLayout &Layout,
|
|||||||
case MCFragment::FT_Inst:
|
case MCFragment::FT_Inst:
|
||||||
return cast<MCInstFragment>(F).getInstSize();
|
return cast<MCInstFragment>(F).getInstSize();
|
||||||
|
|
||||||
|
case MCFragment::FT_LEB:
|
||||||
|
return cast<MCLEBFragment>(F).getSize();
|
||||||
|
|
||||||
case MCFragment::FT_Align: {
|
case MCFragment::FT_Align: {
|
||||||
const MCAlignFragment &AF = cast<MCAlignFragment>(F);
|
const MCAlignFragment &AF = cast<MCAlignFragment>(F);
|
||||||
|
|
||||||
@ -514,6 +517,23 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
|||||||
llvm_unreachable("unexpected inst fragment after lowering");
|
llvm_unreachable("unexpected inst fragment after lowering");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MCFragment::FT_LEB: {
|
||||||
|
MCLEBFragment &LF = cast<MCLEBFragment>(F);
|
||||||
|
|
||||||
|
// FIXME: It is probably better if we don't call EvaluateAsAbsolute in
|
||||||
|
// here.
|
||||||
|
int64_t Value;
|
||||||
|
LF.getValue().EvaluateAsAbsolute(Value, &Layout);
|
||||||
|
SmallString<32> Tmp;
|
||||||
|
raw_svector_ostream OSE(Tmp);
|
||||||
|
if (LF.isSigned())
|
||||||
|
MCObjectWriter::EncodeSLEB128(Value, OSE);
|
||||||
|
else
|
||||||
|
MCObjectWriter::EncodeULEB128(Value, OSE);
|
||||||
|
OW->WriteBytes(OSE.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MCFragment::FT_Org: {
|
case MCFragment::FT_Org: {
|
||||||
MCOrgFragment &OF = cast<MCOrgFragment>(F);
|
MCOrgFragment &OF = cast<MCOrgFragment>(F);
|
||||||
|
|
||||||
@ -781,6 +801,63 @@ bool MCAssembler::FragmentNeedsRelaxation(const MCObjectWriter &Writer,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MCAssembler::RelaxInstruction(const MCObjectWriter &Writer,
|
||||||
|
MCAsmLayout &Layout,
|
||||||
|
MCInstFragment &IF) {
|
||||||
|
if (!FragmentNeedsRelaxation(Writer, &IF, Layout))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
++stats::RelaxedInstructions;
|
||||||
|
|
||||||
|
// FIXME-PERF: We could immediately lower out instructions if we can tell
|
||||||
|
// they are fully resolved, to avoid retesting on later passes.
|
||||||
|
|
||||||
|
// Relax the fragment.
|
||||||
|
|
||||||
|
MCInst Relaxed;
|
||||||
|
getBackend().RelaxInstruction(IF.getInst(), Relaxed);
|
||||||
|
|
||||||
|
// Encode the new instruction.
|
||||||
|
//
|
||||||
|
// FIXME-PERF: If it matters, we could let the target do this. It can
|
||||||
|
// probably do so more efficiently in many cases.
|
||||||
|
SmallVector<MCFixup, 4> Fixups;
|
||||||
|
SmallString<256> Code;
|
||||||
|
raw_svector_ostream VecOS(Code);
|
||||||
|
getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups);
|
||||||
|
VecOS.flush();
|
||||||
|
|
||||||
|
// Update the instruction fragment.
|
||||||
|
int SlideAmount = Code.size() - IF.getInstSize();
|
||||||
|
IF.setInst(Relaxed);
|
||||||
|
IF.getCode() = Code;
|
||||||
|
IF.getFixups().clear();
|
||||||
|
// FIXME: Eliminate copy.
|
||||||
|
for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
|
||||||
|
IF.getFixups().push_back(Fixups[i]);
|
||||||
|
|
||||||
|
// Update the layout, and remember that we relaxed.
|
||||||
|
Layout.UpdateForSlide(&IF, SlideAmount);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MCAssembler::RelaxLEB(const MCObjectWriter &Writer,
|
||||||
|
MCAsmLayout &Layout,
|
||||||
|
MCLEBFragment &LF) {
|
||||||
|
int64_t Value;
|
||||||
|
LF.getValue().EvaluateAsAbsolute(Value, &Layout);
|
||||||
|
SmallString<32> Tmp;
|
||||||
|
raw_svector_ostream OSE(Tmp);
|
||||||
|
if (LF.isSigned())
|
||||||
|
MCObjectWriter::EncodeSLEB128(Value, OSE);
|
||||||
|
else
|
||||||
|
MCObjectWriter::EncodeULEB128(Value, OSE);
|
||||||
|
uint64_t OldSize = LF.getSize();
|
||||||
|
LF.setSize(OSE.GetNumBytesInBuffer());
|
||||||
|
return OldSize != LF.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer,
|
bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer,
|
||||||
MCAsmLayout &Layout) {
|
MCAsmLayout &Layout) {
|
||||||
++stats::RelaxationSteps;
|
++stats::RelaxationSteps;
|
||||||
@ -795,43 +872,18 @@ bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer,
|
|||||||
|
|
||||||
for (MCSectionData::iterator it2 = SD.begin(),
|
for (MCSectionData::iterator it2 = SD.begin(),
|
||||||
ie2 = SD.end(); it2 != ie2; ++it2) {
|
ie2 = SD.end(); it2 != ie2; ++it2) {
|
||||||
// Check if this is an instruction fragment that needs relaxation.
|
// Check if this is an fragment that needs relaxation.
|
||||||
MCInstFragment *IF = dyn_cast<MCInstFragment>(it2);
|
switch(it2->getKind()) {
|
||||||
if (!IF || !FragmentNeedsRelaxation(Writer, IF, Layout))
|
default:
|
||||||
continue;
|
break;
|
||||||
|
case MCFragment::FT_Inst:
|
||||||
++stats::RelaxedInstructions;
|
WasRelaxed |= RelaxInstruction(Writer, Layout,
|
||||||
|
*cast<MCInstFragment>(it2));
|
||||||
// FIXME-PERF: We could immediately lower out instructions if we can tell
|
break;
|
||||||
// they are fully resolved, to avoid retesting on later passes.
|
case MCFragment::FT_LEB:
|
||||||
|
WasRelaxed |= RelaxLEB(Writer, Layout, *cast<MCLEBFragment>(it2));
|
||||||
// Relax the fragment.
|
break;
|
||||||
|
}
|
||||||
MCInst Relaxed;
|
|
||||||
getBackend().RelaxInstruction(IF->getInst(), Relaxed);
|
|
||||||
|
|
||||||
// Encode the new instruction.
|
|
||||||
//
|
|
||||||
// FIXME-PERF: If it matters, we could let the target do this. It can
|
|
||||||
// probably do so more efficiently in many cases.
|
|
||||||
SmallVector<MCFixup, 4> Fixups;
|
|
||||||
SmallString<256> Code;
|
|
||||||
raw_svector_ostream VecOS(Code);
|
|
||||||
getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups);
|
|
||||||
VecOS.flush();
|
|
||||||
|
|
||||||
// Update the instruction fragment.
|
|
||||||
int SlideAmount = Code.size() - IF->getInstSize();
|
|
||||||
IF->setInst(Relaxed);
|
|
||||||
IF->getCode() = Code;
|
|
||||||
IF->getFixups().clear();
|
|
||||||
// FIXME: Eliminate copy.
|
|
||||||
for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
|
|
||||||
IF->getFixups().push_back(Fixups[i]);
|
|
||||||
|
|
||||||
// Update the layout, and remember that we relaxed.
|
|
||||||
Layout.UpdateForSlide(IF, SlideAmount);
|
|
||||||
WasRelaxed = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -903,6 +955,7 @@ void MCFragment::dump() {
|
|||||||
case MCFragment::FT_Inst: OS << "MCInstFragment"; break;
|
case MCFragment::FT_Inst: OS << "MCInstFragment"; break;
|
||||||
case MCFragment::FT_Org: OS << "MCOrgFragment"; break;
|
case MCFragment::FT_Org: OS << "MCOrgFragment"; break;
|
||||||
case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break;
|
case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break;
|
||||||
|
case MCFragment::FT_LEB: OS << "MCLEBFragment"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
|
OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
|
||||||
@ -970,6 +1023,12 @@ void MCFragment::dump() {
|
|||||||
<< " LineDelta:" << OF->getLineDelta();
|
<< " LineDelta:" << OF->getLineDelta();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MCFragment::FT_LEB: {
|
||||||
|
const MCLEBFragment *LF = cast<MCLEBFragment>(this);
|
||||||
|
OS << "\n ";
|
||||||
|
OS << " Value:" << LF->getValue() << " Signed:" << LF->isSigned();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
OS << ">";
|
OS << ">";
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ static inline void EmitDwarfSetAddress(MCObjectStreamer *MCOS,
|
|||||||
MCOS->EmitIntValue(dwarf::DW_LNS_extended_op, 1);
|
MCOS->EmitIntValue(dwarf::DW_LNS_extended_op, 1);
|
||||||
|
|
||||||
int sizeof_address = MCOS->getAssembler().getBackend().getPointerSize();
|
int sizeof_address = MCOS->getAssembler().getBackend().getPointerSize();
|
||||||
MCOS->EmitULEB128Value(sizeof_address + 1);
|
MCOS->EmitULEB128IntValue(sizeof_address + 1);
|
||||||
|
|
||||||
MCOS->EmitIntValue(dwarf::DW_LNE_set_address, 1);
|
MCOS->EmitIntValue(dwarf::DW_LNE_set_address, 1);
|
||||||
MCOS->EmitSymbolValue(Symbol, sizeof_address);
|
MCOS->EmitSymbolValue(Symbol, sizeof_address);
|
||||||
@ -157,17 +157,17 @@ static inline bool EmitDwarfLineTable(MCObjectStreamer *MCOS,
|
|||||||
if (FileNum != it->getFileNum()) {
|
if (FileNum != it->getFileNum()) {
|
||||||
FileNum = it->getFileNum();
|
FileNum = it->getFileNum();
|
||||||
MCOS->EmitIntValue(dwarf::DW_LNS_set_file, 1);
|
MCOS->EmitIntValue(dwarf::DW_LNS_set_file, 1);
|
||||||
MCOS->EmitULEB128Value(FileNum);
|
MCOS->EmitULEB128IntValue(FileNum);
|
||||||
}
|
}
|
||||||
if (Column != it->getColumn()) {
|
if (Column != it->getColumn()) {
|
||||||
Column = it->getColumn();
|
Column = it->getColumn();
|
||||||
MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
|
MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
|
||||||
MCOS->EmitULEB128Value(Column);
|
MCOS->EmitULEB128IntValue(Column);
|
||||||
}
|
}
|
||||||
if (Isa != it->getIsa()) {
|
if (Isa != it->getIsa()) {
|
||||||
Isa = it->getIsa();
|
Isa = it->getIsa();
|
||||||
MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
|
MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
|
||||||
MCOS->EmitULEB128Value(Isa);
|
MCOS->EmitULEB128IntValue(Isa);
|
||||||
}
|
}
|
||||||
if ((it->getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
|
if ((it->getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
|
||||||
Flags = it->getFlags();
|
Flags = it->getFlags();
|
||||||
@ -303,7 +303,8 @@ void MCDwarfFileTable::Emit(MCObjectStreamer *MCOS,
|
|||||||
for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
|
for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
|
||||||
MCOS->EmitBytes(MCDwarfFiles[i]->getName(), 0); // FileName
|
MCOS->EmitBytes(MCDwarfFiles[i]->getName(), 0); // FileName
|
||||||
MCOS->EmitBytes(StringRef("\0", 1), 0); // the null term. of the string
|
MCOS->EmitBytes(StringRef("\0", 1), 0); // the null term. of the string
|
||||||
MCOS->EmitULEB128Value(MCDwarfFiles[i]->getDirIndex()); // the Directory num
|
// the Directory num
|
||||||
|
MCOS->EmitULEB128IntValue(MCDwarfFiles[i]->getDirIndex());
|
||||||
MCOS->EmitIntValue(0, 1); // last modification timestamp (always 0)
|
MCOS->EmitIntValue(0, 1); // last modification timestamp (always 0)
|
||||||
MCOS->EmitIntValue(0, 1); // filesize (always 0)
|
MCOS->EmitIntValue(0, 1); // filesize (always 0)
|
||||||
}
|
}
|
||||||
|
@ -152,6 +152,18 @@ public:
|
|||||||
return Child->EmitIntValue(Value, Size, AddrSpace);
|
return Child->EmitIntValue(Value, Size, AddrSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void EmitULEB128Value(const MCExpr *Value,
|
||||||
|
unsigned AddrSpace = 0) {
|
||||||
|
LogCall("EmitULEB128Value");
|
||||||
|
return Child->EmitULEB128Value(Value, AddrSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void EmitSLEB128Value(const MCExpr *Value,
|
||||||
|
unsigned AddrSpace = 0) {
|
||||||
|
LogCall("EmitSLEB128Value");
|
||||||
|
return Child->EmitSLEB128Value(Value, AddrSpace);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void EmitGPRel32Value(const MCExpr *Value) {
|
virtual void EmitGPRel32Value(const MCExpr *Value) {
|
||||||
LogCall("EmitGPRel32Value");
|
LogCall("EmitGPRel32Value");
|
||||||
return Child->EmitGPRel32Value(Value);
|
return Child->EmitGPRel32Value(Value);
|
||||||
|
@ -66,6 +66,10 @@ namespace {
|
|||||||
|
|
||||||
virtual void EmitValue(const MCExpr *Value, unsigned Size,
|
virtual void EmitValue(const MCExpr *Value, unsigned Size,
|
||||||
unsigned AddrSpace) {}
|
unsigned AddrSpace) {}
|
||||||
|
virtual void EmitULEB128Value(const MCExpr *Value,
|
||||||
|
unsigned AddrSpace = 0) {}
|
||||||
|
virtual void EmitSLEB128Value(const MCExpr *Value,
|
||||||
|
unsigned AddrSpace = 0) {}
|
||||||
virtual void EmitGPRel32Value(const MCExpr *Value) {}
|
virtual void EmitGPRel32Value(const MCExpr *Value) {}
|
||||||
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
|
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
|
||||||
unsigned ValueSize = 1,
|
unsigned ValueSize = 1,
|
||||||
|
@ -75,6 +75,16 @@ const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
|
|||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value,
|
||||||
|
unsigned AddrSpace) {
|
||||||
|
new MCLEBFragment(*Value, false, getCurrentSectionData());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value,
|
||||||
|
unsigned AddrSpace) {
|
||||||
|
new MCLEBFragment(*Value, true, getCurrentSectionData());
|
||||||
|
}
|
||||||
|
|
||||||
void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
|
void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
|
||||||
const MCSymbol *Symbol) {
|
const MCSymbol *Symbol) {
|
||||||
report_fatal_error("This file format doesn't support weak aliases.");
|
report_fatal_error("This file format doesn't support weak aliases.");
|
||||||
|
@ -261,8 +261,6 @@ public:
|
|||||||
bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
|
bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
|
||||||
bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc);
|
bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc);
|
||||||
|
|
||||||
void ParseUleb128(uint64_t Value);
|
|
||||||
void ParseSleb128(int64_t Value);
|
|
||||||
bool ParseDirectiveLEB128(StringRef, SMLoc);
|
bool ParseDirectiveLEB128(StringRef, SMLoc);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2178,44 +2176,22 @@ bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive,
|
|||||||
"no current macro definition");
|
"no current macro definition");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericAsmParser::ParseUleb128(uint64_t Value) {
|
|
||||||
const uint64_t Mask = (1 << 7) - 1;
|
|
||||||
do {
|
|
||||||
unsigned Byte = Value & Mask;
|
|
||||||
Value >>= 7;
|
|
||||||
if (Value) // Not the last one
|
|
||||||
Byte |= (1 << 7);
|
|
||||||
getStreamer().EmitIntValue(Byte, 1, DEFAULT_ADDRSPACE);
|
|
||||||
} while (Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericAsmParser::ParseSleb128(int64_t Value) {
|
|
||||||
const int64_t Mask = (1 << 7) - 1;
|
|
||||||
for(;;) {
|
|
||||||
unsigned Byte = Value & Mask;
|
|
||||||
Value >>= 7;
|
|
||||||
bool Done = ((Value == 0 && (Byte & 0x40) == 0) ||
|
|
||||||
(Value == -1 && (Byte & 0x40) != 0));
|
|
||||||
if (!Done)
|
|
||||||
Byte |= (1 << 7);
|
|
||||||
getStreamer().EmitIntValue(Byte, 1, DEFAULT_ADDRSPACE);
|
|
||||||
if (Done)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) {
|
bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) {
|
||||||
int64_t Value;
|
getParser().CheckForValidSection();
|
||||||
if (getParser().ParseAbsoluteExpression(Value))
|
|
||||||
|
const MCExpr *Value;
|
||||||
|
|
||||||
|
if (getParser().ParseExpression(Value))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (getLexer().isNot(AsmToken::EndOfStatement))
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||||
return TokError("unexpected token in directive");
|
return TokError("unexpected token in directive");
|
||||||
|
|
||||||
if (DirName[1] == 's')
|
if (DirName[1] == 's')
|
||||||
ParseSleb128(Value);
|
getStreamer().EmitSLEB128Value(Value);
|
||||||
else
|
else
|
||||||
ParseUleb128(Value);
|
getStreamer().EmitULEB128Value(Value);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,22 +37,16 @@ void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
|
|||||||
EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
|
EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitULEB128Value - Special case of EmitValue that emits a ULEB128 of the
|
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
|
||||||
// Value as the sequence of ULEB128 encoded bytes.
|
/// client having to pass in a MCExpr for constant integers.
|
||||||
void MCStreamer::EmitULEB128Value(uint64_t Value, unsigned AddrSpace) {
|
void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace) {
|
||||||
SmallString<32> Tmp;
|
EmitULEB128Value(MCConstantExpr::Create(Value, getContext()), AddrSpace);
|
||||||
raw_svector_ostream OS(Tmp);
|
|
||||||
MCObjectWriter::EncodeULEB128(Value, OS);
|
|
||||||
EmitBytes(OS.str(), AddrSpace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitSLEB128Value - Special case of EmitValue that emits a SLEB128 of the
|
/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
|
||||||
// Value as the sequence of ULEB128 encoded bytes.
|
/// client having to pass in a MCExpr for constant integers.
|
||||||
void MCStreamer::EmitSLEB128Value(int64_t Value, unsigned AddrSpace) {
|
void MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) {
|
||||||
SmallString<32> Tmp;
|
EmitSLEB128Value(MCConstantExpr::Create(Value, getContext()), AddrSpace);
|
||||||
raw_svector_ostream OS(Tmp);
|
|
||||||
MCObjectWriter::EncodeSLEB128(Value, OS);
|
|
||||||
EmitBytes(OS.str(), AddrSpace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
|
void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
|
||||||
|
19
test/MC/ELF/leb128.s
Normal file
19
test/MC/ELF/leb128.s
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s
|
||||||
|
|
||||||
|
.sleb128 .Lfoo - .Lbar
|
||||||
|
.Lfoo:
|
||||||
|
.uleb128 .Lbar - .Lfoo
|
||||||
|
.fill 126, 1, 0x90
|
||||||
|
.Lbar:
|
||||||
|
|
||||||
|
// CHECK: (('sh_name', 0x00000001) # '.text'
|
||||||
|
// CHECK-NEXT: ('sh_type', 0x00000001)
|
||||||
|
// CHECK-NEXT: ('sh_flags', 0x00000006)
|
||||||
|
// CHECK-NEXT: ('sh_addr', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('sh_offset', 0x00000040)
|
||||||
|
// CHECK-NEXT: ('sh_size', 0x00000081)
|
||||||
|
// CHECK-NEXT: ('sh_link', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('sh_info', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('sh_addralign', 0x00000004)
|
||||||
|
// CHECK-NEXT: ('sh_entsize', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('_section_data', '817f7f90 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90')
|
Reference in New Issue
Block a user