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]

[PATCH] Fix passing of variable sized arguments on x86_64


Hello,

the patch below implements passing of variable sized arguments by
reference for x86_64. It was approved by Honza, I am commiting it.

Zdenek

	* 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.

Index: config/i386/i386-protos.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.84.2.3
diff -c -3 -p -r1.84.2.3 i386-protos.h
*** config/i386/i386-protos.h	28 Nov 2002 23:19:47 -0000	1.84.2.3
--- config/i386/i386-protos.h	24 Jan 2003 14:57:27 -0000
*************** extern void x86_function_profiler PARAMS
*** 192,197 ****
--- 192,200 ----
  #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: config/i386/i386.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.490.2.16
diff -c -3 -p -r1.490.2.16 i386.c
*** config/i386/i386.c	12 Jan 2003 14:24:20 -0000	1.490.2.16
--- config/i386/i386.c	24 Jan 2003 14:57:27 -0000
*************** function_arg (cum, mode, type, named)
*** 2356,2361 ****
--- 2356,2387 ----
    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.   */
  
*************** ix86_va_arg (valist, type)
*** 2711,2716 ****
--- 2737,2743 ----
    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)
*************** ix86_va_arg (valist, type)
*** 2730,2735 ****
--- 2757,2769 ----
    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,
*************** ix86_va_arg (valist, type)
*** 2919,2924 ****
--- 2953,2965 ----
  
    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;
  }
Index: config/i386/i386.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.305.2.7
diff -c -3 -p -r1.305.2.7 i386.h
*** config/i386/i386.h	14 Dec 2002 22:06:12 -0000	1.305.2.7
--- config/i386/i386.h	24 Jan 2003 14:57:27 -0000
*************** typedef struct ix86_args {
*** 1744,1749 ****
--- 1744,1758 ----
  
  #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)
+ 
  /* If PIC, we cannot make sibling calls to global functions
     because the PLT requires %ebx live.
     If we are returning floats on the register stack, we cannot make


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