summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2019-08-23 13:36:24 +0000
committerSimon Atanasyan <simon@atanasyan.com>2019-08-23 13:36:24 +0000
commit5f7d6ac7bf3b7a954d9826b93872063f8eb08810 (patch)
tree8b0a5a136d562971373a44c86fb2aef1a5cf07db /llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
parent58492b1895e23869253592544ae87f58742013e3 (diff)
downloadbcm5719-llvm-5f7d6ac7bf3b7a954d9826b93872063f8eb08810.tar.gz
bcm5719-llvm-5f7d6ac7bf3b7a954d9826b93872063f8eb08810.zip
[mips] Reduce number of instructions used for loading a global symbol's value
Now `lw/sw $reg, sym+offset` pseudo instructions for global symbol `sym` are lowering into the following three instructions. ``` lw $reg, %got(symbol)($gp) addiu $reg, $reg, offset lw/sw $reg, 0($reg) ``` It's possible to reduce the number of instructions by taking the offset in account in the final `lw/sw` command. This patch implements that optimization. ``` lw $reg, %got(symbol)($gp) lw/sw $reg, offset($reg) ``` Differential Revision: https://reviews.llvm.org/D66553 llvm-svn: 369756
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp18
1 files changed, 13 insertions, 5 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 09dc73b061e..5e5f7279093 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -3655,17 +3655,25 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
if (inPicMode()) {
// FIXME:
// a) Fix lw/sw $reg, symbol($reg) instruction expanding.
- // b) If expression includes offset (sym + number), do not
- // encode the offset into a relocation. Take it in account
- // in the last load/store instruction.
// c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
// do not exceed 16-bit.
// d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
// of R_MIPS_GOT_DISP in appropriate cases to reduce number
// of GOT entries.
- loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, Mips::NoRegister,
+ MCValue Res;
+ if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
+ Error(IDLoc, "expected relocatable expression");
+ return;
+ }
+ if (Res.getSymB() != nullptr) {
+ Error(IDLoc, "expected relocatable expression with only one symbol");
+ return;
+ }
+
+ loadAndAddSymbolAddress(Res.getSymA(), TmpReg, Mips::NoRegister,
!ABI.ArePtrs64bit(), IDLoc, Out, STI);
- TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, 0, IDLoc, STI);
+ TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, Res.getConstant(), IDLoc,
+ STI);
} else {
const MCExpr *ExprOffset = OffsetOp.getExpr();
MCOperand LoOperand = MCOperand::createExpr(
OpenPOWER on IntegriCloud