aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2003-02-11 22:58:09 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2003-02-11 21:58:09 +0000
commit8b978a57fad8f2a6bbf590521b06f606a6f953c0 (patch)
tree14fed9983febcab1ba4bc99d3b37feac8d1370bd
parentce3039af7dc478d4ac6d0fdeda3d1c3e0f97c943 (diff)
downloadgcc-8b978a57fad8f2a6bbf590521b06f606a6f953c0.zip
gcc-8b978a57fad8f2a6bbf590521b06f606a6f953c0.tar.gz
gcc-8b978a57fad8f2a6bbf590521b06f606a6f953c0.tar.bz2
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
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/i386/i386.c83
2 files changed, 86 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 69ef144..f1341b2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index ca9e0aa..cad5c60 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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;