aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2015-06-11 18:58:08 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2015-06-11 18:58:08 +0000
commit6c56decee0607db092e932b20f45c2825bc31684 (patch)
tree7dad9133d0a096b129bb3eca480e64257cdd61b4
parentbc482286fcf06ba573338c5712daac85eaf48722 (diff)
downloadllvm-studio-master-release.tar.gz
This makes emitAbsoluteSymbolDiff always succeed and moves logic from the asm printer to it. The object one now also works on ELF. If two symbols are in the same fragment, we will never move them apart. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239552 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/MC/MCObjectStreamer.h2
-rw-r--r--include/llvm/MC/MCStreamer.h8
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp20
-rw-r--r--lib/MC/MCObjectStreamer.cpp15
-rw-r--r--lib/MC/MCStreamer.cpp19
5 files changed, 30 insertions, 34 deletions
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 462b3b484c58..131da07c23a8 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -136,7 +136,7 @@ public:
///
/// \pre Offset of \c Hi is greater than the offset \c Lo.
/// \return true on success.
- bool emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
+ void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Size) override;
bool mayHaveInstructions(MCSection &Sec) const override;
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 628fb768856e..4dd53df25ec2 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -636,14 +636,12 @@ public:
unsigned Isa, unsigned Discriminator,
StringRef FileName);
- /// Emit the absolute difference between two symbols if possible.
+ /// Emit the absolute difference between two symbols.
///
/// \pre Offset of \c Hi is greater than the offset \c Lo.
/// \return true on success.
- virtual bool emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
- unsigned Size) {
- return false;
- }
+ virtual void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
+ unsigned Size);
virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID);
virtual void EmitCFISections(bool EH, bool Debug);
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 04b936afa06a..dd1d9a980d8d 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1590,25 +1590,7 @@ void AsmPrinter::EmitInt32(int Value) const {
/// .set if it avoids relocations.
void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Size) const {
- if (!MAI->doesDwarfUseRelocationsAcrossSections())
- if (OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size))
- return;
-
- // Get the Hi-Lo expression.
- const MCExpr *Diff =
- MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, OutContext),
- MCSymbolRefExpr::create(Lo, OutContext),
- OutContext);
-
- if (!MAI->doesSetDirectiveSuppressesReloc()) {
- OutStreamer->EmitValue(Diff, Size);
- return;
- }
-
- // Otherwise, emit with .set (aka assignment).
- MCSymbol *SetLabel = createTempSymbol("set");
- OutStreamer->EmitAssignment(SetLabel, Diff);
- OutStreamer->EmitSymbolValue(SetLabel, Size);
+ OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size);
}
/// EmitLabelPlusOffset - Emit something like ".long Label+Offset"
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index 6de02bcb02d8..a73c171bd1c0 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -54,21 +54,18 @@ void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
}
}
-bool MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
+void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
const MCSymbol *Lo,
unsigned Size) {
- // Must both be assigned to the same (valid) fragment.
- if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment())
- return false;
-
- // Must be a data fragment.
- if (!isa<MCDataFragment>(Hi->getFragment()))
- return false;
+ // If not assigned to the same (valid) fragment, fallback.
+ if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment()) {
+ MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
+ return;
+ }
assert(Hi->getOffset() >= Lo->getOffset() &&
"Expected Hi to be greater than Lo");
EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size);
- return true;
}
void MCObjectStreamer::reset() {
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 011969a3da01..349de97a17c3 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -638,6 +638,25 @@ void MCStreamer::EmitInstruction(const MCInst &Inst,
visitUsedExpr(*Inst.getOperand(i).getExpr());
}
+void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
+ unsigned Size) {
+ // Get the Hi-Lo expression.
+ const MCExpr *Diff =
+ MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
+ MCSymbolRefExpr::create(Lo, Context), Context);
+
+ const MCAsmInfo *MAI = Context.getAsmInfo();
+ if (!MAI->doesSetDirectiveSuppressesReloc()) {
+ EmitValue(Diff, Size);
+ return;
+ }
+
+ // Otherwise, emit with .set (aka assignment).
+ MCSymbol *SetLabel = Context.createTempSymbol("set", true);
+ EmitAssignment(SetLabel, Diff);
+ EmitSymbolValue(SetLabel, Size);
+}
+
void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}