[PATCH] FIx mips PR 13509: not all labels are moved

Andrew Pinski andrew.pinski@caviumnetworks.com
Wed Jan 4 19:20:00 GMT 2012


Hi the comment before mips_align in gas/config/tc-mips.c says any
preceding label before an align will be moved.  But currently it only
moves the first preceding label.  This can cause confusing behavior
when you add an extra label or two and those are not moved.  This also
can cause different produced object code when gcc generates -g vs -g0
code because of the placement of the labels.  It had caused a gcc
bootstrap miscompare with a modified gcc.

OK?  Tested on mips64-linux-gnu with no regressions.

Thanks,
Andrew Pinski

gas/ChangeLog:
* tc-mips.c (mips_align): Take the labels rather than just one label.
Move all labels to after the .align.
(s_align): Change the last argument to mips_align.
(s_cons): Likewise.
(s_float_cons): Likewise.
(s_gpword): Likewise.
(s_gpdword): Likewise.
-------------- next part --------------
? gas/.symbols.c.swp
? gas/doc/.internals.texi.swp
? gas/testsuite/gas/mips/.mips32-mt.d.swp
? opcodes/.mips-opc.c.swp
Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.501
diff -u -p -r1.501 tc-mips.c
--- gas/config/tc-mips.c	19 Dec 2011 07:58:01 -0000	1.501
+++ gas/config/tc-mips.c	4 Jan 2012 19:16:39 -0000
@@ -15653,7 +15653,7 @@ get_symbol (void)
    label.  */
 
 static void
-mips_align (int to, int *fill, symbolS *label)
+mips_align (int to, int *fill, struct insn_label_list *labels)
 {
   mips_emit_delays ();
   mips_record_compressed_mode ();
@@ -15662,11 +15662,13 @@ mips_align (int to, int *fill, symbolS *
   else
     frag_align (to, fill ? *fill : 0, 0);
   record_alignment (now_seg, to);
-  if (label != NULL)
+ while (labels != NULL)
     {
+      symbolS *label = labels->label;
       gas_assert (S_GET_SEGMENT (label) == now_seg);
       symbol_set_frag (label, frag_now);
       S_SET_VALUE (label, (valueT) frag_now_fix ());
+      labels = labels->next;
     }
 }
 
@@ -15709,7 +15711,7 @@ s_align (int x ATTRIBUTE_UNUSED)
       struct insn_label_list *l = si->label_list;
       /* Auto alignment should be switched on by next section change.  */
       auto_align = 1;
-      mips_align (temp, fill_ptr, l != NULL ? l->label : NULL);
+      mips_align (temp, fill_ptr, l);
     }
   else
     {
@@ -15879,12 +15881,10 @@ s_cons (int log_size)
 {
   segment_info_type *si = seg_info (now_seg);
   struct insn_label_list *l = si->label_list;
-  symbolS *label;
 
-  label = l != NULL ? l->label : NULL;
   mips_emit_delays ();
   if (log_size > 0 && auto_align)
-    mips_align (log_size, 0, label);
+    mips_align (log_size, 0, l);
   cons (1 << log_size);
   mips_clear_insn_labels ();
 }
@@ -15894,18 +15894,15 @@ s_float_cons (int type)
 {
   segment_info_type *si = seg_info (now_seg);
   struct insn_label_list *l = si->label_list;
-  symbolS *label;
-
-  label = l != NULL ? l->label : NULL;
 
   mips_emit_delays ();
 
   if (auto_align)
     {
       if (type == 'd')
-	mips_align (3, 0, label);
+	mips_align (3, 0, l);
       else
-	mips_align (2, 0, label);
+	mips_align (2, 0, l);
     }
 
   float_cons (type);
@@ -16685,7 +16682,6 @@ s_gpword (int ignore ATTRIBUTE_UNUSED)
 {
   segment_info_type *si;
   struct insn_label_list *l;
-  symbolS *label;
   expressionS ex;
   char *p;
 
@@ -16698,10 +16694,9 @@ s_gpword (int ignore ATTRIBUTE_UNUSED)
 
   si = seg_info (now_seg);
   l = si->label_list;
-  label = l != NULL ? l->label : NULL;
   mips_emit_delays ();
   if (auto_align)
-    mips_align (2, 0, label);
+    mips_align (2, 0, l);
 
   expression (&ex);
   mips_clear_insn_labels ();
@@ -16725,7 +16720,6 @@ s_gpdword (int ignore ATTRIBUTE_UNUSED)
 {
   segment_info_type *si;
   struct insn_label_list *l;
-  symbolS *label;
   expressionS ex;
   char *p;
 
@@ -16738,10 +16732,9 @@ s_gpdword (int ignore ATTRIBUTE_UNUSED)
 
   si = seg_info (now_seg);
   l = si->label_list;
-  label = l != NULL ? l->label : NULL;
   mips_emit_delays ();
   if (auto_align)
-    mips_align (3, 0, label);
+    mips_align (3, 0, l);
 
   expression (&ex);
   mips_clear_insn_labels ();


More information about the Binutils mailing list