public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PATCH: sparc_gimplify_va_arg
@ 2004-06-11  9:15 Jason Merrill
  2004-06-11 10:09 ` Eric Botcazou
  0 siblings, 1 reply; 4+ messages in thread
From: Jason Merrill @ 2004-06-11  9:15 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 193 bytes --]

Tested sparc-sun-solaris2.6, applied to trunk.

2004-06-11  Jason Merrill  <jason@redhat.com>

	* config/sparc/sparc.c (sparc_gimplify_va_arg): New fn.
	(TARGET_GIMPLIFY_VA_ARG_EXPR): Define.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 4029 bytes --]

*** config/sparc/sparc.c.~1~	2004-06-10 23:08:32.000000000 -0400
--- config/sparc/sparc.c	2004-06-10 22:18:04.000000000 -0400
*************** Boston, MA 02111-1307, USA.  */
*** 47,52 ****
--- 47,53 ----
  #include "target.h"
  #include "target-def.h"
  #include "cfglayout.h"
+ #include "tree-gimple.h"
  
  /* Global variables for machine-dependent things.  */
  
*************** static bool sparc_promote_prototypes (tr
*** 181,186 ****
--- 182,188 ----
  static rtx sparc_struct_value_rtx (tree, int);
  static bool sparc_return_in_memory (tree, tree);
  static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *);
+ static tree sparc_gimplify_va_arg (tree, tree, tree *, tree *);
  \f
  /* Option handling.  */
  
*************** enum processor_type sparc_cpu;
*** 289,294 ****
--- 291,299 ----
  #undef TARGET_STRICT_ARGUMENT_NAMING
  #define TARGET_STRICT_ARGUMENT_NAMING sparc_strict_argument_naming
  
+ #undef TARGET_GIMPLIFY_VA_ARG_EXPR
+ #define TARGET_GIMPLIFY_VA_ARG_EXPR sparc_gimplify_va_arg
+ 
  struct gcc_target targetm = TARGET_INITIALIZER;
  \f
  /* Validate and override various options, and do some machine dependent
*************** sparc_va_arg (tree valist, tree type)
*** 6041,6046 ****
--- 6046,6141 ----
  
    return addr_rtx;
  }
+ 
+ tree
+ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
+ {
+   HOST_WIDE_INT size, rsize, align;
+   tree addr, incr;
+   bool indirect;
+   tree ptrtype = build_pointer_type (type);
+ 
+   if (function_arg_pass_by_reference (0, TYPE_MODE (type), type, 0))
+     {
+       indirect = true;
+       size = rsize = UNITS_PER_WORD;
+       align = 0;
+     }
+   else
+     {
+       indirect = false;
+       size = int_size_in_bytes (type);
+       rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
+       align = 0;
+     
+       if (TARGET_ARCH64)
+ 	{
+ 	  /* For SPARC64, objects requiring 16-byte alignment get it.  */
+ 	  if (TYPE_ALIGN (type) >= 2 * (unsigned) BITS_PER_WORD)
+ 	    align = 2 * UNITS_PER_WORD;
+ 
+ 	  /* SPARC-V9 ABI states that structures up to 16 bytes in size
+ 	     are given whole slots as needed.  */
+ 	  if (AGGREGATE_TYPE_P (type))
+ 	    {
+ 	      if (size == 0)
+ 		size = rsize = UNITS_PER_WORD;
+ 	      else
+ 		size = rsize;
+ 	    }
+ 	}
+     }
+ 
+   incr = valist;
+   if (align)
+     {
+       incr = fold (build2 (PLUS_EXPR, ptr_type_node, incr,
+ 			   ssize_int (align - 1)));
+       incr = fold (build2 (BIT_AND_EXPR, ptr_type_node, incr,
+ 			   ssize_int (-align)));
+     }
+ 
+   gimplify_expr (&incr, pre_p, post_p, is_gimple_val, fb_rvalue);
+   addr = incr;
+ 
+   if (BYTES_BIG_ENDIAN && size < rsize)
+     addr = fold (build2 (PLUS_EXPR, ptr_type_node, incr,
+ 			 ssize_int (rsize - size)));
+ 
+   if (indirect)
+     {
+       addr = fold_convert (build_pointer_type (ptrtype), addr);
+       addr = build_fold_indirect_ref (addr);
+     }
+   /* If the address isn't aligned properly for the type,
+      we may need to copy to a temporary.  
+      FIXME: This is inefficient.  Usually we can do this
+      in registers.  */
+   else if (align == 0
+ 	   && TYPE_ALIGN (type) > BITS_PER_WORD)
+     {
+       tree tmp = create_tmp_var (type, "va_arg_tmp");
+       tree dest_addr = build_fold_addr_expr (tmp);
+ 
+       tree copy = build_function_call_expr
+ 	(implicit_built_in_decls[BUILT_IN_MEMCPY],
+ 	 tree_cons (NULL_TREE, dest_addr,
+ 		    tree_cons (NULL_TREE, addr,
+ 			       tree_cons (NULL_TREE, size_int (rsize),
+ 					  NULL_TREE))));
+ 
+       gimplify_and_add (copy, pre_p);
+       addr = dest_addr;
+     }
+   else
+     addr = fold_convert (ptrtype, addr);
+ 
+   incr = fold (build2 (PLUS_EXPR, ptr_type_node, incr, ssize_int (rsize)));
+   incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
+   gimplify_and_add (incr, post_p);
+ 
+   return build_fold_indirect_ref (addr);
+ }
  \f
  /* Return the string to output a conditional branch to LABEL, which is
     the operand number of the label.  OP is the conditional expression.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PATCH: sparc_gimplify_va_arg
  2004-06-11  9:15 PATCH: sparc_gimplify_va_arg Jason Merrill
@ 2004-06-11 10:09 ` Eric Botcazou
  2004-06-11 16:32   ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Botcazou @ 2004-06-11 10:09 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

