diff options
author | Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> | 2003-01-24 21:48:47 +0100 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2003-01-24 20:48:47 +0000 |
commit | 09b2e78d66d7f45f96567754f81c441546b88b74 (patch) | |
tree | e3d2f2d02bfd5bfbd61c11777e6a10f99b78b074 | |
parent | 3d436d2ac575b85dc7c787fbeacc3c08597000c3 (diff) | |
download | gcc-09b2e78d66d7f45f96567754f81c441546b88b74.zip gcc-09b2e78d66d7f45f96567754f81c441546b88b74.tar.gz gcc-09b2e78d66d7f45f96567754f81c441546b88b74.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 41 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 9 |
4 files changed, 60 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0376555..f22df79 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 01fc203..0f41377 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 91b499a9..45165f4 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 ac53a4f..b4359f1 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. |