This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[3.2/3.3/mainline] Fix alignment of SSE arguments


Hi,
here is even more updated patch to get alignment of SSE arguments right.  I
would really like this to see in 3.3, even when we are still not correct (as
the dynamic stack alignment patches are still not merged).  This makes SSE code
useable, if you accept the assumption that everything keeps stack aligned (is
compiled with default preffered-stack-boundary).  This is "usually the case"

Honza

#include <xmmintrin.h>
struct a
{
  __m128 b __attribute__ ((aligned (8))) __attribute__ ((packed));
} aa;
test (int a, struct a b, int c);

q()
{
  test (1,aa,2);
}
Mon Oct 21 17:07:47 CEST 2002  Jan Hubicka  <jh@suse.cz>

	* i386.c (contains_128bit_aligned_vector_p): New function
	(ix86_function_arg_boundary): Properly align vector modes.
Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.532
diff -c -3 -p -r1.532 i386.c
*** i386.c	9 Feb 2003 23:30:51 -0000	1.532
--- i386.c	10 Feb 2003 12:25:56 -0000
*************** static bool ix86_function_ok_for_sibcall
*** 880,885 ****
--- 880,886 ----
  static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
  static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
  static int ix86_value_regno PARAMS ((enum machine_mode));
+ static bool contains_128bit_aligned_vector_p PARAMS ((tree));
  static bool ix86_ms_bitfield_layout_p PARAMS ((tree));
  static tree ix86_handle_struct_attribute PARAMS ((tree *, tree, tree, int, bool *));
  static int extended_reg_mentioned_1 PARAMS ((rtx *, void *));
*************** function_arg_pass_by_reference (cum, mod
*** 2533,2538 ****
--- 2534,2597 ----
    return 0;
  }
  
+ /* Return true when TYPE should be 128bit aligned for 32bit argument passing
+    ABI  */
+ static bool
+ contains_128bit_aligned_vector_p (type)
+      tree type;
+ {
+   enum machine_mode mode = TYPE_MODE (type);
+   if (SSE_REG_MODE_P (mode)
+       && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
+     return true;
+   if (TYPE_ALIGN (type) < 128)
+     return false;
+ 
+   if (AGGREGATE_TYPE_P (type))
+     {
+       /* Walk the agregates recursivly.  */
+       if (TREE_CODE (type) == RECORD_TYPE
+ 	  || TREE_CODE (type) == UNION_TYPE
+ 	  || TREE_CODE (type) == QUAL_UNION_TYPE)
+ 	{
+ 	  tree field;
+ 
+ 	  if (TYPE_BINFO (type) != NULL
+ 	      && TYPE_BINFO_BASETYPES (type) != NULL)
+ 	    {
+ 	      tree bases = TYPE_BINFO_BASETYPES (type);
+ 	      int n_bases = TREE_VEC_LENGTH (bases);
+ 	      int i;
+ 
+ 	      for (i = 0; i < n_bases; ++i)
+ 		{
+ 		  tree binfo = TREE_VEC_ELT (bases, i);
+ 		  tree type = BINFO_TYPE (binfo);
+ 
+ 		  if (contains_128bit_aligned_vector_p (type))
+ 		    return true;
+ 		}
+ 	    }
+ 	  /* And now merge the fields of structure.   */
+ 	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ 	    {
+ 	      if (TREE_CODE (field) == FIELD_DECL
+ 		  && contains_128bit_aligned_vector_p (TREE_TYPE (field)))
+ 		return true;
+ 	    }
+ 	}
+       /* Just for use if some languages passes arrays by value.  */
+       else if (TREE_CODE (type) == ARRAY_TYPE)
+ 	{
+ 	  if (contains_128bit_aligned_vector_p (TREE_TYPE (type)))
+ 	    return true;
+ 	}
+       else
+ 	abort ();
+     }
+   return false;
+ }
+ 
  /* Gives the alignment boundary, in bits, of an argument with the specified mode
     and type.   */
  
*************** ix86_function_arg_boundary (mode, type)
*** 2542,2555 ****
       tree type;
  {
    int align;
-   if (!TARGET_64BIT)
-     return PARM_BOUNDARY;
    if (type)
      align = TYPE_ALIGN (type);
    else
      align = GET_MODE_ALIGNMENT (mode);
    if (align < PARM_BOUNDARY)
      align = PARM_BOUNDARY;
    if (align > 128)
      align = 128;
    return align;
--- 2601,2634 ----
       tree type;
  {
    int align;
    if (type)
      align = TYPE_ALIGN (type);
    else
      align = GET_MODE_ALIGNMENT (mode);
    if (align < PARM_BOUNDARY)
      align = PARM_BOUNDARY;
+   if (!TARGET_64BIT)
+     {
+       /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
+ 	 make an exception for SSE modes since these require 128bit
+ 	 alignment.  
+ 
+ 	 The handling here differs from field_alignment.  ICC aligns MMX
+ 	 arguments to 4 byte boundaries, while structure fields are aligned
+ 	 to 8 byte boundaries.  */
+       if (!type)
+ 	{
+ 	  if (!SSE_REG_MODE_P (mode))
+ 	    align = PARM_BOUNDARY;
+ 	}
+       else
+ 	{
+ 	  if (!contains_128bit_aligned_vector_p (type))
+ 	    align = PARM_BOUNDARY;
+ 	}
+       if (align != PARM_BOUNDARY && !TARGET_SSE)
+ 	abort();
+     }
    if (align > 128)
      align = 128;
    return align;


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