Committed, CRIS: Fix gcc.c-torture/execute/20020307-2.c again

Hans-Peter Nilsson hp@bitrange.com
Wed Apr 3 15:56:00 GMT 2002


Apparently the last change was incorrect (as was
gcc.c-torture/execute/20020307-2.c at the time).  An argument
passed as a fixed-size type must be va_arg:d as a fixed-size
type, and a varying-size type va_arg:ed as a varying-size type,
or you can't make a decent ABI out of it.
Also silences some warnings due to recent changes causing
PIC_OFFSET_TABLE_REGNUM to be promoted to unsigned.
Will commit this to 3.1 too.

	* config/cris/cris.c (cris_target_asm_function_prologue): Cast
	uses of PIC_OFFSET_TABLE_REGNUM to int to silence warnings.
	(cris_target_asm_function_epilogue): Ditto.
	(cris_initial_frame_pointer_offset): Ditto.
	(cris_simple_epilogue): Ditto.
	(cris_expand_builtin_va_arg): Variable-size types come in
	by-reference.

Index: cris.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/cris/cris.c,v
retrieving revision 1.19
diff -p -c -r1.19 cris.c
*** cris.c	2002/03/13 13:33:39	1.19
--- cris.c	2002/04/03 23:39:50
*************** cris_target_asm_function_prologue (file,
*** 711,717 ****
      {
        if ((((regs_ever_live[regno]
  	     && !call_used_regs[regno])
! 	    || (regno == PIC_OFFSET_TABLE_REGNUM
  		&& (current_function_uses_pic_offset_table
  		    /* It is saved anyway, if there would be a gap.  */
  		    || (flag_pic
--- 711,717 ----
      {
        if ((((regs_ever_live[regno]
  	     && !call_used_regs[regno])
! 	    || (regno == (int) PIC_OFFSET_TABLE_REGNUM
  		&& (current_function_uses_pic_offset_table
  		    /* It is saved anyway, if there would be a gap.  */
  		    || (flag_pic
*************** cris_target_asm_function_epilogue (file,
*** 1043,1049 ****
         regno++)
      if ((((regs_ever_live[regno]
  	   && !call_used_regs[regno])
! 	  || (regno == PIC_OFFSET_TABLE_REGNUM
  	      && (current_function_uses_pic_offset_table
  		  /* It is saved anyway, if there would be a gap.  */
  		  || (flag_pic
--- 1043,1049 ----
         regno++)
      if ((((regs_ever_live[regno]
  	   && !call_used_regs[regno])
! 	  || (regno == (int) PIC_OFFSET_TABLE_REGNUM
  	      && (current_function_uses_pic_offset_table
  		  /* It is saved anyway, if there would be a gap.  */
  		  || (flag_pic
*************** cris_target_asm_function_epilogue (file,
*** 1069,1075 ****
         regno--)
      if ((((regs_ever_live[regno]
  	   && !call_used_regs[regno])
! 	  || (regno == PIC_OFFSET_TABLE_REGNUM
  	      && (current_function_uses_pic_offset_table
  		  /* It is saved anyway, if there would be a gap.  */
  		  || (flag_pic
--- 1069,1075 ----
         regno--)
      if ((((regs_ever_live[regno]
  	   && !call_used_regs[regno])
! 	  || (regno == (int) PIC_OFFSET_TABLE_REGNUM
  	      && (current_function_uses_pic_offset_table
  		  /* It is saved anyway, if there would be a gap.  */
  		  || (flag_pic
*************** cris_initial_frame_pointer_offset ()
*** 1659,1665 ****
    for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
      if ((((regs_ever_live[regno]
  	   && !call_used_regs[regno])
! 	  || (regno == PIC_OFFSET_TABLE_REGNUM
  	      && (current_function_uses_pic_offset_table
  		  /* It is saved anyway, if there would be a gap.  */
  		  || (flag_pic
--- 1659,1665 ----
    for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
      if ((((regs_ever_live[regno]
  	   && !call_used_regs[regno])
! 	  || (regno == (int) PIC_OFFSET_TABLE_REGNUM
  	      && (current_function_uses_pic_offset_table
  		  /* It is saved anyway, if there would be a gap.  */
  		  || (flag_pic
*************** cris_simple_epilogue ()
*** 2051,2057 ****
       in the delay-slot of the "ret".  */
    for (regno = 0; regno < reglimit; regno++)
      if ((regs_ever_live[regno] && ! call_used_regs[regno])
! 	|| (regno == PIC_OFFSET_TABLE_REGNUM
  	    && (current_function_uses_pic_offset_table
  		/* It is saved anyway, if there would be a gap.  */
  		|| (flag_pic
--- 2051,2057 ----
       in the delay-slot of the "ret".  */
    for (regno = 0; regno < reglimit; regno++)
      if ((regs_ever_live[regno] && ! call_used_regs[regno])
! 	|| (regno == (int) PIC_OFFSET_TABLE_REGNUM
  	    && (current_function_uses_pic_offset_table
  		/* It is saved anyway, if there would be a gap.  */
  		|| (flag_pic
*************** cris_expand_builtin_va_arg (valist, type
*** 2626,2632 ****
    if (type == error_mark_node
        || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
        || TREE_OVERFLOW (type_size))
!     /* Presumable an error; the size isn't computable.  A message has
         supposedly been emitted elsewhere.  */
      rounded_size = size_zero_node;
    else
--- 2626,2632 ----
    if (type == error_mark_node
        || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
        || TREE_OVERFLOW (type_size))
!     /* Presumably an error; the size isn't computable.  A message has
         supposedly been emitted elsewhere.  */
      rounded_size = size_zero_node;
    else
*************** cris_expand_builtin_va_arg (valist, type
*** 2640,2667 ****

    if (!integer_zerop (rounded_size))
      {
!       /* Check if the type is passed by value or by reference.  This test must
! 	 be different than the call-site test and be done at run-time:
! 	 gcc.c-torture/execute/20020307-2.c.  Hence the tree stuff.
!
! 	 Values up to 8 bytes are passed by-value, padded to register-size
! 	 (4 bytes).  Larger values are passed by-reference.  */
        passed_size
! 	= fold (build (COND_EXPR, sizetype,
! 		       fold (build (GT_EXPR, sizetype,
! 				    rounded_size,
! 				    size8)),
! 		       size4,
! 		       rounded_size));

        addr_tree
!        = fold (build (COND_EXPR, TREE_TYPE (addr_tree),
! 		      fold (build (GT_EXPR, sizetype,
! 				   rounded_size,
! 				   size8)),
! 		      build1 (INDIRECT_REF, build_pointer_type (type),
! 			      addr_tree),
! 		      addr_tree));
      }

    addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
--- 2640,2669 ----

    if (!integer_zerop (rounded_size))
      {
!       /* Check if the type is passed by value or by reference.  Values up
! 	 to 8 bytes are passed by-value, padded to register-size (4
! 	 bytes).  Larger values and varying-size types are passed
! 	 by reference.  */
        passed_size
! 	= (!really_constant_p (type_size)
! 	   ? size4
! 	   : fold (build (COND_EXPR, sizetype,
! 			  fold (build (GT_EXPR, sizetype,
! 				       rounded_size,
! 				       size8)),
! 			  size4,
! 			  rounded_size)));

        addr_tree
! 	= (!really_constant_p (type_size)
! 	   ? build1 (INDIRECT_REF, build_pointer_type (type), addr_tree)
! 	   : fold (build (COND_EXPR, TREE_TYPE (addr_tree),
! 			  fold (build (GT_EXPR, sizetype,
! 				       rounded_size,
! 				       size8)),
! 			  build1 (INDIRECT_REF, build_pointer_type (type),
! 				  addr_tree),
! 			  addr_tree)));
      }

    addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);

brgds, H-P



More information about the Gcc-patches mailing list