aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2002-07-27 04:12:48 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2002-07-27 04:12:48 +0000
commita4b0320c2dc76e2c47427a558a3dd65279624055 (patch)
treed2c328af1dac3d5fb98e828fb82bb393896363dd /gcc
parentc427db5dabb1af0d148f463cfc5a56d374b6ab6f (diff)
downloadgcc-a4b0320c2dc76e2c47427a558a3dd65279624055.zip
gcc-a4b0320c2dc76e2c47427a558a3dd65279624055.tar.gz
gcc-a4b0320c2dc76e2c47427a558a3dd65279624055.tar.bz2
rs6000.c (function_arg_advance): SPE vararg vectors are split into two registers.
2002-07-25 Aldy Hernandez <aldyh@redhat.com> * config/rs6000/rs6000.c (function_arg_advance): SPE vararg vectors are split into two registers. (function_arg): Same. From-SVN: r55791
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/rs6000/rs6000.c39
2 files changed, 33 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 61cfc8e..32034bd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2002-07-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (function_arg_advance): SPE vararg
+ vectors are split into two registers.
+ (function_arg): Same.
+
Thu Jul 26 23:00:13 2002 J"orn Rennecke <joern.rennecke@superh.com>
* pa.md (extv): Check predicates before emitting extv_32.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 2df15f2..5b6cabb 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2918,11 +2918,9 @@ function_arg_advance (cum, mode, type, named)
else
cum->words += RS6000_ARG_SIZE (mode, type);
}
- else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))
- {
- cum->words += RS6000_ARG_SIZE (mode, type);
- cum->sysv_gregno++;
- }
+ else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
+ && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
+ cum->sysv_gregno++;
else if (DEFAULT_ABI == ABI_V4)
{
if (TARGET_HARD_FLOAT && TARGET_FPRS
@@ -2949,11 +2947,12 @@ function_arg_advance (cum, mode, type, named)
else
n_words = RS6000_ARG_SIZE (mode, type);
- /* Long long is put in odd registers. */
+ /* Long long and SPE vectors are put in odd registers. */
if (n_words == 2 && (gregno & 1) == 0)
gregno += 1;
- /* Long long is not split between registers and stack. */
+ /* Long long and SPE vectors are not split between registers
+ and stack. */
if (gregno + n_words - 1 > GP_ARG_MAX_REG)
{
/* Long long is aligned on the stack. */
@@ -3062,9 +3061,9 @@ function_arg (cum, mode, type, named)
else
return NULL;
}
- else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))
+ else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
{
- if (cum->sysv_gregno - 1 <= GP_ARG_MAX_REG)
+ if (cum->sysv_gregno <= GP_ARG_MAX_REG)
return gen_rtx_REG (mode, cum->sysv_gregno);
else
return NULL;
@@ -3091,13 +3090,29 @@ function_arg (cum, mode, type, named)
else
n_words = RS6000_ARG_SIZE (mode, type);
- /* Long long is put in odd registers. */
+ /* Long long and SPE vectors are put in odd registers. */
if (n_words == 2 && (gregno & 1) == 0)
gregno += 1;
- /* Long long is not split between registers and stack. */
+ /* Long long and SPE vectors are not split between registers
+ and stack. */
if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
- return gen_rtx_REG (mode, gregno);
+ {
+ /* 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 = GET_MODE_INNER (mode);
+
+ 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);
+ }
else
return NULL;
}