]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
MIPS/GAS: Use non-zero frag offset directly in PIC branch relaxation
authorMaciej W. Rozycki <macro@imgtec.com>
Fri, 30 Jun 2017 23:42:19 +0000 (00:42 +0100)
committerMaciej W. Rozycki <macro@imgtec.com>
Fri, 30 Jun 2017 23:42:19 +0000 (00:42 +0100)
Use frag symbols with a non-zero offset directly in `fix_new_exp' calls
made in PIC branch relaxation.  There is no need here to make a helper
symbol to hold the result of a `symbol+offset' calculation requested as
only branches to local symbols are relaxed and in this case the LO16
part of the PIC address load sequence will have the offset accounted for
in calculation against the local GOT entry retrieved as the GOT16 high
part.  Consequently actual code produed is identical whether a helper
symbol is used or the original `symbol+offset' expression used directly.
Verify that this is indeed the case with GAS and LD tests.

gas/
* config/tc-mips.c (md_convert_frag): Don't make a helper
expression symbol for `fix_new_exp' called with a non-zero
offset.
* testsuite/gas/mips/relax-offset.d: New test.
* testsuite/gas/mips/mips1@relax-offset.d: New test.
* testsuite/gas/mips/r3000@relax-offset.d: New test.
* testsuite/gas/mips/r3900@relax-offset.d: New test.
* testsuite/gas/mips/micromips@relax-offset.d: New test.
* testsuite/gas/mips/relax-offset.l: New stderr output.
* testsuite/gas/mips/relax-offset.s: New test source.
* testsuite/gas/mips/mips.exp: Run the new tests.

ld/
* testsuite/ld-mips-elf/relax-offset.dd: New test.
* testsuite/ld-mips-elf/relax-offset.gd: New test.
* testsuite/ld-mips-elf/relax-offset-umips.dd: New test.
* testsuite/ld-mips-elf/relax-offset-umips.gd: New test.
* testsuite/ld-mips-elf/relax-offset.ld: New test linker script.
* testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
(prune_warnings): New temporary procedure.

