2003-10-31 Fariborz Jahanian <fjahanian@apple.com>
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 31 Oct 2003 15:50:49 +0000 (15:50 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 31 Oct 2003 15:50:49 +0000 (15:50 +0000)
            David Edelsohn  <edelsohn@gnu.org>

        * config/rs6000/rs6000.c (rs6000_mixed_function_arg): New.
        (function_arg): Call it.
        (rs6000_function_value): Widen integral return value to mode based
        on TARGET_32BIT, not word_mode.
        * config/rs6000/rs6000.h (PROMOTE_MODE): Likewise.

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

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

index 663f879..4b06022 100644 (file)
@@ -1,3 +1,12 @@
+2003-10-31  Fariborz Jahanian  <fjahanian@apple.com>
+           David Edelsohn  <edelsohn@gnu.org>
+
+       * config/rs6000/rs6000.c (rs6000_mixed_function_arg): New.
+       (function_arg): Call it.
+       (rs6000_function_value): Widen integral return value to mode based
+       on TARGET_32BIT, not word_mode.
+       * config/rs6000/rs6000.h (PROMOTE_MODE): Likewise.
+
 2003-10-31  Gerald Pfeifer  <gerald@pfeifer.com>
 
        * .cvsignore: No longer ignore gengtype-lex.c, gengtype-yacc.c,
index 9452701..4297314 100644 (file)
@@ -347,6 +347,8 @@ static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
 static rtx rs6000_complex_function_value (enum machine_mode);
 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
                                    enum machine_mode, tree);
+static rtx rs6000_mixed_function_arg (CUMULATIVE_ARGS *,
+                                     enum machine_mode, tree, int);
 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
                                    enum machine_mode, tree,
                                    int *, int);
@@ -3211,7 +3213,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
          || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
        {
          if (ud1 & 0x8000)
-           emit_move_insn (dest, GEN_INT (((ud1  ^ 0x8000) -  0x8000)));
+           emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) -  0x8000)));
          else
            emit_move_insn (dest, GEN_INT (ud1));
        }
