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 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

Reply via email to