> 2004-06-11  Jason Merrill  <jason@redhat.com>
>
> 	* config/sparc/sparc.c (sparc_gimplify_va_arg): New fn.
> 	(TARGET_GIMPLIFY_VA_ARG_EXPR): Define.

Thanks for doing this.  However, I see you duplicated sparc_va_arg pretty 
much entirely.  Would it not be better to factor out the common structure 
between both functions?  Or is sparc_va_arg already doomed to death?

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PATCH: sparc_gimplify_va_arg
  2004-06-11 10:09 ` Eric Botcazou
@ 2004-06-11 16:32   ` Jason Merrill
  2004-06-11 20:09     ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Jason Merrill @ 2004-06-11 16:32 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

On Fri, 11 Jun 2004 08:55:46 +0200, Eric Botcazou <ebotcazou@libertysurf.fr> wrote:

>> 2004-06-11  Jason Merrill  <jason@redhat.com>
>>
>> 	* config/sparc/sparc.c (sparc_gimplify_va_arg): New fn.
>> 	(TARGET_GIMPLIFY_VA_ARG_EXPR): Define.
>
> Thanks for doing this.  However, I see you duplicated sparc_va_arg pretty 
> much entirely.  Would it not be better to factor out the common structure 
> between both functions?  Or is sparc_va_arg already doomed to death?

The latter.  Once all targets have the gimplifier hook, the expanders will
go away.

Hmm, actually, maybe they can go away individually as targets are
converted...

Jason

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PATCH: sparc_gimplify_va_arg
  2004-06-11 16:32   ` Jason Merrill
@ 2004-06-11 20:09     ` Jason Merrill
  0 siblings, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2004-06-11 20:09 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 588 bytes --]

Like so.  Tested x86_64-pc-linux-gnu, verified that the other three
compilers built, applied to trunk.

2004-06-11  Jason Merrill  <jason@redhat.com>

	* config/i386/i386.h (EXPAND_BUILTIN_VA_ARG): Just abort.
	* config/i386/i386.c (ix86_va_arg): Remove.
	* config/rs6000/rs6000.h (EXPAND_BUILTIN_VA_ARG): Just abort.
	* config/rs6000/rs6000.c (rs6000_va_arg): Remove.
	* config/alpha/alpha.h (EXPAND_BUILTIN_VA_ARG): Just abort.
	* config/alpha/alpha.c (alpha_va_arg): Remove.
	* config/sparc/sparc.h (EXPAND_BUILTIN_VA_ARG): Just abort.
	* config/sparc/sparc.c (sparc_va_arg): Remove.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 30439 bytes --]

Index: gcc/config/alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.365
diff -c -p -r1.365 alpha.c
*** gcc/config/alpha/alpha.c	10 Jun 2004 15:49:44 -0000	1.365
--- gcc/config/alpha/alpha.c	11 Jun 2004 17:33:12 -0000
*************** alpha_va_start (tree valist, rtx nextarg
*** 6291,6405 ****
      }
  }
  
- rtx
- alpha_va_arg (tree valist, tree type)
- {
-   rtx addr;
-   tree t, type_size, rounded_size;
-   tree offset_field, base_field, addr_tree, addend;
-   tree wide_type, wide_ofs;
-   int indirect = 0;
- 
-   if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
-     return std_expand_builtin_va_arg (valist, type);
- 
-   if (type == error_mark_node
-       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
-       || TREE_OVERFLOW (type_size))
-     rounded_size = size_zero_node;
-   else
-     rounded_size = fold (build (MULT_EXPR, sizetype,
- 				fold (build (TRUNC_DIV_EXPR, sizetype,
- 					     fold (build (PLUS_EXPR, sizetype,
- 							  type_size,
- 							  size_int (7))),
- 					     size_int (8))),
- 				size_int (8)));
- 
-   base_field = TYPE_FIELDS (TREE_TYPE (valist));
-   offset_field = TREE_CHAIN (base_field);
- 
-   base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
- 		      valist, base_field);
-   offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
- 			valist, offset_field);
- 
-   /* If the type could not be passed in registers, skip the block
-      reserved for the registers.  */
-   if (MUST_PASS_IN_STACK (TYPE_MODE (type), type))
-     {
-       t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
- 		 build (MAX_EXPR, TREE_TYPE (offset_field), 
- 			offset_field, build_int_2 (6*8, 0)));
-       TREE_SIDE_EFFECTS (t) = 1;
-       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-     }
- 
-   wide_type = make_signed_type (64);
-   wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
- 
-   addend = wide_ofs;
- 
-   if (TYPE_MODE (type) == TFmode || TYPE_MODE (type) == TCmode)
-     {
-       indirect = 1;
-       rounded_size = size_int (UNITS_PER_WORD);
-     }
-   else if (TREE_CODE (type) == COMPLEX_TYPE)
-     {
-       rtx real_part, imag_part, value, tmp;
- 
-       real_part = alpha_va_arg (valist, TREE_TYPE (type));
-       imag_part = alpha_va_arg (valist, TREE_TYPE (type));
- 
-       /* ??? Most irritatingly, we're not returning the value here,
- 	 but the address.  Since real_part and imag_part are not
- 	 necessarily contiguous, we must copy to local storage.  */
- 
-       real_part = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (type)), real_part);
-       imag_part = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (type)), imag_part);
-       value = gen_rtx_CONCAT (TYPE_MODE (type), real_part, imag_part);
- 
-       tmp = assign_temp (type, 0, 1, 0);
-       emit_move_insn (tmp, value);
- 
-       return XEXP (tmp, 0);
-     }
-   else if (TREE_CODE (type) == REAL_TYPE)
-     {
-       tree fpaddend, cond;
- 
-       fpaddend = fold (build (PLUS_EXPR, TREE_TYPE (addend),
- 			      addend, build_int_2 (-6*8, 0)));
- 
-       cond = fold (build (LT_EXPR, integer_type_node,
- 			  wide_ofs, build_int_2 (6*8, 0)));
- 
-       addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
- 			    fpaddend, addend));
-     }
- 
-   addr_tree = build (PLUS_EXPR, TREE_TYPE (base_field),
- 		     base_field, addend);
- 
-   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
-   addr = copy_to_reg (addr);
- 
-   t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
- 	     build (PLUS_EXPR, TREE_TYPE (offset_field), 
- 		    offset_field, rounded_size));
-   TREE_SIDE_EFFECTS (t) = 1;
-   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- 
-   if (indirect)
-     {
-       addr = force_reg (Pmode, addr);
-       addr = gen_rtx_MEM (Pmode, addr);
-     }
- 
-   return addr;
- }
- 
  static tree
  alpha_gimplify_va_arg_1 (tree type, tree base, tree offset,
  			 tree *pre_p, tree *post_p)
--- 6291,6296 ----
Index: gcc/config/alpha/alpha.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.h,v
retrieving revision 1.219
diff -c -p -r1.219 alpha.h
*** gcc/config/alpha/alpha.h	12 Mar 2004 10:03:09 -0000	1.219
--- gcc/config/alpha/alpha.h	11 Jun 2004 17:33:12 -0000
*************** do {						\
*** 1687,1694 ****
    alpha_va_start (valist, nextarg)
  
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(valist, type) \
!   alpha_va_arg (valist, type)
  \f
  /* Tell collect that the object format is ECOFF.  */
  #define OBJECT_FORMAT_COFF
--- 1687,1693 ----
    alpha_va_start (valist, nextarg)
  
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX)
  \f
  /* Tell collect that the object format is ECOFF.  */
  #define OBJECT_FORMAT_COFF
Index: gcc/config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.674
diff -c -p -r1.674 i386.c
*** gcc/config/i386/i386.c	10 Jun 2004 15:49:45 -0000	1.674
--- gcc/config/i386/i386.c	11 Jun 2004 17:33:13 -0000
*************** ix86_va_start (tree valist, rtx nextarg)
*** 3177,3422 ****
  }
  
  /* Implement va_arg.  */
