mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-11 12:54:00 +08:00
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
This commit is contained in:
parent
a6e4343fc4
commit
628c4eee53
@ -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):
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
28
gcc/testsuite/gcc.target/i386/aggregate-ret1.c
Normal file
28
gcc/testsuite/gcc.target/i386/aggregate-ret1.c
Normal file
@ -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" } } */
|
||||
|
||||
|
28
gcc/testsuite/gcc.target/i386/aggregate-ret2.c
Normal file
28
gcc/testsuite/gcc.target/i386/aggregate-ret2.c
Normal file
@ -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" } } */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user