public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH][COMMITTED] gas: sparc: fix relaxation of CALL instruction into branches in a.out targets
@ 2017-04-25  9:53 Jose E. Marchesi
  0 siblings, 0 replies; only message in thread
From: Jose E. Marchesi @ 2017-04-25  9:53 UTC (permalink / raw)
  To: binutils


I just applied the patch below in order to fix PR gas/21407.

---

gas: sparc: fix relaxation of CALL instruction into branches in a.out targets
    
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.

diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
index 030e10d..4c930b5 100644
--- a/gas/config/tc-sparc.c
+++ b/gas/config/tc-sparc.c
@@ -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
index 0000000..8afcf5e
--- /dev/null
+++ b/gas/testsuite/gas/sparc/call-relax-aout.d
@@ -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
index 0000000..de52274
--- /dev/null
+++ b/gas/testsuite/gas/sparc/call-relax.d
@@ -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
index 0000000..f5ebbb6
--- /dev/null
+++ b/gas/testsuite/gas/sparc/call-relax.s
@@ -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
diff --git a/gas/testsuite/gas/sparc/sparc.exp b/gas/testsuite/gas/sparc/sparc.exp
index eb69e50..1e9cc2c 100644
--- a/gas/testsuite/gas/sparc/sparc.exp
+++ b/gas/testsuite/gas/sparc/sparc.exp
@@ -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] {

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2017-04-25  9:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-25  9:53 [PATCH][COMMITTED] gas: sparc: fix relaxation of CALL instruction into branches in a.out targets Jose E. Marchesi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).