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