Recently, I've been thinking about floating point trap issues in
general, and on the PPC in particular.
When I went to see what sbcl did about this, I found the answer was
;; FIXME: This apparently doesn't work on Darwin
#!-darwin (setf (floating-point-modes) modes))
After much head scratching, I think I've got things working, thus
fixing BUG 372 -- on my system (a G3 ibook2 running Panther), at
There were a few broad problems:
1) The MSR. On the PPC you need to set a couple of bits in the
Machine State Register before floating point exceptions are enabled
at all, and accessing the MSR is privileged operation. This
doesn't appear to be an issue on Panther, as the OS seems to set
these bits when you set a handler for SIGFPE. It's also not *that*
hard to get the bits set ourselves, though it involves jumping
through some hoops.
2) Startup. For reasons I haven't even tried to understand, a random
selection of exception bits seem to be set on application startup,
which means that the call to set-floating-point-modes in !cold-init
just crashes out (because the sigfpe-handler tries to call
cl:error, and it's too early for that). This is easy to fix (clear
the bits before setting the traps), except...
3) The Invalid Operation 'bit'. SBCL assumes that each IEEE 754
exception corresponds to a single bit in the floating point control
word, and this just isn't true on the PPC for the Invalid Operation
exception -- in fact there are five different bits in the FPSCR
that each mean a different kind of Invalid Operation. There is a
'summary' bit that's set if any Invalid Operation bit is set, but
you cannot affect it directly, only by clearing each particular bit
I haven't done anything about this in the attached patch, I just
don't set the :invalid-operation trap. I guess that asking
set-floating-point-modes to clear the :invalid-operation exception
should clear all the VX bits, asking it to set the exception should
set VXSOFT and asking if an exception is set should test the
(This should also be an issue on linux-ppc, afaict).
4) The thing that caused the most confusion to me is that behaviour
changes wildly depending on whether the SIGFPE handler returns
normally or not. If it returns normally, the execution environment
described by the third argument to the handler (which you can
mutate to your heart's content) replaces the environment of the
handler but if you make a non-normal exit (either longjmp in C or
cl:error) this doesn't happen. In addition, if you jump out, the
handler for SIGFPE is lost (though resetting it by hand works
5) I had to implement os_context_fp_control for Darwin (easy peasy).
6) You need to clear the exception occurred bits of the FPSCR before
leaving the handler or you just end up back in the handler
immediately (this could be an issue on linux-ppc too).
Anyway, patch attached. It should most certainly be tested on a G5
and on Tiger before going anywhere near CVS (I wouldn't be surprised
if point 4 was Panther-specific, it certainly doesn't seem the sort of
thing someone would do deliberately).
I'm so happy that Apple are switching to x86, now I know so much about
For their next act, they'll no doubt be buying a firewall
running under NT, which makes about as much sense as
building a prison out of meringue. -- -:Tanuki:-