[lld] r372951 - [mips] Relax jalr/jr instructions using R_MIPS_JALR relocation
Simon Atanasyan via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 26 02:13:21 PDT 2019
Author: atanasyan
Date: Thu Sep 26 02:13:20 2019
New Revision: 372951
URL: http://llvm.org/viewvc/llvm-project?rev=372951&view=rev
Log:
[mips] Relax jalr/jr instructions using R_MIPS_JALR relocation
The R_MIPS_JALR relocation denotes jalr/jr instructions in position
independent code. Both these instructions take a target's address from
the $25 register. If offset to the target symbol fits into the 18-bits,
it's more efficient to replace jalr/jr by bal/b instructions.
Differential Revision: https://reviews.llvm.org/D68057
Modified:
lld/trunk/ELF/Arch/Mips.cpp
lld/trunk/test/ELF/mips-jalr.s
Modified: lld/trunk/ELF/Arch/Mips.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/Mips.cpp?rev=372951&r1=372950&r2=372951&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/Mips.cpp (original)
+++ lld/trunk/ELF/Arch/Mips.cpp Thu Sep 26 02:13:20 2019
@@ -85,8 +85,14 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType t
switch (type) {
case R_MIPS_JALR:
+ // If the target symbol is not preemptible and is not microMIPS,
+ // it might be possible to replace jalr/jr instruction by bal/b.
+ // It depends on the target symbol's offset.
+ if (!s.isPreemptible && !(s.getVA() & 0x1))
+ return R_PC;
+ return R_NONE;
case R_MICROMIPS_JALR:
- return R_HINT;
+ return R_NONE;
case R_MIPS_GPREL16:
case R_MIPS_GPREL32:
case R_MICROMIPS_GPREL16:
@@ -633,6 +639,20 @@ void MIPS<ELFT>::relocateOne(uint8_t *lo
writeValue<e>(loc, val + 0x800080008000, 16, 48);
break;
case R_MIPS_JALR:
+ val -= 4;
+ // Replace jalr/jr instructions by bal/b if the target
+ // offset fits into the 18-bit range.
+ if (isInt<18>(val)) {
+ switch (read32<e>(loc)) {
+ case 0x0320f809: // jalr $25 => bal sym
+ write32<e>(loc, 0x04110000 | ((val >> 2) & 0xffff));
+ break;
+ case 0x03200008: // jr $25 => b sym
+ write32<e>(loc, 0x10000000 | ((val >> 2) & 0xffff));
+ break;
+ }
+ }
+ break;
case R_MICROMIPS_JALR:
// Ignore this optimization relocation for now
break;
Modified: lld/trunk/test/ELF/mips-jalr.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-jalr.s?rev=372951&r1=372950&r2=372951&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-jalr.s (original)
+++ lld/trunk/test/ELF/mips-jalr.s Thu Sep 26 02:13:20 2019
@@ -1,20 +1,56 @@
# REQUIRES: mips
-# Check that lld ignores R_MIPS_JALR relocation for now.
-# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
-# RUN: ld.lld %t.o -o %t.exe
+## Check handling of the R_MIPS_JALR relocation.
+
+# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t.o
# RUN: llvm-readelf -r %t.o | FileCheck -check-prefix=REL %s
-# RUN: llvm-objdump -d --no-show-raw-insn %t.exe | FileCheck %s
-# REL: R_MIPS_CALL16 {{.*}} foo
+# RUN: ld.lld %t.o -shared -o %t.so
+# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck -check-prefix=SO %s
+
+# RUN: ld.lld %t.o --defsym=bar=__start -o %t.so
+# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck -check-prefix=EXE %s
+
+# REL: R_MIPS_JALR {{.*}} bar
# REL: R_MIPS_JALR {{.*}} foo
+# REL: R_MIPS_JALR {{.*}} far
+
+# SO: jalr $25
+# SO: bal -24 <foo>
+# SO: jalr $25
+
+# SO: jr $25
+# SO: b -64 <foo>
+# SO: jr $25
-# CHECK: jalr $25
+# EXE: bal -4 <foo>
+# EXE: bal -24 <foo>
+# EXE: jalr $25
+
+# EXE: b -56 <foo>
+# EXE: b -64 <foo>
+# EXE: jr $25
.text
- .global __start
+ .global bar
+ .global __start
.option pic2
+far:
+ .space 0x4fff0
__start:
- jal foo
foo:
+ jal bar
+ nop
+ jal foo
+ nop
+ jal far
nop
+l1:
+ jr $25
+ .reloc l1, R_MIPS_JALR, bar
+l2:
+ jr $25
+ .reloc l2, R_MIPS_JALR, foo
+l3:
+ jr $25
+ .reloc l3, R_MIPS_JALR, far
More information about the llvm-commits
mailing list