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.
+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.
-/* 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. */
+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)
{
+ mips_move_text_labels ();
#ifndef NO_ECOFF_DEBUGGING
if (ECOFF_DEBUGGING)
#ifndef NO_ECOFF_DEBUGGING
if (ECOFF_DEBUGGING)
{
while (nops-- > 0)
add_fixed_insn (NOP_INSN);
{
while (nops-- > 0)
add_fixed_insn (NOP_INSN);
+ mips_move_text_labels ();
}
}
mips_no_prev_insn ();
}
}
mips_no_prev_insn ();
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_text_labels ();
}
mips_mark_labels ();
mips_clear_insn_labels ();
}
mips_mark_labels ();
mips_clear_insn_labels ();
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. */
-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 ();
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
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);
{
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;
- 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 ();
}
{
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 (2, 0, label);
{
segment_info_type *si;
struct insn_label_list *l;
{
segment_info_type *si;
struct insn_label_list *l;
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);
expression (&ex);
mips_clear_insn_labels ();
expression (&ex);
mips_clear_insn_labels ();
{
segment_info_type *si;
struct insn_label_list *l;
{
segment_info_type *si;
struct insn_label_list *l;
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);
expression (&ex);
mips_clear_insn_labels ();
expression (&ex);
mips_clear_insn_labels ();
+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.
--- /dev/null
+# objdump: -sj.data
+
+.*
+
+Contents of section \.data:
+ 0000 00000000 (00000004|04000000) (00000004|04000000) 00000000 ................
--- /dev/null
+ .data
+start:
+ .byte 0
+foo:
+bar:
+ .align 2
+ .word foo - start
+ .word bar - start
+ .word 0
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 "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" \