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]

gimple va_arg for i860


Tested as with c4x.


r~


        * config/i860/i860-protos.h (i860_va_arg): Remove.
        * config/i860/i860.c (TARGET_GIMPLIFY_VA_ARG_EXPR): New.
        (i860_gimplify_va_arg_expr): Rewrite from i860_va_arg.
        * config/i860/i860.h (EXPAND_BUILTIN_VA_ARG): Remove.

Index: config/i860/i860-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i860/i860-protos.h,v
retrieving revision 1.9
diff -c -p -d -r1.9 i860-protos.h
*** config/i860/i860-protos.h	25 Jan 2004 17:41:01 -0000	1.9
--- config/i860/i860-protos.h	8 Jul 2004 23:35:04 -0000
*************** extern int logic_int (rtx, enum machine_
*** 46,52 ****
  extern int call_insn_operand (rtx, enum machine_mode);
  #ifdef TREE_CODE
  extern void i860_va_start (tree, rtx);
- extern rtx i860_va_arg (tree, tree);
  #endif /* TREE_CODE */
  #endif /* RTX_CODE */
  
--- 46,51 ----
Index: config/i860/i860.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i860/i860.c,v
retrieving revision 1.45
diff -c -p -d -r1.45 i860.c
*** config/i860/i860.c	7 Jul 2004 19:24:24 -0000	1.45
--- config/i860/i860.c	8 Jul 2004 23:35:04 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 49,54 ****
--- 49,55 ----
  #include "target.h"
  #include "target-def.h"
  #include "langhooks.h"
+ #include "tree-gimple.h"
  
  static rtx find_addr_reg (rtx);
  
*************** i860_va_start (tree valist, rtx nextarg 
*** 1923,1935 ****
  /* Update the VALIST structure as necessary for an
     argument of the given TYPE, and return the argument.  */
  
! rtx
! i860_va_arg (tree valist, tree type)
  {
    tree f_gpr, f_fpr, f_mem, f_sav;
!   tree gpr, fpr, mem, sav, reg, t, u;
!   int size, n_reg, sav_ofs, sav_scale, max_reg;
!   rtx lab_false, lab_over, addr_rtx, r;
  
  #ifdef I860_SVR4_VA_LIST
    f_gpr = TYPE_FIELDS (va_list_type_node);
--- 1924,1937 ----
  /* Update the VALIST structure as necessary for an
     argument of the given TYPE, and return the argument.  */
  
! static tree
! i860_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
  {
    tree f_gpr, f_fpr, f_mem, f_sav;
!   tree gpr, fpr, mem, sav;
!   tree size, t, u, addr, type_ptr;
!   tree reg, n_reg, sav_ofs, lim_reg;
!   HOST_WIDE_INT isize;
  
  #ifdef I860_SVR4_VA_LIST
    f_gpr = TYPE_FIELDS (va_list_type_node);
*************** i860_va_arg (tree valist, tree type)
*** 1948,1954 ****
    mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem, NULL_TREE);
    sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
!   size = int_size_in_bytes (type);
  
    if (AGGREGATE_TYPE_P (type))
      {
--- 1950,1957 ----
    mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem, NULL_TREE);
    sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
!   size = size_in_bytes (type);
!   type_ptr = build_pointer_type (type);
  
    if (AGGREGATE_TYPE_P (type))
      {
*************** i860_va_arg (tree valist, tree type)
*** 1960,2054 ****
          align = BITS_PER_WORD;
        align /= BITS_PER_UNIT;
  
!       addr_rtx = gen_reg_rtx (Pmode);
!       t = build (PLUS_EXPR, ptr_type_node, mem, build_int_2 (align - 1, 0));
!       t = build (BIT_AND_EXPR, ptr_type_node, t, build_int_2 (-align, -1));
!       r = expand_expr (t, addr_rtx, VOIDmode /* Pmode */, EXPAND_NORMAL);
!       if (r != addr_rtx)
!         emit_move_insn (addr_rtx, r);
  
!       t = fold (build (PLUS_EXPR, ptr_type_node, 
! 		make_tree (ptr_type_node, addr_rtx),
! 		build_int_2 (size, 0)));
        t = build (MODIFY_EXPR, ptr_type_node, mem, t);
!       TREE_SIDE_EFFECTS (t) = 1;
!       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
! 
!       return addr_rtx;
!     }
!   else if (FLOAT_TYPE_P (type) || (INTEGRAL_TYPE_P (type) && size == 8))
!     {
!       /* Floats and long longs are passed in the floating-point registers.  */
!       reg = fpr;
!       n_reg = size / UNITS_PER_WORD;
!       sav_ofs = FREG_OFFSET;
!       sav_scale = UNITS_PER_WORD;
!       max_reg = NUM_PARM_FREGS;
      }
    else
      {
!       /* Everything else is passed in general registers.  */
!       reg = gpr;
!       n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
!       sav_ofs = IREG_OFFSET;
!       sav_scale = UNITS_PER_WORD;
!       max_reg = NUM_PARM_IREGS;
!       if (n_reg > 1)
!         abort ();
!     }
! 
!   /* The value was passed in a register, so read it from the register
!      save area initialized by __builtin_saveregs.  */
! 
!   lab_false = gen_label_rtx ();
!   lab_over = gen_label_rtx ();
!   addr_rtx = gen_reg_rtx (Pmode);
! 
!   emit_cmp_and_jump_insns (expand_expr (reg, NULL_RTX, Pmode, EXPAND_NORMAL),
! 			   GEN_INT (max_reg - n_reg),
! 			   GT, const1_rtx, Pmode, 0, lab_false);
! 
!   if (sav_ofs)
!     t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
!   else
!     t = sav;
! 
!   u = build (MULT_EXPR, long_integer_type_node,
! 	     reg, 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);
  
!   /* The value was passed in memory, so read it from the overflow area.  */
  
!   t = save_expr (mem);
!   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 (mem), mem, t);
!   TREE_SIDE_EFFECTS (t) = 1;
!   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
  
!   emit_label (lab_over);
  
!   /* Increment either the ireg_used or freg_used field.  */
  
!   u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg, build_int_2 (n_reg, 0));
!   TREE_SIDE_EFFECTS (u) = 1;
!   expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
  
!   return addr_rtx;
  }
  
  /* Compute a (partial) cost for rtx X.  Return true if the complete
--- 1963,2035 ----
          align = BITS_PER_WORD;
        align /= BITS_PER_UNIT;
  
!       u = fold_convert (ptr_type_node, size_int (align - 1));
!       t = build (PLUS_EXPR, ptr_type_node, mem, u);
!       u = fold (build (BIT_NOT_EXPR, ptr_type_node, u));
!       t = build (BIT_AND_EXPR, ptr_type_node, t, u);
!       addr = get_initialized_tmp_var (t, pre_p, post_p);
  
!       u = fold_convert (ptr_type_node, size);
!       t = build (PLUS_EXPR, ptr_type_node, addr, size);
        t = build (MODIFY_EXPR, ptr_type_node, mem, t);
!       gimplify_and_add (t, pre_p);
      }
    else
      {
!       isize = tree_low_cst (size, 0);
  
!       if (FLOAT_TYPE_P (type) || (INTEGRAL_TYPE_P (type) && isize == 8))
! 	{
! 	  /* Floats and long longs are passed in the fp registers.  */
! 	  reg = fpr;
! 	  n_reg = size_int (isize / UNITS_PER_WORD);
! 	  n_reg = fold_convert (unsigned_type_node, n_reg);
! 	  lim_reg = size_int (NUM_PARM_FREGS - (isize / UNITS_PER_WORD));
! 	  lim_reg = fold_convert (unsigned_type_node, lim_reg);
! 	  sav_ofs = size_int (FREG_OFFSET);
! 	}
!       else
! 	{
! 	  /* Everything else is passed in general registers.  */
! 	  reg = gpr;
! 	  if ((isize + UNITS_PER_WORD - 1) / UNITS_PER_WORD > 1)
! 	    abort ();
! 	  n_reg = fold_convert (unsigned_type_node, integer_one_node);
! 	  lim_reg = size_int (NUM_PARM_IREGS - 1);
! 	  lim_reg = fold_convert (unsigned_type_node, lim_reg);
! 	  sav_ofs = size_int (IREG_OFFSET);
! 	}
  
