Fix PR16116 - stoe previous subseg state with prev instructionss.
authorNick Clifton <nickc@redhat.com>
Fri, 5 Jun 1998 17:51:58 +0000 (17:51 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 5 Jun 1998 17:51:58 +0000 (17:51 +0000)
gas/ChangeLog
gas/config/tc-d30v.c

index 7df5bf6..178c2e7 100644 (file)
@@ -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.
index fb71de1..9a75789 100644 (file)
@@ -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);