Fixed altivec vararg problem.
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 7 May 2004 23:00:39 +0000 (23:00 +0000)
committerFariborz Jahanian <fjahanian@gcc.gnu.org>
Fri, 7 May 2004 23:00:39 +0000 (23:00 +0000)
Approved by Aldy Hernandez.

From-SVN: r81635

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

index 5b036b2..f50b106 100644 (file)
@@ -1,3 +1,9 @@
+2004-05-07 Fariborz Jahanian <fjahanian@apple.com>
+       * config/rs6000/rs6000.c (rs6000_mixed_function_arg):
+       Generate appropriate parallels for vector arguments
+       passed to vararg functions. (function_arg): make the call
+       to rs6000_mixed_function_arg for vector args as needed.
+       
 2004-05-07  Richard Sandiford  <rsandifo@redhat.com>
 
        * config/mips/mips.c (mips_va_arg): Fix calculation of osize for
index 654891c..5c82d75 100644 (file)
@@ -4344,8 +4344,28 @@ rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
                                                              + align_words),
                                                 const0_rtx)));
     }
-  else if (mode == BLKmode && align_words <= (GP_ARG_NUM_REG - 1))
-    {
+  else if (ALTIVEC_VECTOR_MODE (mode) && align_words == GP_ARG_NUM_REG - 2)
+    {
+      /* Varargs vector regs must be saved in R9-R10.  */
+      return gen_rtx_PARALLEL (mode,
+                              gen_rtvec (3,
+                                gen_rtx_EXPR_LIST (VOIDmode,
+                                                    NULL_RTX, const0_rtx),
+                                gen_rtx_EXPR_LIST (VOIDmode,
+                                                   gen_rtx_REG (SImode,
+                                                                GP_ARG_MIN_REG
+                                                                + align_words),
+                                                   const0_rtx),
+                                gen_rtx_EXPR_LIST (VOIDmode,
+                                                   gen_rtx_REG (SImode,
+                                                                GP_ARG_MIN_REG
+                                                                + align_words + 1),
+                                                   GEN_INT (4))));
+    }
+  else if ((mode == BLKmode || ALTIVEC_VECTOR_MODE (mode))
+           && align_words <= (GP_ARG_NUM_REG - 1))
+    {
+      /* AltiVec vector regs are saved in R5-R8. */
       int k;
       int size = int_size_in_bytes (type);
       int no_units = ((size - 1) / 4) + 1;
@@ -4362,9 +4382,8 @@ rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
                                                    + align_words + k),
                                       k == 0 ? const0_rtx : GEN_INT (k*4));
 
-      return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k, rtlvec));
-  }
-
+      return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rtlvec));
+    }
   return NULL_RTX;
 }
 
@@ -4482,7 +4501,11 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
               is either wholly in GPRs or half in GPRs and half not.  */
            part_mode = DImode;
          
-         return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
+         if (TARGET_32BIT
+             && (TARGET_POWERPC64 || (align_words == GP_ARG_NUM_REG - 2)))
+           return rs6000_mixed_function_arg (cum, part_mode, type, align_words);
+         else
+           return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
        }
     }
   else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))