Commit ff46d64d by Ulrich Weigand Committed by Ulrich Weigand

rs6000.c (rs6000_function_arg): If a float argument does not fit fully into…

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
parent c41e1ae6
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.
......
......@@ -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
......
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.
2014-07-24 Jiong Wang <jiong.wang@arm.com>
......
/* { 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" } */
{
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment