This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: sparc_gimplify_va_arg


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.

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)
  
  /* 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)
  
  /* 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)))
  
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(valist, type) \
!   ia64_va_arg (valist, type)
  
  /* How Scalar Function Values are Returned */
  
--- 1403,1409 ----
   || ((REGNO) >= FR_ARG_FIRST && (REGNO) < (FR_ARG_FIRST + MAX_ARGUMENT_SLOTS)))
  
  /* Implement `va_arg'.  */
! #define EXPAND_BUILTIN_VA_ARG(valist, type) (abort (), NULL_RTX)
  
  /* 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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]