[Vm-dev] Help: Float returns on RISCV

ken.dickey at whidbey.com ken.dickey at whidbey.com
Wed Jun 29 14:32:12 UTC 2022


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


More information about the Vm-dev mailing list