@@ -57,6 +57,18 @@ reencode_add_imm (uint32_t insn, uint32_t imm)
return (insn & ~(MASK (12) << 10)) | ((imm & MASK (12)) << 10);
}
+/* Base encoding for MOV Wd, Wm (ORR Wd, WZR, Wm). */
+#define AARCH64_MOV_REG_OPCODE 0x2a0003e0U
+/* NOP encoding */
+#define AARCH64_NOP_OPCODE 0xd503201fU
+
+/* Reencode ADD immediate as MOV-register (ORR Rd, ZR, Rm). */
+static inline uint32_t
+reencode_add_to_mov (uint32_t insn, unsigned int rd, unsigned int rn)
+{
+ return ((insn & (1U << 31)) | AARCH64_MOV_REG_OPCODE | (rn << 16) | rd);
+}
+
/* Reencode the IMM field of ADR. */
uint32_t
@@ -261,11 +273,23 @@ _bfd_aarch64_elf_put_addend (bfd *abfd,
case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
- /* Corresponds to: add rd, rn, #uimm12 to provide the low order
- 12 bits of the page offset following
- BFD_RELOC_AARCH64_ADR_HI21_PCREL which computes the
- (pc-relative) page base. */
- contents = reencode_add_imm (contents, addend);
+ /* Optimize an ADD whose relocated 12-bit immediate is zero. */
+ if ((addend & MASK (12)) == 0)
+ {
+ unsigned int rd = contents & MASK (5);
+ unsigned int rn = (contents >> 5) & MASK (5);
+ /* ADD Xd, Xd, #0 --> NOP, check for the 32 bit version
+ since it clear the upper half of the destination register. */
+ if (rd == rn && rd != 31 && (contents & (1U << 31)) != 0)
+ contents = AARCH64_NOP_OPCODE;
+ /* Register 31 denotes SP in ADD but ZR in MOV (ORR). */
+ else if (rd != 31 && rn != 31)
+ contents = reencode_add_to_mov (contents, rd, rn);
+ else
+ contents = reencode_add_imm (contents, addend);
+ }
+ else
+ contents = reencode_add_imm (contents, addend);
break;
case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
@@ -284,6 +284,11 @@ run_dump_test_lp64 "tls-large-desc-be"
run_dump_test "tls-tiny-ld"
run_dump_test "tls-small-ld"
run_dump_test_lp64 "tlsle"
+run_dump_test_lp64 "tlsle-add-hi12-opt"
+run_dump_test_lp64 "add-imm-zero-opt"
+run_dump_test_lp64 "add-imm-zero-opt-tlsgd"
+run_dump_test_lp64 "add-imm-zero-opt-tlsld"
+run_dump_test_lp64 "add-imm-zero-opt-tlsdesc"
run_dump_test "tlsle-symbol-offset"
run_dump_test "gc-got-relocs"
run_dump_test "gc-tls-relocs"
new file mode 100644
@@ -0,0 +1,16 @@
+#source: add-imm-zero-opt-tlsdesc.s
+#target: [check_shared_lib_support]
+#ld: -shared -T add-imm-zero-opt.ld --defsym=got_base=0x1ffd8 -e0 --no-warn-rwx-segments
+#objdump: -dr
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+10000 <test>:
+ +10000: aa0103e0 mov x0, x1
+ +10004: d503201f nop
+ +10008: 910003e3 mov x3, sp
+ +1000c: 9100009f mov sp, x4
+ +10010: d65f03c0 ret
+#...
new file mode 100644
@@ -0,0 +1,16 @@
+ .section .tbss,"awT",%nobits
+ .global tls_desc
+tls_desc:
+ .zero 8
+
+ .text
+ .global test
+ .type test, %function
+test:
+ add x0, x1, #:tlsdesc_lo12:tls_desc
+ add x2, x2, #:tlsdesc_lo12:tls_desc
+ add x3, sp, #:tlsdesc_lo12:tls_desc
+ add sp, x4, #:tlsdesc_lo12:tls_desc
+ ret
+ .size test, .-test
+
new file mode 100644
@@ -0,0 +1,15 @@
+#source: add-imm-zero-opt-tlsgd.s
+#target: [check_shared_lib_support]
+#ld: -shared -T add-imm-zero-opt.ld --defsym=got_base=0x1fff8 -e0 --no-warn-rwx-segments
+#objdump: -dr
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+10000 <test>:
+ +10000: aa0103e0 mov x0, x1
+ +10004: d503201f nop
+ +10008: 910003e3 mov x3, sp
+ +1000c: 9100009f mov sp, x4
+ +10010: d65f03c0 ret
new file mode 100644
@@ -0,0 +1,16 @@
+ .section .tbss,"awT",%nobits
+ .global tls_gd
+tls_gd:
+ .zero 8
+
+ .text
+ .global test
+ .type test, %function
+test:
+ add x0, x1, #:tlsgd_lo12:tls_gd
+ add x2, x2, #:tlsgd_lo12:tls_gd
+ add x3, sp, #:tlsgd_lo12:tls_gd
+ add sp, x4, #:tlsgd_lo12:tls_gd
+ ret
+ .size test, .-test
+
new file mode 100644
@@ -0,0 +1,15 @@
+#source: add-imm-zero-opt-tlsld.s
+#target: [check_shared_lib_support]
+#ld: -shared -T add-imm-zero-opt.ld --defsym=got_base=0x1fff8 -e0 --no-warn-rwx-segments
+#objdump: -dr
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+10000 <test>:
+ +10000: aa0103e0 mov x0, x1
+ +10004: d503201f nop
+ +10008: 910003e3 mov x3, sp
+ +1000c: 9100009f mov sp, x4
+ +10010: d65f03c0 ret
new file mode 100644
@@ -0,0 +1,15 @@
+ .section .tbss,"awT",%nobits
+tls_ld:
+ .zero 8
+
+ .text
+ .global test
+ .type test, %function
+test:
+ add x0, x1, #:tlsldm_lo12_nc:tls_ld
+ add x2, x2, #:tlsldm_lo12_nc:tls_ld
+ add x3, sp, #:tlsldm_lo12_nc:tls_ld
+ add sp, x4, #:tlsldm_lo12_nc:tls_ld
+ ret
+ .size test, .-test
+
new file mode 100644
@@ -0,0 +1,22 @@
+#source: add-imm-zero-opt.s
+#target: [check_shared_lib_support]
+#ld: -shared -T add-imm-zero-opt.ld --defsym=got_base=0x20000 -e0
+#objdump: -dr
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+10000 <test>:
+ +10000: d503201f nop
+ +10004: aa0203e1 mov x1, x2
+ +10008: d503201f nop
+ +1000c: aa0503e4 mov x4, x5
+ +10010: aa0703e6 mov x6, x7
+ +10014: d503201f nop
+ +10018: aa0a03e9 mov x9, x10
+ +1001c: 2a0b03eb mov w11, w11
+ +10020: 910003ec mov x12, sp
+ +10024: 910001bf mov sp, x13
+ +10028: 910021ce add x14, x14, #0x8
+ +1002c: d65f03c0 ret
new file mode 100644
@@ -0,0 +1,16 @@
+OUTPUT_ARCH(aarch64)
+SECTIONS
+{
+ . = 0x10000;
+ .text : { *(.text) }
+ . = got_base;
+ .got : { *(.got) *(.got.plt) }
+ . = 0x30000;
+ .tdata : { *(.tdata) }
+ .tbss : { *(.tbss) }
+ .data :
+ {
+ *(.data)
+ *(.data.*)
+ }
+}
new file mode 100644
@@ -0,0 +1,34 @@
+ .section .tbss,"awT",%nobits
+tls0:
+ .zero 4096
+tls_page:
+ .zero 8
+
+ .section .data.page,"aw"
+ .p2align 12
+page_sym:
+ .xword 0
+
+ .text
+ .global test
+ .type test, %function
+test:
+ add x0, x0, #:lo12:page_sym
+ add x1, x2, #:dtprel_hi12:tls0, lsl #12
+ add x3, x3, #:dtprel_lo12:tls0
+ add x4, x5, #:dtprel_lo12_nc:tls_page
+ add x6, x7, #:tprel_hi12:tls0, lsl #12
+ add x8, x8, #:tprel_lo12:tls0-16
+ add x9, x10, #:tprel_lo12_nc:tls_page-16
+
+ /* A 32-bit write must not be replaced with NOP. */
+ add w11, w11, #:lo12:page_sym
+
+ /* Uses of SP must remain ADD instructions. */
+ add x12, sp, #:lo12:page_sym
+ add sp, x13, #:lo12:page_sym
+
+ /* A nonzero immediate must remain an ADD instruction. */
+ add x14, x14, #:lo12:page_sym+8
+ ret
+ .size test, .-test
@@ -33,7 +33,7 @@ Disassembly of section .e843419:
0*20001030 <__e835769_veneer>:
[ ]*20001030: f0f17ff0 adrp x16, 3000000 <e835769>
-[ ]*20001034: 91000210 add x16, x16, #0x0
+[ ]*20001034: d503201f nop
[ ]*20001038: d61f0200 br x16
...
@@ -68,6 +68,6 @@ Disassembly of section .text:
0*400020 <__e843419_veneer>:
[ ]*400020: 900fe010 adrp x16, 20000000 <e843419>
-[ ]*400024: 91000210 add x16, x16, #0x0
+[ ]*400024: d503201f nop
[ ]*400028: d61f0200 br x16
...
@@ -44,6 +44,6 @@ Disassembly of section .text:
0*400020 <__farbranch_veneer>:
[ ]*400020: 900fe010 adrp x16, 20000000 <farbranch>
-[ ]*400024: 91000210 add x16, x16, #0x0
+[ ]*400024: d503201f nop
[ ]*400028: d61f0200 br x16
...
@@ -14,6 +14,6 @@ Disassembly of section .text:
[ \t]+100c:[ \t]+d503201f[ \t]+nop
0+1010 <__bar_veneer>:
1010: 90040010 adrp x16, 8001000 <bar>
- 1014: 91000210 add x16, x16, #0x0
+ 1014: d503201f nop
1018: d61f0200 br x16
...
@@ -15,7 +15,7 @@ Disassembly of section .text:
.* <__bar_veneer>:
1010: 90040010 adrp x16, 8001000 <bar>
- 1014: 91000210 add x16, x16, #0x0
+ 1014: d503201f nop
1018: d61f0200 br x16
...
@@ -17,7 +17,7 @@ Disassembly of section .text:
.* <__bar_veneer>:
1018: 90040010 adrp x16, 8001000 <bar>
- 101c: 91000210 add x16, x16, #0x0
+ 101c: d503201f nop
1020: d61f0200 br x16
1024: 00000000 udf #0
@@ -14,7 +14,7 @@ Disassembly of section .text:
[ \t]+100c:[ \t]+d503201f[ \t]+nop
0+1010 <__bar_veneer>:
1010: 90040010 adrp x16, 8001000 <bar>
- 1014: 91000210 add x16, x16, #0x0
+ 1014: d503201f nop
1018: d61f0200 br x16
...
@@ -38,7 +38,7 @@ Disassembly of section .text:
000000000000204c <__bar1_veneer>:
204c: d07ffff0 adrp x16, 100000000 <bar1>
- 2050: 91000210 add x16, x16, #0x0
+ 2050: d503201f nop
2054: d61f0200 br x16
...
@@ -39,7 +39,7 @@ Disassembly of section .text:
0000000000002050 <__bar1_veneer>:
2050: d07ffff0 adrp x16, 100000000 <bar1>
- 2054: 91000210 add x16, x16, #0x0
+ 2054: d503201f nop
2058: d61f0200 br x16
...
@@ -14,6 +14,6 @@ Disassembly of section .text:
[ \t]+100c:[ \t]+d503201f[ \t]+nop
0+1010 <__bar_veneer>:
[ \t]+1010:[ \t]+90040010[ \t]+adrp[ \t]+x16, 8001000 <bar>
-[ \t]+1014:[ \t]+91000210[ \t]+add[ \t]+x16, x16, #0x0
+[ \t]+1014:[ \t]+d503201f[ \t]+nop
[ \t]+1018:[ \t]+d61f0200[ \t]+br[ \t]+x16
...
@@ -15,7 +15,7 @@ Disassembly of section .text:
.* <__bar_veneer>:
1010: 90040010 adrp x16, 8001000 <bar>
- 1014: 91000210 add x16, x16, #0x0
+ 1014: d503201f nop
1018: d61f0200 br x16
...
@@ -17,7 +17,7 @@ Disassembly of section .text:
.* <__bar_veneer>:
1018: 90040010 adrp x16, 8001000 <bar>
- 101c: 91000210 add x16, x16, #0x0
+ 101c: d503201f nop
1020: d61f0200 br x16
1024: 00000000 udf #0
@@ -14,7 +14,7 @@ Disassembly of section .text:
[ \t]+100c:[ \t]+d503201f[ \t]+nop
0+1010 <__bar_veneer>:
[ \t]+1010:[ \t]+90040010[ \t]+adrp[ \t]+x16, 8001000 <bar>
-[ \t]+1014:[ \t]+91000210[ \t]+add[ \t]+x16, x16, #0x0
+[ \t]+1014:[ \t]+d503201f[ \t]+nop
[ \t]+1018:[ \t]+d61f0200[ \t]+br[ \t]+x16
...
@@ -58,7 +58,7 @@ Disassembly of section \.ramu:
0000000020000010 \<__code4_veneer\>:
20000010: 90080210 adrp x16, 30040000 \<code4\>
- 20000014: 91000210 add x16, x16, #0x0
+ 20000014: d503201f nop
20000018: d61f0200 br x16
\.\.\.
@@ -53,7 +53,7 @@ Disassembly of section \.raml:
000000001fff0028 \<__code4_veneer\>:
1fff0028: 90100290 adrp x16, 40040000 \<code4\>
- 1fff002c: 91000210 add x16, x16, #0x0
+ 1fff002c: d503201f nop
1fff0030: d61f0200 br x16
...
@@ -57,7 +57,7 @@ Disassembly of section \.raml:
000000001fff0028 \<__code4_veneer\>:
1fff0028: 90100290 adrp x16, 40040000 \<code4\>
- 1fff002c: 91000210 add x16, x16, #0x0
+ 1fff002c: d503201f nop
1fff0030: d61f0200 br x16
...
@@ -9,7 +9,7 @@
+10008: 11002000 add w0, w0, #0x8
+1000c: d503201f nop
+10010: d503201f nop
- +10014: 91400001 add x1, x0, #0x0, lsl #12
- +10018: 91000021 add x1, x1, #0x0
+ +10014: aa0003e1 mov x1, x0
+ +10018: d503201f nop
+1001c: 90000000 adrp x0, 10000 <.*>
+10020: d65f03c0 ret
@@ -7,7 +7,7 @@
+10008: 91004000 add x0, x0, #0x10
+1000c: d503201f nop
+10010: d503201f nop
- +10014: 91400001 add x1, x0, #0x0, lsl #12
- +10018: 91000021 add x1, x1, #0x0
+ +10014: aa0003e1 mov x1, x0
+ +10018: d503201f nop
+1001c: 90000000 adrp x0, 10000 <.*>
+10020: d65f03c0 ret
@@ -8,7 +8,7 @@
+10004: d53bd040 mrs x0, tpidr_el0
+10008: 11002000 add w0, w0, #0x8
+1000c: d503201f nop
- +10010: 91400001 add x1, x0, #0x0, lsl #12
- +10014: 91000021 add x1, x1, #0x0
+ +10010: aa0003e1 mov x1, x0
+ +10014: d503201f nop
+10018: 90000000 adrp x0, 10000 <main>
+1001c: d65f03c0 ret
@@ -6,7 +6,7 @@
+10004: d53bd040 mrs x0, tpidr_el0
+10008: 91004000 add x0, x0, #0x10
+1000c: d503201f nop
- +10010: 91400001 add x1, x0, #0x0, lsl #12
- +10014: 91000021 add x1, x1, #0x0
+ +10010: aa0003e1 mov x1, x0
+ +10014: d503201f nop
+10018: 90000000 adrp x0, 10000 <main>
+1001c: d65f03c0 ret
@@ -9,5 +9,5 @@ Disassembly of section .text:
00010000 \<test\>:
+10000: d53bd041 mrs x1, tpidr_el0
- +10004: 11400020 add w0, w1, #0x0, lsl #12
+ +10004: 2a0103e0 mov w0, w1
+10008: 11002000 add w0, w0, #0x8
@@ -7,5 +7,5 @@ Disassembly of section .text:
0000000000010000 \<test\>:
+10000: d53bd041 mrs x1, tpidr_el0
- +10004: 91400020 add x0, x1, #0x0, lsl #12
+ +10004: aa0103e0 mov x0, x1
+10008: 91004000 add x0, x0, #0x10
new file mode 100644
@@ -0,0 +1,14 @@
+#source: tlsle-add-hi12-opt.s
+#target: [check_shared_lib_support]
+#ld: -shared -T relocs.ld -e0
+#objdump: -dr
+
+.*: .*
+
+Disassembly of section .text:
+
+0+10000 <test>:
+ +10000: aa0103e0 mov x0, x1
+ +10004: 914003e2 add x2, sp, #0x0, lsl #12
+ +10008: 9140007f add sp, x3, #0x0, lsl #12
+ +1000c: 914004a4 add x4, x5, #0x1, lsl #12
new file mode 100644
@@ -0,0 +1,13 @@
+ .global test
+ .section .tbss,"awT",%nobits
+tlsvar:
+ .zero 4080
+tlsvar_hi12:
+ .zero 8
+
+ .text
+test:
+ add x0, x1, #:tprel_hi12:tlsvar
+ add x2, sp, #:tprel_hi12:tlsvar
+ add sp, x3, #:tprel_hi12:tlsvar
+ add x4, x5, #:tprel_hi12:tlsvar_hi12
@@ -15,4 +15,4 @@
+f0000028: 58000000 ldr x0, f0000028 <main\+0x28>
+f000002c: 10000000 adr x0, f000002c <main\+0x2c>
+f0000030: 90000000 adrp x0, f0000000 <main>
- +f0000034: 91000000 add x0, x0, #0x0
+ +f0000034: d503201f nop