diff options
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 20 |
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. */ |