diff options
author | Kai Tietz <kai.tietz@onevision.com> | 2010-12-18 10:16:13 +0000 |
---|---|---|
committer | Kai Tietz <ktietz@gcc.gnu.org> | 2010-12-18 11:16:13 +0100 |
commit | 628c4eee537f82b0422fb0990ee75384bf7e984e (patch) | |
tree | 5575fa8c752c52fdeae36d42bd59040213bf7c70 | |
parent | a6e4343fc4368e356348e47afbf432bf7f1b339d (diff) | |
download | gcc-628c4eee537f82b0422fb0990ee75384bf7e984e.zip gcc-628c4eee537f82b0422fb0990ee75384bf7e984e.tar.gz gcc-628c4eee537f82b0422fb0990ee75384bf7e984e.tar.bz2 |
re PR target/36834 (structure return ABI for windows targets differs from native MSVC)
2010-12-18 Kai Tietz <kai.tietz@onevision.com>
PR target/36834
* config/i386/i386.c (ix86_keep_aggregate_return_pointer):
New local function.
(ix86_return_pops_args): Use ix86_keep_aggregate_return_pointer
function instead of KEEP_AGGREGATE_RETURN_POINTER.
(ix86_handle_callee_pop_aggregate_return): New handler.
(ix86_attribute_table): Add new attribute
callee_pop_aggregate_return.
* doc/extend.texi (callee_pop_aggregate_return): Add
attribute documentation.
2010-12-18 Kai Tietz <kai.tietz@onevision.com>
PR target/36834
* gcc.target/i386/aggregate-ret1.c: New.
* gcc.target/i386/aggregate-ret2.c: New.
From-SVN: r168019
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 69 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/aggregate-ret1.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/aggregate-ret2.c | 28 |
6 files changed, 156 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 90fe876..5b7241e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2010-12-18 Kai Tietz <kai.tietz@onevision.com> + + PR target/36834 + * config/i386/i386.c (ix86_keep_aggregate_return_pointer): + New local function. + (ix86_return_pops_args): Use ix86_keep_aggregate_return_pointer + function instead of KEEP_AGGREGATE_RETURN_POINTER. + (ix86_handle_callee_pop_aggregate_return): New handler. + (ix86_attribute_table): Add new attribute + callee_pop_aggregate_return. + * doc/extend.texi (callee_pop_aggregate_return): Add + attribute documentation. + 2010-12-18 Iain Sandoe <iains@gcc.gnu.org> * config/darwin.h (SUBTARGET_C_COMMON_OVERRIDE_OPTIONS): diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index a5603e6..40999c8 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5436,6 +5436,19 @@ ix86_eax_live_at_start_p (void) return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR), 0); } +static bool +ix86_keep_aggregate_return_pointer (tree fntype) +{ + tree attr; + + attr = lookup_attribute ("callee_pop_aggregate_return", + TYPE_ATTRIBUTES (fntype)); + if (attr) + return (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) == 0); + + return KEEP_AGGREGATE_RETURN_POINTER != 0; +} + /* Value is the number of bytes of arguments automatically popped when returning from a subroutine call. FUNDECL is the declaration node of the function (as a tree), @@ -5480,7 +5493,7 @@ ix86_return_pops_args (tree fundecl, tree funtype, int size) /* Lose any fake structure return argument if it is passed on the stack. */ if (aggregate_value_p (TREE_TYPE (funtype), fundecl) - && !KEEP_AGGREGATE_RETURN_POINTER) + && !ix86_keep_aggregate_return_pointer (funtype)) { int nregs = ix86_function_regparm (funtype, fundecl); if (nregs == 0) @@ -29060,6 +29073,58 @@ x86_order_regs_for_local_alloc (void) reg_alloc_order [pos++] = 0; } +/* Handle a "callee_pop_aggregate_return" attribute; arguments as + in struct attribute_spec handler. */ +static tree +ix86_handle_callee_pop_aggregate_return (tree *node, tree name, + tree args, + int flags ATTRIBUTE_UNUSED, + bool *no_add_attrs) +{ + if (TREE_CODE (*node) != FUNCTION_TYPE + && TREE_CODE (*node) != METHOD_TYPE + && TREE_CODE (*node) != FIELD_DECL + && TREE_CODE (*node) != TYPE_DECL) + { + warning (OPT_Wattributes, "%qE attribute only applies to functions", + name); + *no_add_attrs = true; + return NULL_TREE; + } + if (TARGET_64BIT) + { + warning (OPT_Wattributes, "%qE attribute only available for 32-bit", + name); + *no_add_attrs = true; + return NULL_TREE; + } + if (is_attribute_p ("callee_pop_aggregate_return", name)) + { + tree cst; + + cst = TREE_VALUE (args); + if (TREE_CODE (cst) != INTEGER_CST) + { + warning (OPT_Wattributes, + "%qE attribute requires an integer constant argument", + name); + *no_add_attrs = true; + } + else if (compare_tree_int (cst, 0) != 0 + && compare_tree_int (cst, 1) != 0) + { + warning (OPT_Wattributes, + "argument to %qE attribute is neither zero, nor one", + name); + *no_add_attrs = true; + } + + return NULL_TREE; + } + + return NULL_TREE; +} + /* Handle a "ms_abi" or "sysv" attribute; arguments as in struct attribute_spec.handler. */ static tree @@ -32229,6 +32294,8 @@ static const struct attribute_spec ix86_attribute_table[] = { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute }, { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute }, { "ms_hook_prologue", 0, 0, true, false, false, ix86_handle_fndecl_attribute }, + { "callee_pop_aggregate_return", 1, 1, false, true, true, + ix86_handle_callee_pop_aggregate_return }, /* End element. */ { NULL, 0, 0, false, false, false, NULL } }; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 654c3b0..cbfb440 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2823,6 +2823,19 @@ when targeting Windows. On all other systems, the default is the AMD ABI. Note, the @code{ms_abi} attribute for Windows targets currently requires the @option{-maccumulate-outgoing-args} option. +@item callee_pop_aggregate_return (@var{number}) +@cindex @code{callee_pop_aggregate_return} attribute + +On 32-bit i?86-*-* targets, you can control by those attribute for +aggregate return in memory, if the caller is responsible to pop the hidden +pointer together with the rest of the arguments - @var{number} equal to +zero -, or if the callee is responsible to pop hidden pointer - @var{number} +equal to one. + +For i?86-netware, the caller pops the stack for the hidden arguments pointing +to aggregate return value. This differs from the default i386 ABI which assumes +that the callee pops the stack for hidden pointer. + @item ms_hook_prologue @cindex @code{ms_hook_prologue} attribute diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1e4d1b7..5991aac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-12-18 Kai Tietz <kai.tietz@onevision.com> + + PR target/36834 + * gcc.target/i386/aggregate-ret1.c: New. + * gcc.target/i386/aggregate-ret2.c: New. + 2010-12-18 Iain Sandoe <iains@gcc.gnu.org> * gcc.target/powerpc/darwin-split-ld-stret.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/aggregate-ret1.c b/gcc/testsuite/gcc.target/i386/aggregate-ret1.c new file mode 100644 index 0000000..a506067 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/aggregate-ret1.c @@ -0,0 +1,28 @@ +/* target/36834 */ +/* Check that, with keep_aggregate_return_pointer attribute, callee does + not pop the stack for the implicit pointer arg when returning a large + structure in memory. */ +/* { dg-do compile { target i?86-*-* } } */ + +struct foo { + int a; + int b; + int c; + int d; +}; + +__attribute__ ((callee_pop_aggregate_return(0))) +struct foo +bar (void) +{ + struct foo retval; + retval.a = 1; + retval.b = 2; + retval.c = 3; + retval.d = 4; + return retval; +} + +/* { dg-final { scan-assembler-not "ret\[ \t\]\\\$4" } } */ + + diff --git a/gcc/testsuite/gcc.target/i386/aggregate-ret2.c b/gcc/testsuite/gcc.target/i386/aggregate-ret2.c new file mode 100644 index 0000000..03e9bae --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/aggregate-ret2.c @@ -0,0 +1,28 @@ +/* target/36834 */ +/* Check that, with dont_keep_aggregate_return_pointer attribute, callee + pops the stack for the implicit pointer arg when returning a large + structure in memory. */ +/* { dg-do compile { target i?86-*-* } } */ + +struct foo { + int a; + int b; + int c; + int d; +}; + +__attribute__ ((callee_pop_aggregate_return(1))) +struct foo +bar (void) +{ + struct foo retval; + retval.a = 1; + retval.b = 2; + retval.c = 3; + retval.d = 4; + return retval; +} + +/* { dg-final { scan-assembler "ret\[ \t\]\\\$4" } } */ + + |