diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2003-06-12 21:38:46 +0000 |
---|---|---|
committer | Aldy Hernandez <aldyh@gcc.gnu.org> | 2003-06-12 21:38:46 +0000 |
commit | a6c9bed4449cd054050ad31bdbebce2b4ff21534 (patch) | |
tree | 19a3858d595ea420f9f935de48a649e50b0bb55d /gcc | |
parent | 4dcc01f3f16e86dd0c4c20252b57ce803da7ca90 (diff) | |
download | gcc-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/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 83 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 1 |
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; |