2004-07-22 Paolo Bonzini * config/rs6000/rs6000.c (USE_ALTIVEC_FOR_ARG_P, init_cumulative_args, function_arg_boundary, function_arg_advance, function_arg, rs6000_pass_by_reference, rs6000_gimplify_va_arg): Look into the type instead of using ALTIVEC_VECTOR_MODE. * config/i386/i386.c (function_arg): Always treat 8- and 16-byte wide vectors the same, even if MMX/SSE are disabled. (contains_128bit_aligned_vector_p): Add comment. Index: config/rs6000/rs6000.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v retrieving revision 1.671 diff -u -r1.671 rs6000.c --- config/rs6000/rs6000.c 23 Jul 2004 04:35:17 -0000 1.671 +++ config/rs6000/rs6000.c 23 Jul 2004 13:44:19 -0000 @@ -4426,7 +4426,9 @@ /* Nonzero if we can use an AltiVec register to pass this arg. */ #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \ - (ALTIVEC_VECTOR_MODE (MODE) \ + (type \ + && TREE_CODE (TYPE) == VECTOR_TYPE \ + && int_size_in_bytes (TYPE) == 16 \ && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \ && TARGET_ALTIVEC_ABI \ && (NAMED)) @@ -4521,7 +4523,8 @@ if (fntype && !TARGET_ALTIVEC && TARGET_ALTIVEC_ABI - && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype)))) + && TREE_CODE (TREE_TYPE (fntype)) == VECTOR_TYPE + && int_size_in_bytes (TREE_TYPE (fntype)) == 16) { error ("Cannot return value in vector register because" " altivec instructions are disabled, use -maltivec" @@ -4609,14 +4612,15 @@ V.4 wants long longs to be double word aligned. */ int -function_arg_boundary (enum machine_mode mode, tree type ATTRIBUTE_UNUSED) +function_arg_boundary (enum machine_mode mode, tree type) { if (DEFAULT_ABI == ABI_V4 && GET_MODE_SIZE (mode) == 8) return 64; - else if (SPE_VECTOR_MODE (mode)) - return 64; - else if (ALTIVEC_VECTOR_MODE (mode)) - return 128; + else if (type + && TREE_CODE (type) == VECTOR_TYPE + && (int_size_in_bytes (type) == 8 + || int_size_in_bytes (type) == 16)) + return 8 * int_size_in_bytes (type); else return PARM_BOUNDARY; } @@ -4653,7 +4657,10 @@ { cum->nargs_prototype--; - if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) + if (TARGET_ALTIVEC_ABI + && type + && TREE_CODE (type) == VECTOR_TYPE + && int_size_in_bytes (type) == 16) { bool stack = false; @@ -4956,7 +4963,10 @@ } else return gen_rtx_REG (mode, cum->vregno); - else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) + else if (TARGET_ALTIVEC_ABI + && type + && TREE_CODE (type) == VECTOR_TYPE + && int_size_in_bytes (type) == 16) { if (named || abi == ABI_V4) return NULL_RTX; @@ -5189,13 +5199,17 @@ static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED, - tree type, bool named ATTRIBUTE_UNUSED) + enum machine_mode mode, tree type, + bool named ATTRIBUTE_UNUSED) { if ((DEFAULT_ABI == ABI_V4 && ((type && AGGREGATE_TYPE_P (type)) || mode == TFmode)) - || (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) + || (TARGET_32BIT + && !TARGET_ALTIVEC_ABI + && type + && TREE_CODE (type) == VECTOR_TYPE + && int_size_in_bytes (type) == 16) || (type && int_size_in_bytes (type) < 0)) { if (TARGET_DEBUG_ARG) @@ -5534,7 +5548,9 @@ DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set (); /* AltiVec vectors never go in registers when -mabi=altivec. */ - if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))) + if (TARGET_ALTIVEC_ABI + && TREE_CODE (type) == VECTOR_TYPE + && int_size_in_bytes (type) == 16) align = 16; else { Index: config/i386/i386.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v retrieving revision 1.697 diff -u -p -r1.697 i386.c --- config/i386/i386.c 23 Jul 2004 04:35:15 -0000 1.697 +++ config/i386/i386.c 23 Jul 2004 15:24:20 -0000 @@ -2664,6 +2664,28 @@ function_arg (CUMULATIVE_ARGS *cum, /* c int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; static bool warnedsse, warnedmmx; + /* To simplify the code below, represent vector types with a vector mode + even if MMX/SSE are not active. */ + if (type + && TREE_CODE (type) == VECTOR_TYPE + && (bytes == 8 || bytes == 16) + && GET_MODE_CLASS (TYPE_MODE (type)) != MODE_VECTOR_INT + && GET_MODE_CLASS (TYPE_MODE (type)) != MODE_VECTOR_FLOAT) + { + enum machine_mode innermode = TYPE_MODE (TREE_TYPE (type)); + mode = TREE_CODE (TREE_TYPE (type)) == REAL_TYPE + ? MIN_MODE_VECTOR_FLOAT : MIN_MODE_VECTOR_INT; + + /* Get the mode which has this inner mode and number of units. */ + while (GET_MODE_NUNITS (mode) != TYPE_VECTOR_SUBPARTS (type) + || GET_MODE_INNER (mode) != innermode) + { + mode = GET_MODE_WIDER_MODE (mode); + if (mode == VOIDmode) + abort (); + } + } + /* Handle a hidden AL argument containing number of registers for varargs x86-64 functions. For i386 ABI just return constm1_rtx to avoid any AL settings. */ @@ -2794,7 +2816,7 @@ ix86_pass_by_reference (CUMULATIVE_ARGS } /* Return true when TYPE should be 128bit aligned for 32bit argument passing - ABI */ + ABI. Only called if TARGET_SSE. */ static bool contains_128bit_aligned_vector_p (tree type) {