This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 3.0/4 v3] MIPS/GAS: Record fake labels like regular ones


Hi Richard,

On Sat, 30 Oct 2010, Richard Sandiford wrote:

> >  The fix below implements it.  I've used the hook called by generic code 
> > for each new symbol, but compared to the initial version I have removed 
> > the explicit check for fake labels based on your comments addressing the 
> > other change.  Like with the original the recording hook is called like it 
> > is done for regular labels (except DWARF-2 information is not produced 
> > preserving current behaviour).
> >
> >  Depending on the way symbols are defined this approach causes the 
> > recording hook to be called once or twice for the same symbol.  It will be 
> > called once for symbols that are not defined as labels, i.e. other than 
> > with colon() (which I think still should prevent branch swapping if they 
> > refer to code), and for true labels that have been referenced before the 
> > actual definition (i.e. forward referenced in the other sense ;) ).  It 
> > will be called twice for true labels whose definition is lexically the 
> > first ocurrence of the symbol defined.  Due to the complicated matter of 
> > dependencies here I have failed to find a way to avoid this double call 
> > without turning half of GAS upside down and I didn't feel like defining a 
> > new target hook would be the right way to do that either.
> 
> Hmm, the target hook sounds good to me TBH.  With your 2.5 patch, we can
> now pinpoint exactly when fake labels are created from ".", so a
> 
>   tc_instantiate_dot
> 
> or suchlike seems like a nice fit.  It avoids having to check the
> label value (which looks like a false generalisation) and should
> avoid the double calls as well.  (Well, OK, if "." is used twice
> in an expression, we'll create two fake labels and get a new call
> for each one.  But that's as it should be.)

 OK, I've changed the change.  I named the hook tc_new_dot_label.

> >  I had to reorder call to clear labels recorded for data directives 
> > though.  The problem with them was a newly generated label was recorded 
> > in the list as if applying to code that follows.  That would in turn move 
> > the label incorrectly if alignment operation was involved.  It could be 
> > triggered by code like this:
> >
> > 	.word	.
> > 	.word	.
> >
> > and possibly for symbols created with .eqv (I haven't checked the latter).  
> > The new arrangement is consistent with that used by append_insn() which 
> > only calls mips_clear_insn_labels() once all instruction processing has 
> > been made that further assures me it's the right change.
> 
> This part looks OK to me.  AIUI, the current code doesn't care whether
> the mips_clear_insn_labels call is in the old or new position.

 Yes, these ops cannot make labels other than by referring to the dot 
special symbol, so it is only this hook that makes it matter.

2010-12-08  Maciej W. Rozycki  <macro@codesourcery.com>

        gas/
	* symbols.c (symbol_clone_if_forward_ref): Call tc_new_dot_label
	for new fake labels created off the dot special symbol.
        * config/tc-mips.h (tc_new_dot_label): New macro.
        (mips_record_label): New prototype.
	* config/tc-mips.c (my_getExpression): Remove MIPS16 fake label
	annotation.
	(s_cons, s_float_cons, s_gpword, s_gpdword): Only clear labels
	recorded once data expressions have been evaluated.
	(mips_define_label): Move code to record labels over to...
	(mips_record_label): ... this new function.
	* doc/internals.texi: Document tc_new_dot_label.

  Maciej

binutils-gas-mips-label.diff
Index: binutils-fsf-trunk-quilt/gas/config/tc-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-mips.c	2010-12-07 21:00:02.000000000 +0000
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.c	2010-12-07 23:54:13.000000000 +0000
@@ -11136,26 +11136,12 @@ static void
 my_getExpression (expressionS *ep, char *str)
 {
   char *save_in;
-  valueT val;
 
   save_in = input_line_pointer;
   input_line_pointer = str;
   expression (ep);
   expr_end = input_line_pointer;
   input_line_pointer = save_in;
-
-  /* If we are in mips16 mode, and this is an expression based on `.',
-     then we bump the value of the symbol by 1 since that is how other
-     text symbols are handled.  We don't bother to handle complex
-     expressions, just `.' plus or minus a constant.  */
-  if (mips_opts.mips16
-      && ep->X_op == O_symbol
-      && strcmp (S_GET_NAME (ep->X_add_symbol), FAKE_LABEL_NAME) == 0
-      && S_GET_SEGMENT (ep->X_add_symbol) == now_seg
-      && symbol_get_frag (ep->X_add_symbol) == frag_now
-      && symbol_constant_p (ep->X_add_symbol)
-      && (val = S_GET_VALUE (ep->X_add_symbol)) == frag_now_fix ())
-    S_SET_VALUE (ep->X_add_symbol, val + 1);
 }
 
 char *
@@ -12727,8 +12713,8 @@ s_cons (int log_size)
   mips_emit_delays ();
   if (log_size > 0 && auto_align)
     mips_align (log_size, 0, label);
-  mips_clear_insn_labels ();
   cons (1 << log_size);
+  mips_clear_insn_labels ();
 }
 
 static void
@@ -12750,9 +12736,8 @@ s_float_cons (int type)
 	mips_align (2, 0, label);
     }
 
