gcc:
authorIain Sandoe <iains@gcc.gnu.org>
Fri, 10 Dec 2010 10:13:36 +0000 (10:13 +0000)
committerIain Sandoe <iains@gcc.gnu.org>
Fri, 10 Dec 2010 10:13:36 +0000 (10:13 +0000)
* config/rs6000/rs6000.c
(rs6000_darwin64_record_arg_advance_recurse): Name register increment
explicitly.  (rs6000_darwin64_record_arg_recurse): Make sure we split
long doubles when we run out of regs.   Also flag that this requires
stack and therefore cannot be returned by value.
(rs6000_darwin64_record_arg): Update comment.
(rs6000_function_value): Likewise.

From-SVN: r167682

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index 66ece2c..6828fcd 100644 (file)
@@ -1,3 +1,13 @@
+2010-12-10  Iain Sandoe <iains@gcc.gnu.org>
+
+       * config/rs6000/rs6000.c
+       (rs6000_darwin64_record_arg_advance_recurse): Name register increment
+       explicitly.  (rs6000_darwin64_record_arg_recurse): Make sure we split
+       long doubles when we run out of regs.   Also flag that this requires
+       stack and therefore cannot be returned by value.
+       (rs6000_darwin64_record_arg): Update comment.
+       (rs6000_function_value): Likewise.
+
 2010-12-10  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * c-parser.c (c_parser_objc_class_definition): Recognize
index df7a428..bc27f73 100644 (file)
@@ -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.  */