aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-mips.c
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@imgtec.com>2016-04-09 00:20:35 +0100
committerMaciej W. Rozycki <macro@imgtec.com>2016-04-13 13:32:41 +0100
commitc1f61bd2b0644fc710dcfbb378a63f0b34be8903 (patch)
tree0bbb911a341ba1d2c67dcca23f3562f77f990f2f /gas/config/tc-mips.c
parentd6bb17b07976ecbced934c1ad2cfec9976dbd8ce (diff)
downloadgdb-c1f61bd2b0644fc710dcfbb378a63f0b34be8903.zip
gdb-c1f61bd2b0644fc710dcfbb378a63f0b34be8903.tar.gz
gdb-c1f61bd2b0644fc710dcfbb378a63f0b34be8903.tar.bz2
MIPS/GAS: Relax branches to symbols resolved at link time
Where branch relaxation is enabled emit the long sequence for branches whose distance cannot be determined, i.e. to symbols that are undefined or in a different segment. These symbols are only resolved at link time and therefore the longer sequence ensures the branch target is in range, which cannot be guaranteed with a direct branch. This is the opposite to the current implementation, originally proposed here: <https://sourceware.org/ml/binutils/2002-09/msg00218.html>. The proposal was then extensively discussed before the final version was posted here: <https://sourceware.org/ml/binutils/2002-10/msg00191.html> and eventually committed: commit 4a6a3df43dbb37853a7b88b10ae97d9ec5daf987 Author: Alexandre Oliva <aoliva@redhat.com> Date: Sat Oct 12 05:23:33 2002 +0000 The case considered here was not commented in the review however and the original version remains. With branch relaxation enabled it makes more sense to do it consistently, so that all code impure with respect to branch distances can be linked. Direct branches are still produced for the cases concerned where branch relaxation is disabled, which is the default. gas/ * config/tc-mips.c (relaxed_branch_length): Use the long sequence where the distance cannot be determined. (relaxed_micromips_32bit_branch_length): Likewise. * testsuite/gas/mips/branch-extern-1.d: New test. * testsuite/gas/mips/branch-extern-2.d: New test. * testsuite/gas/mips/branch-extern-3.d: New test. * testsuite/gas/mips/branch-extern-4.d: New test. * testsuite/gas/mips/branch-extern.l: New stderr output. * testsuite/gas/mips/branch-extern.s: New test source. * testsuite/gas/mips/branch-section-1.d: New test. * testsuite/gas/mips/branch-section-2.d: New test. * testsuite/gas/mips/branch-section-3.d: New test. * testsuite/gas/mips/branch-section-4.d: New test. * testsuite/gas/mips/branch-section.l: New stderr output. * testsuite/gas/mips/branch-section.s: New test source. * testsuite/gas/mips/mips.exp: Run the new tests.
Diffstat (limited to 'gas/config/tc-mips.c')
-rw-r--r--gas/config/tc-mips.c14
1 files changed, 4 insertions, 10 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index db3ec67..dba147a 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -16811,12 +16811,9 @@ relaxed_branch_length (fragS *fragp, asection *sec, int update)
toofar = val < - (0x8000 << 2) || val >= (0x8000 << 2);
}
- else if (fragp)
- /* If the symbol is not defined or it's in a different segment,
- assume the user knows what's going on and emit a short
- branch. */
- toofar = FALSE;
else
+ /* If the symbol is not defined or it's in a different segment,
+ we emit the long sequence. */
toofar = TRUE;
if (fragp && update && toofar != RELAX_BRANCH_TOOFAR (fragp->fr_subtype))
@@ -16881,12 +16878,9 @@ relaxed_micromips_32bit_branch_length (fragS *fragp, asection *sec, int update)
toofar = val < - (0x8000 << 1) || val >= (0x8000 << 1);
}
- else if (fragp)
- /* If the symbol is not defined or it's in a different segment,
- assume the user knows what's going on and emit a short
- branch. */
- toofar = FALSE;
else
+ /* If the symbol is not defined or it's in a different segment,
+ we emit the long sequence. */
toofar = TRUE;
if (fragp && update