* config/tc-mips.h (TC_SEGMENT_INFO_TYPE): Declare per-segment

label_list.
	* config/tc-mips.c (label_list): Define per-segment label_list.
	(mips_clear_insn_labels, mips_move_labels, mips16_mark_labels,
	append_insn, s_align, s_cons, s_float_cons, s_gpword, s_gpdword,
	mips_from_file_after_relocs, mips_define_label): Use per-segment
	label_list.
This commit is contained in:
Thiemo Seufer 2006-06-23 16:26:13 +00:00
parent d58c2e3acd
commit a8dbcb8573
3 changed files with 67 additions and 28 deletions

View file

@ -1,3 +1,14 @@
2006-06-23 Thiemo Seufer <ths@mips.com>
David Ung <davidu@mips.com>
* config/tc-mips.h (TC_SEGMENT_INFO_TYPE): Declare per-segment
label_list.
* config/tc-mips.c (label_list): Define per-segment label_list.
(mips_clear_insn_labels, mips_move_labels, mips16_mark_labels,
append_insn, s_align, s_cons, s_float_cons, s_gpword, s_gpdword,
mips_from_file_after_relocs, mips_define_label): Use per-segment
label_list.
2006-06-22 Thiemo Seufer <ths@mips.com>
* config/tc-mips.c (ISA_SUPPORTS_MIPS16E): New macro.

View file

@ -1168,8 +1168,8 @@ struct insn_label_list
symbolS *label;
};
static struct insn_label_list *insn_labels;
static struct insn_label_list *free_insn_labels;
#define label_list tc_segment_info_data
static void mips_clear_insn_labels (void);
@ -1177,12 +1177,19 @@ static inline void
mips_clear_insn_labels (void)
{
register struct insn_label_list **pl;
segment_info_type *si;
for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next)
;
*pl = insn_labels;
insn_labels = NULL;
if (now_seg)
{
for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next)
;
si = seg_info (now_seg);
*pl = si->label_list;
si->label_list = NULL;
}
}
static char *expr_end;
@ -2115,10 +2122,11 @@ reg_needs_delay (unsigned int reg)
static void
mips_move_labels (void)
{
segment_info_type *si = seg_info (now_seg);
struct insn_label_list *l;
valueT val;
for (l = insn_labels; l != NULL; l = l->next)
for (l = si->label_list; l != NULL; l = l->next)
{
assert (S_GET_SEGMENT (l->label) == now_seg);
symbol_set_frag (l->label, frag_now);
@ -2141,21 +2149,22 @@ mips_move_labels (void)
static void
mips16_mark_labels (void)
{
if (mips_opts.mips16)
{
struct insn_label_list *l;
valueT val;
segment_info_type *si = seg_info (now_seg);
struct insn_label_list *l;
for (l = insn_labels; l != NULL; l = l->next)
{
#ifdef OBJ_ELF
if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
S_SET_OTHER (l->label, STO_MIPS16);
if (!mips_opts.mips16)
return;
for (l = si->label_list; l != NULL; l = l->next)
{
symbolS *label = l->label;
#if defined(OBJ_ELF) || defined(OBJ_MAYBE_ELF)
if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
S_SET_OTHER (label, STO_MIPS16);
#endif
val = S_GET_VALUE (l->label);
if ((val & 1) == 0)
S_SET_VALUE (l->label, val + 1);
}
if ((S_GET_VALUE (label) & 1) == 0)
S_SET_VALUE (label, S_GET_VALUE (label) | 1);
}
}
@ -2483,6 +2492,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
unsigned long prev_pinfo, pinfo;
relax_stateT prev_insn_frag_type = 0;
bfd_boolean relaxed_branch = FALSE;
segment_info_type *si = seg_info (now_seg);
/* Mark instruction labels in mips16 mode. */
mips16_mark_labels ();
@ -2899,7 +2909,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
whether there is a label on this instruction. If
there are any branches to anything other than a
label, users must use .set noreorder. */
|| insn_labels != NULL
|| si->label_list != NULL
/* If the previous instruction is in a variant frag
other than this branch's one, we cannot do the swap.
This does not apply to the mips16, which uses variant
@ -11966,9 +11976,11 @@ s_align (int x ATTRIBUTE_UNUSED)
temp_fill = 0;
if (temp)
{
segment_info_type *si = seg_info (now_seg);
struct insn_label_list *l = si->label_list;
/* Auto alignment should be switched on by next section change */
auto_align = 1;
mips_align (temp, (int) temp_fill,
insn_labels != NULL ? insn_labels->label : NULL);
mips_align (temp, (int) temp_fill, l != NULL ? l->label : NULL);
}
else
{
@ -12121,9 +12133,11 @@ mips_enable_auto_align (void)
static void
s_cons (int log_size)
{
segment_info_type *si = seg_info (now_seg);
struct insn_label_list *l = si->label_list;
symbolS *label;
label = insn_labels != NULL ? insn_labels->label : NULL;
label = l != NULL ? l->label : NULL;
mips_emit_delays ();
if (log_size > 0 && auto_align)
mips_align (log_size, 0, label);
@ -12134,9 +12148,11 @@ s_cons (int log_size)
static void
s_float_cons (int type)
{
segment_info_type *si = seg_info (now_seg);
struct insn_label_list *l = si->label_list;
symbolS *label;
label = insn_labels != NULL ? insn_labels->label : NULL;
label = l != NULL ? l->label : NULL;
mips_emit_delays ();
@ -12811,6 +12827,8 @@ s_gpvalue (int ignore ATTRIBUTE_UNUSED)
static void
s_gpword (int ignore ATTRIBUTE_UNUSED)
{
segment_info_type *si;
struct insn_label_list *l;
symbolS *label;
expressionS ex;
char *p;
@ -12822,7 +12840,9 @@ s_gpword (int ignore ATTRIBUTE_UNUSED)
return;
}
label = insn_labels != NULL ? insn_labels->label : NULL;
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);
@ -12847,6 +12867,8 @@ s_gpword (int ignore ATTRIBUTE_UNUSED)
static void
s_gpdword (int ignore ATTRIBUTE_UNUSED)
{
segment_info_type *si;
struct insn_label_list *l;
symbolS *label;
expressionS ex;
char *p;
@ -12858,7 +12880,9 @@ s_gpdword (int ignore ATTRIBUTE_UNUSED)
return;
}
label = insn_labels != NULL ? insn_labels->label : NULL;
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);
@ -13997,6 +14021,7 @@ mips_frob_file_after_relocs (void)
void
mips_define_label (symbolS *sym)
{
segment_info_type *si = seg_info (now_seg);
struct insn_label_list *l;
if (free_insn_labels == NULL)
@ -14008,8 +14033,8 @@ mips_define_label (symbolS *sym)
}
l->label = sym;
l->next = insn_labels;
insn_labels = l;
l->next = si->label_list;
si->label_list = l;
#ifdef OBJ_ELF
dwarf2_emit_label (sym);

View file

@ -58,6 +58,9 @@ extern void mips_handle_align (struct frag *);
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
struct insn_label_list;
#define TC_SEGMENT_INFO_TYPE struct insn_label_list *
/* Tell assembler that we have an itbl_mips.h header file to include. */
#define HAVE_ITBL_CPU