]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* config/tc-xtensa.c (xtensa_symbol_new_hook): New.
authorBob Wilson <bob.wilson@acm.org>
Fri, 2 Nov 2007 00:45:34 +0000 (00:45 +0000)
committerBob Wilson <bob.wilson@acm.org>
Fri, 2 Nov 2007 00:45:34 +0000 (00:45 +0000)
(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.

gas/ChangeLog
gas/config/tc-xtensa.c
gas/config/tc-xtensa.h

index 9dd33e7ddc2753c18460be73788ffb48d287dc27..8ec67340f8ae25bd442fcfab29b4b012ec86d81b 100644 (file)
@@ -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
index 1882572a1a8828c110cc9ab7e7254d3554a908d7..0738f2740d6f7c296acfeb35985d670810d46008 100644 (file)
@@ -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,
index 86980c0f3c6e3312a77cf2a1676bfc94012807da..d3ae0241ee36b6bf533a15b959a94567dcde801b 100644 (file)
@@ -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