From 36a454e1f16009a72f68b010359546494311dfd6 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 7 May 2004 23:00:39 +0000 Subject: [PATCH] Fixed altivec vararg problem. Approved by Aldy Hernandez. From-SVN: r81635 --- gcc/ChangeLog | 6 ++++++ gcc/config/rs6000/rs6000.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5b036b28e81..f50b1060ab8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2004-05-07 Fariborz Jahanian + * config/rs6000/rs6000.c (rs6000_mixed_function_arg): + Generate appropriate parallels for vector arguments + passed to vararg functions. (function_arg): make the call + to rs6000_mixed_function_arg for vector args as needed. + 2004-05-07 Richard Sandiford * config/mips/mips.c (mips_va_arg): Fix calculation of osize for 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))