summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
authorfjahanian <fjahanian@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-07 23:00:39 +0000
committerfjahanian <fjahanian@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-07 23:00:39 +0000
commit5b55053a40617368571ecd02bf7bb9245f48b415 (patch)
treeecc49c97cb25d4d041edf7a2be45ee073cf8b323 /gcc/config/rs6000
parenta12555e9b0e961eee6652bfc42eeeb10e6d5356a (diff)
downloadgcc-5b55053a40617368571ecd02bf7bb9245f48b415.tar.gz
Fixed altivec vararg problem.
Approved by Aldy Hernandez. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@81635 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r--gcc/config/rs6000/rs6000.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 654891c5ab2..5c82d75c071 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4344,8 +4344,28 @@ rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ align_words),
const0_rtx)));
}
- else if (mode == BLKmode && align_words <= (GP_ARG_NUM_REG - 1))
- {
+ else if (ALTIVEC_VECTOR_MODE (mode) && align_words == GP_ARG_NUM_REG - 2)
+ {
+ /* Varargs vector regs must be saved in R9-R10. */
+ return gen_rtx_PARALLEL (mode,
+ gen_rtvec (3,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ NULL_RTX, const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words + 1),
+ GEN_INT (4))));
+ }
+ else if ((mode == BLKmode || ALTIVEC_VECTOR_MODE (mode))
+ && align_words <= (GP_ARG_NUM_REG - 1))
+ {
+ /* AltiVec vector regs are saved in R5-R8. */
int k;
int size = int_size_in_bytes (type);
int no_units = ((size - 1) / 4) + 1;
@@ -4362,9 +4382,8 @@ rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ align_words + k),
k == 0 ? const0_rtx : GEN_INT (k*4));
- return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k, rtlvec));
- }
-
+ return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rtlvec));
+ }
return NULL_RTX;
}
@@ -4482,7 +4501,11 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
is either wholly in GPRs or half in GPRs and half not. */
part_mode = DImode;
- return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
+ if (TARGET_32BIT
+ && (TARGET_POWERPC64 || (align_words == GP_ARG_NUM_REG - 2)))
+ return rs6000_mixed_function_arg (cum, part_mode, type, align_words);
+ else
+ return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
}
}
else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))