Should we have a function to check if a float (frac?) is positive or negative infinity i.e. Num.isInfinite : Frac range -> Bool
? and while I'm at it Num.isNaN : Frac range -> Bool
?
» (1 / 0)
inf : Float * # val1
» (-1 / 0)
-inf : Float * # val2
I think so yeah!
(should be Frac
, not Float
- I think the repl needs to be updated)
That reminds me: for floats, should we have a builtin for distinguishing -0.0
and +0.0
? It’s probably not a very common use case, and it seems like a lot of languages don’t have it.
Rust has a few methods that can do this:
(-0.0).is_sign_negative() == true
(+0.0).is_sign_negative() == false
(-0.0).is_sign_positive() == false
(+0.0).is_sign_positive() == true
(-0.0).signum() == -1.0
(+0.0).signum() == +1.0
C has signbit()
, which returns -1
for -0.0
and +1
for +0.0
.
It should be possible to tell the difference yourself by checking whether you get positive or negative infinity when dividing by it:
isNegativeZero = \n -> n == 0.0 && 1.0 / n < 0
I'd say no by default...if there's specific demand for it later, we can revisit
I am working on the gen_dev backend implementation for this, and I'm struggling to find examples in the code for casting a float to an int.
I have some idea of what the instructions should look like (https://godbolt.org/z/se8EsTGhr), is this the first time this is needed and I need to build the abstraction for it?
we should have function to move a float to the stack , and then to read that memory as an integer from the stack
stack_offset_and_size
is probably the magic function
hm, I think we'd need more than that, right?
like if you have 8 bytes organized as an F64
, the integer portion of those bytes will not be laid out the same way as (for example) an I64
would be laid out
Yeah, we will need the proper functions that do conversion if we don't have them (don't recall at this point).
So not just data movement but also type conversion
Looks like we have to_float
, but I don't see the reverse yet
Yeah I think I need to use movss and movsd (for x86) to properly move the bytes between float and int. That first godbolt example used the stack to do that, but maybe we can do it without?
Wait, are you trying to get the exact bytes moved or convert to an int?
Looking at to_float
I don't think I want to convert like it is done there. I need the raw bits in order to bitwise AND it with a constant
Oh, then i think we have all the move instructions you might need for that
...hmmm...actually not quite. We have enough that you can do it if you dump it to the stack and then load it. We don't have the direct movement between general and float regs
I couldn't find the right one, but maybe I just missed it? There are a few to move between stack and freg, but it should be possible to skip the stack I think.
Here is a more full-fledged set of instructions I'm looking to generate: https://godbolt.org/z/cf4znYE68
Would be mov_reg64_freg64
. You can add it if you want.
Would be the best answer here
We just haven't added it yet
Alright, I'll try to add it! :sweat_smile:
I just added a movss/movsd from a pointer into a float register
as in, it's on a branch that I'm working on right now
because we did not implement that correctly, and LIst.get
on a list of floats would just use the last float that the program stored in that register
it did not look at the pointer at all, even
Oh nice! And it need to be a pointer? I don't fully understand how to control the storage associated with a symbol just yet. I have implemented isNaN already, but I have just been assuming they're already in a register. It seems to work
Oh, and what's your workflow to test aarch64 when you're running x86? Do we have guides on how to run the test suites in qemu?
I suspect you actually want the movd
instruction from that example?
that would be a more direct solution, anyway
I mostly ignore aarch
for the time being, my work is usually on a slightly higher level. when the dev backend is fully functional on x86 linux we can (hopefully) quickly fill in the final translation to assembly
I have just been assuming they're already in a register
You probably start by calling something like load_to_general_reg
or load_to_float_reg
. That deals with the storage for you.
Oh yes I did do that :sweat_smile:
Folkert de Vries said:
I suspect you actually want the
movd
instruction from that example?
So I should add an abstraction for it in ASM? I don't think we generate movd
movq
at the moment
yes that needs some custom "putting the bytes in the right order"
Last updated: Jul 06 2025 at 12:14 UTC