aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>2003-01-24 21:48:47 +0100
committerZdenek Dvorak <rakdver@gcc.gnu.org>2003-01-24 20:48:47 +0000
commit09b2e78d66d7f45f96567754f81c441546b88b74 (patch)
treee3d2f2d02bfd5bfbd61c11777e6a10f99b78b074
parent3d436d2ac575b85dc7c787fbeacc3c08597000c3 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/config/i386/i386-protos.h3
-rw-r--r--gcc/config/i386/i386.c41
-rw-r--r--gcc/config/i386/i386.h9
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.