Example #1
0
// 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);
}
Example #2
0
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;
  }
}
Example #3
0
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));
}
Example #4
0
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;
}
Example #5
0
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);
}
Example #6
0
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);
}