This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Return value on MIPS N64 ABI
- From: Heiher <admin at heiher dot info>
- To: Matthew Fortune <Matthew dot Fortune at imgtec dot com>
- Cc: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Tue, 21 Jun 2016 09:05:18 +0800
- Subject: Re: Return value on MIPS N64 ABI
- Authentication-results: sourceware.org; auth=none
- References: <CAHirt9guFFWnYm8+WyiDpjC1ycUkHoR=_+1=U1DPpzqV3DHx+Q at mail dot gmail dot com> <6D39441BF12EF246A7ABCE6654B023537E445BBA at HHMAIL01 dot hh dot imgtec dot org>
Thank you.
On Mon, Jun 13, 2016 at 6:19 PM, Matthew Fortune
<Matthew.Fortune@imgtec.com> wrote:
> Heiher <admin@heiher.info> writes:
>> Looks the return value of TestNewA is passed on $f0/$f2 from disassembly
>> code. I don't known why the return value of TestNewB is passed on
>> $v0/$v1? a bug?
>
> I believe this is an area where GNU strays from the N64 ABI definition but
> is defacto standard. TestA is a struct of two floating point fields which
> is passed and returned in FP registers. TestB is a struct of a struct of
> two floating point fields (or at least I think that is the interpretation).
>
> The ABI does say that this should be flattened and be seen as simply two
> floating point fields but GCC does not and passes it in integer registers
> instead. Or at least the ABI says this for arguments but not results.
>
> The relevant bit of the ABI we are not adhering to is 'Structs,unions' on
> page 7 which covers arguments, however the corresponding text for results
> does not include the part about ignoring the struct field structure
> when determining between floating point and integer chunks.
>
> https://dmz-portal.ba.imgtec.org/mw/images/6/6f/007-2816-005-1.pdf
>
> FWIW: Clang/LLVM ABI implementation matches GCC in this regard as we run
> cross linking tests and use GCC as 'correct'.
>
> Thanks,
> Matthew
>
>> 229 0000000120000c40 <_Z8TestNewAv>:
>> 230 120000c40: 3c030002 lui v1,0x2
>> 231 120000c44: 0079182d daddu v1,v1,t9
>> 232 120000c48: 64638400 daddiu v1,v1,-31744
>> 233 120000c4c: dc628050 ld v0,-32688(v1)
>> 234 120000c50: 67bdffe0 daddiu sp,sp,-32
>> 235 120000c54: d4400e68 ldc1 $f0,3688(v0)
>> 236 120000c58: dc628050 ld v0,-32688(v1)
>> 237 120000c5c: 67bd0020 daddiu sp,sp,32
>> 238 120000c60: 03e00008 jr ra
>> 239 120000c64: d4420e70 ldc1 $f2,3696(v0)
>> 240
>> 241 0000000120000c68 <_Z8TestNewBv>:
>> 242 120000c68: 3c0307f9 lui v1,0x7f9
>> 243 120000c6c: 3c0207f7 lui v0,0x7f7
>> 244 120000c70: 34633333 ori v1,v1,0x3333
>> 245 120000c74: 34423333 ori v0,v0,0x3333
>> 246 120000c78: 00031cb8 dsll v1,v1,0x12
>> 247 120000c7c: 000214b8 dsll v0,v0,0x12
>> 248 120000c80: 3463cccd ori v1,v1,0xcccd
>> 249 120000c84: 3442cccd ori v0,v0,0xcccd
>> 250 120000c88: 67bdfff0 daddiu sp,sp,-16
>> 251 120000c8c: 00031c78 dsll v1,v1,0x11
>> 252 120000c90: 00021478 dsll v0,v0,0x11
>> 253 120000c94: 6463999a daddiu v1,v1,-26214
>> 254 120000c98: 6442999a daddiu v0,v0,-26214
>> 255 120000c9c: 03e00008 jr ra
>> 256 120000ca0: 67bd0010 daddiu sp,sp,16
>>
>> // test.cpp
>> // gcc -march=mips64r2 -mabi=64 -O3 -o test test.cpp #include <stdio.h>
>>
>> class TestA
>> {
>> public:
>> double l;
>> double h;
>>
>> TestA(double l, double h) : l(l), h(h) {} };
>>
>> class TestB : public TestA
>> {
>> public:
>> TestB(const TestA& a) : TestA(a) {} };
>>
>> TestA
>> TestNewA(void)
>> {
>> return TestA(0.1, 0.2);
>> }
>>
>> TestB
>> TestNewB(void)
>> {
>> return TestA(0.1, 0.2);
>> }
>>
>> int
>> main(int argch, char *argv[])
>> {
>> TestA a = TestNewA();
>> printf("%lf, %lf\n", a.l, a.h);
>>
>> TestB b = TestNewB();
>> printf("%lf, %lf\n", b.l, b.h);
>>
>> return 0;
>> }
--
Best regards!
Heiher
http://hev.cc