OSDN Git Service

* config/mips/mips-protos.h (mips_va_arg): Delete.
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Jul 2004 05:58:30 +0000 (05:58 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Jul 2004 05:58:30 +0000 (05:58 +0000)
* config/mips/mips.h (EXPAND_BUILTIN_VA_ARG): Delete.
* config/mips/mips.c: Include tree-gimple.h.
(TARGET_GIMPLIFY_VA_ARG_EXPR): Define.
(mips_arg_info): Remove special handling of must_pass_in_stck args.
(mips_gimplify_va_arg_expr): Rewritten from mips_va_arg.
(function_arg_pass_by_reference): Return true if must_pass_in_stack.

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

gcc/ChangeLog
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h

index 4ac79c6..d0bfe32 100644 (file)
@@ -1,3 +1,14 @@
+2004-07-14  Richard Henderson  <rth@redhat.com>
+           Richard Sandiford  <rsandifo@redhat.com>
+
+       * config/mips/mips-protos.h (mips_va_arg): Delete.
+       * config/mips/mips.h (EXPAND_BUILTIN_VA_ARG): Delete.
+       * config/mips/mips.c: Include tree-gimple.h.
+       (TARGET_GIMPLIFY_VA_ARG_EXPR): Define.
+       (mips_arg_info): Remove special handling of must_pass_in_stck args.
+       (mips_gimplify_va_arg_expr): Rewritten from mips_va_arg.
+       (function_arg_pass_by_reference): Return true if must_pass_in_stack.
+
 2004-07-13  Bob Wilson  <bob.wilson@acm.org>
 
        * config/xtensa/xtensa.c (xtensa_gimplify_va_arg_expr): Swap
index f1c42ab..f38809e 100644 (file)
@@ -143,7 +143,6 @@ extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *,
 extern bool mips_pad_arg_upward (enum machine_mode, tree);
 extern bool mips_pad_reg_upward (enum machine_mode, tree);
 extern void mips_va_start (tree, rtx);
-extern struct rtx_def *mips_va_arg (tree, tree);
 
 extern bool mips_expand_unaligned_load (rtx, rtx, unsigned int, int);
 extern bool mips_expand_unaligned_store (rtx, rtx, unsigned int, int);
index cb470b4..3e93a01 100644 (file)
@@ -55,6 +55,7 @@ Boston, MA 02111-1307, USA.  */
 #include "langhooks.h"
 #include "cfglayout.h"
 #include "sched-int.h"
+#include "tree-gimple.h"
 
 /* Enumeration for all of the relational tests, so that we can build
    arrays indexed by the test type, and not worry about the order
@@ -288,6 +289,7 @@ static void mips_init_libfuncs (void);
 static void mips_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
                                         tree, int *, int);
 static tree mips_build_builtin_va_list (void);
+static tree mips_gimplify_va_arg_expr (tree, tree, tree *, tree *);
 
 #if TARGET_IRIX
 static void irix_asm_named_section_1 (const char *, unsigned int,
@@ -716,6 +718,8 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
 
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST mips_build_builtin_va_list
+#undef TARGET_GIMPLIFY_VA_ARG_EXPR
+#define TARGET_GIMPLIFY_VA_ARG_EXPR mips_gimplify_va_arg_expr
 
 #undef TARGET_PROMOTE_FUNCTION_ARGS
 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
@@ -3554,22 +3558,15 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
        even_reg_p = true;
     }
 
-  if (mips_abi != ABI_EABI && targetm.calls.must_pass_in_stack (mode, type))
-    /* This argument must be passed on the stack.  Eat up all the
-       remaining registers.  */
-    info->reg_offset = MAX_ARGS_IN_REGISTERS;
-  else
-    {
-      /* Set REG_OFFSET to the register count we're interested in.
-        The EABI allocates the floating-point registers separately,
-        but the other ABIs allocate them like integer registers.  */
-      info->reg_offset = (mips_abi == ABI_EABI && info->fpr_p
-                         ? cum->num_fprs
-                         : cum->num_gprs);
+  /* Set REG_OFFSET to the register count we're interested in.
+     The EABI allocates the floating-point registers separately,
+     but the other ABIs allocate them like integer registers.  */
+  info->reg_offset = (mips_abi == ABI_EABI && info->fpr_p
+                     ? cum->num_fprs
+                     : cum->num_gprs);
 
-      if (even_reg_p)
-       info->reg_offset += info->reg_offset & 1;
-    }
+  if (even_reg_p)
+    info->reg_offset += info->reg_offset & 1;
 
   /* The alignment applied to registers is also applied to stack arguments.  */
   info->stack_offset = cum->stack_words;
@@ -4041,272 +4038,179 @@ mips_va_start (tree valist, rtx nextarg)
 \f
 /* Implement va_arg.  */
 
-rtx
-mips_va_arg (tree valist, tree type)
+static tree
+mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
 {
   HOST_WIDE_INT size, rsize;
-  rtx addr_rtx;
-  tree t;
+  tree addr;
+  bool indirect;
+
+  indirect
+    = function_arg_pass_by_reference (NULL, TYPE_MODE (type), type, 0);
+
+  if (indirect)
+    type = build_pointer_type (type);
 
   size = int_size_in_bytes (type);
   rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
 
-  if (mips_abi == ABI_EABI)
+  if (mips_abi != ABI_EABI || !EABI_FLOAT_VARARGS_P)
+    addr = std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
+  else
     {
-      bool indirect;
-      rtx r;
-
-      indirect
-       = function_arg_pass_by_reference (NULL, TYPE_MODE (type), type, 0);
-
-      if (indirect)
-       {
-         size = POINTER_SIZE / BITS_PER_UNIT;
-         rsize = UNITS_PER_WORD;
-       }
-
-      if (!EABI_FLOAT_VARARGS_P)
+      /* Not a simple merged stack.     */
+
+      tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
+      tree ovfl, top, off, align;
+      HOST_WIDE_INT osize;
+      tree t, u;
+
+      f_ovfl = TYPE_FIELDS (va_list_type_node);
+      f_gtop = TREE_CHAIN (f_ovfl);
+      f_ftop = TREE_CHAIN (f_gtop);
+      f_goff = TREE_CHAIN (f_ftop);
+      f_foff = TREE_CHAIN (f_goff);
+
+      /* We maintain separate pointers and offsets for floating-point
+        and integer arguments, but we need similar code in both cases.
+        Let:
+
+        TOP be the top of the register save area;
+        OFF be the offset from TOP of the next register;
+        ADDR_RTX be the address of the argument;
+        RSIZE be the number of bytes used to store the argument
+        when it's in the register save area;
+        OSIZE be the number of bytes used to store it when it's
+        in the stack overflow area; and
+        PADDING be (BYTES_BIG_ENDIAN ? OSIZE - RSIZE : 0)
+
+        The code we want is:
+
+        1: off &= -rsize;        // round down
+        2: if (off != 0)
+        3:   {
+        4:      addr_rtx = top - off;
+        5:      off -= rsize;
+        6:   }
+        7: else
+        8:   {
+        9:      ovfl += ((intptr_t) ovfl + osize - 1) & -osize;
+        10:     addr_rtx = ovfl + PADDING;
+        11:     ovfl += osize;
+        14:   }
+
+        [1] and [9] can sometimes be optimized away.  */
+
+      ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
+                   NULL_TREE);
+
+      if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
+         && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
        {
-         /* Case of all args in a merged stack.  No need to check bounds,
-            just advance valist along the stack.  */
-
-         tree gpr = valist;
-         if (!indirect
-             && !TARGET_64BIT
-             && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
-           {
-             /* Align the pointer using: ap = (ap + align - 1) & -align,
-                where align is 2 * UNITS_PER_WORD.  */
-             t = build (PLUS_EXPR, TREE_TYPE (gpr), gpr,
-                        build_int_2 (2 * UNITS_PER_WORD - 1, 0));
-             t = build (BIT_AND_EXPR, TREE_TYPE (t), t,
-                        build_int_2 (-2 * UNITS_PER_WORD, -1));
-             t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, t);
-             expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-           }
-
-         /* Emit code to set addr_rtx to the valist, and postincrement
-            the valist by the size of the argument, rounded up to the
-            next word.  Account for padding on big-endian targets.  */
-         t = build (POSTINCREMENT_EXPR, TREE_TYPE (gpr), gpr,
-                    size_int (rsize));
-         addr_rtx = expand_expr (t, 0, Pmode, EXPAND_NORMAL);
-         if (BYTES_BIG_ENDIAN)
-           addr_rtx = plus_constant (addr_rtx, rsize - size);
-
-         /* Flush the POSTINCREMENT.  */
-         emit_queue();
+         top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
+                      NULL_TREE);
+         off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
+                      NULL_TREE);
+
+         /* When floating-point registers are saved to the stack,
+            each one will take up UNITS_PER_HWFPVALUE bytes, regardless
+            of the float's precision.  */
+         rsize = UNITS_PER_HWFPVALUE;
+
+         /* Overflow arguments are padded to UNITS_PER_WORD bytes
+            (= PARM_BOUNDARY bits).  This can be different from RSIZE
+            in two cases:
+
+            (1) On 32-bit targets when TYPE is a structure such as:
+
+            struct s { float f; };
+
+            Such structures are passed in paired FPRs, so RSIZE
+            will be 8 bytes.  However, the structure only takes
+            up 4 bytes of memory, so OSIZE will only be 4.
+
+            (2) In combinations such as -mgp64 -msingle-float
+            -fshort-double.  Doubles passed in registers
+            will then take up 4 (UNITS_PER_HWFPVALUE) bytes,
+            but those passed on the stack take up
+            UNITS_PER_WORD bytes.  */
+         osize = MAX (GET_MODE_SIZE (TYPE_MODE (type)), UNITS_PER_WORD);
        }
       else
        {
-         /* Not a simple merged stack.  */
-
-         tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
-         tree ovfl, top, off;
-         rtx lab_over = NULL_RTX, lab_false;
-         HOST_WIDE_INT osize;
-
-         addr_rtx = gen_reg_rtx (Pmode);
-
-         f_ovfl = TYPE_FIELDS (va_list_type_node);
-         f_gtop = TREE_CHAIN (f_ovfl);
-         f_ftop = TREE_CHAIN (f_gtop);
-         f_goff = TREE_CHAIN (f_ftop);
-         f_foff = TREE_CHAIN (f_goff);
-
-         /* We maintain separate pointers and offsets for floating-point
-            and integer arguments, but we need similar code in both cases.
-            Let:
-
-                TOP be the top of the register save area;
-                OFF be the offset from TOP of the next register;
-                ADDR_RTX be the address of the argument;
-                RSIZE be the number of bytes used to store the argument
-                  when it's in the register save area;
-                OSIZE be the number of bytes used to store it when it's
-                  in the stack overflow area; and
-                PADDING be (BYTES_BIG_ENDIAN ? OSIZE - RSIZE : 0)
-
-            The code we want is:
-
-                 1: off &= -rsize;       // round down
-                 2: if (off != 0)
-                 3:   {
-                 4:     addr_rtx = top - off;
-                 5:     off -= rsize;
-                 6:   }
-                 7: else
-                 8:   {
-                 9:     ovfl += ((intptr_t) ovfl + osize - 1) & -osize;
-                10:     addr_rtx = ovfl + PADDING;
-                11:     ovfl += osize;
-                14:   }
-
-            [1] and [9] can sometimes be optimized away.  */
-
-         lab_false = gen_label_rtx ();
-         lab_over = gen_label_rtx ();
-
-         ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
-                       NULL_TREE);
-         if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
-             && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
+         top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
+                      NULL_TREE);
+         off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
+                      NULL_TREE);
+         if (rsize > UNITS_PER_WORD)
            {
-             top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
-                          NULL_TREE);
-             off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
-                          NULL_TREE);
-
-             /* When floating-point registers are saved to the stack,
-                each one will take up UNITS_PER_HWFPVALUE bytes, regardless
-                of the float's precision.  */
-             rsize = UNITS_PER_HWFPVALUE;
-
-             /* Overflow arguments are padded to UNITS_PER_WORD bytes
-                (= PARM_BOUNDARY bits).  This can be different from RSIZE
-                in two cases:
-
-                    (1) On 32-bit targets when TYPE is a structure such as:
-
-                            struct s { float f; };
-
-                        Such structures are passed in paired FPRs, so RSIZE
-                        will be 8 bytes.  However, the structure only takes
-                        up 4 bytes of memory, so OSIZE will only be 4.
-
-                    (2) In combinations such as -mgp64 -msingle-float
-                        -fshort-double.  Doubles passed in registers
-                        will then take up 4 (UNITS_PER_HWFPVALUE) bytes,
-                        but those passed on the stack take up
-                        UNITS_PER_WORD bytes.  */
-             osize = MAX (GET_MODE_SIZE (TYPE_MODE (type)), UNITS_PER_WORD);
+             /* [1] Emit code for: off &= -rsize.      */
+             t = build (BIT_AND_EXPR, TREE_TYPE (off), off,
+                        build_int_2 (-rsize, -1));
+             t = build (MODIFY_EXPR, TREE_TYPE (off), off, t);
+             gimplify_and_add (t, pre_p);
            }
