Snapshot that requires a check in the Mu compiler.
Currently I don't spill a register if it could possibly be over-written
by a function output within. However, find-in-call-path is a good example
of where this constraint is too lenient and results in unsafe code. The
variable `curr` gets clobbered during loop update by the variable `match?`.
What's the answer? Perhaps we should ban all conditional updates to function
outputs? That'd be dashed inconvenient.
The final fix to the raytracing program involves rounding modes. It turns
out x86 processors round floats by default, unlike C which has trained
me to expect truncation. Rather than mess with the MXCSR register, I added
another instruction for truncation. Now milestone 3 emits perfectly correct
results.
The image is now visually indistinguishable from the baseline, though the
file isn't quite bit-for-bit correct.
I found 3 bugs:
a) I forgot to normalize the ray. After creating a helper to "automatically"
do it for me, it turns out said helper requires manually using.
b) I forgot to multiply by t at one place.
c) vec3-length was half-written.
For the umpteenth time, the bugs were all in the last place I looked. I
was worried about spending a lot of time transcribing `main` without any
feedback, but that turned out to be perfect.
Not yet right, but worth a snapshot just because it gives a cool result.
Here, try it out:
$ ./translate_mu_debug apps/raytracing/3.mu
$ ./a.elf > x.ppm
Now view x.ppm as an image.
In general, this was quite tedious to write. And a still-open question
is how to emit the progress bar to stderr. My options are to either duplicate
all my print-* functions (already proliferating) or add global variables
to Mu.
Move some implementation around for floating-point.
I originally thought I wouldn't bother supporting sigils like %xmm0. But
it turns out I need them to pass floats into SubX function calls. And it
turns out the sigils work fine for free.
For most of Mu's history we've selected between primitives based on types
just by checking whether a type is a literal or not. Now we've started
checking if it's a float as well. However, floats need one additional check:
the call site may have an (addr float) that is dereferenced.