gas: sparc: fix relaxation of CALL instruction into branches in a.out targets
authorJose E. Marchesi <jose.marchesi@oracle.com>
Tue, 25 Apr 2017 09:40:43 +0000 (02:40 -0700)
committerJose E. Marchesi <jose.marchesi@oracle.com>
Tue, 25 Apr 2017 09:40:43 +0000 (02:40 -0700)
This patch avoids CALL instructions to be optimized into branches if
the symbols referred to in the CALL instruction are not fully resolved
at the time the assembler writes its output.

Tested in sparc64-linux-gnu and sparc-sun-sunos4.1.3 targets.
No regressions.

gas/ChangeLog:

2017-04-25  Jose E. Marchesi  <jose.marchesi@oracle.com>

PR gas/21407
* config/tc-sparc.c (md_apply_fix): Do not transform `call'
instructions into branch instructions in fixups generating
additional relocations.
* testsuite/gas/sparc/call-relax.s: New file.
* testsuite/gas/sparc/call-relax.d: Likewise.
* testsuite/gas/sparc/call-relax-aout.d: Likewise.
* testsuite/gas/sparc/sparc.exp: Test call-relax and call-relax-aout.

gas/ChangeLog
gas/config/tc-sparc.c
gas/testsuite/gas/sparc/call-relax-aout.d [new file with mode: 0644]
gas/testsuite/gas/sparc/call-relax.d [new file with mode: 0644]
gas/testsuite/gas/sparc/call-relax.s [new file with mode: 0644]
gas/testsuite/gas/sparc/sparc.exp

index 7c9697bd0454a1c20ede10c9784dd81f7291d471..f85422353f2bcdbdef27d10e8e7ec2e60003a8ba 100644 (file)
@@ -1,3 +1,14 @@
+2017-04-25  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+       PR gas/21407
+       * config/tc-sparc.c (md_apply_fix): Do not transform `call'
+       instructions into branch instructions in fixups generating
+       additional relocations.
+       * testsuite/gas/sparc/call-relax.s: New file.
+       * testsuite/gas/sparc/call-relax.d: Likewise.
+       * testsuite/gas/sparc/call-relax-aout.d: Likewise.
+       * testsuite/gas/sparc/sparc.exp: Test call-relax and call-relax-aout.
+
 2017-04-24  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        * config/tc-arm.c (move_or_literal_pool): Remove code generating MOVS.
index 030e10d77495419094262eb8a210ba9324986cc8..4c930b5ddfc1a5829b7009bdb212dc5ef63da8ca 100644 (file)
@@ -3584,8 +3584,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
 
          insn |= val & 0x3fffffff;
 
-         /* See if we have a delay slot.  */
-         if (sparc_relax && fixP->fx_where + 8 <= fixP->fx_frag->fr_fix)
+         /* See if we have a delay slot.  In that case we attempt to
+             optimize several cases transforming CALL instructions
+             into branches.  But we can only do that if the relocation
+             can be completely resolved here, i.e. if no undefined
+             symbol is associated with it.  */
+         if (sparc_relax && fixP->fx_addsy == NULL
+             && fixP->fx_where + 8 <= fixP->fx_frag->fr_fix)
            {
 #define G0             0
 #define O7             15
diff --git a/gas/testsuite/gas/sparc/call-relax-aout.d b/gas/testsuite/gas/sparc/call-relax-aout.d
new file mode 100644 (file)
index 0000000..8afcf5e
--- /dev/null
@@ -0,0 +1,19 @@
+#as: -Av9 -relax
+#source: call-relax.s
+#objdump: -dr
+#name: sparc relax CALL (a.out)
+
+.*: +file format .*a\.out.*
+
+Disassembly of section .text:
+
+0+ <foo>:
+   0:  31 00 00 00     sethi  %hi\(0\), %i0
+   4:  10 80 00 02     b  c <bar>
+   8:  91 ee 20 00     restore  %i0, 0, %o0
+
+0+c <bar>:
+   c:  31 00 00 00     sethi  %hi\(0\), %i0
+  10:  40 00 00 00     call  10 <bar\+0x4>
+                       10: WDISP30     _undefined-0x10
+  14:  91 ee 20 00     restore  %i0, 0, %o0
diff --git a/gas/testsuite/gas/sparc/call-relax.d b/gas/testsuite/gas/sparc/call-relax.d
new file mode 100644 (file)
index 0000000..de52274
--- /dev/null
@@ -0,0 +1,18 @@
+#as: -Av9 -relax
+#objdump: -dr
+#name: sparc relax CALL
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <foo>:
+   0:  31 00 00 00     sethi  %hi\(0\), %i0
+   4:  10 68 00 02     b  %xcc, c <bar>
+   8:  91 ee 20 00     restore  %i0, 0, %o0
+
+0+c <bar>:
+   c:  31 00 00 00     sethi  %hi\(0\), %i0
+  10:  40 00 00 00     call  10 <bar\+0x4>
+                       10: R_SPARC_WDISP30     _undefined
+  14:  91 ee 20 00     restore  %i0, 0, %o0
diff --git a/gas/testsuite/gas/sparc/call-relax.s b/gas/testsuite/gas/sparc/call-relax.s
new file mode 100644 (file)
index 0000000..f5ebbb6
--- /dev/null
@@ -0,0 +1,10 @@
+# Test relaxation of CALL instructions into branches.
+        .text
+foo:
+        sethi %hi(0), %i0
+        call   bar, 0
+          restore %i0, %lo(0), %o0
+bar:
+        sethi %hi(0), %i0
+        call   _undefined, 0
+         restore %i0, %lo(0), %o0
index eb69e50515843d079b51c2744ba1cb81c515c95c..1e9cc2cbdddfbadeca134aa8ea0ce4ef082df3f2 100644 (file)
@@ -72,6 +72,10 @@ if [istarget sparc*-*-*] {
         run_dump_test "v9branch1"
         run_dump_test "imm-plus-rreg"
         run_dump_test "dcti-couples-v9"
+        run_dump_test "call-relax"
+    } else {
+        # The next tests are a.out only.
+        run_dump_test "call-relax-aout"
     }
 
     if [gas_64_check] {