-         else
-           {
-             top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
-                          NULL_TREE);
-             off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
-                          NULL_TREE);
-             if (rsize > UNITS_PER_WORD)
-               {
-                 /* [1] Emit code for: off &= -rsize.  */
-                 t = build (BIT_AND_EXPR, TREE_TYPE (off), off,
-                            build_int_2 (-rsize, -1));
-                 t = build (MODIFY_EXPR, TREE_TYPE (off), off, t);
-                 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-               }
-             osize = rsize;
-           }
-
-         /* [2] Emit code to branch if off == 0.  */
-         r = expand_expr (off, NULL_RTX, TYPE_MODE (TREE_TYPE (off)),
-                          EXPAND_NORMAL);
-         emit_cmp_and_jump_insns (r, const0_rtx, EQ, const1_rtx, GET_MODE (r),
-                                  1, lab_false);
-
-         /* [4] Emit code for: addr_rtx = top - off.  On big endian machines,
-            the argument has RSIZE - SIZE bytes of leading padding.  */
-         t = build (MINUS_EXPR, TREE_TYPE (top), top, off);
-         if (BYTES_BIG_ENDIAN && rsize > size)
-           t = build (PLUS_EXPR, TREE_TYPE (t), t,
-                      build_int_2 (rsize - size, 0));
-         r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
-         if (r != addr_rtx)
-           emit_move_insn (addr_rtx, r);
-
-         /* [5] Emit code for: off -= rsize.  */
-         t = build (MINUS_EXPR, TREE_TYPE (off), off, build_int_2 (rsize, 0));
-         t = build (MODIFY_EXPR, TREE_TYPE (off), off, t);
-         expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
-         /* [7] Emit code to jump over the else clause, then the label
-            that starts it.  */
-         emit_queue();
-         emit_jump (lab_over);
-         emit_barrier ();
-         emit_label (lab_false);
+         osize = rsize;
+       }
 