@@ -3894,6 +3896,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
 }
 
 /* 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)
@@ -3919,17 +3922,121 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
          return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
        }
       else
-       return NULL;
+       return NULL_RTX;
     }
   else
     {
       if (cum->sysv_gregno <= GP_ARG_MAX_REG)
        return gen_rtx_REG (mode, cum->sysv_gregno);
       else
-       return NULL;
+       return NULL_RTX;
     }
 }
 
+/* Determine where to place an argument in 64-bit mode with 32-bit ABI.  */
+
+static rtx
+rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, 
+                          tree type, int align_words)
+{
+  if (mode == DFmode)
+    {
+      /* -mpowerpc64 with 32bit ABI splits up a DFmode argument
+        in vararg list into zero, one or two GPRs */
+      if (align_words >= GP_ARG_NUM_REG)
+       return gen_rtx_PARALLEL (DFmode,
+                gen_rtvec (2,
+                           gen_rtx_EXPR_LIST (VOIDmode,
+                                              NULL_RTX, const0_rtx), 
+                           gen_rtx_EXPR_LIST (VOIDmode,
+                                              gen_rtx_REG (mode,
+                                                           cum->fregno),
+                                              const0_rtx)));
+      else if (align_words + RS6000_ARG_SIZE (mode, type)
+              > GP_ARG_NUM_REG)
+       /* If this is partially on the stack, then we only
+          include the portion actually in registers here. */
+       return gen_rtx_PARALLEL (DFmode,
+                gen_rtvec (2,   
+                           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 (mode,
+                                                           cum->fregno),
+                                              const0_rtx)));
+
+      /* split a DFmode arg into two GPRs */
+      return gen_rtx_PARALLEL (DFmode,
+              gen_rtvec (3,
+                         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)),
+                         gen_rtx_EXPR_LIST (VOIDmode,
+                                            gen_rtx_REG (mode, cum->fregno),
+                                            const0_rtx)));
+    }
+  /* -mpowerpc64 with 32bit ABI splits up a DImode argument into one
+     or two GPRs */
+  else if (mode == DImode)
+    {
+      if (align_words < GP_ARG_NUM_REG - 1)
+       return gen_rtx_PARALLEL (DImode,
+                gen_rtvec (2,
+                           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 (align_words == GP_ARG_NUM_REG - 1)
+         return gen_rtx_PARALLEL (DImode,
+                  gen_rtvec (2,
+                             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)));
+    }
+  else if (mode == BLKmode && align_words <= (GP_ARG_NUM_REG - 1))
+    {
+      int k;
+      int size = int_size_in_bytes (type);
+      int no_units = size / 4;
+      int max_no_words = GP_ARG_NUM_REG - align_words;
+      int rtlvec_len = no_units < max_no_words ? no_units : max_no_words;
+      rtx *rtlvec = (rtx *) alloca (rtlvec_len * sizeof (rtx));
+
+      memset ((char *) rtlvec, 0, rtlvec_len * sizeof (rtx));
+
+      for (k=0; k < rtlvec_len; k++)
+       rtlvec[k] = gen_rtx_EXPR_LIST (VOIDmode,
+                                      gen_rtx_REG (SImode,
+                                                   GP_ARG_MIN_REG
+                                                   + align_words + k),
+                                      k == 0 ? const0_rtx : GEN_INT (k*4));
+
+      return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k, rtlvec));
+  }
+
+  return NULL_RTX;
+}
+
 /* 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.
@@ -4029,7 +4136,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
          if (cum->fregno <= FP_ARG_V4_MAX_REG)
            return gen_rtx_REG (mode, cum->fregno);
          else
-           return NULL;
+           return NULL_RTX;
        }
       else
        {
@@ -4051,7 +4158,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
          if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
            return gen_rtx_REG (mode, gregno);
          else
-           return NULL;
+           return NULL_RTX;
        }
     }
   else
@@ -4063,6 +4170,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
       if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
         return NULL_RTX;
 
+      if (TARGET_32BIT && TARGET_POWERPC64
+         && (mode == DFmode || mode == DImode || mode == BLKmode))
+       return rs6000_mixed_function_arg (cum, mode, type, align_words);
+
       if (USE_FP_FOR_ARG_P (*cum, mode, type))
        {
          if (! type
@@ -4075,53 +4186,6 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
                      || (align_words < GP_ARG_NUM_REG))))
            return gen_rtx_REG (mode, cum->fregno);
 
-         if (TARGET_32BIT && TARGET_POWERPC64 && mode == DFmode)
-           {
-              /* -mpowerpc64 with 32bit ABI splits up a DFmode argument
-                in vararg list into zero, one or two GPRs */
-             if (align_words >= GP_ARG_NUM_REG)
-               return gen_rtx_PARALLEL (DFmode,
-                 gen_rtvec (2,
-                            gen_rtx_EXPR_LIST (VOIDmode,
-                                               NULL_RTX, const0_rtx), 
-                            gen_rtx_EXPR_LIST (VOIDmode,
-                                               gen_rtx_REG (mode,
-                                                            cum->fregno),
-                                               const0_rtx)));
-             else if (align_words + RS6000_ARG_SIZE (mode, type)
-                      > GP_ARG_NUM_REG)
-               /* If this is partially on the stack, then we only
-                  include the portion actually in registers here. */
-               return gen_rtx_PARALLEL (DFmode,
-                 gen_rtvec (2,   
-                            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 (mode,
-                                                            cum->fregno),
-                                               const0_rtx)));
-
-             /* split a DFmode arg into two GPRs */
-             return gen_rtx_PARALLEL (DFmode,
-               gen_rtvec (3,
-                          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)),
-                          gen_rtx_EXPR_LIST (VOIDmode,
-                                             gen_rtx_REG (mode, cum->fregno),
-                                             const0_rtx)));
-            }
-
           return gen_rtx_PARALLEL (mode,
            gen_rtvec (2,
                       gen_rtx_EXPR_LIST (VOIDmode,
@@ -4142,37 +4206,6 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
                                gen_rtx_REG (mode, cum->fregno),
                                const0_rtx)));
        }
-      /* -mpowerpc64 with 32bit ABI splits up a DImode argument into one
-        or two GPRs */
-      else if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode
-              && align_words < GP_ARG_NUM_REG - 1)
-       {
-         return gen_rtx_PARALLEL (DImode,
-           gen_rtvec (2,
-                      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 (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode
-              && align_words == GP_ARG_NUM_REG - 1)
-       {
-         return gen_rtx_PARALLEL (DImode,
-           gen_rtvec (2,
-                      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)));
-       }
       else if (align_words < GP_ARG_NUM_REG)
        return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
       else
@@ -11365,7 +11398,7 @@ rs6000_emit_prologue (void)
   rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
   rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
   rtx frame_reg_rtx = sp_reg_rtx;
-  rtx cr_save_rtx = NULL;
+  rtx cr_save_rtx = NULL_RTX;
   rtx insn;
   int saving_FPRs_inline;
   int using_store_multiple;
@@ -15456,7 +15489,7 @@ rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
   if ((INTEGRAL_TYPE_P (valtype)
        && TYPE_PRECISION (valtype) < BITS_PER_WORD)
       || POINTER_TYPE_P (valtype))
-    mode = word_mode;
+    mode = TARGET_32BIT ? SImode : DImode;
   else
     mode = TYPE_MODE (valtype);
 
index d2c3109..e36c6c1 100644 (file)
@@ -604,7 +604,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)      \
   if (GET_MODE_CLASS (MODE) == MODE_INT                \
       && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
-    (MODE) = word_mode;
+    (MODE) = TARGET_32BIT ? SImode : DImode;
 
 /* Define this if most significant bit is lowest numbered
    in instructions that operate on numbered bit-fields.  */