Greetings,
I could use some help in how register values are passed in the FFI.
The basic situation is that on RISC-V, simple float/double values are returned in FA0 (float reg), not A0 (integer reg).
E.g. for unit test:
======================================= testConstructedDoubleCall "Test using generic FFI spec" | result meth | meth := ExternalLibraryFunction name:'ffiTestDoubles' module: FFITestLibrary moduleName callType: 0 returnType: ExternalType double argumentTypes: ((1 to: 2) collect:[:i| ExternalType double]). result := meth invokeWithArguments: (Array with: 41 with: true). self assert: result = 42.0 ======================================= EXPORT(double) ffiTestDoubles(double d1, double d2) { printf("The two floats are %f and %f\n", (float)d1, (float)d2); return d1+d2; }
Looking at: ThreadedARM64FFIPlugin>>ffiCalloutTo:SpecOnStack:in: =======================================
Stepping in GDB --> ffiCallArgArrayOrNilNumArgs() .. (floatRet.d = dispatchFunctionPointerwithwithwithwithwithwithwithwith(...)
At this point, I can single step to ffiTestDoubles(), the proper values are printed (41,1), 42 is placed in register FA0
But the first value in float.d is _1_ (value presumably from A0).
So I need to set GDB into asm mode and crawl through the C assign to floatRet.d, but some theory of operations could help me out here.
Different setup passed to #setReturnRegister:andCall:withArgsArray: ??
Thanks much for help, -KenD
vm-dev@lists.squeakfoundation.org