* 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> 2006-06-22 Thiemo Seufer <ths@mips.com>
* config/tc-mips.c (ISA_SUPPORTS_MIPS16E): New macro. * config/tc-mips.c (ISA_SUPPORTS_MIPS16E): New macro.

View File

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