aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1996-12-09 23:34:20 +0000
committerIan Lance Taylor <ian@airs.com>1996-12-09 23:34:20 +0000
commit559c664adb7cadda0979198b9605f66d381c45bf (patch)
tree274b39a4213b696cd0499225edb7be0f8bef48e5 /gas
parent8728fa92639a428e7b02fc7693879665a8337c6f (diff)
downloadgdb-559c664adb7cadda0979198b9605f66d381c45bf.zip
gdb-559c664adb7cadda0979198b9605f66d381c45bf.tar.gz
gdb-559c664adb7cadda0979198b9605f66d381c45bf.tar.bz2
* config/tc-mips.c (mips16_extended_frag): Avoid an infinite loop
when extending because the value is exactly maxtiny + 1.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog3
-rw-r--r--gas/config/tc-mips.c26
2 files changed, 27 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 03f5bbb..cf501df 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,8 @@
Mon Dec 9 17:09:42 1996 Ian Lance Taylor <ian@cygnus.com>
+ * config/tc-mips.c (mips16_extended_frag): Avoid an infinite loop
+ when extending because the value is exactly maxtiny + 1.
+
* config/tc-mips.c (RELAX_MIPS16_ENCODE): Add small and ext
arguments, and store them. Adjust other RELAX_MIPS16 macros.
(RELAX_MIPS16_USER_SMALL): Define.
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index c1a348e..954d047 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -9154,8 +9154,30 @@ mips16_extended_frag (fragp, sec, stretch)
/* If any of the shifted bits are set, we must use an extended
opcode. If the address depends on the size of this
instruction, this can lead to a loop, so we arrange to always
- use an extended opcode. */
- if ((val & ((1 << op->shift) - 1)) != 0)
+ use an extended opcode. We only check this when we are in
+ the main relaxation loop, when SEC is NULL. */
+ if ((val & ((1 << op->shift) - 1)) != 0 && sec == NULL)
+ {
+ fragp->fr_subtype =
+ RELAX_MIPS16_MARK_LONG_BRANCH (fragp->fr_subtype);
+ return 1;
+ }
+
+ /* If we are about to mark a frag as extended because the value
+ is precisely maxtiny + 1, then there is a chance of an
+ infinite loop as in the following code:
+ la $4,foo
+ .skip 1020
+ .align 2
+ foo:
+ In this case when the la is extended, foo is 0x3fc bytes
+ away, so the la can be shrunk, but then foo is 0x400 away, so
+ the la must be extended. To avoid this loop, we mark the
+ frag as extended if it was small, and is about to become
+ extended with a value of maxtiny + 1. */
+ if (val == ((maxtiny + 1) << op->shift)
+ && ! RELAX_MIPS16_EXTENDED (fragp->fr_subtype)
+ && sec == NULL)
{
fragp->fr_subtype =
RELAX_MIPS16_MARK_LONG_BRANCH (fragp->fr_subtype);