diff options
author | Jan Hubicka <jh@suse.cz> | 2003-02-11 22:58:09 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2003-02-11 21:58:09 +0000 |
commit | 8b978a57fad8f2a6bbf590521b06f606a6f953c0 (patch) | |
tree | 14fed9983febcab1ba4bc99d3b37feac8d1370bd | |
parent | ce3039af7dc478d4ac6d0fdeda3d1c3e0f97c943 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 83 |
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; |