-         if (osize > UNITS_PER_WORD)
-           {
-             /* [9] Emit: ovfl += ((intptr_t) ovfl + osize - 1) & -osize.  */
-             t = build (PLUS_EXPR, TREE_TYPE (ovfl), ovfl,
-                        build_int_2 (osize - 1, 0));
-             t = build (BIT_AND_EXPR, TREE_TYPE (ovfl), t,
-                        build_int_2 (-osize, -1));
-             t = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
-             expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-           }
+      /* [2] Emit code to branch if off == 0.  */
+      t = lang_hooks.truthvalue_conversion (off);
+      addr = build (COND_EXPR, ptr_type_node, t, NULL, NULL);
+
+      /* [5] Emit code for: off -= rsize.  We do this as a form of
+        post-increment not available to C.  Also widen for the
+        coming pointer arithmetic.  */
+      t = fold_convert (TREE_TYPE (off), build_int_2 (rsize, 0));
+      t = build (POSTDECREMENT_EXPR, TREE_TYPE (off), off, t);
+      t = fold_convert (sizetype, t);
+      t = fold_convert (TREE_TYPE (top), t);
+
+      /* [4] Emit code for: addr_rtx = top - off.  On big endian machines,
+        the argument has RSIZE - SIZE bytes of leading padding.  */
+      t = build (MINUS_EXPR, TREE_TYPE (top), top, t);
+      if (BYTES_BIG_ENDIAN && rsize > size)
+       {
+         u = fold_convert (TREE_TYPE (t), build_int_2 (rsize - size, 0));
+         t = build (PLUS_EXPR, TREE_TYPE (t), t, u);
+       }
+      COND_EXPR_THEN (addr) = t;
 
