gas/
authorRichard Sandiford <rdsandiford@googlemail.com>
Sun, 8 Jan 2012 12:11:42 +0000 (12:11 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Sun, 8 Jan 2012 12:11:42 +0000 (12:11 +0000)
2011-01-08  Andrew Pinski  <andrew.pinski@caviumnetworks.com>
    Richard Sandiford  <rdsandiford@googlemail.com>

* config/tc-mips.c (mips_move_labels): Take the list of labels and
textness as parameters.
(mips_move_text_labels): New function.
(append_insn): Use it instead of mips_move_labels.
(mips_emit_delays, start_noreorder): Likewise.
(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.

gas/testsuite/
* gas/mips/align3.s, gas/mips/align3.d: New testcase.
* gas/mips/mips.exp: Run it.

gas/ChangeLog
gas/config/tc-mips.c
gas/testsuite/ChangeLog
gas/testsuite/gas/mips/align3.d [new file with mode: 0644]
gas/testsuite/gas/mips/align3.s [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp

index 3b896e5..9f9d5a0 100644 (file)
@@ -1,3 +1,19 @@
+2012-01-08  Andrew Pinski  <andrew.pinski@caviumnetworks.com>
+           Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * config/tc-mips.c (mips_move_labels): Take the list of labels and
+       textness as parameters.
+       (mips_move_text_labels): New function.
+       (append_insn): Use it instead of mips_move_labels.
+       (mips_emit_delays, start_noreorder): Likewise.
+       (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.
+
 2012-01-06  Tristan Gingold  <gingold@adacore.com>
 
        * config/tc-i386.c: Update copyright year.
 2012-01-06  Tristan Gingold  <gingold@adacore.com>
 
        * config/tc-i386.c: Update copyright year.
index b967663..842d890 100644 (file)
@@ -2761,27 +2761,36 @@ reg_needs_delay (unsigned int reg)
   return 0;
 }
 
   return 0;
 }
 
-/* Move all labels in insn_labels to the current insertion point.  */
+/* Move all labels in LABELS to the current insertion point.  TEXT_P
+   says whether the labels refer to text or data.  */
 
 static void
 
 static void
-mips_move_labels (void)
+mips_move_labels (struct insn_label_list *labels, bfd_boolean text_p)
 {
 {
-  segment_info_type *si = seg_info (now_seg);
   struct insn_label_list *l;
   valueT val;
 
   struct insn_label_list *l;
   valueT val;
 
-  for (l = si->label_list; l != NULL; l = l->next)
+  for (l = labels; l != NULL; l = l->next)
     {
       gas_assert (S_GET_SEGMENT (l->label) == now_seg);
       symbol_set_frag (l->label, frag_now);
       val = (valueT) frag_now_fix ();
       /* MIPS16/microMIPS text labels are stored as odd.  */
     {
       gas_assert (S_GET_SEGMENT (l->label) == now_seg);
       symbol_set_frag (l->label, frag_now);
       val = (valueT) frag_now_fix ();
       /* MIPS16/microMIPS text labels are stored as odd.  */
-      if (HAVE_CODE_COMPRESSION)
+      if (text_p && HAVE_CODE_COMPRESSION)
        ++val;
       S_SET_VALUE (l->label, val);
     }
 }
 
        ++val;
       S_SET_VALUE (l->label, val);
     }
 }
 
+/* Move all labels in insn_labels to the current insertion point
+   and treat them as text labels.  */
+
+static void
+mips_move_text_labels (void)
+{
+  mips_move_labels (seg_info (now_seg)->label_list, TRUE);
+}
+
 static bfd_boolean
 s_is_linkonce (symbolS *sym, segT from_seg)
 {
 static bfd_boolean
 s_is_linkonce (symbolS *sym, segT from_seg)
 {
@@ -4149,7 +4158,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
              frag_grow (40);
            }
 
              frag_grow (40);
            }
 
-         mips_move_labels ();
+         mips_move_text_labels ();
 
 #ifndef NO_ECOFF_DEBUGGING
          if (ECOFF_DEBUGGING)
 
 #ifndef NO_ECOFF_DEBUGGING
          if (ECOFF_DEBUGGING)
@@ -4541,7 +4550,7 @@ mips_emit_delays (void)
        {
          while (nops-- > 0)
            add_fixed_insn (NOP_INSN);
        {
          while (nops-- > 0)
            add_fixed_insn (NOP_INSN);
-         mips_move_labels ();
+         mips_move_text_labels ();
        }
     }
   mips_no_prev_insn ();
        }
     }
   mips_no_prev_insn ();
@@ -4585,7 +4594,7 @@ start_noreorder (void)
             decrease the size of prev_nop_frag.  */
          frag_wane (frag_now);
          frag_new (0);
             decrease the size of prev_nop_frag.  */
          frag_wane (frag_now);
          frag_new (0);
-         mips_move_labels ();
+         mips_move_text_labels ();
        }
       mips_mark_labels ();
       mips_clear_insn_labels ();
        }
       mips_mark_labels ();
       mips_clear_insn_labels ();
@@ -15649,11 +15658,18 @@ get_symbol (void)
    fill byte should be used, FILL points to an integer that contains
    that byte, otherwise FILL is null.
 
    fill byte should be used, FILL points to an integer that contains
    that byte, otherwise FILL is null.
 
