aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Tietz <kai.tietz@onevision.com>2010-12-18 10:16:13 +0000
committerKai Tietz <ktietz@gcc.gnu.org>2010-12-18 11:16:13 +0100
commit628c4eee537f82b0422fb0990ee75384bf7e984e (patch)
tree5575fa8c752c52fdeae36d42bd59040213bf7c70
parenta6e4343fc4368e356348e47afbf432bf7f1b339d (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--gcc/config/i386/i386.c69
-rw-r--r--gcc/doc/extend.texi13
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/aggregate-ret1.c28
-rw-r--r--gcc/testsuite/gcc.target/i386/aggregate-ret2.c28
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" } } */
+
+