Thank you.
On Mon, Jun 13, 2016 at 6:19 PM, Matthew Fortune
<matthew.fort...@imgtec.com> wrote:
> Heiher <ad...@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 00012c40 <_Z8TestNewAv>:
>> 23012c40: 3c030002lui v1,0x2
>> 23112c44: 0079182ddaddu v1,v1,t9
>> 23212c48: 64638400daddiu v1,v1,-31744
>> 23312c4c: dc628050ld v0,-32688(v1)
>> 23412c50: 67bdffe0daddiu sp,sp,-32
>> 23512c54: d4400e68ldc1$f0,3688(v0)
>> 23612c58: dc628050ld v0,-32688(v1)
>> 23712c5c: 67bd0020daddiu sp,sp,32
>> 23812c60: 03e8jr ra
>> 23912c64: d4420e70ldc1$f2,3696(v0)
>> 240
>> 241 00012c68 <_Z8TestNewBv>:
>> 24212c68: 3c0307f9lui v1,0x7f9
>> 24312c6c: 3c0207f7lui v0,0x7f7
>> 24412c70: 3463ori v1,v1,0x
>> 24512c74: 3442ori v0,v0,0x
>> 24612c78: 00031cb8dsllv1,v1,0x12
>> 24712c7c: 000214b8dsllv0,v0,0x12
>> 24812c80: 3463cccdori v1,v1,0xcccd
>> 24912c84: 3442cccdori v0,v0,0xcccd
>> 25012c88: 67bdfff0daddiu sp,sp,-16
>> 25112c8c: 00031c78dsllv1,v1,0x11
>> 25212c90: 00021478dsllv0,v0,0x11
>> 25312c94: 6463999adaddiu v1,v1,-26214
>> 25412c98: 6442999adaddiu v0,v0,-26214
>> 25512c9c: 03e8jr ra
>> 25612ca0: 67bd0010daddiu sp,sp,16
>>
>> // test.cpp
>> // gcc -march=mips64r2 -mabi=64 -O3 -o test test.cpp #include
>>
>> 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