!       u = build (LE_EXPR, boolean_type_node, reg, lim_reg);
!       addr = build (COND_EXPR, ptr_type_node, u, NULL, NULL);
  
!       /* The value was passed in a register, so read it from the register
! 	 save area initialized by __builtin_saveregs.  */
  
!       sav_ofs = fold_convert (ptr_type_node, sav_ofs);
!       sav_ofs = fold (build (PLUS_EXPR, ptr_type_node, sav, sav_ofs));
  
!       u = fold_convert (unsigned_type_node, size_int (UNITS_PER_WORD));
!       u = build (MULT_EXPR, unsigned_type_node, reg, u);
!       u = fold_convert (ptr_type_node, u);
!       u = build (PLUS_EXPR, ptr_type_node, sav_ofs, u);
!       COND_EXPR_THEN (addr) = u;
  
!       /* The value was passed in memory, so read it from the overflow area.  */
  
!       t = fold_convert (ptr_type_node, size);
!       u = build (POSTINCREMENT_EXPR, ptr_type_node, mem, t);
!       COND_EXPR_ELSE (addr) = u;
  
!       /* Increment either the ireg_used or freg_used field.  */
  
!       t = build (PLUS_EXPR, unsigned_type_node, reg, n_reg);
!       t = build (MODIFY_EXPR, unsigned_type_node, reg, t);
!       gimplify_and_add (t, post_p);
!     }
  
!   addr = fold_convert (type_ptr, addr);
!   return build_fold_indirect_ref (addr);
  }
  
  /* Compute a (partial) cost for rtx X.  Return true if the complete
*************** i860_struct_value_rtx (tree fntype ATTRI
*** 2126,2131 ****
--- 2107,2114 ----
  
  #undef TARGET_BUILD_BUILTIN_VA_LIST
  #define TARGET_BUILD_BUILTIN_VA_LIST i860_build_builtin_va_list
+ #undef TARGET_GIMPLIFY_VA_ARG_EXPR
+ #define TARGET_GIMPLIFY_VA_ARG_EXPR i860_gimplify_va_arg_expr
  
  #undef TARGET_STRUCT_VALUE_RTX
  #define TARGET_STRUCT_VALUE_RTX i860_struct_value_rtx
Index: config/i860/i860.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i860/i860.h,v
retrieving revision 1.44
diff -c -p -d -r1.44 i860.h
*** config/i860/i860.h	11 Mar 2004 05:54:31 -0000	1.44
--- config/i860/i860.h	8 Jul 2004 23:35:04 -0000
*************** struct cumulative_args { int ints, float
*** 571,580 ****
  #define EXPAND_BUILTIN_VA_START(valist, nextarg) \
    i860_va_start (valist, nextarg)
  
- /* Implement `va_arg'.  */
- #define EXPAND_BUILTIN_VA_ARG(valist, type) \
-   i860_va_arg (valist, type)
- 
  /* Store in the variable DEPTH the initial difference between the
     frame pointer reg contents and the stack pointer reg contents,
     as of the start of the function body.  This depends on the layout
--- 571,576 ----


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