aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MCObjectStreamer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCObjectStreamer.cpp')
-rw-r--r--lib/MC/MCObjectStreamer.cpp81
1 files changed, 68 insertions, 13 deletions
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index c2171ffaa5..d34eb3c435 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -16,6 +16,7 @@
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSection.h" // @LOCALMOD
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
@@ -99,9 +100,9 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
EmitIntValue(AbsValue, Size, AddrSpace);
return;
}
- DF->getFixups().push_back(
- MCFixup::Create(DF->getContents().size(), Value,
- MCFixup::getKindForSize(Size, false)));
+ DF->addFixup(MCFixup::Create(DF->getContents().size(),
+ Value,
+ MCFixup::getKindForSize(Size, false)));
DF->getContents().resize(DF->getContents().size() + Size, 0);
}
@@ -153,18 +154,68 @@ void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
report_fatal_error("This file format doesn't support weak aliases.");
}
+// @LOCALMOD-BEGIN ========================================================
+
+void MCObjectStreamer::EmitBundleAlignStart() {
+ MCSectionData *SD = getCurrentSectionData();
+ assert(SD->isBundlingEnabled() &&
+ ".bundle_align_start called, but bundling disabled!");
+ assert(!SD->isBundleLocked() &&
+ ".bundle_align_start while bundle locked");
+ SD->setBundleAlignNext(MCFragment::BundleAlignStart);
+}
+
+void MCObjectStreamer::EmitBundleAlignEnd() {
+ MCSectionData *SD = getCurrentSectionData();
+ assert(SD->isBundlingEnabled() &&
+ ".bundle_align_end called, but bundling disabled!");
+ assert(!SD->isBundleLocked() &&
+ ".bundle_align_end while bundle locked");
+ SD->setBundleAlignNext(MCFragment::BundleAlignEnd);
+}
+
+void MCObjectStreamer::EmitBundleLock() {
+ MCSectionData *SD = getCurrentSectionData();
+ assert(SD->isBundlingEnabled() &&
+ ".bundle_lock called, but bundling disabled!");
+ assert(!SD->isBundleLocked() &&
+ ".bundle_lock issued when bundle already locked");
+ SD->setBundleLocked(true);
+ SD->setBundleGroupFirstFrag(true);
+}
+
+void MCObjectStreamer::EmitBundleUnlock() {
+ MCSectionData *SD = getCurrentSectionData();
+ assert(SD->isBundlingEnabled() &&
+ ".bundle_unlock called, but bundling disabled!");
+ assert(SD->isBundleLocked() &&
+ ".bundle_unlock called when bundle not locked");
+ // If there has been at least one fragment emitted inside
+ // this bundle lock, then we need to mark the last emitted
+ // fragment as the group end.
+ if (!SD->isBundleGroupFirstFrag()) {
+ assert(getCurrentFragment() != NULL);
+ getCurrentFragment()->setBundleGroupEnd(true);
+ }
+ SD->setBundleLocked(false);
+ SD->setBundleGroupFirstFrag(false);
+}
+// @LOCALMOD-END ==========================================================
+
void MCObjectStreamer::ChangeSection(const MCSection *Section) {
assert(Section && "Cannot switch to a null section!");
CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
}
-void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
- getAssembler().getOrCreateSymbolData(*Symbol);
- Symbol->setVariableValue(AddValueSymbols(Value));
-}
-
void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
+
+ // @LOCALMOD-BEGIN
+ if (getAssembler().getBackend().CustomExpandInst(Inst, *this)) {
+ return;
+ }
+ // @LOCALMOD-END
+
// Scan for values.
for (unsigned i = Inst.getNumOperands(); i--; )
if (Inst.getOperand(i).isExpr())
@@ -204,7 +255,7 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
raw_svector_ostream VecOS(Code);
getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
VecOS.flush();
- IF->getContents().append(Code.begin(), Code.end());
+ IF->getCode().append(Code.begin(), Code.end());
}
void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
@@ -240,6 +291,7 @@ void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
void MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
assert(AddrSpace == 0 && "Address space must be 0!");
getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
+ getCurrentSectionData()->MarkBundleOffsetUnknown(); // @LOCALMOD
}
void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
@@ -251,6 +303,10 @@ void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
getCurrentSectionData());
+ // @LOCALMOD-BEGIN
+ // Bump the bundle offset to account for alignment.
+ getCurrentSectionData()->AlignBundleOffsetTo(ByteAlignment);
+ // @LOCALMOD-END
// Update the maximum alignment on the current section if necessary.
if (ByteAlignment > getCurrentSectionData()->getAlignment())
getCurrentSectionData()->setAlignment(ByteAlignment);
@@ -288,8 +344,7 @@ bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
- DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
- Value, FK_GPRel_4));
+ DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4));
DF->getContents().resize(DF->getContents().size() + 4, 0);
}
@@ -297,8 +352,7 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
- DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
- Value, FK_GPRel_4));
+ DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4));
DF->getContents().resize(DF->getContents().size() + 8, 0);
}
@@ -308,6 +362,7 @@ void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
// FIXME: A MCFillFragment would be more memory efficient but MCExpr has
// problems evaluating expressions across multiple fragments.
getOrCreateDataFragment()->getContents().append(NumBytes, FillValue);
+ getCurrentSectionData()->MarkBundleOffsetUnknown();
}
void MCObjectStreamer::FinishImpl() {