i960 varargs/stdarg bug fix patch

Jim Wilson wilson@cygnus.com
Thu Oct 28 10:15:00 GMT 1999


varargs/stdarg are broken in the i960 port.  The i960 has an array type
va_list, and it is trying to use ARRAY_REF to dereference it.  However, the
array type always decays to a pointer, so we have to use INDIRECT_REF here
instead.

This fixes build failures I encountered while trying to build newlib
and libstdc++.  I have installed this patch.

I tested this patch on the i960 simulator, running the gcc testsuite.
The only suspicious failures were for relatively new testcases,
compile/990801-1.c, and compile/990829-1.c, which I will worry about later.

Thu Oct 28 10:02:00 1999  Jim Wilson  <wilson@cygnus.com>

	* config/i960/i960.c (i960_va_start): New locals base, num.
	Use INDIRECT_REF instead of ARRAY_REF on valist.
	(i960_va_arg): Use INDIRECT_REF instead of ARRAY_REF on valist.

Index: i960.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/i960/i960.c,v
retrieving revision 1.47
diff -p -r1.47 i960.c
*** i960.c	1999/10/05 08:07:40	1.47
--- i960.c	1999/10/28 17:01:00
*************** i960_va_start (stdarg_p, valist, nextarg
*** 2841,2858 ****
       tree valist;
       rtx nextarg ATTRIBUTE_UNUSED;
  {
!   tree d, s, t;
  
    s = make_tree (unsigned_type_node, arg_pointer_rtx);
!   d = build (ARRAY_REF, unsigned_type_node, valist, size_zero_node);
!   t = build (MODIFY_EXPR, unsigned_type_node, d, s);
    TREE_SIDE_EFFECTS (t) = 1;
    expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
  
    s = build_int_2 ((current_function_args_info.ca_nregparms
  		    + current_function_args_info.ca_nstackparms) * 4, 0);
!   d = build (ARRAY_REF, unsigned_type_node, valist, size_one_node);
!   t = build (MODIFY_EXPR, unsigned_type_node, d, s);
    TREE_SIDE_EFFECTS (t) = 1;
    expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
  }
--- 2841,2863 ----
       tree valist;
       rtx nextarg ATTRIBUTE_UNUSED;
  {
!   tree s, t, base, num;
  
+   /* The array type always decays to a pointer before we get here, so we
+      can't use ARRAY_REF.  */
+   base = build1 (INDIRECT_REF, unsigned_type_node, valist);
+   num = build1 (INDIRECT_REF, unsigned_type_node,
+ 		build (PLUS_EXPR, unsigned_type_node, valist,
+ 		       TYPE_SIZE_UNIT (TREE_TYPE (valist))));
+ 
    s = make_tree (unsigned_type_node, arg_pointer_rtx);
!   t = build (MODIFY_EXPR, unsigned_type_node, base, s);
    TREE_SIDE_EFFECTS (t) = 1;
    expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
  
    s = build_int_2 ((current_function_args_info.ca_nregparms
  		    + current_function_args_info.ca_nstackparms) * 4, 0);
!   t = build (MODIFY_EXPR, unsigned_type_node, num, s);
    TREE_SIDE_EFFECTS (t) = 1;
    expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
  }
*************** i960_va_arg (valist, type)
*** 2867,2874 ****
    tree base, num, pad, next, this, t1, t2, int48;
    rtx addr_rtx;
  
!   base = build (ARRAY_REF, unsigned_type_node, valist, size_zero_node);
!   num = build (ARRAY_REF, unsigned_type_node, valist, size_one_node);
  
    /* Round up sizeof(type) to a word.  */
    siz = (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
--- 2872,2883 ----
    tree base, num, pad, next, this, t1, t2, int48;
    rtx addr_rtx;
  
!   /* The array type always decays to a pointer before we get here, so we
!      can't use ARRAY_REF.  */
!   base = build1 (INDIRECT_REF, unsigned_type_node, valist);
!   num = build1 (INDIRECT_REF, unsigned_type_node,
! 		build (PLUS_EXPR, unsigned_type_node, valist,
! 		       TYPE_SIZE_UNIT (TREE_TYPE (valist))));
  
    /* Round up sizeof(type) to a word.  */
    siz = (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;


More information about the Gcc-patches mailing list