rs6000.c (rs6000_function_arg): If a float argument does not fit fully into floating-point registers...

gcc/

	* config/rs6000/rs6000.c (rs6000_function_arg): If a float argument
	does not fit fully into floating-point registers, and there is still
	space in the register parameter area, use GPRs to pass those parts
	of the argument.  Issue -Wpsabi note if any parameter is now treated
	differently than before.
	(rs6000_arg_partial_bytes): Update.

gcc/testsuite/

	* gcc.target/powerpc/ppc64-abi-warn-1.c: New test.

From-SVN: r213015
This commit is contained in:
Ulrich Weigand 2014-07-24 17:11:02 +00:00 committed by Ulrich Weigand
parent c41e1ae6c0
commit ff46d64d82
4 changed files with 84 additions and 2 deletions

View File

@ -1,3 +1,12 @@
2014-07-24 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* config/rs6000/rs6000.c (rs6000_function_arg): If a float argument
does not fit fully into floating-point registers, and there is still
space in the register parameter area, use GPRs to pass those parts
of the argument. Issue -Wpsabi note if any parameter is now treated
differently than before.
(rs6000_arg_partial_bytes): Update.
2014-07-24 Uros Bizjak <ubizjak@gmail.com>
* config/alpha/elf.h: Define TARGET_UNWIND_TABLES_DEFAULT.

View File

@ -10229,6 +10229,7 @@ rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
rtx r, off;
int i, k = 0;
unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
int fpr_words;
/* Do we also need to pass this argument in the parameter
save area? */
@ -10257,6 +10258,47 @@ rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
}
/* If there were not enough FPRs to hold the argument, the rest
usually goes into memory. However, if the current position
is still within the register parameter area, a portion may
actually have to go into GPRs.
Note that it may happen that the portion of the argument
passed in the first "half" of the first GPR was already
passed in the last FPR as well.
For unnamed arguments, we already set up GPRs to cover the
whole argument in rs6000_psave_function_arg, so there is
nothing further to do at this point. */
fpr_words = (i * GET_MODE_SIZE (elt_mode)) / (TARGET_32BIT ? 4 : 8);
if (i < n_elts && align_words + fpr_words < GP_ARG_NUM_REG
&& cum->nargs_prototype > 0)
{
static bool warned;
enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
int n_words = rs6000_arg_size (mode, type);
align_words += fpr_words;
n_words -= fpr_words;
do
{
r = gen_rtx_REG (rmode, GP_ARG_MIN_REG + align_words);
off = GEN_INT (fpr_words++ * GET_MODE_SIZE (rmode));
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
}
while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
if (!warned && warn_psabi)
{
warned = true;
inform (input_location,
"the ABI of passing homogeneous float aggregates"
" has changed in GCC 4.10");
}
}
return rs6000_finish_function_arg (mode, rvec, k);
}
else if (align_words < GP_ARG_NUM_REG)
@ -10332,8 +10374,23 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
/* Otherwise, we pass in FPRs only. Check for partial copies. */
passed_in_gprs = false;
if (cum->fregno + n_elts * n_fpreg > FP_ARG_MAX_REG + 1)
ret = ((FP_ARG_MAX_REG + 1 - cum->fregno)
* MIN (8, GET_MODE_SIZE (elt_mode)));
{
/* Compute number of bytes / words passed in FPRs. If there
is still space available in the register parameter area
*after* that amount, a part of the argument will be passed
in GPRs. In that case, the total amount passed in any
registers is equal to the amount that would have been passed
in GPRs if everything were passed there, so we fall back to
the GPR code below to compute the appropriate value. */
int fpr = ((FP_ARG_MAX_REG + 1 - cum->fregno)
* MIN (8, GET_MODE_SIZE (elt_mode)));
int fpr_words = fpr / (TARGET_32BIT ? 4 : 8);
if (align_words + fpr_words < GP_ARG_NUM_REG)
passed_in_gprs = true;
else
ret = fpr;
}
}
if (passed_in_gprs

View File

@ -1,3 +1,7 @@
2014-07-24 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* gcc.target/powerpc/ppc64-abi-warn-1.c: New test.
2014-07-24 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* g++.dg/compat/struct-layout-1.exp: Load g++-dg.exp.

View File

@ -0,0 +1,12 @@
/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
/* { dg-options "-mabi=elfv2" } */
struct f8
{
float x[8];
};
void test (struct f8 a, struct f8 b) /* { dg-message "note: the ABI of passing homogeneous float aggregates has changed" } */
{
}