OSDN Git Service

* alpha.h (EXPAND_BUILTIN_SAVEREGS): Delete.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 26 Jul 1999 05:48:39 +0000 (05:48 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 26 Jul 1999 05:48:39 +0000 (05:48 +0000)
        (BUILD_VA_LIST_TYPE): New.
        (EXPAND_BUILTIN_VA_START): New.
        (EXPAND_BUILTIN_VA_ARG): New.
        * alpha.c (alpha_builtin_saveregs): Delete.
        (alpha_build_va_list): New.
        (alpha_va_start): New.
        (alpha_va_arg): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@28252 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h

index 901e413..1dfcd6c 100644 (file)
@@ -1,3 +1,14 @@
+Sun Jul 25 22:45:55 1999  Richard Henderson  <rth@cygnus.com>
+
+       * alpha.h (EXPAND_BUILTIN_SAVEREGS): Delete.
+       (BUILD_VA_LIST_TYPE): New.
+       (EXPAND_BUILTIN_VA_START): New.
+       (EXPAND_BUILTIN_VA_ARG): New.
+       * alpha.c (alpha_builtin_saveregs): Delete.
+       (alpha_build_va_list): New.
+       (alpha_va_start): New.
+       (alpha_va_arg): New.
+
 Sun Jul 25 21:40:33 1999  Jeffrey A Law  (law@cygnus.com)
 
        * gcc.texi: More changes related to list conversion.
index a1e8770..9f07b21 100644 (file)
@@ -3083,101 +3083,132 @@ alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
     emit_insn (gen_imb ());
 }
 \f
-/* Do what is necessary for `va_start'.  The argument is ignored;
-   We look at the current function to determine if stdarg or varargs
-   is used and fill in an initial va_list.  A pointer to this constructor
-   is returned.  */
-
-struct rtx_def *
-alpha_builtin_saveregs (arglist)
-     tree arglist ATTRIBUTE_UNUSED;
+tree
+alpha_build_va_list ()
 {
-  rtx block, addr, dest, argsize;
-  tree fntype = TREE_TYPE (current_function_decl);
-  int stdarg = (TYPE_ARG_TYPES (fntype) != 0
-               && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
-                   != void_type_node));
+  tree base, ofs, record;
+
+  if (TARGET_OPEN_VMS)
+    return ptr_type_node;
 
-  /* Compute the current position into the args, taking into account
-     both registers and memory.  Both of these are already included in
-     NUM_ARGS.  */
+  record = make_node (RECORD_TYPE);
+  /* C++? SET_IS_AGGR_TYPE (record, 1); */
 
-  argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
+  ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
+                   integer_type_node);
+  DECL_FIELD_CONTEXT (ofs) = record;
 
-  /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
-     storing fp arg registers in the first 48 bytes, and the integer arg
-     registers in the next 48 bytes.  This is only done, however, if any
-     integer registers need to be stored.
+  base = build_decl (FIELD_DECL, get_identifier ("__base"),
+                    ptr_type_node);
+  DECL_FIELD_CONTEXT (base) = record;
+  TREE_CHAIN (base) = ofs;
 
