diff options
author | Nirav Dave <niravd@google.com> | 2018-04-30 19:22:40 +0000 |
---|---|---|
committer | Nirav Dave <niravd@google.com> | 2018-04-30 19:22:40 +0000 |
commit | 6c0665e22174d474050e85ca367424f6e02476be (patch) | |
tree | 0fc4c2920b2bd5768aedf8c28b1a7098542eb33b /llvm/lib/MC/MCObjectStreamer.cpp | |
parent | 8fe04ad3f7acf9eac603602cfc2980b7ad85d7a1 (diff) | |
download | bcm5719-llvm-6c0665e22174d474050e85ca367424f6e02476be.tar.gz bcm5719-llvm-6c0665e22174d474050e85ca367424f6e02476be.zip |
[MC] Change AsmParser to leverage Assembler during evaluation
Teach AsmParser to check with Assembler for when evaluating constant
expressions. This improves the handing of preprocessor expressions
that must be resolved at parse time. This idiom can be found as
assembling-time assertion checks in source-level assemblers. Note that
this relies on the MCStreamer to keep sufficient tabs on Section /
Fragment information which the MCAsmStreamer does not. As a result the
textual output may fail where the equivalent object generation would
pass. This can most easily be resolved by folding the MCAsmStreamer
and MCObjectStreamer together which is planned for in a separate
patch.
Currently, this feature is only enabled for assembly input, keeping IR
compilation consistent between assembly and object generation.
Reviewers: echristo, rnk, probinson, espindola, peter.smith
Reviewed By: peter.smith
Subscribers: eraman, peter.smith, arichardson, jyknight, hiraditya, llvm-commits
Differential Revision: https://reviews.llvm.org/D45164
llvm-svn: 331218
Diffstat (limited to 'llvm/lib/MC/MCObjectStreamer.cpp')
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 19c41df473c..ebedd9bf815 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -35,6 +35,15 @@ MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCObjectStreamer::~MCObjectStreamer() {} +// AssemblerPtr is used for evaluation of expressions and causes +// difference between asm and object outputs. Return nullptr to in +// inline asm mode to limit divergence to assembly inputs. +MCAssembler *MCObjectStreamer::getAssemblerPtr() { + if (getUseAssemblerInfoForParsing()) + return Assembler.get(); + return nullptr; +} + void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) { if (PendingLabels.empty()) return; @@ -155,7 +164,7 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, // Avoid fixups when possible. int64_t AbsValue; - if (Value->evaluateAsAbsolute(AbsValue, getAssembler())) { + if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) { if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) { getContext().reportError( Loc, "value evaluated as " + Twine(AbsValue) + " is out of range."); @@ -217,7 +226,7 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) { void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { int64_t IntValue; - if (Value->evaluateAsAbsolute(IntValue, getAssembler())) { + if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) { EmitULEB128IntValue(IntValue); return; } @@ -226,7 +235,7 @@ void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { int64_t IntValue; - if (Value->evaluateAsAbsolute(IntValue, getAssembler())) { + if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) { EmitSLEB128IntValue(IntValue); return; } @@ -254,7 +263,7 @@ bool MCObjectStreamer::changeSectionImpl(MCSection *Section, int64_t IntSubsection = 0; if (Subsection && - !Subsection->evaluateAsAbsolute(IntSubsection, getAssembler())) + !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr())) report_fatal_error("Cannot evaluate subsection number"); if (IntSubsection < 0 || IntSubsection > 8192) report_fatal_error("Subsection number out of range"); @@ -400,7 +409,7 @@ void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, } const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel); int64_t Res; - if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) { + if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) { MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta, Res); return; @@ -412,7 +421,7 @@ void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label) { const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel); int64_t Res; - if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) { + if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) { MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); return; } @@ -608,7 +617,7 @@ void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, SMLoc Loc) { int64_t IntNumValues; - if (!NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) { + if (!NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) { getContext().reportError(Loc, "expected absolute expression"); return; } |