diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-06-11 18:58:08 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-06-11 18:58:08 +0000 |
commit | 7c6e6e49cc2ed0b35b03f06a2a3a3208bb35fe45 (patch) | |
tree | 86d12c4c05629520caa0689bd6bff2a10e9b6fa0 /llvm/lib | |
parent | 770f65ca6aa4d6a6a81b6129fcd48ef12d20f1f0 (diff) | |
download | bcm5719-llvm-7c6e6e49cc2ed0b35b03f06a2a3a3208bb35fe45.tar.gz bcm5719-llvm-7c6e6e49cc2ed0b35b03f06a2a3a3208bb35fe45.zip |
Generalize emitAbsoluteSymbolDiff.
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.
llvm-svn: 239552
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 19 |
3 files changed, 26 insertions, 28 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 04b936afa06..dd1d9a980d8 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/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/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 6de02bcb02d..a73c171bd1c 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/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/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 011969a3da0..349de97a17c 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/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) {} |