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:
parent
c41e1ae6c0
commit
ff46d64d82
|
@ -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>
|
2014-07-24 Uros Bizjak <ubizjak@gmail.com>
|
||||||
|
|
||||||
* config/alpha/elf.h: Define TARGET_UNWIND_TABLES_DEFAULT.
|
* 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;
|
rtx r, off;
|
||||||
int i, k = 0;
|
int i, k = 0;
|
||||||
unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
|
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
|
/* Do we also need to pass this argument in the parameter
|
||||||
save area? */
|
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);
|
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);
|
return rs6000_finish_function_arg (mode, rvec, k);
|
||||||
}
|
}
|
||||||
else if (align_words < GP_ARG_NUM_REG)
|
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. */
|
/* Otherwise, we pass in FPRs only. Check for partial copies. */
|
||||||
passed_in_gprs = false;
|
passed_in_gprs = false;
|
||||||
if (cum->fregno + n_elts * n_fpreg > FP_ARG_MAX_REG + 1)
|
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
|
if (passed_in_gprs
|
||||||
|
|
|
@ -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>
|
2014-07-24 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
|
||||||
|
|
||||||
* g++.dg/compat/struct-layout-1.exp: Load g++-dg.exp.
|
* g++.dg/compat/struct-layout-1.exp: Load g++-dg.exp.
|
||||||
|
|
|
@ -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" } */
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue