// Try to fully compute Expr to an absolute value and if that fails produce // a relocatable expr. // FIXME: Should this be the behavior of EvaluateAsRelocatable itself? static bool evaluate(const MCExpr &Expr, const MCAsmLayout &Layout, const MCFixup &Fixup, MCValue &Target) { if (Expr.EvaluateAsValue(Target, &Layout, &Fixup)) { if (Target.isAbsolute()) return true; } return Expr.EvaluateAsRelocatable(Target, &Layout, &Fixup); }
void MCStreamer::visitUsedExpr(const MCExpr &Expr) { switch (Expr.getKind()) { case MCExpr::Target: cast<MCTargetExpr>(Expr).visitUsedExpr(*this); break; case MCExpr::Constant: break; case MCExpr::Binary: { const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr); visitUsedExpr(*BE.getLHS()); visitUsedExpr(*BE.getRHS()); break; } case MCExpr::SymbolRef: visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol()); break; case MCExpr::Unary: visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr()); break; } }
void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, SMLoc Loc) { int64_t IntNumValues; // Do additional checking now if we can resolve the value. if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) { if (IntNumValues < 0) { getContext().getSourceManager()->PrintMessage( Loc, SourceMgr::DK_Warning, "'.fill' directive with negative repeat count has no effect"); return; } // Emit now if we can for better errors. int64_t NonZeroSize = Size > 4 ? 4 : Size; Expr &= ~0ULL >> (64 - NonZeroSize * 8); for (uint64_t i = 0, e = IntNumValues; i != e; ++i) { EmitIntValue(Expr, NonZeroSize); if (NonZeroSize < Size) EmitIntValue(0, Size - NonZeroSize); } return; } // Otherwise emit as fragment. MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); assert(getCurrentSectionOnly() && "need a section"); insert(new MCFillFragment(Expr, Size, NumValues, Loc)); }
bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI) { int64_t OffsetValue; if (!Offset.evaluateAsAbsolute(OffsetValue)) llvm_unreachable("Offset is not absolute"); if (OffsetValue < 0) llvm_unreachable("Offset is negative"); MCDataFragment *DF = getOrCreateDataFragment(&STI); flushPendingLabels(DF, DF->getContents().size()); Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name); if (!MaybeKind.hasValue()) return true; MCFixupKind Kind = *MaybeKind; if (Expr == nullptr) Expr = MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext()); DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc)); return false; }
void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, SMLoc Loc) { int64_t IntNumValues; if (!NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) { getContext().reportError(Loc, "expected absolute expression"); return; } if (IntNumValues < 0) { getContext().getSourceManager()->PrintMessage( Loc, SourceMgr::DK_Warning, "'.fill' directive with negative repeat count has no effect"); return; } MCStreamer::emitFill(IntNumValues, Size, Expr); }
void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, SMLoc Loc) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); int64_t IntNumBytes; if (!NumBytes.evaluateAsAbsolute(IntNumBytes, getAssembler())) { getContext().reportError(Loc, "expected absolute expression"); return; } if (IntNumBytes <= 0) { getContext().reportError(Loc, "invalid number of bytes"); return; } emitFill(IntNumBytes, FillValue); }