OSDN Git Service

2003-06-12 Aldy Hernandez <aldyh@redhat.com>
authoraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 Jun 2003 21:38:46 +0000 (21:38 +0000)
committeraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 Jun 2003 21:38:46 +0000 (21:38 +0000)
* config/rs6000/rs6000.c (function_arg): Always split vectors for
e500 if it's a stdarg function.
(function_arg_advance): Advance 2 registers for vectors in a
stdarg function.
(init_cumulative_args): Initialize stdarg.
(rs6000_spe_function_arg): New.

* config/rs6000/rs6000.h (rs6000_args): Add stdarg.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@67854 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 3a48c92..99e786b 100644 (file)
@@ -1,5 +1,16 @@
 2003-06-12  Aldy Hernandez  <aldyh@redhat.com>
 
+       * config/rs6000/rs6000.c (function_arg): Always split vectors for
+       e500 if it's a stdarg function.
+       (function_arg_advance): Advance 2 registers for vectors in a
+       stdarg function.
+       (init_cumulative_args): Initialize stdarg.
+       (rs6000_spe_function_arg): New.
+
+       * config/rs6000/rs6000.h (rs6000_args): Add stdarg.
+
+2003-06-12  Aldy Hernandez  <aldyh@redhat.com>
+
         * config/rs6000/rs6000.h (MODES_TIEABLE_P): Add SPE vectors.
 
 2003-06-12  Roger Sayle  <roger@eyesopen.com>
index 6a9c436..33936b8 100644 (file)
@@ -314,6 +314,7 @@ static inline int rs6000_tls_symbol_ref_1 PARAMS ((rtx *, void *));
 static const char *rs6000_get_some_local_dynamic_name PARAMS ((void));
 static int rs6000_get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
 static rtx rs6000_complex_function_value (enum machine_mode);
+static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree);
 
 /* Hash table stuff for keeping track of TOC entries.  */
 
@@ -3652,6 +3653,10 @@ init_cumulative_args (cum, fntype, libname, incoming)
   cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
   cum->call_cookie = CALL_NORMAL;
   cum->sysv_gregno = GP_ARG_MIN_REG;
+  cum->stdarg = fntype
+    && (TYPE_ARG_TYPES (fntype) != 0
+       && (TREE_VALUE (tree_last  (TYPE_ARG_TYPES (fntype)))
+           != void_type_node));
 
   if (incoming)
     cum->nargs_prototype = 1000;               /* don't return a PARALLEL */
@@ -3759,7 +3764,8 @@ function_arg_advance (cum, mode, type, named)
        cum->words += RS6000_ARG_SIZE (mode, type);
     }
   else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
-          && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
+          && !cum->stdarg
+          && cum->sysv_gregno <= GP_ARG_MAX_REG)
     cum->sysv_gregno++;
   else if (DEFAULT_ABI == ABI_V4)
     {
@@ -3838,7 +3844,43 @@ function_arg_advance (cum, mode, type, named)
        }
     }
 }
-\f
+
+/* Determine where to put a SIMD argument on the SPE.  */
+static rtx
+rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type)
+{
+  if (cum->stdarg)
+    {
+      int gregno = cum->sysv_gregno;
+      int n_words = RS6000_ARG_SIZE (mode, type);
+
+      /* SPE vectors are put in odd registers.  */
+      if (n_words == 2 && (gregno & 1) == 0)
+       gregno += 1;
+
+      if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
+       {
+         rtx r1, r2;
+         enum machine_mode m = SImode;
+
+         r1 = gen_rtx_REG (m, gregno);
+         r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
+         r2 = gen_rtx_REG (m, gregno + 1);
+         r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
+         return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
+       }
+      else
+       return NULL;
+    }
+  else
+    {
+      if (cum->sysv_gregno <= GP_ARG_MAX_REG)
+       return gen_rtx_REG (mode, cum->sysv_gregno);
+      else
+       return NULL;
+    }
+}
+
 /* Determine where to put an argument to a function.
    Value is zero to push the argument on the stack,
    or a hard register in which to store the argument.
@@ -3901,13 +3943,8 @@ function_arg (cum, mode, type, named)
       else
        return NULL;
     }
-  else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
-    {
-      if (cum->sysv_gregno <= GP_ARG_MAX_REG)
-       return gen_rtx_REG (mode, cum->sysv_gregno);
-      else
-       return NULL;
-    }
+  else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))
+    return rs6000_spe_function_arg (cum, mode, type);
   else if (abi == ABI_V4)
     {
       if (TARGET_HARD_FLOAT && TARGET_FPRS
@@ -3923,6 +3960,14 @@ function_arg (cum, mode, type, named)
          int n_words;
          int gregno = cum->sysv_gregno;
 
+         if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
+             && !cum->stdarg
+             && cum->sysv_gregno <= GP_ARG_MAX_REG)
+           {
+             cum->sysv_gregno++;
+             return;
+           }
+
          /* Aggregates and IEEE quad get passed by reference.  */
          if ((type && AGGREGATE_TYPE_P (type))
              || mode == TFmode)
@@ -3934,25 +3979,9 @@ function_arg (cum, mode, type, named)
          if (n_words == 2 && (gregno & 1) == 0)
            gregno += 1;
 
-         /* Long long and SPE vectors are not split between registers
-            and stack.  */
+         /* Long long do not split between registers and stack.  */
          if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
-           {
-             /* SPE vectors in ... get split into 2 registers.  */
-             if (TARGET_SPE && TARGET_SPE_ABI
-                 && SPE_VECTOR_MODE (mode) && !named)
-               {
-                 rtx r1, r2;
-                 enum machine_mode m = SImode;
-
-                 r1 = gen_rtx_REG (m, gregno);
-                 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
-                 r2 = gen_rtx_REG (m, gregno + 1);
-                 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
-                 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
-               }
-             return gen_rtx_REG (mode, gregno);
-           }
+           return gen_rtx_REG (mode, gregno);
          else
            return NULL;
        }
index ffdf403..f0c7ef9 100644 (file)
@@ -1725,6 +1725,7 @@ typedef struct rs6000_args
   int nargs_prototype;         /* # args left in the current prototype */
   int orig_nargs;              /* Original value of nargs_prototype */
   int prototype;               /* Whether a prototype was defined */
+  int stdarg;                  /* Whether function is a stdarg function.  */
   int call_cookie;             /* Do special things for this call */
   int sysv_gregno;             /* next available GP register */
 } CUMULATIVE_ARGS;