ia64.c (ia64_function_value): Use PARALLEL for aggregates with XF/XCmode.
authorRichard Henderson <rth@redhat.com>
Thu, 30 Dec 2004 08:59:15 +0000 (00:59 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 30 Dec 2004 08:59:15 +0000 (00:59 -0800)
        * config/ia64/ia64.c (ia64_function_value): Use PARALLEL for
        aggregates with XF/XCmode.

From-SVN: r92728

gcc/ChangeLog
gcc/config/ia64/ia64.c

index b03786d..3be00eb 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-30  Richard Henderson  <rth@redhat.com>
+
+       * config/ia64/ia64.c (ia64_function_value): Use PARALLEL for 
+       aggregates with XF/XCmode.
+
 2004-12-29  Richard Henderson  <rth@redhat.com>
 
        * target.h (targetm.calls.arg_partial_bytes): New.
@@ -71,7 +76,7 @@
        * config/mcore/mcore.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
        * config/mcore/mcore.c (mcore_arg_partial_bytes): Rename from
        mcore_function_arg_partial_nregs.  Adjust to return bytes.
-        (TARGET_ARG_PARTIAL_BYTES): New.
+       (TARGET_ARG_PARTIAL_BYTES): New.
        * config/mcore/mcore-protos.h: Update.
 
        * config/mips/mips.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
        * config/sparc/sparc.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
        * config/sparc/sparc.c (sparc_arg_partial_bytes): Rename from
        function_arg_partial_nregs.  Adjust to return bytes.
-        (TARGET_ARG_PARTIAL_BYTES): New.
+       (TARGET_ARG_PARTIAL_BYTES): New.
        * config/sparc/sparc-protos.h: Update.
 
        * config/v850/v850.h (FUNCTION_ARG_PARTIAL_NREGS): Remove.
        * config/v850/v850.c (v850_arg_partial_bytes): Rename from
-        function_arg_partial_nregs.  Adjust to return bytes.
-        (TARGET_ARG_PARTIAL_BYTES): New.
+       function_arg_partial_nregs.  Adjust to return bytes.
+       (TARGET_ARG_PARTIAL_BYTES): New.
        * config/v850/v850-protos.h: Update.
 
 2004-12-30  Hans-Peter Nilsson  <hp@bitrange.com>
index 6478cb1..2d819c6 100644 (file)
@@ -3522,8 +3522,24 @@ ia64_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
     return gen_rtx_REG (mode, FR_ARG_FIRST);
   else
     {
+      bool need_parallel = false;
+
+      /* In big-endian mode, we need to manage the layout of aggregates
+        in the registers so that we get the bits properly aligned in
+        the highpart of the registers.  */
       if (BYTES_BIG_ENDIAN
          && (mode == BLKmode || (valtype && AGGREGATE_TYPE_P (valtype))))
+       need_parallel = true;
+
+      /* Something like struct S { long double x; char a[0] } is not an
+        HFA structure, and therefore doesn't go in fp registers.  But
+        the middle-end will give it XFmode anyway, and XFmode values
+        don't normally fit in integer registers.  So we need to smuggle
+        the value inside a parallel.  */
+      else if (mode == XFmode || mode == XCmode)
+       need_parallel = true;
+
+      if (need_parallel)
        {
          rtx loc[8];
          int offset;
@@ -3542,8 +3558,8 @@ ia64_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
            }
          return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
        }
-      else
-       return gen_rtx_REG (mode, GR_RET_FIRST);
+
+      return gen_rtx_REG (mode, GR_RET_FIRST);
     }
 }