From 09b2e78d66d7f45f96567754f81c441546b88b74 Mon Sep 17 00:00:00 2001 From: Zdenek Dvorak Date: Fri, 24 Jan 2003 21:48:47 +0100 Subject: [PATCH] i386-protos.h (function_arg_pass_by_reference): Declare. * 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. From-SVN: r61731 --- gcc/ChangeLog | 7 ++++++ gcc/config/i386/i386-protos.h | 3 +++ gcc/config/i386/i386.c | 41 +++++++++++++++++++++++++++++++++++ gcc/config/i386/i386.h | 9 ++++++++ 4 files changed, 60 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 03765553c94..f22df791000 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2003-01-24 Zdenek Dvorak + + * 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 * cfgloopanal.c: New file. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 01fc203377f..0f4137712b6 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -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)); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 91b499a9e78..45165f48c97 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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; } diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index ac53a4f3f11..b4359f1f8c6 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -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.