PR2076

Dale Johannesen dalej@apple.com
Wed Apr 25 17:03:00 GMT 2001


OK,  here is my attempt at fixing this.  It works on Darwin and I'm 
reasonably confident it will work on AIX; I'm sure somebody who has one 
will let me know if this is wrong.  I don't believe the behavior for 
SVR4 or Solaris has been altered, but I'm less sure of this.

I've set up unnamed parameters (those matching ...) to be passed only in 
Rn, not in Fn as well.  This works with the usual receiving mechanism in 
the callee, which stores all Rn to memory at the beginning.  If somebody 
needs them passed in Fn as well for some reason, there are (I think) 2 
places you have to change, which are indicated in comments.

Index: rs6000.c
===================================================================
RCS file: /cvs/repository/CoreTools/gcc3/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.18
diff -u -d -b -w -p -r1.18 rs6000.c
--- rs6000.c    2001/04/17 02:14:18     1.18
+++ rs6000.c    2001/04/25 23:51:26
@@ -2004,12 +2004,10 @@ function_arg_advance (cum, mode, type, n
                    && function_arg_boundary (mode, type) == 64) ? 1 : 0;
        cum->words += align;

-      if (named)
-       {
-         cum->words += RS6000_ARG_SIZE (mode, type, named);
-         if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_HARD_FLOAT)
+      cum->words += RS6000_ARG_SIZE (mode, type, 1);
+      /* Unnamed params are not passed in FP regs. */
+      if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_HARD_FLOAT && 
named)
             cum->fregno++;
-       }

        if (TARGET_DEBUG_ARG)
         {
@@ -2113,13 +2111,11 @@ function_arg (cum, mode, type, named)
                    && function_arg_boundary (mode, type) == 64) ? 1 : 0;
        int align_words = cum->words + align;

-      if (! named)
-       return NULL_RTX;
-
        if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
          return NULL_RTX;

-      if (USE_FP_FOR_ARG_P (*cum, mode, type))
+      /* unnamed args should be passed in Rn regardless of type. */
+      if (USE_FP_FOR_ARG_P (*cum, mode, type) && named )
         {
           if (! type
               || ((cum->nargs_prototype > 0)
@@ -2169,20 +2165,17 @@ function_arg_partial_nregs (cum, mode, t
       tree type;
       int named;
  {
-  if (! named)
-    return 0;
-
    if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
      return 0;

-  if (USE_FP_FOR_ARG_P (*cum, mode, type))
+  if (USE_FP_FOR_ARG_P (*cum, mode, type) && named )
      {
        if (cum->nargs_prototype >= 0)
         return 0;
      }

    if (cum->words < GP_ARG_NUM_REG
-      && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type, 
named)))
+      && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type, 
1)))
      {
        int ret = GP_ARG_NUM_REG - cum->words;
        if (ret && TARGET_DEBUG_ARG)
@@ -2249,9 +2242,6 @@ setup_incoming_varargs (cum, mode, type,
    int reg_size = TARGET_32BIT ? 4 : 8;
    rtx save_area = NULL_RTX, mem;
    int first_reg_offset, set;
-
-  if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
-    {
        tree fntype;
        int stdarg_p;

@@ -2266,6 +2256,8 @@ setup_incoming_varargs (cum, mode, type,
        if (stdarg_p)
         function_arg_advance (&next_cum, mode, type, 1);

+  if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
+    {
        /* Indicate to allocate space on the stack for varargs save 
area.  */
        /* ??? Does this really have to be located at a magic spot on the
          stack, or can we allocate this with assign_stack_local 
instead.  */
@@ -2278,10 +2270,10 @@ setup_incoming_varargs (cum, mode, type,
      }
    else
      {
+      first_reg_offset = next_cum.words;
        save_area = virtual_incoming_args_rtx;
        cfun->machine->sysv_varargs_p = 0;

-      first_reg_offset = cum->words;
        if (MUST_PASS_IN_STACK (mode, type))
         first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type, 1);
      }
Index: rs6000.h
===================================================================
RCS file: /cvs/repository/CoreTools/gcc3/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.6
diff -u -d -b -w -p -r1.6 rs6000.h
--- rs6000.h    2001/04/03 01:53:17     1.6
+++ rs6000.h    2001/04/25 23:51:26
@@ -205,6 +205,12 @@ extern int target_flags;
  /* Nonzero if we need to schedule the prolog and epilog.  */
  #define MASK_SCHED_PROLOG      0x00040000

+/* This causes the last named parameter to a varargs function to
+   be treated as an ordinary parameter, not as part of the varargs
+   area.  Slightly improves generated code, and fixes a bug that
+   shows up in 980205.c.  Does not affect SVR4 or Solaris. */
+#define STRICT_ARGUMENT_NAMING 1
+
  #define TARGET_POWER           (target_flags & MASK_POWER)
  #define TARGET_POWER2          (target_flags & MASK_POWER2)
  #define TARGET_POWERPC         (target_flags & MASK_POWERPC)



More information about the Gcc mailing list