summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp4
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp27
-rw-r--r--llvm/lib/MC/MCStreamer.cpp22
3 files changed, 38 insertions, 15 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 4e8dcf61491..927c1889c88 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -910,7 +910,7 @@ void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
EmitULEB128IntValue(IntValue);
return;
}
- OS << ".uleb128 ";
+ OS << "\t.uleb128 ";
Value->print(OS, MAI);
EmitEOL();
}
@@ -921,7 +921,7 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
EmitSLEB128IntValue(IntValue);
return;
}
- OS << ".sleb128 ";
+ OS << "\t.sleb128 ";
Value->print(OS, MAI);
EmitEOL();
}
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 230c02188a6..9c69a5a962d 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -51,17 +51,34 @@ void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
PendingLabels.clear();
}
+// As a compile-time optimization, avoid allocating and evaluating an MCExpr
+// tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
+static Optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
+ const MCSymbol *Lo) {
+ if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
+ Hi->isVariable() || Lo->isVariable())
+ return None;
+
+ return Hi->getOffset() - Lo->getOffset();
+}
+
void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
const MCSymbol *Lo,
unsigned Size) {
- // If not assigned to the same (valid) fragment, fallback.
- if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
- Hi->isVariable() || Lo->isVariable()) {
- MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
+ if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
+ EmitIntValue(*Diff, Size);
return;
}
+ MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
+}
- EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size);
+void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
+ const MCSymbol *Lo) {
+ if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
+ EmitULEB128IntValue(*Diff);
+ return;
+ }
+ MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
}
void MCObjectStreamer::reset() {
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 9dcd1e9101c..bc9c93f144e 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -120,20 +120,16 @@ void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
EmitBytes(StringRef(buf, Size));
}
-/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
+/// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
-void MCStreamer::EmitPaddedULEB128IntValue(uint64_t Value, unsigned PadTo) {
+void MCStreamer::EmitULEB128IntValue(uint64_t Value) {
SmallString<128> Tmp;
raw_svector_ostream OSE(Tmp);
- encodeULEB128(Value, OSE, PadTo);
+ encodeULEB128(Value, OSE);
EmitBytes(OSE.str());
}
-void MCStreamer::EmitULEB128IntValue(uint64_t Value) {
- EmitPaddedULEB128IntValue(Value, 0);
-}
-
-/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
+/// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
SmallString<128> Tmp;
@@ -902,6 +898,16 @@ void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
EmitSymbolValue(SetLabel, Size);
}
+void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
+ const MCSymbol *Lo) {
+ // Get the Hi-Lo expression.
+ const MCExpr *Diff =
+ MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
+ MCSymbolRefExpr::create(Lo, Context), Context);
+
+ EmitULEB128Value(Diff);
+}
+
void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
OpenPOWER on IntegriCloud