// If SD is a variable, evaluate it.
MCValue Target;
- if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout, nullptr))
+ if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout, nullptr))
report_fatal_error("unable to evaluate offset for variable '" +
S.getName() + "'");
const MCExpr *Expr = Symbol.getVariableValue();
MCValue Value;
- if (!Expr->EvaluateAsValue(Value, this, nullptr))
+ if (!Expr->evaluateAsValue(Value, *this))
llvm_unreachable("Invalid Expression");
const MCSymbolRefExpr *RefB = Value.getSymB();
if (RefB)
- Assembler.getContext().FatalError(
+ Assembler.getContext().reportFatalError(
SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() +
"' could not be evaluated in a subtraction expression");
const MCSymbolData &ASD = Asm.getSymbolData(ASym);
if (ASD.isCommon()) {
// FIXME: we should probably add a SMLoc to MCExpr.
- Asm.getContext().FatalError(SMLoc(),
+ Asm.getContext().reportFatalError(SMLoc(),
"Common symbol " + ASym.getName() +
" cannot be used in assignment expr");
}
return getSectionAddressSize(SD);
}
-uint64_t MCAsmLayout::computeBundlePadding(const MCFragment *F,
- uint64_t FOffset, uint64_t FSize) {
+uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler,
+ const MCFragment *F,
+ uint64_t FOffset, uint64_t FSize) {
uint64_t BundleSize = Assembler.getBundleAlignSize();
assert(BundleSize > 0 &&
"computeBundlePadding should only be called if bundling is enabled");
getFragmentList().insert(IP, F);
F->setParent(this);
}
+
return IP;
}
MCSymbolData::MCSymbolData() : Symbol(nullptr) {}
-MCSymbolData::MCSymbolData(const MCSymbol &Symbol, MCFragment *Fragment,
- uint64_t Offset, MCAssembler *A)
- : Symbol(&Symbol), Fragment(Fragment), Offset(Offset), SymbolSize(nullptr),
- CommonAlign(-1U), Flags(0), Index(0) {
- if (A)
- A->getSymbolList().push_back(this);
+void MCSymbolData::initialize(const MCSymbol &Symbol, MCFragment *Fragment,
+ uint64_t Offset) {
+ assert(!isInitialized() && "Expected uninitialized symbol");
+
+ this->Symbol = &Symbol;
+ this->Fragment.setPointer(Fragment);
+ this->Offset = Offset;
+ this->SymbolSize = nullptr;
+ this->CommonAlign = -1U;
+ this->Flags = 0;
+ this->Index = 0;
}
/* *** */
Sections.clear();
Symbols.clear();
SectionMap.clear();
- SymbolMap.clear();
IndirectSymbols.clear();
DataRegions.clear();
LinkerOptions.clear();
return false;
}
-const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const {
+const MCSymbol *MCAssembler::getAtom(const MCSymbolData *SD) const {
// Linker visible symbols define atoms.
if (isSymbolLinkerVisible(SD->getSymbol()))
- return SD;
+ return &SD->getSymbol();
// Absolute and undefined symbols have no defining atom.
if (!SD->getFragment())
return SD->getFragment()->getAtom();
}
-// 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);
-}
-
bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
MCValue &Target, uint64_t &Value) const {
// probably merge the two into a single callback that tries to evaluate a
// fixup and records a relocation if one is needed.
const MCExpr *Expr = Fixup.getValue();
- if (!evaluate(*Expr, Layout, Fixup, Target))
- getContext().FatalError(Fixup.getLoc(), "expected relocatable expression");
+ if (!Expr->EvaluateAsRelocatable(Target, &Layout, &Fixup))
+ getContext().reportFatalError(Fixup.getLoc(), "expected relocatable expression");
bool IsPCRel = Backend.getFixupKindInfo(
Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel;
} else {
const MCSymbolRefExpr *A = Target.getSymA();
const MCSymbol &SA = A->getSymbol();
- if (A->getKind() != MCSymbolRefExpr::VK_None ||
- SA.AliasedSymbol().isUndefined()) {
+ if (A->getKind() != MCSymbolRefExpr::VK_None || SA.isUndefined()) {
IsResolved = false;
} else {
- const MCSymbolData &DataA = getSymbolData(SA);
- IsResolved =
- getWriter().IsSymbolRefDifferenceFullyResolvedImpl(*this, DataA,
- *DF, false, true);
+ IsResolved = getWriter().IsSymbolRefDifferenceFullyResolvedImpl(
+ *this, SA, *DF, false, true);
}
}
} else {
Value = Target.getConstant();
if (const MCSymbolRefExpr *A = Target.getSymA()) {
- const MCSymbol &Sym = A->getSymbol().AliasedSymbol();
+ const MCSymbol &Sym = A->getSymbol();
if (Sym.isDefined())
Value += Layout.getSymbolOffset(&getSymbolData(Sym));
}
if (const MCSymbolRefExpr *B = Target.getSymB()) {
- const MCSymbol &Sym = B->getSymbol().AliasedSymbol();
+ const MCSymbol &Sym = B->getSymbol();
if (Sym.isDefined())
Value -= Layout.getSymbolOffset(&getSymbolData(Sym));
}
// The fragment's offset will point to after the padding, and its computed
// size won't include the padding.
//
- if (Assembler.isBundlingEnabled() && F->hasInstructions()) {
+ // When the -mc-relax-all flag is used, we optimize bundling by writting the
+ // bundle padding directly into fragments when the instructions are emitted
+ // inside the streamer.
+ //
+ if (Assembler.isBundlingEnabled() && !Assembler.getRelaxAll() &&
+ F->hasInstructions()) {
assert(isa<MCEncodedFragment>(F) &&
"Only MCEncodedFragment implementations have instructions");
uint64_t FSize = Assembler.computeFragmentSize(*this, *F);
if (FSize > Assembler.getBundleAlignSize())
report_fatal_error("Fragment can't be larger than a bundle size");
- uint64_t RequiredBundlePadding = computeBundlePadding(F, F->Offset, FSize);
+ uint64_t RequiredBundlePadding = computeBundlePadding(Assembler, F,
+ F->Offset, FSize);
if (RequiredBundlePadding > UINT8_MAX)
report_fatal_error("Padding cannot exceed 255 bytes");
F->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
OW->WriteBytes(EF.getContents());
}
-/// \brief Write the fragment \p F to the output file.
-static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
- const MCFragment &F) {
- MCObjectWriter *OW = &Asm.getWriter();
-
- // FIXME: Embed in fragments instead?
- uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
-
+void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize,
+ MCObjectWriter *OW) const {
// Should NOP padding be written out before this fragment?
unsigned BundlePadding = F.getBundlePadding();
if (BundlePadding > 0) {
- assert(Asm.isBundlingEnabled() &&
+ assert(isBundlingEnabled() &&
"Writing bundle padding with disabled bundling");
assert(F.hasInstructions() &&
"Writing bundle padding for a fragment without instructions");
- unsigned TotalLength = BundlePadding + static_cast<unsigned>(FragmentSize);
- if (F.alignToBundleEnd() && TotalLength > Asm.getBundleAlignSize()) {
+ unsigned TotalLength = BundlePadding + static_cast<unsigned>(FSize);
+ if (F.alignToBundleEnd() && TotalLength > getBundleAlignSize()) {
// If the padding itself crosses a bundle boundary, it must be emitted
// in 2 pieces, since even nop instructions must not cross boundaries.
// v--------------v <- BundleAlignSize
// | Prev |####|####| F |
// ----------------------------
// ^-------------------^ <- TotalLength
- unsigned DistanceToBoundary = TotalLength - Asm.getBundleAlignSize();
- if (!Asm.getBackend().writeNopData(DistanceToBoundary, OW))
+ unsigned DistanceToBoundary = TotalLength - getBundleAlignSize();
+ if (!getBackend().writeNopData(DistanceToBoundary, OW))
report_fatal_error("unable to write NOP sequence of " +
Twine(DistanceToBoundary) + " bytes");
BundlePadding -= DistanceToBoundary;
}
- if (!Asm.getBackend().writeNopData(BundlePadding, OW))
+ if (!getBackend().writeNopData(BundlePadding, OW))
report_fatal_error("unable to write NOP sequence of " +
Twine(BundlePadding) + " bytes");
}
+}
+
+/// \brief Write the fragment \p F to the output file.
+static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment &F) {
+ MCObjectWriter *OW = &Asm.getWriter();
+
+ // FIXME: Embed in fragments instead?
+ uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
+
+ Asm.writeFragmentPadding(F, FragmentSize, OW);
// This variable (and its dummy usage) is to participate in the assert at
// the end of the function.
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
- getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo());
+ getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo());
VecOS.flush();
// Update the fragment.
int64_t AddrDelta;
bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout);
assert(Abs && "We created a line delta with an invalid expression");
+ (void) Abs;
int64_t LineDelta;
LineDelta = DF.getLineDelta();
SmallString<8> &Data = DF.getContents();
int64_t AddrDelta;
bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout);
assert(Abs && "We created call frame with an invalid expression");
+ (void) Abs;
SmallString<8> &Data = DF.getContents();
Data.clear();
raw_svector_ostream OSE(Data);