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.
This commit is contained in:
Jose E. Marchesi 2017-04-25 02:40:43 -07:00
parent b0b92aeb38
commit d28b6364b1
6 changed files with 69 additions and 2 deletions

View 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.

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View 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] {