aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2003-06-12 21:38:46 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2003-06-12 21:38:46 +0000
commita6c9bed4449cd054050ad31bdbebce2b4ff21534 (patch)
tree19a3858d595ea420f9f935de48a649e50b0bb55d /gcc
parent4dcc01f3f16e86dd0c4c20252b57ce803da7ca90 (diff)
downloadgcc-a6c9bed4449cd054050ad31bdbebce2b4ff21534.zip
gcc-a6c9bed4449cd054050ad31bdbebce2b4ff21534.tar.gz
gcc-a6c9bed4449cd054050ad31bdbebce2b4ff21534.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/rs6000/rs6000.c83
-rw-r--r--gcc/config/rs6000/rs6000.h1
3 files changed, 68 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3a48c92..99e786b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
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.
2003-06-12 Roger Sayle <roger@eyesopen.com>
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 6a9c436..33936b8 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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 int rs6000_get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
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. */
@@ -3652,6 +3653,10 @@ init_cumulative_args (cum, fntype, libname, incoming)
cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
cum->call_cookie = CALL_NORMAL;
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)
cum->nargs_prototype = 1000; /* don't return a PARALLEL */
@@ -3759,7 +3764,8 @@ function_arg_advance (cum, mode, type, named)
cum->words += RS6000_ARG_SIZE (mode, type);
}
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++;
else if (DEFAULT_ABI == ABI_V4)
{
@@ -3838,7 +3844,43 @@ 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.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
@@ -3901,13 +3943,8 @@ function_arg (cum, mode, type, named)
else
return NULL;
}
- else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
- {
- if (cum->sysv_gregno <= GP_ARG_MAX_REG)
- return gen_rtx_REG (mode, cum->sysv_gregno);
- else
- return NULL;
- }
+ else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))
+ return rs6000_spe_function_arg (cum, mode, type);
else if (abi == ABI_V4)
{
if (TARGET_HARD_FLOAT && TARGET_FPRS
@@ -3923,6 +3960,14 @@ function_arg (cum, mode, type, named)
int n_words;
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. */
if ((type && AGGREGATE_TYPE_P (type))
|| mode == TFmode)
@@ -3934,25 +3979,9 @@ function_arg (cum, mode, type, named)
if (n_words == 2 && (gregno & 1) == 0)
gregno += 1;
- /* Long long and SPE vectors are not split between registers
- and stack. */
+ /* Long long do not split between registers and stack. */
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
return NULL;
}
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index ffdf403..f0c7ef9 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1725,6 +1725,7 @@ typedef struct rs6000_args
int nargs_prototype; /* # args left in the current prototype */
int orig_nargs; /* Original value of nargs_prototype */
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 sysv_gregno; /* next available GP register */
} CUMULATIVE_ARGS;