summaryrefslogtreecommitdiff
path: root/gas/config/tc-rx.c
diff options
context:
space:
mode:
authorDJ Delorie <dj@delorie.com>2010-07-02 20:24:22 +0000
committerDJ Delorie <dj@delorie.com>2010-07-02 20:24:22 +0000
commit006633973aecc89d2e0d254739c7a9d89c2791ce (patch)
tree0dbec9c49a802c03946430fc70a8a85ceba0f77c /gas/config/tc-rx.c
parent46860b32fbb593b42caba312fb0fc4c7b49713d2 (diff)
downloadbinutils-redhat-006633973aecc89d2e0d254739c7a9d89c2791ce.tar.gz
* config/tc-rx.c (rx_bytesT): Add grown/shrank counters for
relaxation. (rx_relax_frag): Prevent infinite loops of grow/shrink/grow/etc.
Diffstat (limited to 'gas/config/tc-rx.c')
-rw-r--r--gas/config/tc-rx.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/gas/config/tc-rx.c b/gas/config/tc-rx.c
index 3bb9a5afe7..00101e0318 100644
--- a/gas/config/tc-rx.c
+++ b/gas/config/tc-rx.c
@@ -624,6 +624,8 @@ typedef struct rx_bytesT
int n_relax;
int link_relax;
fixS *link_relax_fixP;
+ char times_grown;
+ char times_shrank;
} rx_bytesT;
static rx_bytesT rx_bytes;
@@ -1485,6 +1487,21 @@ rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
break;
}
+ /* This prevents infinite loops in align-heavy sources. */
+ if (newsize < oldsize)
+ {
+ if (fragP->tc_frag_data->times_shrank > 10
+ && fragP->tc_frag_data->times_grown > 10)
+ newsize = oldsize;
+ if (fragP->tc_frag_data->times_shrank < 20)
+ fragP->tc_frag_data->times_shrank ++;
+ }
+ else if (newsize > oldsize)
+ {
+ if (fragP->tc_frag_data->times_grown < 20)
+ fragP->tc_frag_data->times_grown ++;
+ }
+
fragP->fr_subtype = newsize;
tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
return newsize - oldsize;