-  mips_clear_insn_labels ();
-
   float_cons (type);
+  mips_clear_insn_labels ();
 }
 
 /* Handle .globl.  We need to override it because on Irix 5 you are
@@ -13517,9 +13502,9 @@ s_gpword (int ignore ATTRIBUTE_UNUSED)
   mips_emit_delays ();
   if (auto_align)
     mips_align (2, 0, label);
-  mips_clear_insn_labels ();
 
   expression (&ex);
+  mips_clear_insn_labels ();
 
   if (ex.X_op != O_symbol || ex.X_add_number != 0)
     {
@@ -13557,9 +13542,9 @@ s_gpdword (int ignore ATTRIBUTE_UNUSED)
   mips_emit_delays ();
   if (auto_align)
     mips_align (3, 0, label);
-  mips_clear_insn_labels ();
 
   expression (&ex);
+  mips_clear_insn_labels ();
 
   if (ex.X_op != O_symbol || ex.X_add_number != 0)
     {
@@ -14707,12 +14692,14 @@ mips_frob_file_after_relocs (void)
 
 #endif
 
-/* This function is called whenever a label is defined.  It is used
-   when handling branch delays; if a branch has a label, we assume we
-   can not move it.  */
+/* This function is called whenever a label is defined, including fake
+   labels instantiated off the dot special symbol.  It is used when
+   handling branch delays; if a branch has a label, we assume we cannot
+   move it.  This also bumps the value of the symbol by 1 in compressed
+   code.  */
 
 void
-mips_define_label (symbolS *sym)
+mips_record_label (symbolS *sym)
 {
   segment_info_type *si = seg_info (now_seg);
   struct insn_label_list *l;
@@ -14728,7 +14715,15 @@ mips_define_label (symbolS *sym)
   l->label = sym;
   l->next = si->label_list;
   si->label_list = l;
+}
+
+/* This function is called as tc_frob_label() whenever a label is defined
+   and adds a DWARF-2 record we only want for true labels.  */
 
+void
+mips_define_label (symbolS *sym)
+{
+  mips_record_label (sym);
 #ifdef OBJ_ELF
   dwarf2_emit_label (sym);
 #endif
Index: binutils-fsf-trunk-quilt/gas/config/tc-mips.h
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-mips.h	2010-12-07 21:00:02.000000000 +0000
+++ binutils-fsf-trunk-quilt/gas/config/tc-mips.h	2010-12-07 23:54:13.000000000 +0000
@@ -112,6 +112,9 @@ extern int mips_parse_long_option (const
 #define tc_frob_label(sym) mips_define_label (sym)
 extern void mips_define_label (symbolS *);
 
+#define tc_new_dot_label(sym) mips_record_label (sym)
+extern void mips_record_label (symbolS *);
+
 #define tc_frob_file_before_adjust() mips_frob_file_before_adjust ()
 extern void mips_frob_file_before_adjust (void);
 
Index: binutils-fsf-trunk-quilt/gas/doc/internals.texi
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/doc/internals.texi	2010-09-23 00:11:08.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/doc/internals.texi	2010-12-08 00:10:14.000000000 +0000
@@ -1395,6 +1395,11 @@ that @code{md_pcrel_from} does not take 
 @cindex tc_frob_label
 If you define this macro, GAS will call it each time a label is defined.
 
+@item tc_new_dot_label
+@cindex tc_new_dot_label
+If you define this macro, GAS will call it each time a fake label is created
+off the special dot symbol.
+
 @item md_section_align
 @cindex md_section_align
 GAS will call this function for each section at the end of the assembly, to
Index: binutils-fsf-trunk-quilt/gas/symbols.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/symbols.c	2010-12-07 23:03:24.000000000 +0000
+++ binutils-fsf-trunk-quilt/gas/symbols.c	2010-12-07 23:54:13.000000000 +0000
@@ -668,7 +668,12 @@ symbol_clone_if_forward_ref (symbolS *sy
 	      symbolP->sy_resolving = 0;
 	    }
 	  else
-	    symbolP = symbol_temp_new_now ();
+	    {
+	      symbolP = symbol_temp_new_now ();
+#ifdef tc_new_dot_label
+	      tc_new_dot_label (symbolP);
+#endif
+	    }
 	}
 
       symbolP->sy_value.X_add_symbol = add_symbol;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]