This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFC/RFT] Tree-level lowering of generic vectors, part 2
- From: Paolo Bonzini <paolo dot bonzini at polimi dot it>
- To: David Edelsohn <dje at watson dot ibm dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 06 Aug 2004 10:23:08 +0200
- Subject: Re: [RFC/RFT] Tree-level lowering of generic vectors, part 2
- References: <40FE496F.9090608@polimi.it> <200408052014.i75KE5D32016@makai.watson.ibm.com>
Any ideas on how to correct this problem?
This is caused by vector modes introducing a new beast: non-aggregate
types of BLKmode. This conflicts with the implementation of the
return_in_memory target hook in a couple of targets, one of which is rs6000.
The attached patch is an update of
http://gcc.gnu.org/ml/gcc-patches/2004-07/msg02197.html which takes care
of this as well. I checked manually that vector-2 now compiles at all
optimization levels.
Here is the situation.
Target which are not ok
-----------------------
pdp11: ?? should we care ??
rs6000: aggregates are passed in memory if bigger than 8 bytes, but
vectors are not.
Targets which are ok
--------------------
alpha: FP vectors passed in memory, int vectors only if bigger than a word
arc, arm, avr, h8300, ip2k, iq2000, m32r, m68hc11, mcore, pa, stormy16,
xtensa: vectors passed in memory if bigger than a fixed threshold,
typically 4/8/16 bytes
i386, mn10300, sh, sparc, v850: BLKmode stuff always passed in memory
mips: One of the above two depending on the ABI (no wonder...)
ia64: not sure about whether it is ok, but it has a fixed threshold
above which values are passed in memory... from looking at
function_value, it knows how to cope with BLKmode and it treats
aggregates and non-aggregates the same
s390: vectors always passed in memory
Paolo
2004-07-22 Paolo Bonzini <bonzini@gnu.org>
* 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.
(rs6000_return_in_memory): Return true for vectors
above 16 bytes.
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.678
diff -u -p -r1.678 rs6000.c
--- rs6000.c 4 Aug 2004 23:38:34 -0000 1.678
+++ rs6000.c 6 Aug 2004 08:06:14 -0000
@@ -4432,7 +4432,9 @@ rs6000_emit_move (rtx dest, rtx source,
/* 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))
@@ -4465,6 +4467,9 @@ rs6000_return_in_memory (tree type, tree
&& (TARGET_AIX_STRUCT_RET
|| (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
return true;
+ if (TREE_CODE (type) == VECTOR_TYPE
+ && int_size_in_bytes (type) > (TARGET_ALTIVEC ? 16 : 8))
+ return true;
if (DEFAULT_ABI == ABI_V4 && TYPE_MODE (type) == TFmode)
return true;
return false;
@@ -4527,7 +4532,8 @@ init_cumulative_args (CUMULATIVE_ARGS *c
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"
@@ -4615,14 +4621,15 @@ function_arg_padding (enum machine_mode
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;
}
@@ -4659,7 +4666,10 @@ function_arg_advance (CUMULATIVE_ARGS *c
{
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;
@@ -4962,7 +4972,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum
}
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;
@@ -5195,13 +5208,17 @@ function_arg_partial_nregs (CUMULATIVE_A
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)
@@ -5540,7 +5557,9 @@ rs6000_gimplify_va_arg (tree valist, tre
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
{