-         /* [10, 11].  Emit code to store ovfl in addr_rtx, then
-            post-increment ovfl by osize.  On big-endian machines,
-            the argument has OSIZE - SIZE bytes of leading padding.  */
-         t = build (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl,
-                    size_int (osize));
-         if (BYTES_BIG_ENDIAN && osize > size)
-           t = build (PLUS_EXPR, TREE_TYPE (t), t,
-                      build_int_2 (osize - size, 0));
-         r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
-         if (r != addr_rtx)
-           emit_move_insn (addr_rtx, r);
-
-         emit_queue();
-         emit_label (lab_over);
+      if (osize > UNITS_PER_WORD)
+       {
+         /* [9] Emit: ovfl += ((intptr_t) ovfl + osize - 1) & -osize.  */
+         u = fold_convert (TREE_TYPE (ovfl), build_int_2 (osize - 1, 0));
+         t = build (PLUS_EXPR, TREE_TYPE (ovfl), ovfl, u);
+         u = fold_convert (TREE_TYPE (ovfl), build_int_2 (-osize, -1));
+         t = build (BIT_AND_EXPR, TREE_TYPE (ovfl), t, u);
+         align = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
        }
-      if (indirect)
+      else
+       align = NULL;
+
+      /* [10, 11].     Emit code to store ovfl in addr_rtx, then
+        post-increment ovfl by osize.  On big-endian machines,
+        the argument has OSIZE - SIZE bytes of leading padding.  */
+      u = fold_convert (TREE_TYPE (ovfl), build_int_2 (osize, 0));
+      t = build (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl, u);
+      if (BYTES_BIG_ENDIAN && osize > size)
        {
-         addr_rtx = force_reg (Pmode, addr_rtx);
-         r = gen_rtx_MEM (Pmode, addr_rtx);
-         set_mem_alias_set (r, get_varargs_alias_set ());
-         emit_move_insn (addr_rtx, r);
+         u = fold_convert (TREE_TYPE (t), build_int_2 (osize - size, 0));
+         t = build (PLUS_EXPR, TREE_TYPE (t), t, u);
        }
