Commit 2858f73a by Geoffrey Keating Committed by Geoffrey Keating

rs6000.h (USE_FP_FOR_ARG_P): Move to rs6000.c.

	* config/rs6000/rs6000.h (USE_FP_FOR_ARG_P): Move to rs6000.c.
	(USE_ALTIVEC_FOR_ARG_P): Likewise.
	* config/rs6000/rs6000.c (USE_FP_FOR_ARG_P): Move from rs6000.h.
	Take a pointer as the CUM parameter.  Update callers.
	(USE_ALTIVEC_FOR_ARG_P): Likewise.  Also correct for Darwin/AIX
	32-bit ABIs.
	(function_arg_advance): Use USE_ALTIVEC_FOR_ARG_P.  Correct case
	of vector parameters as named arguments of stdarg function.
	(function_arg): Likewise.

	* config/rs6000/darwin.h (ASM_SPEC): Use -force_cpusubtype_ALL when
	-maltivec is specified, not the non-existent -faltivec.

From-SVN: r73317
parent 8c17530e
2003-11-06 Geoffrey Keating <geoffk@apple.com>
* config/rs6000/rs6000.h (USE_FP_FOR_ARG_P): Move to rs6000.c.
(USE_ALTIVEC_FOR_ARG_P): Likewise.
* config/rs6000/rs6000.c (USE_FP_FOR_ARG_P): Move from rs6000.h.
Take a pointer as the CUM parameter. Update callers.
(USE_ALTIVEC_FOR_ARG_P): Likewise. Also correct for Darwin/AIX
32-bit ABIs.
(function_arg_advance): Use USE_ALTIVEC_FOR_ARG_P. Correct case
of vector parameters as named arguments of stdarg function.
(function_arg): Likewise.
* config/rs6000/darwin.h (ASM_SPEC): Use -force_cpusubtype_ALL when
-maltivec is specified, not the non-existent -faltivec.
2003-11-06 Ulrich Weigand <uweigand@de.ibm.com> 2003-11-06 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390-protos.h (s390_function_value): Declare. * config/s390/s390-protos.h (s390_function_value): Declare.
......
...@@ -100,7 +100,7 @@ do { \ ...@@ -100,7 +100,7 @@ do { \
#define ASM_SPEC "-arch ppc \ #define ASM_SPEC "-arch ppc \
%{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \ %{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \
%{!Zforce_cpusubtype_ALL:%{faltivec:-force_cpusubtype_ALL}}" %{!Zforce_cpusubtype_ALL:%{maltivec:-force_cpusubtype_ALL}}"
#undef SUBTARGET_EXTRA_SPECS #undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \ #define SUBTARGET_EXTRA_SPECS \
......
...@@ -3618,6 +3618,19 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) ...@@ -3618,6 +3618,19 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
} }
/* Nonzero if we can use a floating-point register to pass this arg. */
#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
(GET_MODE_CLASS (MODE) == MODE_FLOAT \
&& (CUM)->fregno <= FP_ARG_MAX_REG \
&& TARGET_HARD_FLOAT && TARGET_FPRS)
/* 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) \
&& (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
&& TARGET_ALTIVEC_ABI \
&& (DEFAULT_ABI == ABI_V4 || (NAMED)))
/* Return a nonzero value to say to return the function value in /* Return a nonzero value to say to return the function value in
memory, just as large structures are always returned. TYPE will be memory, just as large structures are always returned. TYPE will be
the data type of the value, and FNTYPE will be the type of the the data type of the value, and FNTYPE will be the type of the
...@@ -3802,23 +3815,35 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -3802,23 +3815,35 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
{ {
if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG) if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
cum->vregno++; cum->vregno++;
else
/* In variable-argument functions, vector arguments get GPRs allocated
even if they are going to be passed in a vector register. */
if (cum->stdarg && DEFAULT_ABI != ABI_V4)
{ {
int align; int align;
/* Vector parameters must be 16-byte aligned. This places them at /* Vector parameters must be 16-byte aligned. This places
2 mod 4 in terms of words (on both ABIs). */ them at 2 mod 4 in terms of words in 32-bit mode, since
align = ((6 - (cum->words & 3)) & 3); the parameter save area starts at offset 24 from the
stack. In 64-bit mode, they just have to start on an
even word, since the parameter save area is 16-byte
aligned. Space for GPRs is reserved even if the argument
will be passed in memory. */
if (TARGET_32BIT)
align = ((6 - (cum->words & 3)) & 3);
else
align = cum->words & 1;
cum->words += align + RS6000_ARG_SIZE (mode, type); cum->words += align + RS6000_ARG_SIZE (mode, type);
if (TARGET_DEBUG_ARG) if (TARGET_DEBUG_ARG)
{ {
fprintf (stderr, "function_adv: words = %2d, align=%d, ", fprintf (stderr, "function_adv: words = %2d, align=%d, ",
cum->words, align); cum->words, align);
fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n", fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode)); cum->nargs_prototype, cum->prototype,
GET_MODE_NAME (mode));
} }
} }
} }
...@@ -4099,40 +4124,43 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4099,40 +4124,43 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
return GEN_INT (cum->call_cookie); return GEN_INT (cum->call_cookie);
} }
if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
return gen_rtx_REG (mode, cum->vregno);
else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
{ {
if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG) if (named || abi == ABI_V4)
return gen_rtx_REG (mode, cum->vregno);
else if (named || abi == ABI_V4)
return NULL_RTX; return NULL_RTX;
else else
{ {
/* Vector parameters to varargs functions under AIX or Darwin /* Vector parameters to varargs functions under AIX or Darwin
get passed in memory and possibly also in GPRs. */ get passed in memory and possibly also in GPRs. */
int align, align_words; int align, align_words;
rtx reg; enum machine_mode part_mode = mode;
/* Vector parameters must be 16-byte aligned. This places them at /* Vector parameters must be 16-byte aligned. This places them at
2 mod 4 in terms of words. */ 2 mod 4 in terms of words in 32-bit mode, since the parameter
align = ((6 - (cum->words & 3)) & 3); save area starts at offset 24 from the stack. In 64-bit mode,
they just have to start on an even word, since the parameter
save area is 16-byte aligned. */
if (TARGET_32BIT)
align = ((6 - (cum->words & 3)) & 3);
else
align = cum->words & 1;
align_words = cum->words + align; align_words = cum->words + align;
/* Out of registers? Memory, then. */ /* Out of registers? Memory, then. */
if (align_words >= GP_ARG_NUM_REG) if (align_words >= GP_ARG_NUM_REG)
return NULL_RTX; return NULL_RTX;
/* The vector value goes in both memory and GPRs. Varargs /* The vector value goes in GPRs. Only the part of the
vector regs will always be saved in R5-R8 or R9-R12. */ value in GPRs is reported here. */
reg = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); if (align_words + CLASS_MAX_NREGS (mode, GENERAL_REGS)
> GP_ARG_NUM_REG)
return gen_rtx_PARALLEL (mode, /* Fortunately, there are only two possibilites, the value
gen_rtvec (2, is either wholly in GPRs or half in GPRs and half not. */
gen_rtx_EXPR_LIST (VOIDmode, part_mode = DImode;
NULL_RTX,
const0_rtx), return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
gen_rtx_EXPR_LIST (VOIDmode,
reg,
const0_rtx)));
} }
} }
else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)) else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))
...@@ -4183,7 +4211,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4183,7 +4211,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
&& (mode == DFmode || mode == DImode || mode == BLKmode)) && (mode == DFmode || mode == DImode || mode == BLKmode))
return rs6000_mixed_function_arg (cum, mode, type, align_words); return rs6000_mixed_function_arg (cum, mode, type, align_words);
if (USE_FP_FOR_ARG_P (*cum, mode, type)) if (USE_FP_FOR_ARG_P (cum, mode, type))
{ {
if (! type if (! type
|| ((cum->nargs_prototype > 0) || ((cum->nargs_prototype > 0)
...@@ -4228,13 +4256,13 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4228,13 +4256,13 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
int int
function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode, function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
tree type, int named ATTRIBUTE_UNUSED) tree type, int named)
{ {
if (DEFAULT_ABI == ABI_V4) if (DEFAULT_ABI == ABI_V4)
return 0; return 0;
if (USE_FP_FOR_ARG_P (*cum, mode, type) if (USE_FP_FOR_ARG_P (cum, mode, type)
|| USE_ALTIVEC_FOR_ARG_P (*cum, mode, type)) || USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
{ {
if (cum->nargs_prototype >= 0) if (cum->nargs_prototype >= 0)
return 0; return 0;
......
...@@ -1800,18 +1800,6 @@ typedef struct rs6000_args ...@@ -1800,18 +1800,6 @@ typedef struct rs6000_args
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
function_arg_advance (&CUM, MODE, TYPE, NAMED) function_arg_advance (&CUM, MODE, TYPE, NAMED)
/* Nonzero if we can use a floating-point register to pass this arg. */
#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
(GET_MODE_CLASS (MODE) == MODE_FLOAT \
&& (CUM).fregno <= FP_ARG_MAX_REG \
&& TARGET_HARD_FLOAT && TARGET_FPRS)
/* Nonzero if we can use an AltiVec register to pass this arg. */
#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE) \
(ALTIVEC_VECTOR_MODE (MODE) \
&& (CUM).vregno <= ALTIVEC_ARG_MAX_REG \
&& TARGET_ALTIVEC_ABI)
/* Determine where to put an argument to a function. /* Determine where to put an argument to a function.
Value is zero to push the argument on the stack, Value is zero to push the argument on the stack,
or a hard register in which to store the argument. or a hard register in which to store the argument.
......
2003-11-06 Geoffrey Keating <geoffk@apple.com>
* gcc.dg/altivec-varargs-1.c: New test.
2003-11-05 Eric Botcazou <ebotcazou@libertysurf.fr> 2003-11-05 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/compile/20031023-4.c: XFAIL on SPARC64 * gcc.c-torture/compile/20031023-4.c: XFAIL on SPARC64
......
/* { dg-do run { target powerpc*-*-darwin* powerpc*-*-*altivec* } } */
/* { dg-options "-maltivec" } */
/* This test requires altivec, which means it'll fail on Darwin running
on G3. FIXME. */
#include <stdarg.h>
#define vector __attribute__((mode(V4SI)))
const vector unsigned int v1 = {10,11,12,13};
const vector unsigned int v2 = {20,21,22,23};
const vector unsigned int v3 = {30,31,32,33};
const vector unsigned int v4 = {40,41,42,43};
void foo(vector unsigned int a, ...)
{
va_list args;
vector unsigned int v;
va_start (args, a);
if (memcmp (&a, &v1, sizeof (v)) != 0)
abort ();
v = va_arg (args, vector unsigned int);
if (memcmp (&v, &v2, sizeof (v)) != 0)
abort ();
v = va_arg (args, vector unsigned int);
if (memcmp (&v, &v3, sizeof (v)) != 0)
abort ();
v = va_arg (args, vector unsigned int);
if (memcmp (&v, &v4, sizeof (v)) != 0)
abort ();
va_end (args);
}
void bar(vector unsigned int a, ...)
{
va_list args;
vector unsigned int v;
int b;
va_start (args, a);
if (memcmp (&a, &v1, sizeof (v)) != 0)
abort ();
b = va_arg (args, int);
if (b != 2)
abort ();
v = va_arg (args, vector unsigned int);
if (memcmp (&v, &v2, sizeof (v)) != 0)
abort ();
v = va_arg (args, vector unsigned int);
if (memcmp (&v, &v3, sizeof (v)) != 0)
abort ();
va_end (args);
}
int main(void)
{
/* In this call, in the Darwin ABI, the first argument goes into v2
the second one into r9-r10 and memory,
and the next two in memory. */
foo ((vector unsigned int){10,11,12,13},
(vector unsigned int){20,21,22,23},
(vector unsigned int){30,31,32,33},
(vector unsigned int){40,41,42,43});
/* In this call, in the Darwin ABI, the first argument goes into v2
the second one into r9, then r10 is reserved and
there are two words of padding in memory, and the next two arguments
go after the padding. */
bar ((vector unsigned int){10,11,12,13}, 2,
(vector unsigned int){20,21,22,23},
(vector unsigned int){30,31,32,33});
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment