aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/tc-d30v.c37
2 files changed, 40 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 7df5bf6..178c2e7 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jun 5 10:50:53 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): Store previous segment state
+ with previous instruction.
+
Wed Jun 3 18:21:56 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
* config/tc-i386.c (SCALE1_WHEN_NO_INDEX): Define.
diff --git a/gas/config/tc-d30v.c b/gas/config/tc-d30v.c
index fb71de1..9a75789 100644
--- a/gas/config/tc-d30v.c
+++ b/gas/config/tc-d30v.c
@@ -1126,6 +1126,8 @@ md_assemble (str)
as_fatal (_("First opcode is long. Unable to mix instructions as specified."));
fixups = fixups->next;
str = str2 + 2;
+ prev_seg = now_seg;
+ prev_subseg = now_subseg;
}
}
@@ -1820,9 +1822,40 @@ d30v_align (n, pfill, label)
if (label != NULL)
{
+ symbolS * sym;
+ int label_seen = false;
+ struct frag * old_frag;
+ valueT old_value;
+ valueT new_value;
+
assert (S_GET_SEGMENT (label) == now_seg);
- label->sy_frag = frag_now;
- S_SET_VALUE (label, (valueT) frag_now_fix ());
+
+ old_frag = label->sy_frag;
+ old_value = S_GET_VALUE (label);
+ new_value = (valueT) frag_now_fix();
+
+ /* It is possible to have more than one label at a particular
+ address, especially if debugging is enabled, so we must
+ take care to adjust all the labels at this address in this
+ fragment. To save time we search from the end of the symbol
+ list, backwards, since the symbols we are interested in are
+ almost certainly the ones that were most recently added.
+ Also to save time we stop searching once we have seen at least
+ one matching label, and we encounter a label that is no longer
+ in the target fragment. Note, this search is guaranteed to
+ find at least one match when sym == label, so no special case
+ code is necessary. */
+ for (sym = symbol_lastP; sym != NULL; sym = sym->sy_previous)
+ {
+ if (sym->sy_frag == old_frag && S_GET_VALUE (sym) == old_value)
+ {
+ label_seen = true;
+ sym->sy_frag = frag_now;
+ S_SET_VALUE (sym, new_value);
+ }
+ else if (label_seen && sym->sy_frag != old_frag)
+ break;
+ }
}
record_alignment(now_seg, n);