17 files changed:
gas/ChangeLog
gas/config/tc-mips.c
gas/testsuite/gas/mips/micromips@relax-offset.d [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp
gas/testsuite/gas/mips/mips1@relax-offset.d [new file with mode: 0644]
gas/testsuite/gas/mips/r3000@relax-offset.d [new file with mode: 0644]
gas/testsuite/gas/mips/r3900@relax-offset.d [new file with mode: 0644]
gas/testsuite/gas/mips/relax-offset.d [new file with mode: 0644]
gas/testsuite/gas/mips/relax-offset.l [new file with mode: 0644]
gas/testsuite/gas/mips/relax-offset.s [new file with mode: 0644]
ld/ChangeLog
ld/testsuite/ld-mips-elf/mips-elf.exp
ld/testsuite/ld-mips-elf/relax-offset-umips.dd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/relax-offset-umips.gd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/relax-offset.dd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/relax-offset.gd [new file with mode: 0644]
ld/testsuite/ld-mips-elf/relax-offset.ld [new file with mode: 0644]

index 9989f313c63a338e7a9a67809717f8836481e719..7dad3418c7169e8035ebc15d75e625212763bd51 100644 (file)
@@ -1,3 +1,17 @@
+2017-06-30  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * config/tc-mips.c (md_convert_frag): Don't make a helper
+       expression symbol for `fix_new_exp' called with a non-zero
+       offset.
+       * testsuite/gas/mips/relax-offset.d: New test.
+       * testsuite/gas/mips/mips1@relax-offset.d: New test.
+       * testsuite/gas/mips/r3000@relax-offset.d: New test.
+       * testsuite/gas/mips/r3900@relax-offset.d: New test.
+       * testsuite/gas/mips/micromips@relax-offset.d: New test.
+       * testsuite/gas/mips/relax-offset.l: New stderr output.
+       * testsuite/gas/mips/relax-offset.s: New test source.
+       * testsuite/gas/mips/mips.exp: Run the new tests.
+
 2017-06-30  Georg-Johann Lay  <avr@gjlay.de>
 
        PR gas/21683
index 1d477a11341eafe8f4661f45a58e6658ee6d4881..3682cd5b0d0958094daaa38522f30dc9963b0a5c 100644 (file)
@@ -18289,12 +18289,6 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
              exp.X_add_symbol = fragp->fr_symbol;
              exp.X_add_number = fragp->fr_offset;
 
-             if (fragp->fr_offset)
-               {
-                 exp.X_add_symbol = make_expr_symbol (&exp);
-                 exp.X_add_number = 0;
-               }
-
              fixp = fix_new_exp (fragp, buf - fragp->fr_literal, 4, &exp,
                                  FALSE, BFD_RELOC_MIPS_GOT16);
              fixp->fx_file = fragp->fr_file;
@@ -18548,12 +18542,6 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
          insn = HAVE_64BIT_ADDRESSES ? 0xdc1c0000 : 0xfc1c0000;
          insn |= at << MICROMIPSOP_SH_RT;
 
-         if (exp.X_add_number)
-           {
-             exp.X_add_symbol = make_expr_symbol (&exp);
-             exp.X_add_number = 0;
-           }
-
          fixp = fix_new_exp (fragp, buf - fragp->fr_literal, 4, &exp, FALSE,
                              BFD_RELOC_MICROMIPS_GOT16);
          fixp->fx_file = fragp->fr_file;
diff --git a/gas/testsuite/gas/mips/micromips@relax-offset.d b/gas/testsuite/gas/mips/micromips@relax-offset.d
new file mode 100644 (file)
index 0000000..95fbf11
--- /dev/null
@@ -0,0 +1,26 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS PIC branch relaxation with offset
+#as: -32 -relax-branch
+#stderr: relax-offset.l
+#source: relax-offset.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 41bc 0000    lui     gp,0x0
+[      ]*[0-9a-f]+: R_MICROMIPS_HI16   _gp_disp
+[0-9a-f]+ <[^>]*> 339c 0000    addiu   gp,gp,0
+[      ]*[0-9a-f]+: R_MICROMIPS_LO16   _gp_disp
+[0-9a-f]+ <[^>]*> 033c e150    addu    gp,gp,t9
+[0-9a-f]+ <[^>]*> 40a4 fffe    bnezc   a0,0000000c <foo\+0xc>
+[      ]*[0-9a-f]+: R_MICROMIPS_PC16_S1        .*
+[0-9a-f]+ <[^>]*> fc3c 0002    lw      at,2\(gp\)
+[      ]*[0-9a-f]+: R_MICROMIPS_GOT16  \.text
+[0-9a-f]+ <[^>]*> 3021 0025    addiu   at,at,37
+[      ]*[0-9a-f]+: R_MICROMIPS_LO16   \.text
+[0-9a-f]+ <[^>]*> 45a1         jrc     at
+[0-9a-f]+ <[^>]*> 45bf         jrc     ra
+       \.\.\.
+[0-9a-f]+ <[^>]*> 0000 8b7c    syscall
+[0-9a-f]+ <[^>]*> 45bf         jrc     ra
+       \.\.\.
index 81dfd342934fc45ec0b1920fbc1e491603fbeb8b..0ea9f61b9694d501cacfa2350f455dac6b7d5d0a 100644 (file)
@@ -1069,6 +1069,8 @@ if { [istarget mips*-*-vxworks*] } {
 
     run_dump_test_arches "relax"       [mips_arch_list_matching mips2 !mips32r6]
     run_dump_test_arches "relax-at"    [mips_arch_list_matching mips2 !mips32r6]
+    run_dump_test_arches "relax-offset"        [mips_arch_list_matching mips1 \
+                                           !mips32r6]
     run_dump_test "relax-swap1-mips1"
     run_dump_test "relax-swap1-mips2"
     run_dump_test "relax-swap2"
diff --git a/gas/testsuite/gas/mips/mips1@relax-offset.d b/gas/testsuite/gas/mips/mips1@relax-offset.d
new file mode 100644 (file)
index 0000000..bd38410
--- /dev/null
@@ -0,0 +1,30 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS PIC branch relaxation with offset
+#as: -32 -relax-branch
+#stderr: relax-offset.l
+#source: relax-offset.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 3c1c0000     lui     gp,0x0
+[      ]*[0-9a-f]+: R_MIPS_HI16        _gp_disp
+[0-9a-f]+ <[^>]*> 279c0000     addiu   gp,gp,0
+[      ]*[0-9a-f]+: R_MIPS_LO16        _gp_disp
+[0-9a-f]+ <[^>]*> 0399e021     addu    gp,gp,t9
+[0-9a-f]+ <[^>]*> 14800005     bnez    a0,00000024 <foo\+0x24>
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 8f810002     lw      at,2\(gp\)
+[      ]*[0-9a-f]+: R_MIPS_GOT16       \.text
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 24210034     addiu   at,at,52
+[      ]*[0-9a-f]+: R_MIPS_LO16        \.text
+[0-9a-f]+ <[^>]*> 00200008     jr      at
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 03e00008     jr      ra
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
+[0-9a-f]+ <[^>]*> 0000000c     syscall
+[0-9a-f]+ <[^>]*> 03e00008     jr      ra
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/r3000@relax-offset.d b/gas/testsuite/gas/mips/r3000@relax-offset.d
new file mode 100644 (file)
index 0000000..d726d32
--- /dev/null
@@ -0,0 +1,6 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS PIC branch relaxation with offset
+#as: -32 -relax-branch
+#stderr: relax-offset.l
+#source: relax-offset.s
+#dump: mips1@relax-offset.d
diff --git a/gas/testsuite/gas/mips/r3900@relax-offset.d b/gas/testsuite/gas/mips/r3900@relax-offset.d
new file mode 100644 (file)
index 0000000..d726d32
--- /dev/null
@@ -0,0 +1,6 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS PIC branch relaxation with offset
+#as: -32 -relax-branch
+#stderr: relax-offset.l
+#source: relax-offset.s
+#dump: mips1@relax-offset.d
diff --git a/gas/testsuite/gas/mips/relax-offset.d b/gas/testsuite/gas/mips/relax-offset.d
new file mode 100644 (file)
index 0000000..e7f36e2
--- /dev/null
@@ -0,0 +1,28 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS PIC branch relaxation with offset
+#as: -32 -relax-branch
+#stderr: relax-offset.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 3c1c0000     lui     gp,0x0
+[      ]*[0-9a-f]+: R_MIPS_HI16        _gp_disp
+[0-9a-f]+ <[^>]*> 279c0000     addiu   gp,gp,0
+[      ]*[0-9a-f]+: R_MIPS_LO16        _gp_disp
+[0-9a-f]+ <[^>]*> 0399e021     addu    gp,gp,t9
+[0-9a-f]+ <[^>]*> 14800004     bnez    a0,00000020 <foo\+0x20>
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 8f810002     lw      at,2\(gp\)
+[      ]*[0-9a-f]+: R_MIPS_GOT16       \.text
+[0-9a-f]+ <[^>]*> 24210034     addiu   at,at,52
+[      ]*[0-9a-f]+: R_MIPS_LO16        \.text
+[0-9a-f]+ <[^>]*> 00200008     jr      at
+[0-9a-f]+ <[^>]*> 00000000     nop
+[0-9a-f]+ <[^>]*> 03e00008     jr      ra
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
+[0-9a-f]+ <[^>]*> 0000000c     syscall
+[0-9a-f]+ <[^>]*> 03e00008     jr      ra
+[0-9a-f]+ <[^>]*> 00000000     nop
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/relax-offset.l b/gas/testsuite/gas/mips/relax-offset.l
new file mode 100644 (file)
index 0000000..570a783
--- /dev/null
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:10: Warning: relaxed out-of-range branch into a jump
diff --git a/gas/testsuite/gas/mips/relax-offset.s b/gas/testsuite/gas/mips/relax-offset.s
new file mode 100644 (file)
index 0000000..6255322
--- /dev/null
@@ -0,0 +1,23 @@
+       .abicalls
+
+       .align  4, 0
+       .globl  foo
+       .ent    foo
+foo:
+       .set    noreorder
+       .cpload $25
+       .set    reorder
+       beq     $4, $0, bar + 4
+       jr      $31
+
+       .space  131072
+
+       .align  4, 0
+bar:
+       syscall
+       jr      $31
+       .end    foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .space  16
+       .align  4, 0
index 8c80daf2f342b15b207828c7e920116d91a5da61..33fda8ba7dedc3f08b411a972b178fe94cfffcaa 100644 (file)
@@ -1,3 +1,13 @@
+2017-06-30  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * testsuite/ld-mips-elf/relax-offset.dd: New test.
+       * testsuite/ld-mips-elf/relax-offset.gd: New test.
+       * testsuite/ld-mips-elf/relax-offset-umips.dd: New test.
+       * testsuite/ld-mips-elf/relax-offset-umips.gd: New test.
+       * testsuite/ld-mips-elf/relax-offset.ld: New test linker script.
+       * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
+       (prune_warnings): New temporary procedure.
+
 2017-06-28  Maciej W. Rozycki  <macro@imgtec.com>
 
        * testsuite/ld-mips-elf/mips-elf-flags.exp: Add interAptiv MR2
index 66b2ae46771a745090dcd6eea68022ceb0e30052..4360b83e2b4d46ebae4e2601aa5253952c5f4211 100644 (file)
@@ -1179,3 +1179,37 @@ run_ld_link_tests [list \
 
 # Check that the ISA level is consistently II for the LSI 4010.
 run_dump_test "lsi-4010-isa" [list [list ld $abi_ldflags(o32)]]
+
+# PIC branch relaxation with offset tests.  We need to use our version
+# of `prune_warnings' to get rid of GAS branch relaxation noise.
+rename prune_warnings mips_old_prune_warnings
+proc prune_warnings { msg } {
+    set msg1 "Assembler messages:"
+    set msg2 "Warning: relaxed out-of-range branch into a jump"
+    set msgx "(?:$msg1|$msg2)"
+    regsub -all "(^|\[\n\r\]*)\[^\n\r\]*: $msgx\[\n\r\]*" $msg "\\1" msg
+    return [mips_old_prune_warnings $msg]
+}
+run_ld_link_tests [list \
+    [list \
+       "MIPS link PIC branch relaxation with offset" \
+       "$abi_ldflags(o32) -shared -T relax-offset.ld" "" \
+       "$abi_asflags(o32) -relax-branch -mips2" \
+       {../../../gas/testsuite/gas/mips/relax-offset.s} \
+       {{objdump \
+         {-d --prefix-addresses --show-raw-insn} \
+         relax-offset.dd} \
+        {readelf -A relax-offset.gd}} \
+       "relax-offset"] \
+    [list \
+       "microMIPS link PIC branch relaxation with offset" \
+       "$abi_ldflags(o32) -shared -T relax-offset.ld" "" \
+       "$abi_asflags(o32) -relax-branch -mmicromips" \
+       {../../../gas/testsuite/gas/mips/relax-offset.s} \
+       {{objdump \
+         {-d --prefix-addresses --show-raw-insn} \
+         relax-offset-umips.dd} \
+        {readelf -A relax-offset-umips.gd}} \
+       "relax-offset-umips"]]
+rename prune_warnings ""
+rename mips_old_prune_warnings prune_warnings
diff --git a/ld/testsuite/ld-mips-elf/relax-offset-umips.dd b/ld/testsuite/ld-mips-elf/relax-offset-umips.dd
new file mode 100644 (file)
index 0000000..8e23931
--- /dev/null
@@ -0,0 +1,15 @@
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+00000000 <.*> 41bc 0003        lui     gp,0x3
+00000004 <.*> 339c 802f        addiu   gp,gp,-32721
+00000008 <.*> 033c e150        addu    gp,gp,t9
+0000000c <.*> 40a4 0005        bnezc   a0,0000001a <.*>
+00000010 <.*> fc3c 8018        lw      at,-32744\(gp\)
+00000014 <.*> 3021 0025        addiu   at,at,37
+00000018 <.*> 45a1             jrc     at
+0000001a <.*> 45bf             jrc     ra
+       \.\.\.
+00020020 <.*> 0000 8b7c        syscall
+00020024 <.*> 45bf             jrc     ra
+       \.\.\.
diff --git a/ld/testsuite/ld-mips-elf/relax-offset-umips.gd b/ld/testsuite/ld-mips-elf/relax-offset-umips.gd
new file mode 100644 (file)
index 0000000..119667f
--- /dev/null
@@ -0,0 +1,11 @@
+Primary GOT:
+ Canonical gp value: 00028030
+
+ Reserved entries:
+   Address     Access  Initial Purpose
+  00020040 -32752\(gp\) 00000000 Lazy resolver
+  00020044 -32748\(gp\) 80000000 Module pointer \(GNU extension\)
+
+ Local entries:
+   Address     Access  Initial
+  00020048 -32744\(gp\) 00020000
diff --git a/ld/testsuite/ld-mips-elf/relax-offset.dd b/ld/testsuite/ld-mips-elf/relax-offset.dd
new file mode 100644 (file)
index 0000000..322a0c9
--- /dev/null
@@ -0,0 +1,19 @@
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+00000000 <.*> 3c1c0003         lui     gp,0x3
+00000004 <.*> 279c8040         addiu   gp,gp,-32704
+00000008 <.*> 0399e021         addu    gp,gp,t9
+0000000c <.*> 14800004         bnez    a0,00000020 <.*>
+00000010 <.*> 00000000         nop
+00000014 <.*> 8f818018         lw      at,-32744\(gp\)
+00000018 <.*> 24210034         addiu   at,at,52
+0000001c <.*> 00200008         jr      at
+00000020 <.*> 00000000         nop
+00000024 <.*> 03e00008         jr      ra
+00000028 <.*> 00000000         nop
+       \.\.\.
+00020030 <.*> 0000000c         syscall
+00020034 <.*> 03e00008         jr      ra
+00020038 <.*> 00000000         nop
+       \.\.\.
diff --git a/ld/testsuite/ld-mips-elf/relax-offset.gd b/ld/testsuite/ld-mips-elf/relax-offset.gd
new file mode 100644 (file)
index 0000000..41f4af9
--- /dev/null
@@ -0,0 +1,11 @@
+Primary GOT:
+ Canonical gp value: 00028040
+
+ Reserved entries:
+   Address     Access  Initial Purpose
+  00020050 -32752\(gp\) 00000000 Lazy resolver
+  00020054 -32748\(gp\) 80000000 Module pointer \(GNU extension\)
+
+ Local entries:
+   Address     Access  Initial
+  00020058 -32744\(gp\) 00020000
diff --git a/ld/testsuite/ld-mips-elf/relax-offset.ld b/ld/testsuite/ld-mips-elf/relax-offset.ld
new file mode 100644 (file)
index 0000000..39f6367
--- /dev/null
@@ -0,0 +1,16 @@
+ENTRY (foo);
+SECTIONS
+{
+  .text : { *(.text) }
+  HIDDEN (_gp = ALIGN(16) + 0x7ff0);
+  .got : { *(.got) }
+  .dynamic : { *(.dynamic) }
+  .hash : { *(.hash) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .pdr : { *(.pdr) }
+  .shstrtab : { *(.shstrtab) }
+  .symtab : { *(.symtab) }
+  .strtab : { *(.strtab) }
+  /DISCARD/ : { *(*) }
+}