diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 11 | ||||
-rw-r--r-- | gas/config/tc-sparc.c | 9 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/call-relax-aout.d | 19 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/call-relax.d | 18 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/call-relax.s | 10 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/sparc.exp | 4 |
6 files changed, 69 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 7c9697b..f854223 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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. 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] { |