-     If no integer registers need be stored, then we must subtract 48 in
-     order to account for the integer arg registers which are counted in
-     argsize above, but which are not actually stored on the stack.  */
+  TYPE_FIELDS (record) = base;
+  layout_type (record);
+
+  return record;
+}
+
+void
+alpha_va_start (stdarg_p, valist, nextarg)
+     int stdarg_p;
+     tree valist;
+     rtx nextarg ATTRIBUTE_UNUSED;
+{
+  HOST_WIDE_INT offset;
+  tree t, offset_field, base_field;
 
   if (TARGET_OPEN_VMS)
-    addr = plus_constant (virtual_incoming_args_rtx,
-                         NUM_ARGS <= 5 + stdarg
-                         ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
+    std_expand_builtin_va_start (stdarg_p, valist, nextarg);
+
+  /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
+     up by 48, storing fp arg registers in the first 48 bytes, and the
+     integer arg registers in the next 48 bytes.  This is only done,
+     however, if any integer registers need to be stored.
+
+     If no integer registers need be stored, then we must subtract 48
+     in order to account for the integer arg registers which are counted
+     in argsize above, but which are not actually stored on the stack.  */
+
+  if (NUM_ARGS <= 5 + stdarg_p)
+    offset = 6 * UNITS_PER_WORD;
   else
-    addr = (NUM_ARGS <= 5 + stdarg
-           ? plus_constant (virtual_incoming_args_rtx,
-                            6 * UNITS_PER_WORD)
-           : plus_constant (virtual_incoming_args_rtx,
-                            - (6 * UNITS_PER_WORD)));
-
-  /* For VMS, we include the argsize, while on Unix, it's handled as
-     a separate field.  */
+    offset = -6 * UNITS_PER_WORD;
+
+  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);
+
+  t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
+  t = build (PLUS_EXPR, ptr_type_node, t, build_int_2 (offset, 0));
+  t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
+  TREE_SIDE_EFFECTS (t) = 1;
+  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  t = build_int_2 (NUM_ARGS*UNITS_PER_WORD, 0);
+  t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
+  TREE_SIDE_EFFECTS (t) = 1;
+  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+}
+
+rtx
+alpha_va_arg (valist, type)
+     tree valist, type;
+{
+  HOST_WIDE_INT tsize;
+  rtx addr;
+  tree t;
+  tree offset_field, base_field, addr_tree, addend;
+  tree wide_type, wide_ofs;
+
   if (TARGET_OPEN_VMS)
-    addr = plus_constant (addr, INTVAL (argsize));
+    return std_expand_builtin_va_arg (valist, type);
 
-  addr = force_operand (addr, NULL_RTX);
+  tsize = ((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT + 7) / 8) * 8;
 
-#ifdef POINTERS_EXTEND_UNSIGNED
-  addr = convert_memory_address (ptr_mode, addr);
-#endif
+  base_field = TYPE_FIELDS (TREE_TYPE (valist));
+  offset_field = TREE_CHAIN (base_field);
 
-  if (TARGET_OPEN_VMS)
-    return addr;
-  else
+  base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
+                     valist, base_field);
+  offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
+                       valist, offset_field);
+
+  wide_type = make_signed_type (64);
+  wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
+
+  addend = wide_ofs;
+  if (FLOAT_TYPE_P (type))
     {
-      /* Allocate the va_list constructor */
-      block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
-      RTX_UNCHANGING_P (block) = 1;
-      RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
-
-      /* Store the address of the first integer register in the __base
-        member.  */
-
-      dest = change_address (block, ptr_mode, XEXP (block, 0));
-      emit_move_insn (dest, addr);
-
-      if (current_function_check_memory_usage)
-       emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
-                          dest, ptr_mode,
-                          GEN_INT (GET_MODE_SIZE (ptr_mode)),
-                          TYPE_MODE (sizetype),
-                          GEN_INT (MEMORY_USE_RW), 
-                          TYPE_MODE (integer_type_node));
-  
-      /* Store the argsize as the __va_offset member.  */
-      dest = change_address (block, TYPE_MODE (integer_type_node),
-                            plus_constant (XEXP (block, 0),
-                                           POINTER_SIZE/BITS_PER_UNIT));
-      emit_move_insn (dest, argsize);
-
-      if (current_function_check_memory_usage)
-       emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
-                          dest, ptr_mode,
-                          GEN_INT (GET_MODE_SIZE
-                                   (TYPE_MODE (integer_type_node))),
-                          TYPE_MODE (sizetype),
-                          GEN_INT (MEMORY_USE_RW),
-                          TYPE_MODE (integer_type_node));
-
-      /* Return the address of the va_list constructor, but don't put it in a
-        register.  Doing so would fail when not optimizing and produce worse
-        code when optimizing.  */
-      return XEXP (block, 0);
+      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, build_int_2 (tsize, 0)));
+  TREE_SIDE_EFFECTS (t) = 1;
+  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  return addr;
 }
 \f
 /* This page contains routines that are used to determine what the function
index e9c3f6d..5499edb 100644 (file)
@@ -1161,19 +1161,22 @@ extern int alpha_memory_latency;
     {                                                                  \
       if (! (NO_RTL))                                                  \
        {                                                               \
+         rtx tmp; int set = get_varargs_alias_set ();                  \
+         tmp = gen_rtx_MEM (BLKmode,                                   \
+                            plus_constant (virtual_incoming_args_rtx,  \
+                                           ((CUM) + 6)* UNITS_PER_WORD)); \
+         MEM_ALIAS_SET (tmp) = set;                                    \
          move_block_from_reg                                           \
-           (16 + CUM,                                                  \
-            gen_rtx (MEM, BLKmode,                                     \
-                     plus_constant (virtual_incoming_args_rtx,         \
-                                    ((CUM) + 6)* UNITS_PER_WORD)),     \
+           (16 + CUM, tmp,                                             \
             6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD);                  \
+                                                                       \
+         tmp = gen_rtx_MEM (BLKmode,                                   \
+                            plus_constant (virtual_incoming_args_rtx,  \
+                                           (CUM) * UNITS_PER_WORD));   \
+         MEM_ALIAS_SET (tmp) = set;                                    \
          move_block_from_reg                                           \
-           (16 + (TARGET_FPREGS ? 32 : 0) + CUM,                       \
-            gen_rtx (MEM, BLKmode,                                     \
-                     plus_constant (virtual_incoming_args_rtx,         \
-                                    (CUM) * UNITS_PER_WORD)),          \
+           (16 + (TARGET_FPREGS ? 32 : 0) + CUM, tmp,                  \
             6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD);                  \
-          emit_insn (gen_blockage ());                                 \
         }                                                              \
       PRETEND_SIZE = 12 * UNITS_PER_WORD;                              \
     }                                                                  \
@@ -1189,11 +1192,6 @@ extern struct rtx_def *alpha_emit_set_long_const ();
 extern struct rtx_def *alpha_emit_conditional_branch ();
 extern struct rtx_def *alpha_emit_conditional_move ();
 
-/* Generate necessary RTL for __builtin_saveregs().
-   ARGLIST is the argument list; see expr.c.  */
-extern struct rtx_def *alpha_builtin_saveregs ();
-#define EXPAND_BUILTIN_SAVEREGS(ARGLIST) alpha_builtin_saveregs (ARGLIST)
-
 /* Define the information needed to generate branch and scc insns.  This is
    stored from the compare operation.  Note that we can't use "rtx" here
    since it hasn't been defined!  */
@@ -2348,6 +2346,18 @@ do {                                                                     \
   {"reg_not_elim_operand", {SUBREG, REG}},                             \
   {"reg_no_subreg_operand", {REG}},
 \f
+/* Define the `__builtin_va_list' type for the ABI.  */
+#define BUILD_VA_LIST_TYPE(VALIST) \
+  (VALIST) = alpha_build_va_list ()
+
+/* Implement `va_start' for varargs and stdarg.  */
+#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
+  alpha_va_start (stdarg, valist, nextarg)
+
+/* Implement `va_arg'.  */
+#define EXPAND_BUILTIN_VA_ARG(valist, type) \
+  alpha_va_arg (valist, type)
+\f
 /* Tell collect that the object format is ECOFF.  */
 #define OBJECT_FORMAT_COFF
 #define EXTENDED_COFF
@@ -2548,3 +2558,6 @@ extern int alpha_expand_block_move ();
 extern int alpha_expand_block_clear ();
 extern void alpha_expand_prologue ();
 extern void alpha_expand_epilogue ();
+extern union tree_node *alpha_build_va_list ();
+extern void alpha_va_start ();
+extern struct rtx_def *alpha_va_arg ();