aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/rs6000/rs6000.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index df7a428..bc27f73 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -8150,8 +8150,9 @@ rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
{
+ unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
- cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
+ cum->fregno += n_fpregs;
/* Single-precision floats present a special problem for
us, because they are smaller than an 8-byte GPR, and so
the structure-packing rules combined with the standard
@@ -8186,7 +8187,7 @@ rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
}
}
else
- cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
+ cum->words += n_fpregs;
}
else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
{
@@ -8612,6 +8613,7 @@ rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
{
+ unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
#if 0
switch (mode)
{
@@ -8622,6 +8624,14 @@ rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
}
#endif
rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
+ if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
+ {
+ gcc_assert (cum->fregno == FP_ARG_MAX_REG
+ && (mode == TFmode || mode == TDmode));
+ /* Long double or _Decimal128 split over regs and memory. */
+ mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
+ cum->use_stack=1;
+ }
rvec[(*k)++]
= gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (mode, cum->fregno++),
@@ -8679,7 +8689,7 @@ rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
for the chunks of memory that go in int regs. Note we start at
element 1; 0 is reserved for an indication of using memory, and
may or may not be filled in below. */
- rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
+ rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
/* If any part of the struct went on the stack put all of it there.
@@ -8807,7 +8817,7 @@ rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
{
- rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
+ rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
if (rslt != NULL_RTX)
return rslt;
/* Else fall through to usual handling. */
@@ -26902,7 +26912,7 @@ rs6000_function_value (const_tree valtype,
valcum.vregno = ALTIVEC_ARG_MIN_REG;
/* Do a trial code generation as if this were going to be passed as
an argument; if any part goes in memory, we return NULL. */
- valret = rs6000_darwin64_record_arg (&valcum, valtype, true, true);
+ valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
if (valret)
return valret;
/* Otherwise fall through to standard ABI rules. */