1. Phix: float32 return value
- Posted by andreasWagner 6 days ago
- 143 views
Hello,
It's me again, even at the risk of annoying you all. After a year, I've started working on a wrapper for Raylib again. (Or rather, I've started programming again in general)
So far, I've been able to find a workaround/solution for everything. But now I'm stuck on something that is (in my opinion) relatively simple. More specifically, this:
constant xGetMouseWheelMove = define_c_func(ray,GetMouseWheelMove,{},C_FLOAT)
Under Phix64bit, calling the function returns incorrect values, but under Phix32bit it works. My goal is 64bit.(also because my workarounds/solutions for passing structures and receiving them as return values only work with 64-bit).
And, to be perfectly honest, I don't feel like making my code even more unreadable than it already is with if 32bit then do this else do that.
To make it easier to investigate and visualize the whole thing, I have built a test system.
A DLL:
// File: test_ffi.c
// compile with:- m32 for 32bit dll
//gcc -shared -m64 -o test_ffi64.dll test_ffi.c
//or
//gcc -shared -m64 -s -o test_ffi64.dll test_ffi.c -Wl,--out-implib,libtest_ffi.a
#include <windows.h>
// Funktioniert in GCC/MinGW
__attribute__((dllexport)) float GetTestFloat() {
return 123.456f;
}
__attribute__((dllexport)) float MultiplyFloats(float a, float b) {
return a * b;
}
And a test program:
sequence dll={"test_ffi64.dll","test_ffi32.dll"} atom result atom x=2.5,y=3.5 atom lib=open_dll(dll) constant GetTestFloat= define_c_func(lib,"GetTestFloat",{},C_FLOAT) constant MultiplyFloats=define_c_func(lib,"MultiplyFloats",{C_FLOAT,C_FLOAT},C_FLOAT) printf(1,"%d Bit %s\n",{machine_bits(),"System"}) result=c_func(GetTestFloat,{}) printf(1,"%f should be 123.456\n",result) result=c_func(MultiplyFloats,{x,y}) printf(1,"%f should be %f\n",{result,x*y}) wait_key()
As I said, it works with phix32 bit but not with phix64:
My working system is Windows11 64-bit Phix1.0.5
2. Re: Phix: float32 return value
- Posted by petelomax 6 days ago
- 137 views
- Last edited 5 days ago
Oh my, that is an absolutely perfect error report, can I just say well done and thankyou!
The fix itself is pretty straightforward, pcfunc.e ~line 2219 should end up as
cmp rdx,0x03000004 -- (C_FLOAT)
-- je :cstorexmm0
jne @f
sub rsp,8
movss dword[rsp],xmm0
fld dword[rsp]
jmp :cstorest0
@@:
cmp rdx,0x03000008 -- (C_DOUBLE)
jne @f
-- ::cstorexmm0
-- 14/2/16: (certainly C_DOUBLE, not necessarily C_FLOAT?) [25/2, I think it's the same]
sub rsp,8
movsd qword[rsp],xmm0
fld qword[rsp]
::cstorest0
add rsp,8
However, 1.0.5 does not implement movss, which needs, before making the above changes:
pttree.e line 1289:
global constant T_swi = 6060 tt_stringF("swi",T_swi)
global constant T_movss = 6068 tt_stringF("movss",T_movss)
pilasm.e line 4333:
-- elsif ttidx=T_movsd then
elsif ttidx=T_movsd
or ttidx=T_movss then
op = iff(ttidx=T_movsd?0o362:0o363)
and ten/twenty lines on:
-- s5 &= {0o362,0o017,0o020}
s5 &= {op,0o017,0o020}
-- s5 &= {0o362,0o017,0o021}
s5 &= {op,0o017,0o021}
You'll then need to run p -c p, then make the changes to pcfunc.e, then run p -c p again.
Actually, probably best if you just change pttree.e first and quickly check by running "p p"
whether you get anything like "movss should be 6068(not 6064)", if not kill it and carry on.
Finally, a quick "p -test" should reassure you nothing else got broken.
Thanks again, I would probably never have found or fixed that without your help.
3. Re: Phix: float32 return value
- Posted by andreasWagner 6 days ago
- 123 views
First of all, thank you for your quick reply.
Actually, probably best if you just change pttree.e first and quickly check by running "p p"
whether you get anything like "movss should be 6068(not 6064)", if not kill it and carry on.
okay, i end here:
D:\testpool\ray_workplace\Phix>p p
swi should be 5956(not 6060)
and its more like line 1271 not 1289 in pttree.e where the constants end.
Okay, I'll take another look tomorrow.
4. Re: Phix: float32 return value
- Posted by Icy_Viking 6 days ago
- 119 views
I do have a Raylib wrapper for Euphoria 4.1.0 Beta 2 [https://github.com/gAndy50/EuRayLib5]
It uses the FFI library to help with wrapping structs. It might help with making a Phix wrapper.
5. Re: Phix: float32 return value
- Posted by petelomax 5 days ago
- 111 views
First of all, thank you for your quick reply.
Actually, probably best if you just change pttree.e first and quickly check by running "p p"
whether you get anything like "movss should be 6068(not 6064)", if not kill it and carry on.
okay, i end here:
D:\testpool\ray_workplace\Phix>p p
swi should be 5956(not 6060)
and its more like line 1271 not 1289 in pttree.e where the constants end.
Okay, I'll take another look tomorrow.
Right, the improvements list for 1.0.6 is currently at 156 lines long, so my pttree.e is probably a bit mangled vs yours.
The intention was not to change T_swi (which should be the very last call to tt_stringF() in that file) but to "add 8" or
whatever it actually needs, so I'd take a (blind) stab at 5964 next. No biggie. If you really get stuck you'll have to wait
until 1.0.6 ships, but that's at least a few months off yet.
6. Re: Phix: float32 return value
- Posted by andreasWagner 5 days ago
- 105 views
Hallo,
Right, the improvements list for 1.0.6 is currently at 156 lines long, so my pttree.e is probably a bit mangled vs yours.
The intention was not to change T_swi (which should be the very last call to tt_stringF() in that file) but to "add 8" or
whatever it actually needs, so I'd take a (blind) stab at 5964 next. No biggie. If you really get stuck you'll have to wait
until 1.0.6 ships, but that's at least a few months off yet.
i did this, T_swi is not in pttree.e (from the 1.0.5 release):
pttree.e
begining with line 1271 this:
global constant T_swi = 5956 tt_stringF("swi",T_swi)
global constant T_movss = 5964 tt_stringF("movss",T_movss)
p p worked.
then this in pilasm.e (also from the 1.0.5 release):
pilasm.e
line 4337:
-- elsif ttidx=T_movsd then
elsif ttidx=T_movsd
or ttidx=T_movss then
op = iff(ttidx=T_movsd?0o362:0o363) -- 64-bit move (as per movsb, movsw, movsd)
line 4301: -- s5 &= {0o362,0o017,0o020}
s5 &= {op,0o017,0o020}
line 4311 -- s5 &= {0o362,0o017,0o021}
s5 &= {op,0o017,0o021}
p p now gives this.
D:\testpool\ray_workplace\Phix\pilasm.e:4338
elsif ttidx=T_movsd or ttidx=T_movss then op = iff(ttidx=T_movsd?..
^ duplicate case value [3364, il offset:2791]
I think your local copy of Phix is probably very different from the release version. But thanks for the quick response. It shows that Phix is still alive and being maintained.
Edit:I have found a temporary workaround. I have changed raylib; the return value is now int. That is sufficient for the two examples I have ported for phix and which use the function. Now I can continue until the next problems arise.
7. Re: Phix: float32 return value
- Posted by petelomax 4 days ago
- 77 views
My bad, I shd've gotten line nos from 1.0.5 srcs... maybe next time.
D:\testpool\ray_workplace\Phix\pilasm.e:4338
elsif ttidx=T_movsd or ttidx=T_movss then op = iff(ttidx=T_movsd?..
^ duplicate case value [3364, il offset:2791]
That error means it has converted the if to a switch (for performance reasons) but hit a snag in that
there are two (or more) branches for 3364 (T_movsd) - there is one on the-1.0.5-line 4291 (ie where I should have pointed you).
I'll have a think about making the error say "duplicate case value [3364 on lines 4338 and 4291]".
Edit:I have found a temporary workaround. the return value is now int.
C_DOUBLE instead of C_FLOAT return types would also be hassle-free (as long as the C code is returning a 64-bit float and not a 32-bit float), if that helps or you need the fractions.
Should you want to leave it as-is for now, I'm happy if you`re happy.
(undo if you can, but having non-compilable sources for the compiler itself lying around is not really going to hurt you, unless/until some other snag has no similar workaround)

