From: Bob Wilson Date: Fri, 2 Nov 2007 00:45:34 +0000 (+0000) Subject: * config/tc-xtensa.c (xtensa_symbol_new_hook): New. X-Git-Tag: sid-snapshot-20071201~278 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6a7eedfedcbe83b936a8be8abc489f0202205c7a;p=thirdparty%2Fbinutils-gdb.git * 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. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 9dd33e7ddc2..8ec67340f8a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2007-11-01 Sterling Augustine + + * 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 * config/tc-i386.c (md_assemble): Replace no_xsuf with diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index 1882572a1a8..0738f2740d6 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -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, diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h index 86980c0f3c6..d3ae0241ee3 100644 --- a/gas/config/tc-xtensa.h +++ b/gas/config/tc-xtensa.h @@ -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