-   The MIPS assembler also automatically adjusts any preceding
-   label.  */
+   This function used to have the comment:
+
+      The MIPS assembler also automatically adjusts any preceding label.
+
+   The implementation therefore applied the adjustment to a maximum of
+   one label.  However, other label adjustments are applied to batches
+   of labels, and adjusting just one caused problems when new labels
+   were added for the sake of debugging or unwind information.
+   We therefore adjust all preceding labels (given as LABELS) instead.  */
 
 static void
 
 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 ();
 {
   mips_emit_delays ();
   mips_record_compressed_mode ();
@@ -15662,12 +15678,7 @@ mips_align (int to, int *fill, symbolS *label)
   else
     frag_align (to, fill ? *fill : 0, 0);
   record_alignment (now_seg, to);
   else
     frag_align (to, fill ? *fill : 0, 0);
   record_alignment (now_seg, to);
-  if (label != NULL)
-    {
-      gas_assert (S_GET_SEGMENT (label) == now_seg);
-      symbol_set_frag (label, frag_now);
-      S_SET_VALUE (label, (valueT) frag_now_fix ());
-    }
+  mips_move_labels (labels, FALSE);
 }
 
 /* Align to a given power of two.  .align 0 turns off the automatic
 }
 
 /* Align to a given power of two.  .align 0 turns off the automatic
@@ -15709,7 +15720,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;
       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
     {
     }
   else
     {
@@ -15879,12 +15890,10 @@ s_cons (int log_size)
 {
   segment_info_type *si = seg_info (now_seg);
   struct insn_label_list *l = si->label_list;
 {
   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_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 ();
 }
   cons (1 << log_size);
   mips_clear_insn_labels ();
 }
@@ -15894,18 +15903,15 @@ s_float_cons (int type)
 {
   segment_info_type *si = seg_info (now_seg);
   struct insn_label_list *l = si->label_list;
 {
   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_emit_delays ();
 
   if (auto_align)
     {
       if (type == 'd')
-       mips_align (3, 0, label);
+       mips_align (3, 0, l);
       else
       else
-       mips_align (2, 0, label);
+       mips_align (2, 0, l);
     }
 
   float_cons (type);
     }
 
   float_cons (type);
@@ -16685,7 +16691,6 @@ s_gpword (int ignore ATTRIBUTE_UNUSED)
 {
   segment_info_type *si;
   struct insn_label_list *l;
 {
   segment_info_type *si;
   struct insn_label_list *l;
-  symbolS *label;
   expressionS ex;
   char *p;
 
   expressionS ex;
   char *p;
 
@@ -16698,10 +16703,9 @@ s_gpword (int ignore ATTRIBUTE_UNUSED)
 
   si = seg_info (now_seg);
   l = si->label_list;
 
   si = seg_info (now_seg);
   l = si->label_list;
-  label = l != NULL ? l->label : NULL;
   mips_emit_delays ();
   if (auto_align)
   mips_emit_delays ();
   if (auto_align)
-    mips_align (2, 0, label);
+    mips_align (2, 0, l);
 
   expression (&ex);
   mips_clear_insn_labels ();
 
   expression (&ex);
   mips_clear_insn_labels ();
@@ -16725,7 +16729,6 @@ s_gpdword (int ignore ATTRIBUTE_UNUSED)
 {
   segment_info_type *si;
   struct insn_label_list *l;
 {
   segment_info_type *si;
   struct insn_label_list *l;
-  symbolS *label;
   expressionS ex;
   char *p;
 
   expressionS ex;
   char *p;
 
@@ -16738,10 +16741,9 @@ s_gpdword (int ignore ATTRIBUTE_UNUSED)
 
   si = seg_info (now_seg);
   l = si->label_list;
 
   si = seg_info (now_seg);
   l = si->label_list;
-  label = l != NULL ? l->label : NULL;
   mips_emit_delays ();
   if (auto_align)
   mips_emit_delays ();
   if (auto_align)
-    mips_align (3, 0, label);
+    mips_align (3, 0, l);
 
   expression (&ex);
   mips_clear_insn_labels ();
 
   expression (&ex);
   mips_clear_insn_labels ();
index cc2aa28..e8075e6 100644 (file)
@@ -1,3 +1,8 @@
+2012-01-08  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * gas/mips/align3.s, gas/mips/align3.d: New testcase.
+       * gas/mips/mips.exp: Run it.
+
 2012-01-04  Iain Sandoe  <idsandoe@googlemail.com>
 
        * gas/mach-o/zerofill-2.d: New.
 2012-01-04  Iain Sandoe  <idsandoe@googlemail.com>
 
        * gas/mach-o/zerofill-2.d: New.
diff --git a/gas/testsuite/gas/mips/align3.d b/gas/testsuite/gas/mips/align3.d
new file mode 100644 (file)
index 0000000..4636858
--- /dev/null
@@ -0,0 +1,6 @@
+# objdump: -sj.data
+
+.*
+
+Contents of section \.data:
+ 0000 00000000 (00000004|04000000) (00000004|04000000) 00000000  ................
diff --git a/gas/testsuite/gas/mips/align3.s b/gas/testsuite/gas/mips/align3.s
new file mode 100644 (file)
index 0000000..dc135ef
--- /dev/null
@@ -0,0 +1,9 @@
+       .data
+start:
+       .byte   0
+foo:
+bar:
+       .align  2
+       .word   foo - start
+       .word   bar - start
+       .word   0
index 4beb3e2..597c572 100644 (file)
@@ -1049,6 +1049,7 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test "align"
     run_dump_test "align2"
     run_dump_test "align2-el"
     run_dump_test "align"
     run_dump_test "align2"
     run_dump_test "align2-el"
+    run_dump_test "align3"
     run_dump_test "odd-float"
 
     run_list_test_arches "mips-macro-ill-sfp" "-32 -msingle-float" \
     run_dump_test "odd-float"
 
     run_list_test_arches "mips-macro-ill-sfp" "-32 -msingle-float" \