i386.c (contains_128bit_aligned_vector_p): New function.

* i386.c (contains_128bit_aligned_vector_p): New function.
	(ix86_function_arg_boundary): Properly align vector modes.

From-SVN: r62732
This commit is contained in:
Jan Hubicka 2003-02-11 22:58:09 +01:00 committed by Jan Hubicka
parent ce3039af7d
commit 8b978a57fa
2 changed files with 86 additions and 2 deletions

View File

@ -1,3 +1,8 @@
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.
2003-02-11 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.md (set_frame_ptr): Change rtl to set reg a7.

View File

@ -880,6 +880,7 @@ static bool ix86_function_ok_for_sibcall PARAMS ((tree, tree));
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 *));
@ -2534,6 +2535,64 @@ function_arg_pass_by_reference (cum, mode, type, named)
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. */
@ -2543,14 +2602,34 @@ ix86_function_arg_boundary (mode, type)
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 (!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;