* config/tc-xtensa.c (xtensa_symbol_new_hook): New.
(xtensa_mark_difference_of_two_symbols): New. (xtensa_post_relax_hook): Call xtensa_mark_difference_of_two_symbols. * config/tc-xtensa.h (xtensa_symfield_type): Add next_expr_symbol. (tc_symbol_new_hook): Define.
This commit is contained in:
parent
e4342ca3b8
commit
6a7eedfedc
|
@ -1,3 +1,11 @@
|
|||
2007-11-01 Sterling Augustine <sterling@tensilica.com>
|
||||
|
||||
* config/tc-xtensa.c (xtensa_symbol_new_hook): New.
|
||||
(xtensa_mark_difference_of_two_symbols): New.
|
||||
(xtensa_post_relax_hook): Call xtensa_mark_difference_of_two_symbols.
|
||||
* config/tc-xtensa.h (xtensa_symfield_type): Add next_expr_symbol.
|
||||
(tc_symbol_new_hook): Define.
|
||||
|
||||
2007-11-01 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* config/tc-i386.c (md_assemble): Replace no_xsuf with
|
||||
|
|
|
@ -5599,6 +5599,22 @@ xtensa_fix_adjustable (fixS *fixP)
|
|||
}
|
||||
|
||||
|
||||
/* tc_symbol_new_hook */
|
||||
|
||||
symbolS *expr_symbols = NULL;
|
||||
|
||||
void
|
||||
xtensa_symbol_new_hook (symbolS *sym)
|
||||
{
|
||||
if (S_GET_SEGMENT (sym) == expr_section)
|
||||
{
|
||||
symbol_get_tc (sym)->next_expr_symbol = expr_symbols;
|
||||
expr_symbols = sym;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
md_apply_fix (fixS *fixP, valueT *valP, segT seg)
|
||||
{
|
||||
|
@ -6943,6 +6959,7 @@ static void xtensa_cleanup_align_frags (void);
|
|||
static void xtensa_fix_target_frags (void);
|
||||
static void xtensa_mark_narrow_branches (void);
|
||||
static void xtensa_mark_zcl_first_insns (void);
|
||||
static void xtensa_mark_difference_of_two_symbols (void);
|
||||
static void xtensa_fix_a0_b_retw_frags (void);
|
||||
static void xtensa_fix_b_j_loop_end_frags (void);
|
||||
static void xtensa_fix_close_loop_end_frags (void);
|
||||
|
@ -7206,6 +7223,55 @@ xtensa_mark_zcl_first_insns (void)
|
|||
}
|
||||
|
||||
|
||||
/* Some difference-of-symbols expressions make it out to the linker. Some
|
||||
don't. If one does, then the linker can optimize between the two labels.
|
||||
If it doesn't, then the linker shouldn't. */
|
||||
|
||||
static void
|
||||
xtensa_mark_difference_of_two_symbols (void)
|
||||
{
|
||||
symbolS *expr_sym;
|
||||
|
||||
for (expr_sym = expr_symbols; expr_sym;
|
||||
expr_sym = symbol_get_tc (expr_sym)->next_expr_symbol)
|
||||
{
|
||||
expressionS *expr = symbol_get_value_expression (expr_sym);
|
||||
|
||||
if (expr->X_op == O_subtract)
|
||||
{
|
||||
symbolS *left = expr->X_add_symbol;
|
||||
symbolS *right = expr->X_op_symbol;
|
||||
|
||||
/* Difference of two symbols not in the same section
|
||||
are handled with relocations in the linker. */
|
||||
if (S_GET_SEGMENT (left) == S_GET_SEGMENT (right))
|
||||
{
|
||||
fragS *start;
|
||||
fragS *end;
|
||||
|
||||
if (symbol_get_frag (left)->fr_address
|
||||
<= symbol_get_frag (right)->fr_address)
|
||||
{
|
||||
start = symbol_get_frag (left);
|
||||
end = symbol_get_frag (right);
|
||||
}
|
||||
else
|
||||
{
|
||||
start = symbol_get_frag (right);
|
||||
end = symbol_get_frag (left);
|
||||
}
|
||||
do
|
||||
{
|
||||
start->tc_frag_data.is_no_transform = 1;
|
||||
start = start->fr_next;
|
||||
}
|
||||
while (start && start->fr_address < end->fr_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Re-process all of the fragments looking to convert all of the
|
||||
RELAX_ADD_NOP_IF_A0_B_RETW. If the next instruction is a
|
||||
conditional branch or a retw/retw.n, convert this frag to one that
|
||||
|
@ -10208,6 +10274,7 @@ xtensa_post_relax_hook (void)
|
|||
|
||||
xtensa_find_unmarked_state_frags ();
|
||||
xtensa_mark_frags_for_org ();
|
||||
xtensa_mark_difference_of_two_symbols ();
|
||||
|
||||
xtensa_create_property_segments (get_frag_is_literal,
|
||||
NULL,
|
||||
|
|
|
@ -275,6 +275,7 @@ typedef struct xtensa_symfield_type
|
|||
{
|
||||
unsigned int is_loop_target : 1;
|
||||
unsigned int is_branch_target : 1;
|
||||
symbolS *next_expr_symbol;
|
||||
} xtensa_symfield_type;
|
||||
|
||||
|
||||
|
@ -338,6 +339,7 @@ extern char *xtensa_section_rename (char *);
|
|||
#define tc_fix_adjustable(fix) xtensa_fix_adjustable (fix)
|
||||
#define tc_frob_label(sym) xtensa_frob_label (sym)
|
||||
#define tc_unrecognized_line(ch) xtensa_unrecognized_line (ch)
|
||||
#define tc_symbol_new_hook(sym) xtensa_symbol_new_hook (sym)
|
||||
#define md_do_align(a,b,c,d,e) xtensa_flush_pending_output ()
|
||||
#define md_elf_section_change_hook xtensa_elf_section_change_hook
|
||||
#define md_end xtensa_end
|
||||
|
|
Loading…
Reference in New Issue