This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
ARM structure returns
- To: gcc-bugs at gcc dot gnu dot org
- Subject: ARM structure returns
- From: Richard Sandiford <rsandifo at redhat dot com>
- Date: 22 Oct 2001 16:59:10 +0100
Perhaps not a bug as such, but I wasn't expecting it, and couldn't find
it documented. Sorry if it's been raised before.
With arm-elf-gcc, given the code:
struct foo
{
int a;
int b;
};
struct foo a (struct foo s);
void b (struct foo *s)
{
*s = a (*s);
}
The pointer to a's return value gets passed in r1 rather than r0. r0
goes unused:
mov ip, sp
stmfd sp!, {r4, fp, ip, lr, pc}
sub fp, ip, #4
mov r4, r0 ; r4 = s
sub sp, sp, #8
ldmia r4, {r2-r3} ; r2,r3 = *s
sub r1, fp, #24 ; r1 = &temp
bl a
sub r3, fp, #16
ldmdb r3, {r2-r3} ; copy temp to s
stmia r4, {r2-r3}
ldmea fp, {r4, fp, sp, pc}
Is this behaviour intentional? If not, should it be changed, or would
that create unacceptable ABI incompatiblity?
If it is unintentional, the cause seems to be:
The ARM back-end defines STRUCT_VALUE to NULL, so the generic args code
treats the hidden argument like any other, using the FUNCTION_ARG
interface to find out where it should go. But arm_init_cumulative_args
reads:
arm_init_cumulative_args (pcum, fntype, libname, indirect)
CUMULATIVE_ARGS * pcum;
tree fntype;
rtx libname ATTRIBUTE_UNUSED;
int indirect ATTRIBUTE_UNUSED;
{
/* On the ARM, the offset starts at 0. */
pcum->nregs = ((fntype && aggregate_value_p (TREE_TYPE (fntype))) ? 1 : 0);
So, when the function returns an aggregate, the first argument -- the
hidden one -- gets put in reg 1. The first unhidden argument goes in
reg 2, and so on.
Richard