-      return addr_rtx;
-    }
-  else
-    {
-      /* Not EABI.  */
-      int align;
-      HOST_WIDE_INT min_offset;
 
-      /* ??? The original va-mips.h did always align, despite the fact
-        that alignments <= UNITS_PER_WORD are preserved by the va_arg
-        increment mechanism.  */
+      /* String [9] and [10,11] together.  */
+      if (align)
+       t = build (COMPOUND_EXPR, TREE_TYPE (t), align, t);
+      COND_EXPR_ELSE (addr) = t;
 
-      if (TARGET_NEWABI && TYPE_ALIGN (type) > 64)
-       align = 16;
-      else if (TARGET_64BIT)
-       align = 8;
-      else if (TYPE_ALIGN (type) > 32)
-       align = 8;
-      else
-       align = 4;
-
-      t = build (PLUS_EXPR, TREE_TYPE (valist), valist,
-                build_int_2 (align - 1, 0));
-      t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
-
-      /* If arguments of type TYPE must be passed on the stack,
-        set MIN_OFFSET to the offset of the first stack parameter.  */
-      if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
-       min_offset = 0;
-      else if (TARGET_NEWABI)
-       min_offset = current_function_pretend_args_size;
-      else
-       min_offset = REG_PARM_STACK_SPACE (current_function_decl);
-
-      /* Make sure the new address is at least MIN_OFFSET bytes from
-        the incoming argument pointer.  */
-      if (min_offset > 0)
-       t = build (MAX_EXPR, TREE_TYPE (valist), t,
-                  make_tree (TREE_TYPE (valist),
-                             plus_constant (virtual_incoming_args_rtx,
-                                            min_offset)));
+      addr = fold_convert (build_pointer_type (type), addr);
+      addr = build_fold_indirect_ref (addr);
+    }
 
-      t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
-      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+  if (indirect)
+    addr = build_fold_indirect_ref (addr);
 
-      /* Everything past the alignment is standard.  */
-      return std_expand_builtin_va_arg (valist, type);
-    }
+  return addr;
 }
 \f
 /* Return true if it is possible to use left/right accesses for a
@@ -7425,18 +7329,22 @@ function_arg_pass_by_reference (const CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
                                enum machine_mode mode, tree type,
                                int named ATTRIBUTE_UNUSED)
 {
-  int size;
-
-  /* The EABI is the only one to pass args by reference.  */
-  if (mips_abi != ABI_EABI)
-    return 0;
+  if (mips_abi == ABI_EABI)
+    {
+      int size;
 
-  /* ??? How should SCmode be handled?  */
-  if (type == NULL_TREE || mode == DImode || mode == DFmode)
-    return 0;
+      /* ??? How should SCmode be handled?  */
+      if (type == NULL_TREE || mode == DImode || mode == DFmode)
+       return 0;
 
-  size = int_size_in_bytes (type);
-  return size == -1 || size > UNITS_PER_WORD;
+      size = int_size_in_bytes (type);
+      return size == -1 || size > UNITS_PER_WORD;
+    }
+  else
+    {
+      /* If we have a variable-sized parameter, we have no choice.  */
+      return targetm.calls.must_pass_in_stack (mode, type);
+    }
 }
 
 /* Return the class of registers for which a mode change from FROM to TO
index 04e6ee4..3517780 100644 (file)
@@ -2387,10 +2387,6 @@ typedef struct mips_args {
 /* Implement `va_start' for varargs and stdarg.  */
 #define EXPAND_BUILTIN_VA_START(valist, nextarg) \
   mips_va_start (valist, nextarg)
-
-/* Implement `va_arg'.  */
-#define EXPAND_BUILTIN_VA_ARG(valist, type) \
-  mips_va_arg (valist, type)
 \f
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */