https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114416
Bug ID: 114416
Summary: SPARC V9 struct return with floating-point members
violates ABI
Product: gcc
Version: 14.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: ro at gcc dot gnu.org
CC: ebotcazou at gcc dot gnu.org
Target Milestone: ---
Target: sparc*-sun-solaris2.11
I've been informed of a case where gcc generates code for struct return with
floating-point members that violates the SPARC V9 ABI (SCD 2.4.1): consider the
attached testcase:
$ gcc -m64 -O2 -c fpret.c
$ cc -m64 -O2 caller.c
$ gcc -m64 -o cc-gcc caller.o fpret.o
$ ./cc-gcc
sum2: x[0] = -nan x[1] = -nan
sum2x: x = 0 y = 1
With gcc, sum2 places the return value into %o0/%o1
sum2()
sum2: 9c 03 bf 60 add %sp, -0xa0, %sp
sum2+0x4: 90 10 20 00 clr %o0
sum2+0x8: 92 10 23 ff mov 0x3ff, %o1
sum2+0xc: 93 2a 70 34 sllx %o1, 0x34, %o1
sum2+0x10: 81 c3 e0 08 retl
sum2+0x14: 9c 03 a0 a0 add %sp, 0xa0, %sp
while cc uses %d0/%d2 instead:
sum2()
sum2: 1b 00 00 00 sethi %hi(0x0), %o5
sum2+0x4: 81 b0 0c 00 fzerod %d0
sum2+0x8: c1 3b a8 7f std %d0, [%sp + 0x87f]
sum2+0xc: 98 13 60 00 or %o5, 0x0, %o4
sum2+0x10: 97 2b 30 0c sllx %o4, 0xc, %o3
sum2+0x14: c5 1a e0 00 ldd [%o3], %d2
sum2+0x18: 81 c3 e0 08 retl
sum2+0x1c: c5 3b a8 87 std %d2, [%sp + 0x887]
I believe this in line with SCD 2.4.1:
* 3P-13 states
Structure or Union return values
Structure and union return types up to thirty-two bytes in size are returned
in registers. The registers are assigned as if
the value was being passed as the first argument to a function with a known
prototype.
* and p. 3P-12 has
Structure or union types larger than eight bytes, and up to sixteen bytes in
size are assigned to two consecutive
parameter array words, and align according to the alignment requirements of
the structure or at least to an eight-byte
boundary.
* If I read the table on p. 3P-11 correctly, those parameter array words should
map to %d0/%d2 for double args, just as cc does.