i860-protos.h (i860_va_arg): Remove.
authorRichard Henderson <rth@redhat.com>
Thu, 8 Jul 2004 23:37:00 +0000 (16:37 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 8 Jul 2004 23:37:00 +0000 (16:37 -0700)
        * 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.

From-SVN: r84327

gcc/ChangeLog
gcc/config/i860/i860-protos.h
gcc/config/i860/i860.c
gcc/config/i860/i860.h

index e6886763fd830fdd6f35ddbaa8dc33bedc43ed85..c2993d28995414b909a859301fdee20851dd721c 100644 (file)
@@ -1,3 +1,10 @@
+2004-07-08  Richard Henderson  <rth@redhat.com>
+
+       * 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.
+
 2004-05-31  Aaron W. LaFramboise <aaronraolete36@aaronwl.com>
 
        * system.h: Prototype getpagesize if missing.
index b155b86130d4ebb283de2175b9268567dff501bb..1f61eb13ecc2466ded24d0d1a60cf904245f6bdb 100644 (file)
@@ -46,7 +46,6 @@ extern int logic_int (rtx, enum machine_mode);
 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 */
 
index 6fa9a672ac9f2373b686d68191b1ce84dc2c8d71..1dc58a400519f770a93c52258cb637152113b47a 100644 (file)
@@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA.  */
 #include "target.h"
 #include "target-def.h"
 #include "langhooks.h"
+#include "tree-gimple.h"
 
 static rtx find_addr_reg (rtx);
 
@@ -1923,13 +1924,14 @@ i860_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
 /* 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)
+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, reg, t, u;
-  int size, n_reg, sav_ofs, sav_scale, max_reg;
-  rtx lab_false, lab_over, addr_rtx, r;
+  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);
@@ -1948,7 +1950,8 @@ i860_va_arg (tree valist, tree type)
   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);
+  size = size_in_bytes (type);
+  type_ptr = build_pointer_type (type);
 
   if (AGGREGATE_TYPE_P (type))
     {
@@ -1960,95 +1963,73 @@ i860_va_arg (tree valist, tree type)
         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);
+      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);
 
-      t = fold (build (PLUS_EXPR, ptr_type_node, 
-               make_tree (ptr_type_node, addr_rtx),
-               build_int_2 (size, 0)));
+      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);
-      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;
+      gimplify_and_add (t, pre_p);
     }
   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;
+      isize = tree_low_cst (size, 0);
 
-  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;
+      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);
+       }
 
-  r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
-  if (r != addr_rtx)
-    emit_move_insn (addr_rtx, r);
+      u = build (LE_EXPR, boolean_type_node, reg, lim_reg);
+      addr = build (COND_EXPR, ptr_type_node, u, NULL, NULL);
 
-  emit_jump_insn (gen_jump (lab_over));
-  emit_barrier ();
-  emit_label (lab_false);
+      /* The value was passed in a register, so read it from the register
+        save area initialized by __builtin_saveregs.  */
 
-  /* The value was passed in memory, so read it from the overflow area.  */
+      sav_ofs = fold_convert (ptr_type_node, sav_ofs);
+      sav_ofs = fold (build (PLUS_EXPR, ptr_type_node, sav, sav_ofs));
 
-  t = save_expr (mem);
-  r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
-  if (r != addr_rtx)
-    emit_move_insn (addr_rtx, r);
+      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;
 
-  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);
+      /* The value was passed in memory, so read it from the overflow area.  */
 
-  emit_label (lab_over);
+      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.  */
+      /* 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);
+      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);
+    }
 
-  return addr_rtx;
+  addr = fold_convert (type_ptr, addr);
+  return build_fold_indirect_ref (addr);
 }
 
 /* Compute a (partial) cost for rtx X.  Return true if the complete
@@ -2126,6 +2107,8 @@ i860_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
 
 #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 6e451e5da8d2185bfae4a48becca97b1e1079655..a4e9c8b137f55f035b00f6ac002837475e62934e 100644 (file)
@@ -571,10 +571,6 @@ struct cumulative_args { int ints, floats; };
 #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