Commit a6c9bed4 by Aldy Hernandez Committed by Aldy Hernandez

rs6000.c (function_arg): Always split vectors for e500 if it's a stdarg function.

2003-06-12  Aldy Hernandez  <aldyh@redhat.com>

	* config/rs6000/rs6000.c (function_arg): Always split vectors for
	e500 if it's a stdarg function.
	(function_arg_advance): Advance 2 registers for vectors in a
	stdarg function.
	(init_cumulative_args): Initialize stdarg.
	(rs6000_spe_function_arg): New.

	* config/rs6000/rs6000.h (rs6000_args): Add stdarg.

From-SVN: r67854
parent 4dcc01f3
2003-06-12 Aldy Hernandez <aldyh@redhat.com> 2003-06-12 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/rs6000.c (function_arg): Always split vectors for
e500 if it's a stdarg function.
(function_arg_advance): Advance 2 registers for vectors in a
stdarg function.
(init_cumulative_args): Initialize stdarg.
(rs6000_spe_function_arg): New.
* config/rs6000/rs6000.h (rs6000_args): Add stdarg.
2003-06-12 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/rs6000.h (MODES_TIEABLE_P): Add SPE vectors. * config/rs6000/rs6000.h (MODES_TIEABLE_P): Add SPE vectors.
2003-06-12 Roger Sayle <roger@eyesopen.com> 2003-06-12 Roger Sayle <roger@eyesopen.com>
......
...@@ -314,6 +314,7 @@ static inline int rs6000_tls_symbol_ref_1 PARAMS ((rtx *, void *)); ...@@ -314,6 +314,7 @@ static inline int rs6000_tls_symbol_ref_1 PARAMS ((rtx *, void *));
static const char *rs6000_get_some_local_dynamic_name PARAMS ((void)); static const char *rs6000_get_some_local_dynamic_name PARAMS ((void));
static int rs6000_get_some_local_dynamic_name_1 PARAMS ((rtx *, void *)); static int rs6000_get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
static rtx rs6000_complex_function_value (enum machine_mode); static rtx rs6000_complex_function_value (enum machine_mode);
static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree);
/* Hash table stuff for keeping track of TOC entries. */ /* Hash table stuff for keeping track of TOC entries. */
...@@ -3652,6 +3653,10 @@ init_cumulative_args (cum, fntype, libname, incoming) ...@@ -3652,6 +3653,10 @@ init_cumulative_args (cum, fntype, libname, incoming)
cum->prototype = (fntype && TYPE_ARG_TYPES (fntype)); cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
cum->call_cookie = CALL_NORMAL; cum->call_cookie = CALL_NORMAL;
cum->sysv_gregno = GP_ARG_MIN_REG; cum->sysv_gregno = GP_ARG_MIN_REG;
cum->stdarg = fntype
&& (TYPE_ARG_TYPES (fntype) != 0
&& (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
!= void_type_node));
if (incoming) if (incoming)
cum->nargs_prototype = 1000; /* don't return a PARALLEL */ cum->nargs_prototype = 1000; /* don't return a PARALLEL */
...@@ -3759,7 +3764,8 @@ function_arg_advance (cum, mode, type, named) ...@@ -3759,7 +3764,8 @@ function_arg_advance (cum, mode, type, named)
cum->words += RS6000_ARG_SIZE (mode, type); cum->words += RS6000_ARG_SIZE (mode, type);
} }
else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
&& named && cum->sysv_gregno <= GP_ARG_MAX_REG) && !cum->stdarg
&& cum->sysv_gregno <= GP_ARG_MAX_REG)
cum->sysv_gregno++; cum->sysv_gregno++;
else if (DEFAULT_ABI == ABI_V4) else if (DEFAULT_ABI == ABI_V4)
{ {
...@@ -3839,6 +3845,42 @@ function_arg_advance (cum, mode, type, named) ...@@ -3839,6 +3845,42 @@ function_arg_advance (cum, mode, type, named)
} }
} }
/* Determine where to put a SIMD argument on the SPE. */
static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type)
{
if (cum->stdarg)
{
int gregno = cum->sysv_gregno;
int n_words = RS6000_ARG_SIZE (mode, type);
/* SPE vectors are put in odd registers. */
if (n_words == 2 && (gregno & 1) == 0)
gregno += 1;
if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
{
rtx r1, r2;
enum machine_mode m = SImode;
r1 = gen_rtx_REG (m, gregno);
r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
r2 = gen_rtx_REG (m, gregno + 1);
r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
}
else
return NULL;
}
else
{
if (cum->sysv_gregno <= GP_ARG_MAX_REG)
return gen_rtx_REG (mode, cum->sysv_gregno);
else
return NULL;
}
}
/* 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.
...@@ -3901,13 +3943,8 @@ function_arg (cum, mode, type, named) ...@@ -3901,13 +3943,8 @@ function_arg (cum, mode, type, named)
else else
return NULL; return NULL;
} }
else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named) else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))
{ return rs6000_spe_function_arg (cum, mode, type);
if (cum->sysv_gregno <= GP_ARG_MAX_REG)
return gen_rtx_REG (mode, cum->sysv_gregno);
else
return NULL;
}
else if (abi == ABI_V4) else if (abi == ABI_V4)
{ {
if (TARGET_HARD_FLOAT && TARGET_FPRS if (TARGET_HARD_FLOAT && TARGET_FPRS
...@@ -3923,6 +3960,14 @@ function_arg (cum, mode, type, named) ...@@ -3923,6 +3960,14 @@ function_arg (cum, mode, type, named)
int n_words; int n_words;
int gregno = cum->sysv_gregno; int gregno = cum->sysv_gregno;
if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
&& !cum->stdarg
&& cum->sysv_gregno <= GP_ARG_MAX_REG)
{
cum->sysv_gregno++;
return;
}
/* Aggregates and IEEE quad get passed by reference. */ /* Aggregates and IEEE quad get passed by reference. */
if ((type && AGGREGATE_TYPE_P (type)) if ((type && AGGREGATE_TYPE_P (type))
|| mode == TFmode) || mode == TFmode)
...@@ -3934,25 +3979,9 @@ function_arg (cum, mode, type, named) ...@@ -3934,25 +3979,9 @@ function_arg (cum, mode, type, named)
if (n_words == 2 && (gregno & 1) == 0) if (n_words == 2 && (gregno & 1) == 0)
gregno += 1; gregno += 1;
/* Long long and SPE vectors are not split between registers /* Long long do not split between registers and stack. */
and stack. */
if (gregno + n_words - 1 <= GP_ARG_MAX_REG) if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
{
/* SPE vectors in ... get split into 2 registers. */
if (TARGET_SPE && TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode) && !named)
{
rtx r1, r2;
enum machine_mode m = SImode;
r1 = gen_rtx_REG (m, gregno);
r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
r2 = gen_rtx_REG (m, gregno + 1);
r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
}
return gen_rtx_REG (mode, gregno); return gen_rtx_REG (mode, gregno);
}
else else
return NULL; return NULL;
} }
......
...@@ -1725,6 +1725,7 @@ typedef struct rs6000_args ...@@ -1725,6 +1725,7 @@ typedef struct rs6000_args
int nargs_prototype; /* # args left in the current prototype */ int nargs_prototype; /* # args left in the current prototype */
int orig_nargs; /* Original value of nargs_prototype */ int orig_nargs; /* Original value of nargs_prototype */
int prototype; /* Whether a prototype was defined */ int prototype; /* Whether a prototype was defined */
int stdarg; /* Whether function is a stdarg function. */
int call_cookie; /* Do special things for this call */ int call_cookie; /* Do special things for this call */
int sysv_gregno; /* next available GP register */ int sysv_gregno; /* next available GP register */
} CUMULATIVE_ARGS; } CUMULATIVE_ARGS;
......
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