This is the mail archive of the binutils@sources.redhat.com 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]

Re: Patch: Add a stop bit in alignment for alloc.


On Tue, Mar 02, 2004 at 10:12:16PM -0800, David Mosberger wrote:
> >>>>> On Tue, 2 Mar 2004 20:41:29 -0800, "H. J. Lu" <hjl@lucon.org> said:
> 
>   HJ> I checked in the patch. But it is not complete. If the alignment
>   HJ> directive is a no-op, the stop bit will be missing.
> 
> Yeah, I guess that's counter-intuitive given that gas would normally
> insert a stop-bit in front of the "alloc".  Having said that, putting
> an explicit stop-bit in front of the .align seems to do the right
> thing so hand-crafted assembly would probably be OK.  Also, for the
> first time, the Linux kernel built and worked with -falign-loops=32!
> Very nice!
> 

We only want to set align_frag for ".align N". If we can look back
a bundle, we can add a stop bit when needed. This patch seems to
work OK. When we can't look back and we need to, it will abort.



H.J.
---
2004-03-02  H.J. Lu  <hongjiu.lu@intel.com>

	* config/tc-ia64.c (dot_align): New.
	(ia64_do_align): Make it static.
	(md_pseudo_table): Use "dot_align" for "align".
	(ia64_md_do_align): Don't set align_frag here.
	(ia64_handle_align): Add a stop bit to the previous bundle if
	needed.

	* config/tc-ia64.h (ia64_do_align): Removed.

--- gas/config/tc-ia64.c.noop	2004-03-02 18:52:25.000000000 -0800
+++ gas/config/tc-ia64.c	2004-03-02 23:21:02.000000000 -0800
@@ -705,6 +705,7 @@ static int ar_is_in_integer_unit PARAMS 
 static void set_section PARAMS ((char *name));
 static unsigned int set_regstack PARAMS ((unsigned int, unsigned int,
 					  unsigned int, unsigned int));
+static void dot_align (int);
 static void dot_radix PARAMS ((int));
 static void dot_special_section PARAMS ((int));
 static void dot_proc PARAMS ((int));
@@ -1135,9 +1136,8 @@ ia64_flush_insns ()
     as_bad ("qualifying predicate not followed by instruction");
 }
 
-void
-ia64_do_align (nbytes)
-     int nbytes;
+static void
+ia64_do_align (int nbytes)
 {
   char *saved_input_line_pointer = input_line_pointer;
 
@@ -3034,6 +3034,14 @@ convert_expr_to_xy_reg (e, xy, regp)
 }
 
 static void
+dot_align (int arg)
+{
+  /* The current frag is an alignment frag.  */
+  align_frag = frag_now;
+  s_align_bytes (arg);
+}
+
+static void
 dot_radix (dummy)
      int dummy ATTRIBUTE_UNUSED;
 {
@@ -4960,7 +4968,7 @@ const pseudo_typeS md_pseudo_table[] =
     { "lb", dot_scope, 0 },
     { "le", dot_scope, 1 },
 #endif
-    { "align", s_align_bytes, 0 },
+    { "align", dot_align, 0 },
     { "regstk", dot_regstk, 0 },
     { "rotr", dot_rot, DYNREG_GR },
     { "rotf", dot_rot, DYNREG_FR },
@@ -10828,8 +10836,6 @@ ia64_md_do_align (n, fill, len, max)
      int len ATTRIBUTE_UNUSED;
      int max ATTRIBUTE_UNUSED;
 {
-  /* The current frag is an alignment frag.  */
-  align_frag = frag_now;
   if (subseg_text_p (now_seg))
     ia64_flush_insns ();
 }
@@ -10862,6 +10868,23 @@ ia64_handle_align (fragp)
   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   p = fragp->fr_literal + fragp->fr_fix;
 
+  /* If no paddings are needed, we check if we need a stop bit.  */ 
+  if (!bytes && fragp->tc_frag_data)
+    {
+      if (fragp->fr_fix < 16)
+	as_bad ("Can't add stop bit to mark end of instruction group");
+      else
+	{
+	  bfd_vma t0;
+
+	  /* Bundles are always in little-endian byte order.  */
+	  t0 = bfd_getl64 (p - 16);
+	  /* Add the stop bit to the previous bundle. */
+	  t0 |= 1;
+	  bfd_putl64 (t0, p - 16);
+	}
+    }
+
   /* Make sure we are on a 16-byte boundary, in case someone has been
      putting data into a text section.  */
   if (bytes & 15)
--- gas/config/tc-ia64.h.noop	2004-03-02 22:27:05.000000000 -0800
+++ gas/config/tc-ia64.h	2004-03-02 23:14:53.000000000 -0800
@@ -90,7 +90,6 @@ struct ia64_fix
     enum ia64_opnd opnd;
   };
 
-extern void ia64_do_align PARAMS((int n));
 extern void ia64_end_of_source PARAMS((void));
 extern void ia64_start_line PARAMS((void));
 extern int ia64_unrecognized_line PARAMS((int ch));


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