rs6000.c (rs6000_override_options): Split e500v2 doubles.
authorAldy Hernandez <aldyh@redhat.com>
Wed, 17 Nov 2004 02:19:17 +0000 (02:19 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Wed, 17 Nov 2004 02:19:17 +0000 (02:19 +0000)
        * config/rs6000/rs6000.c (rs6000_override_options): Split e500v2
        doubles.
        (rs6000_complex_function_value): Handle e500 v2 variant.

From-SVN: r90784

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

index e54898105caf033230fca9283745a0c3bb46f961..def3930b57087b8e74dde070ebca69e7cd355d9b 100644 (file)
@@ -1,3 +1,9 @@
+2004-11-16  Aldy Hernandez  <aldyh@redhat.com>
+
+        * config/rs6000/rs6000.c (rs6000_override_options): Split e500v2
+        doubles.
+        (rs6000_complex_function_value): Handle e500 v2 variant.
+
 2004-11-16  Daniel Berlin  <dberlin@dberlin.org>
 
        Fix PR tree-optimization/18519
index a0c607fe7650a64b5d467917decbda551535597f..d67a857a6608a1585493563ac8af87b5f94f7431 100644 (file)
@@ -1493,7 +1493,7 @@ rs6000_override_options (const char *default_cpu)
 
   /* We should always be splitting complex arguments, but we can't break
      Linux and Darwin ABIs at the moment.  For now, only AIX is fixed.  */
-  if (DEFAULT_ABI != ABI_AIX)
+  if (DEFAULT_ABI != ABI_AIX && !TARGET_E500_DOUBLE)
     targetm.calls.split_complex_arg = NULL;
 
   /* Initialize rs6000_cost with the appropriate target costs.  */
@@ -18315,20 +18315,31 @@ rs6000_complex_function_value (enum machine_mode mode)
   enum machine_mode inner = GET_MODE_INNER (mode);
   unsigned int inner_bytes = GET_MODE_SIZE (inner);
 
-  if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
-    regno = FP_ARG_RETURN;
-  else
+  if (TARGET_E500_DOUBLE)
     {
+      /* FIXME: This causes complex values to be returned in the full
+        64-bit GPR.  It works, but is not ABI compatible with
+        soft-float.  Complex doubles should be returned in 4
+        consecutive 32-bit GPRs.  */
       regno = GP_ARG_RETURN;
+    }
+  else
+    {
+      if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
+       regno = FP_ARG_RETURN;
+      else
+       {
+         regno = GP_ARG_RETURN;
 
-      /* 32-bit is OK since it'll go in r3/r4.  */
-      if (TARGET_32BIT && inner_bytes >= 4)
+         /* 32-bit is OK since it'll go in r3/r4.  */
+         if (TARGET_32BIT && inner_bytes >= 4)
+           return gen_rtx_REG (mode, regno);
+       }
+
+      if (inner_bytes >= 8)
        return gen_rtx_REG (mode, regno);
     }
 
-  if (inner_bytes >= 8)
-    return gen_rtx_REG (mode, regno);
-
   r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
                          const0_rtx);
   r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),