- rtx
- ix86_va_arg (tree valist, tree type)
- {
-   static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
-   tree f_gpr, f_fpr, f_ovf, f_sav;
-   tree gpr, fpr, ovf, sav, t;
-   int size, rsize;
-   rtx lab_false, lab_over = NULL_RTX;
-   rtx addr_rtx, r;
-   rtx container;
-   int indirect_p = 0;
- 
-   /* Only 64bit target needs something special.  */
-   if (!TARGET_64BIT)
-     {
-       return std_expand_builtin_va_arg (valist, type);
-     }
- 
-   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
-   f_fpr = TREE_CHAIN (f_gpr);
-   f_ovf = TREE_CHAIN (f_fpr);
-   f_sav = TREE_CHAIN (f_ovf);
- 
-   valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
-   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
-   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
-   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
-   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
- 
-   size = int_size_in_bytes (type);
-   if (size == -1)
-     {
-       /* Passed by reference.  */
-       indirect_p = 1;
-       type = build_pointer_type (type);
-       size = int_size_in_bytes (type);
-     }
-   rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
- 
-   container = construct_container (TYPE_MODE (type), type, 0,
- 				   REGPARM_MAX, SSE_REGPARM_MAX, intreg, 0);
-   /*
-    * Pull the value out of the saved registers ...
-    */
- 
-   addr_rtx = gen_reg_rtx (Pmode);
- 
-   if (container)
-     {
-       rtx int_addr_rtx, sse_addr_rtx;
-       int needed_intregs, needed_sseregs;
-       int need_temp;
- 
-       lab_over = gen_label_rtx ();
-       lab_false = gen_label_rtx ();
- 
-       examine_argument (TYPE_MODE (type), type, 0,
- 		        &needed_intregs, &needed_sseregs);
- 
- 
-       need_temp = ((needed_intregs && TYPE_ALIGN (type) > 64)
- 		   || TYPE_ALIGN (type) > 128);
- 
-       /* In case we are passing structure, verify that it is consecutive block
-          on the register save area.  If not we need to do moves.  */
-       if (!need_temp && !REG_P (container))
- 	{
- 	  /* Verify that all registers are strictly consecutive  */
- 	  if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
- 	    {
- 	      int i;
- 
- 	      for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
- 		{
- 		  rtx slot = XVECEXP (container, 0, i);
- 		  if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i
- 		      || INTVAL (XEXP (slot, 1)) != i * 16)
- 		    need_temp = 1;
- 		}
- 	    }
- 	  else
- 	    {
- 	      int i;
- 
- 	      for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
- 		{
- 		  rtx slot = XVECEXP (container, 0, i);
- 		  if (REGNO (XEXP (slot, 0)) != (unsigned int) i
- 		      || INTVAL (XEXP (slot, 1)) != i * 8)
- 		    need_temp = 1;
- 		}
- 	    }
- 	}
-       if (!need_temp)
- 	{
- 	  int_addr_rtx = addr_rtx;
- 	  sse_addr_rtx = addr_rtx;
- 	}
-       else
- 	{
- 	  int_addr_rtx = gen_reg_rtx (Pmode);
- 	  sse_addr_rtx = gen_reg_rtx (Pmode);
- 	}
-       /* First ensure that we fit completely in registers.  */
-       if (needed_intregs)
- 	{
- 	  emit_cmp_and_jump_insns (expand_expr
- 				   (gpr, NULL_RTX, SImode, EXPAND_NORMAL),
- 				   GEN_INT ((REGPARM_MAX - needed_intregs +
- 					     1) * 8), GE, const1_rtx, SImode,
- 				   1, lab_false);
- 	}
-       if (needed_sseregs)
- 	{
- 	  emit_cmp_and_jump_insns (expand_expr
- 				   (fpr, NULL_RTX, SImode, EXPAND_NORMAL),
- 				   GEN_INT ((SSE_REGPARM_MAX -
- 					     needed_sseregs + 1) * 16 +
- 					    REGPARM_MAX * 8), GE, const1_rtx,
- 				   SImode, 1, lab_false);
- 	}
- 
-       /* Compute index to start of area used for integer regs.  */
-       if (needed_intregs)
- 	{
- 	  t = build (PLUS_EXPR, ptr_type_node, sav, gpr);
- 	  r = expand_expr (t, int_addr_rtx, Pmode, EXPAND_NORMAL);
- 	  if (r != int_addr_rtx)
- 	    emit_move_insn (int_addr_rtx, r);
- 	}
-       if (needed_sseregs)
- 	{
- 	  t = build (PLUS_EXPR, ptr_type_node, sav, fpr);
- 	  r = expand_expr (t, sse_addr_rtx, Pmode, EXPAND_NORMAL);
- 	  if (r != sse_addr_rtx)
- 	    emit_move_insn (sse_addr_rtx, r);
- 	}
-       if (need_temp)
- 	{
- 	  int i;
- 	  rtx mem;
- 	  rtx x;
- 
- 	  /* Never use the memory itself, as it has the alias set.  */
- 	  x = XEXP (assign_temp (type, 0, 1, 0), 0);
- 	  mem = gen_rtx_MEM (BLKmode, x);
- 	  force_operand (x, addr_rtx);
- 	  set_mem_alias_set (mem, get_varargs_alias_set ());
- 	  set_mem_align (mem, BITS_PER_UNIT);
- 
- 	  for (i = 0; i < XVECLEN (container, 0); i++)
- 	    {
- 	      rtx slot = XVECEXP (container, 0, i);
- 	      rtx reg = XEXP (slot, 0);
- 	      enum machine_mode mode = GET_MODE (reg);
- 	      rtx src_addr;
- 	      rtx src_mem;
- 	      int src_offset;
- 	      rtx dest_mem;
- 
- 	      if (SSE_REGNO_P (REGNO (reg)))
- 		{
- 		  src_addr = sse_addr_rtx;
- 		  src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
- 		}
- 	      else
- 		{
- 		  src_addr = int_addr_rtx;
- 		  src_offset = REGNO (reg) * 8;
- 		}
- 	      src_mem = gen_rtx_MEM (mode, src_addr);
- 	      set_mem_alias_set (src_mem, get_varargs_alias_set ());
- 	      src_mem = adjust_address (src_mem, mode, src_offset);
- 	      dest_mem = adjust_address (mem, mode, INTVAL (XEXP (slot, 1)));
- 	      emit_move_insn (dest_mem, src_mem);
- 	    }
- 	}
- 
-       if (needed_intregs)
- 	{
- 	  t =
- 	    build (PLUS_EXPR, TREE_TYPE (gpr), gpr,
- 		   build_int_2 (needed_intregs * 8, 0));
- 	  t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, t);
- 	  TREE_SIDE_EFFECTS (t) = 1;
- 	  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- 	}
-       if (needed_sseregs)
- 	{
- 	  t =
- 	    build (PLUS_EXPR, TREE_TYPE (fpr), fpr,
- 		   build_int_2 (needed_sseregs * 16, 0));
- 	  t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, t);
- 	  TREE_SIDE_EFFECTS (t) = 1;
- 	  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- 	}
- 
-       emit_jump_insn (gen_jump (lab_over));
-       emit_barrier ();
-       emit_label (lab_false);
-     }
- 
-   /* ... otherwise out of the overflow area.  */
- 
-   /* Care for on-stack alignment if needed.  */
-   if (FUNCTION_ARG_BOUNDARY (VOIDmode, type) <= 64)
-     t = ovf;
-   else
-     {
-       HOST_WIDE_INT align = FUNCTION_ARG_BOUNDARY (VOIDmode, type) / 8;
-       t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align - 1, 0));
-       t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
-     }
-   t = save_expr (t);
- 
-   r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
-   if (r != addr_rtx)
-     emit_move_insn (addr_rtx, r);
- 
-   t =
-     build (PLUS_EXPR, TREE_TYPE (t), t,
- 	   build_int_2 (rsize * UNITS_PER_WORD, 0));
-   t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
-   TREE_SIDE_EFFECTS (t) = 1;
-   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- 
-   if (container)
-     emit_label (lab_over);
- 
-   if (indirect_p)
-     {
-       r = gen_rtx_MEM (Pmode, addr_rtx);
-       set_mem_alias_set (r, get_varargs_alias_set ());
-       emit_move_insn (addr_rtx, r);
-     }
- 
-   return addr_rtx;
- }
- 
- /* Lower VA_ARG_EXPR at gimplification time.  */
  
  tree
  ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
