From 8b978a57fad8f2a6bbf590521b06f606a6f953c0 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 11 Feb 2003 22:58:09 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++ gcc/config/i386/i386.c | 83 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 69ef14413a6..f1341b2b576 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Mon Oct 21 17:07:47 CEST 2002 Jan Hubicka + + * i386.c (contains_128bit_aligned_vector_p): New function. + (ix86_function_arg_boundary): Properly align vector modes. + 2003-02-11 Bob Wilson * 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 ca9e0aaad15..cad5c60cd65 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; -- 2.30.2