OSDN Git Service

* config/i386/i386-protos.h (function_arg_pass_by_reference): Declare.
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Jan 2003 20:48:47 +0000 (20:48 +0000)
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Jan 2003 20:48:47 +0000 (20:48 +0000)
* config/i386/i386.h (FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
* config/i386/i386.c (function_arg_pass_by_reference): New.
(ix86_va_arg): Support arguments passed by reference.

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

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

index 0376555..f22df79 100644 (file)
@@ -1,5 +1,12 @@
 2003-01-24  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
 
+       * config/i386/i386-protos.h (function_arg_pass_by_reference): Declare.
+       * config/i386/i386.h (FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
+       * config/i386/i386.c (function_arg_pass_by_reference): New.
+       (ix86_va_arg): Support arguments passed by reference.
+
+2003-01-24  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
+
        * cfgloopanal.c: New file.
        * cfgloopmanip.c: New file.
        * Makefile.in (cfgloopanal.o, cfgloopmanip.o): New.
index 01fc203..0f41377 100644 (file)
@@ -195,6 +195,9 @@ extern void x86_function_profiler PARAMS ((FILE *, int));
 #ifdef TREE_CODE
 extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
 extern rtx function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
+extern int function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
+                                                  enum machine_mode,
+                                                  tree, int));
 extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode,
                                        tree, int));
 extern rtx ix86_function_value PARAMS ((tree));
index 91b499a..45165f4 100644 (file)
@@ -2488,6 +2488,32 @@ function_arg (cum, mode, type, named)
   return ret;
 }
 
+/* A C expression that indicates when an argument must be passed by
+   reference.  If nonzero for an argument, a copy of that argument is
+   made in memory and a pointer to the argument is passed instead of
+   the argument itself.  The pointer is passed in whatever way is
+   appropriate for passing a pointer to that type.  */
+
+int
+function_arg_pass_by_reference (cum, mode, type, named)
+     CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+     tree type;
+     int named ATTRIBUTE_UNUSED;
+{
+  if (!TARGET_64BIT)
+    return 0;
+
+  if (type && int_size_in_bytes (type) == -1)
+    {
+      if (TARGET_DEBUG_ARG)
+       fprintf (stderr, "function_arg_pass_by_reference\n");
+      return 1;
+    }
+
+  return 0;
+}
+
 /* Gives the alignment boundary, in bits, of an argument with the specified mode
    and type.   */
 
@@ -2843,6 +2869,7 @@ ix86_va_arg (valist, type)
   rtx lab_false, lab_over = NULL_RTX;
   rtx addr_rtx, r;
   rtx container;
+  int indirect_p = 0;
 
   /* Only 64bit target needs something special.  */
   if (!TARGET_64BIT)
@@ -2862,6 +2889,13 @@ ix86_va_arg (valist, type)
   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
 
   size = int_size_in_bytes (type);
+  if (size == -1)
+    {
+      /* Passed by reference.  */
+      indirect_p = 1;
+      type = build_pointer_type (type);
+      size = int_size_in_bytes (type);
+    }
   rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 
   container = construct_container (TYPE_MODE (type), type, 0,
@@ -3052,6 +3086,13 @@ ix86_va_arg (valist, type)
   if (container)
     emit_label (lab_over);
 
+  if (indirect_p)
+    {
+      r = gen_rtx_MEM (Pmode, addr_rtx);
+      set_mem_alias_set (r, get_varargs_alias_set ());
+      emit_move_insn (addr_rtx, r);
+    }
+
   return addr_rtx;
 }
 \f
index ac53a4f..b4359f1 100644 (file)
@@ -1753,6 +1753,15 @@ typedef struct ix86_args {
 
 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
 
+/* A C expression that indicates when an argument must be passed by
+   reference.  If nonzero for an argument, a copy of that argument is
+   made in memory and a pointer to the argument is passed instead of
+   the argument itself.  The pointer is passed in whatever way is
+   appropriate for passing a pointer to that type.  */
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
+  function_arg_pass_by_reference(&CUM, MODE, TYPE, NAMED)
 /* Perform any needed actions needed for a function that is receiving a
    variable number of arguments.