--- 3177,3182 ----
Index: gcc/config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.385
diff -c -p -r1.385 i386.h
*** gcc/config/i386/i386.h	21 May 2004 01:03:17 -0000	1.385
--- gcc/config/i386/i386.h	11 Jun 2004 17:33:13 -0000
*************** typedef struct ix86_args {
*** 1790,1797 ****
    ix86_va_start (VALIST, NEXTARG)
  
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(VALIST, TYPE) \
!   ix86_va_arg ((VALIST), (TYPE))
  
  #define TARGET_ASM_FILE_END ix86_file_end
  #define NEED_INDICATE_EXEC_STACK 0
--- 1790,1796 ----
    ix86_va_start (VALIST, NEXTARG)
  
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(VALIST, TYPE) (abort (), NULL_RTX)
  
  #define TARGET_ASM_FILE_END ix86_file_end
  #define NEED_INDICATE_EXEC_STACK 0
Index: gcc/config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.290
diff -c -p -r1.290 ia64.c
*** gcc/config/ia64/ia64.c	10 Jun 2004 15:49:47 -0000	1.290
--- gcc/config/ia64/ia64.c	11 Jun 2004 17:33:13 -0000
*************** ia64_function_ok_for_sibcall (tree decl,
*** 3958,3998 ****
  
  /* Implement va_arg.  */
  
- rtx
- ia64_va_arg (tree valist, tree type)
- {
-   tree t;
- 
-   /* Variable sized types are passed by reference.  */
-   if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
-     {
-       rtx addr = force_reg (ptr_mode,
- 	    std_expand_builtin_va_arg (valist, build_pointer_type (type)));
- #ifdef POINTERS_EXTEND_UNSIGNED
-       addr = convert_memory_address (Pmode, addr);
- #endif
-       return gen_rtx_MEM (ptr_mode, addr);
-     }
- 
-   /* Aggregate arguments with alignment larger than 8 bytes start at
-      the next even boundary.  Integer and floating point arguments
-      do so if they are larger than 8 bytes, whether or not they are
-      also aligned larger than 8 bytes.  */
-   if ((TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == INTEGER_TYPE)
-       ? int_size_in_bytes (type) > 8 : TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
-     {
-       t = build (PLUS_EXPR, TREE_TYPE (valist), valist,
- 		 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 (valist), valist, t);
-       TREE_SIDE_EFFECTS (t) = 1;
-       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-     }
- 
-   return std_expand_builtin_va_arg (valist, type);
- }
- 
  static tree
  ia64_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
  {
--- 3958,3963 ----
Index: gcc/config/ia64/ia64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.h,v
retrieving revision 1.176
diff -c -p -r1.176 ia64.h
*** gcc/config/ia64/ia64.h	25 May 2004 17:05:43 -0000	1.176
--- gcc/config/ia64/ia64.h	11 Jun 2004 17:33:14 -0000
*************** do {									\
*** 1403,1410 ****
   || ((REGNO) >= FR_ARG_FIRST && (REGNO) < (FR_ARG_FIRST + MAX_ARGUMENT_SLOTS)))
  \f
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(valist, type) \
!   ia64_va_arg (valist, type)
  \f
  /* How Scalar Function Values are Returned */
  
--- 1403,1409 ----
   || ((REGNO) >= FR_ARG_FIRST && (REGNO) < (FR_ARG_FIRST + MAX_ARGUMENT_SLOTS)))
  \f
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX)
  \f
  /* How Scalar Function Values are Returned */
  
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.649
diff -c -p -r1.649 rs6000.c
*** gcc/config/rs6000/rs6000.c	10 Jun 2004 15:49:48 -0000	1.649
--- gcc/config/rs6000/rs6000.c	11 Jun 2004 17:33:14 -0000
*************** rs6000_va_start (tree valist, rtx nextar
*** 5069,5297 ****
  
  /* Implement va_arg.  */
  
- rtx
- rs6000_va_arg (tree valist, tree type)
- {
-   tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
-   tree gpr, fpr, ovf, sav, reg, t, u;
-   int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
-   rtx lab_false, lab_over, addr_rtx, r;
-   int align;
- 
-   if (DEFAULT_ABI != ABI_V4)
-     {
-       /* Variable sized types are passed by reference, as are AltiVec
- 	 vectors when 32-bit and not using the AltiVec ABI extension.  */
-       if (int_size_in_bytes (type) < 0
- 	  || (TARGET_32BIT
- 	      && !TARGET_ALTIVEC_ABI
- 	      && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))))
- 	{
- 	  u = build_pointer_type (type);
- 
- 	  /* Args grow upward.  */
- 	  t = build (POSTINCREMENT_EXPR, TREE_TYPE (valist), valist,
- 		     build_int_2 (POINTER_SIZE / BITS_PER_UNIT, 0));
- 	  TREE_SIDE_EFFECTS (t) = 1;
- 
- 	  t = build1 (NOP_EXPR, build_pointer_type (u), t);
- 	  TREE_SIDE_EFFECTS (t) = 1;
- 
- 	  t = build1 (INDIRECT_REF, u, t);
- 	  TREE_SIDE_EFFECTS (t) = 1;
- 
- 	  return expand_expr (t, NULL_RTX, VOIDmode, EXPAND_NORMAL);
- 	}
-       if (targetm.calls.split_complex_arg
- 	  && TREE_CODE (type) == COMPLEX_TYPE)
- 	{
- 	  tree elem_type = TREE_TYPE (type);
- 	  enum machine_mode elem_mode = TYPE_MODE (elem_type);
- 	  int elem_size = GET_MODE_SIZE (elem_mode);
- 
- 	  if (elem_size < UNITS_PER_WORD)
- 	    {
- 	      rtx real_part, imag_part, dest_real, rr;
- 
- 	      real_part = rs6000_va_arg (valist, elem_type);
- 	      imag_part = rs6000_va_arg (valist, elem_type);
- 
- 	      /* We're not returning the value here, but the address.
- 		 real_part and imag_part are not contiguous, and we know
- 		 there is space available to pack real_part next to
- 		 imag_part.  float _Complex is not promoted to
- 		 double _Complex by the default promotion rules that
- 		 promote float to double.  */
- 	      if (2 * elem_size > UNITS_PER_WORD)
- 		abort ();
- 
- 	      real_part = gen_rtx_MEM (elem_mode, real_part);
- 	      imag_part = gen_rtx_MEM (elem_mode, imag_part);
- 
- 	      dest_real = adjust_address (imag_part, elem_mode, -elem_size);
- 	      rr = gen_reg_rtx (elem_mode);
- 	      emit_move_insn (rr, real_part);
- 	      emit_move_insn (dest_real, rr);
- 
- 	      return XEXP (dest_real, 0);
- 	    }
- 	}
- 
-       return std_expand_builtin_va_arg (valist, type);
-     }
- 
-   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
-   f_fpr = TREE_CHAIN (f_gpr);
-   f_res = TREE_CHAIN (f_fpr);
-   f_ovf = TREE_CHAIN (f_res);
-   f_sav = TREE_CHAIN (f_ovf);
- 
-   valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
-   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
-   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
-   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
-   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
- 
-   size = int_size_in_bytes (type);
-   rsize = (size + 3) / 4;
-   align = 1;
- 
-   if (AGGREGATE_TYPE_P (type)
-       || TYPE_MODE (type) == TFmode
-       || (!TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))))
-     {
-       /* Aggregates, long doubles, and AltiVec vectors are passed by
- 	 reference.  */
-       indirect_p = 1;
-       reg = gpr;
-       n_reg = 1;
-       sav_ofs = 0;
-       sav_scale = 4;
-       size = 4;
-       rsize = 1;
-     }
-   else if (TARGET_HARD_FLOAT && TARGET_FPRS
- 	   && (TYPE_MODE (type) == SFmode || TYPE_MODE (type) == DFmode))
-     {
-       /* FP args go in FP registers, if present.  */
-       indirect_p = 0;
-       reg = fpr;
-       n_reg = 1;
-       sav_ofs = 8*4;
-       sav_scale = 8;
-       if (TYPE_MODE (type) == DFmode)
- 	align = 8;
-     }
-   else
-     {
-       /* Otherwise into GP registers.  */
-       indirect_p = 0;
-       reg = gpr;
-       n_reg = rsize;
-       sav_ofs = 0;
-       sav_scale = 4;
-       if (n_reg == 2)
- 	align = 8;
-     }
- 
-   /* Pull the value out of the saved registers....  */
- 
-   lab_over = NULL_RTX;
-   addr_rtx = gen_reg_rtx (Pmode);
- 
-   /*  AltiVec vectors never go in registers when -mabi=altivec.  */
-   if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
-     align = 16;
-   else
-     {
-       lab_false = gen_label_rtx ();
-       lab_over = gen_label_rtx ();
- 
-       /* Long long and SPE vectors are aligned in the registers.
- 	 As are any other 2 gpr item such as complex int due to a
- 	 historical mistake.  */
-       u = reg;
-       if (n_reg == 2)
- 	{
- 	  u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
- 		     build_int_2 (n_reg - 1, 0));
- 	  u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
- 	  TREE_SIDE_EFFECTS (u) = 1;
- 	}
- 
-       emit_cmp_and_jump_insns
- 	(expand_expr (u, NULL_RTX, QImode, EXPAND_NORMAL),
- 	 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
- 	 lab_false);
- 
-       t = sav;
-       if (sav_ofs)
- 	t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
- 
-       u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
- 		 build_int_2 (n_reg, 0));
-       TREE_SIDE_EFFECTS (u) = 1;
- 
-       u = build1 (CONVERT_EXPR, integer_type_node, u);
-       TREE_SIDE_EFFECTS (u) = 1;
- 
-       u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
-       TREE_SIDE_EFFECTS (u) = 1;
- 
-       t = build (PLUS_EXPR, ptr_type_node, t, u);
-       TREE_SIDE_EFFECTS (t) = 1;
- 
-       r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
-       if (r != addr_rtx)
- 	emit_move_insn (addr_rtx, r);
- 
-       emit_jump_insn (gen_jump (lab_over));
-       emit_barrier ();
- 
-       emit_label (lab_false);
-       if (n_reg > 2)
- 	{
- 	  /* Ensure that we don't find any more args in regs.
- 	     Alignment has taken care of the n_reg == 2 case.  */
- 	  t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
- 	  TREE_SIDE_EFFECTS (t) = 1;
- 	  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- 	}
-     }
- 
-   /* ... otherwise out of the overflow area.  */
- 
-   /* Care for on-stack alignment if needed.  */
-   t = ovf;
-   if (align != 1)
-     {
-       t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (align - 1, 0));
-       t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
-     }
-   t = save_expr (t);
- 
-   r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
-   if (r != addr_rtx)
-     emit_move_insn (addr_rtx, r);
- 
-   t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
-   t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
-   TREE_SIDE_EFFECTS (t) = 1;
-   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- 
-   if (lab_over)
-     emit_label (lab_over);
- 
-   if (indirect_p)
-     {
-       r = gen_rtx_MEM (Pmode, addr_rtx);
-       set_mem_alias_set (r, get_varargs_alias_set ());
-       emit_move_insn (addr_rtx, r);
-     }
- 
-   return addr_rtx;
- }
- 
  tree
  rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
  {
--- 5069,5074 ----
Index: gcc/config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.324
diff -c -p -r1.324 rs6000.h
*** gcc/config/rs6000/rs6000.h	9 May 2004 14:32:49 -0000	1.324
--- gcc/config/rs6000/rs6000.h	11 Jun 2004 17:33:14 -0000
*************** typedef struct rs6000_args
*** 1760,1767 ****
    rs6000_va_start (valist, nextarg)
  
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(valist, type) \
!   rs6000_va_arg (valist, type)
  
  #define PAD_VARARGS_DOWN \
     (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
--- 1760,1766 ----
    rs6000_va_start (valist, nextarg)
  
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX)
  
  #define PAD_VARARGS_DOWN \
     (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
Index: gcc/config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.303
diff -c -p -r1.303 sparc.c
*** gcc/config/sparc/sparc.c	11 Jun 2004 06:08:09 -0000	1.303
--- gcc/config/sparc/sparc.c	11 Jun 2004 17:33:14 -0000
*************** sparc_va_start (tree valist, rtx nextarg
*** 5942,6052 ****
  
  /* Implement `va_arg' for stdarg.  */
  
- rtx
- sparc_va_arg (tree valist, tree type)
- {
-   HOST_WIDE_INT size, rsize, align;
-   tree addr, incr;
-   rtx addr_rtx;
-   bool indirect;
- 
-   if (function_arg_pass_by_reference (0, TYPE_MODE (type), type, 0))
-     {
-       indirect = true;
-       size = rsize = UNITS_PER_WORD;
-       align = 0;
-     }
-   else
-     {
-       indirect = false;
-       size = int_size_in_bytes (type);
-       rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
-       align = 0;
-     
-       if (TARGET_ARCH64)
- 	{
- 	  /* For SPARC64, objects requiring 16-byte alignment get it.  */
- 	  if (TYPE_ALIGN (type) >= 2 * (unsigned) BITS_PER_WORD)
- 	    align = 2 * UNITS_PER_WORD;
- 
- 	  /* SPARC-V9 ABI states that structures up to 16 bytes in size
- 	     are given whole slots as needed.  */
- 	  if (AGGREGATE_TYPE_P (type))
- 	    {
- 	      if (size == 0)
- 		size = rsize = UNITS_PER_WORD;
- 	      else
- 		size = rsize;
- 	    }
- 	}
-     }
- 
-   incr = valist;
-   if (align)
-     {
-       incr = fold (build (PLUS_EXPR, ptr_type_node, incr,
- 			 build_int_2 (align - 1, 0)));
-       incr = fold (build (BIT_AND_EXPR, ptr_type_node, incr,
- 			  build_int_2 (-align, -1)));
-     }
- 
-   addr = incr = save_expr (incr);
-   if (BYTES_BIG_ENDIAN && size < rsize)
-     {
-       addr = fold (build (PLUS_EXPR, ptr_type_node, incr,
- 			  build_int_2 (rsize - size, 0)));
-     }
-   incr = fold (build (PLUS_EXPR, ptr_type_node, incr,
- 		      build_int_2 (rsize, 0)));
- 
-   incr = build (MODIFY_EXPR, ptr_type_node, valist, incr);
-   TREE_SIDE_EFFECTS (incr) = 1;
-   expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
- 
-   addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
- 
-   /* If the address isn't aligned properly for the type,
-      we may need to copy to a temporary.  
-      FIXME: This is inefficient.  Usually we can do this
-      in registers.  */
-   if (align == 0
-       && TYPE_ALIGN (type) > BITS_PER_WORD
-       && !indirect)
-     {
-       /* FIXME: We really need to specify that the temporary is live
- 	 for the whole function because expand_builtin_va_arg wants
- 	 the alias set to be get_varargs_alias_set (), but in this
- 	 case the alias set is that for TYPE and if the memory gets
- 	 reused it will be reused with alias set TYPE.  */
-       rtx tmp = assign_temp (type, 0, 1, 0);
-       rtx dest_addr;
- 
-       addr_rtx = force_reg (Pmode, addr_rtx);
-       addr_rtx = gen_rtx_MEM (BLKmode, addr_rtx);
-       set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
-       set_mem_align (addr_rtx, BITS_PER_WORD);
-       tmp = shallow_copy_rtx (tmp);
-       PUT_MODE (tmp, BLKmode);
-       set_mem_alias_set (tmp, 0);
-       
-       dest_addr = emit_block_move (tmp, addr_rtx, GEN_INT (rsize),
- 				   BLOCK_OP_NORMAL);
-       if (dest_addr != NULL_RTX)
- 	addr_rtx = dest_addr;
-       else
- 	addr_rtx = XCEXP (tmp, 0, MEM);
-     }
- 
-   if (indirect)
-     {
-       addr_rtx = force_reg (Pmode, addr_rtx);
-       addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
-       set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
-     }
- 
-   return addr_rtx;
- }
- 
  tree
  sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
  {
--- 5942,5947 ----
Index: gcc/config/sparc/sparc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.h,v
retrieving revision 1.254
diff -c -p -r1.254 sparc.h
*** gcc/config/sparc/sparc.h	9 Jun 2004 18:26:11 -0000	1.254
--- gcc/config/sparc/sparc.h	11 Jun 2004 17:33:15 -0000
*************** do {									\
*** 1804,1811 ****
    sparc_va_start (valist, nextarg)
  
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(valist, type) \
!   sparc_va_arg (valist, type)
  
  /* Generate RTL to flush the register windows so as to make arbitrary frames
     available.  */
--- 1804,1810 ----
    sparc_va_start (valist, nextarg)
  
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX)
  
  /* Generate RTL to flush the register windows so as to make arbitrary frames
     available.  */
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.328
diff -c -p -r1.328 tm.texi
*** gcc/doc/tm.texi	10 Jun 2004 15:49:49 -0000	1.328
--- gcc/doc/tm.texi	11 Jun 2004 17:33:16 -0000
*************** This hook performs target-specific gimpl
*** 3870,3880 ****
  arguments to @code{va_arg}; the latter two are as in
  @code{gimplify.c:gimplify_expr}.
  
! You only need to define this hook if you also define
  @code{EXPAND_BUILTIN_VA_ARG}; it is pretty easy to reuse the same code
  for both.  One significant difference is that
  @code{EXPAND_BUILTIN_VA_ARG} returns an address, whereas this hook
  produces an expression of type @var{type}, usually an @code{INDIRECT_REF}.
  @end deftypefn
  
  @node Scalar Return
--- 3870,3884 ----
  arguments to @code{va_arg}; the latter two are as in
  @code{gimplify.c:gimplify_expr}.
  
! You only need to define this hook if you previously defined
  @code{EXPAND_BUILTIN_VA_ARG}; it is pretty easy to reuse the same code
  for both.  One significant difference is that
  @code{EXPAND_BUILTIN_VA_ARG} returns an address, whereas this hook
  produces an expression of type @var{type}, usually an @code{INDIRECT_REF}.
+ 
+ Once you define this macro, you can change
+ @code{EXPAND_BUILTIN_VA_ARG} to just abort, as it should never be
+ called.
  @end deftypefn
  
  @node Scalar Return

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-06-11 18:39 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-11  9:15 PATCH: sparc_gimplify_va_arg Jason Merrill
2004-06-11 10:09 ` Eric Botcazou
2004-06-11 16:32   ` Jason Merrill
2004-06-11 20:09     ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).