Re: Floating point exceptions: how to mask & set to zero w/ no error

ulmo@q.net
Sat, 13 Apr 1996 13:19:03 -0400


Malcolm,

Thank you very much! I hadn't realized it was so easy. I did as you
suggested exactly (I include a patch below) and it now works perfectly
(as perfectly as LPC works with all its clipping, but at least I can
test it with my friend in Windows :) )

John,

Thanks very much for your great program! I can't wait until a few
people port it to Amiga & Mac and there is true interoperability ...
and I love the fact that you have been doing standards protocol
support since then the whole concept really does come together with
all the available software finally.

As you can see, Malcolm answered my question about how to set
the FPU as you suggest.

Thanks again, Bradley Allen <Ulmo@Q.Net>

In message <199604120758.IAA15166@sable.ox.ac.uk>, Malcolm Beattie writes:
>ulmo@q.net writes:
>>
>> Excuse my Unix & floating point ignorance please, but I'd like to
>> generate some form of compatability with Speak Free (see
>> ftp://ftp.fourmilab.ch/pub/kelvin/speakfree/unix/prior-releases/p/sf61a2.tar.gz
>> ), the main author John Walker <kelvin@fourmilab.ch> said:
>>
>> > If the original PARC LPC code (which remains in the program,
>> > as it is a standard VAT and RTP compression mode) is generating
>> > floating point errors, this indicates that your system is not
>> > masking floating point exceptions and handling them by default.
>> > The LPC code routinely generates floating underflows, which the
>> > FPU should set to zero with no error indication.
>
>Do
> #include <fpu_control.h>
>and then
> __setfpucw(_FPU_IEEE);
>
>You guessed right that the default setting (with your kernel) is set
>up to generate exceptions on underflow (and a few other things).
>Setting the FPU control word to IEEE behaviour as shown above will
>mask those exceptions as you wanted. Somewhere in the 1.3.x kernel
>series, the default (for i386 but not m68k, it seems) changed to IEEE
>behaviour anyway, so you may want to remove the explicit setting when
>you upgrade. If you want more fine-grained control, see
><i386/fpu_control.h> (or <m68k/fpu_control.h> but I doubt you're
>using that ;-) for gory details.

Perhaps it's a C library thing? I run the latest kernel; I have libc
5.0.9, and the default isn't as you describe. Perhaps the patch
should check for this ... I'm not quite sure where the libc version is
stored.

I really ought to peg down a newer stable libc to install on my system ...

<ulmo@q.net>

>
>--Malcolm
>
>--
>Malcolm Beattie <mbeattie@sable.ox.ac.uk>
>Unix Systems Programmer
>Oxford University Computing Services

diff -Nru speak_freely-6.1.orig/lpc/lpc.c speak_freely-6.1/lpc/lpc.c
--- speak_freely-6.1.orig/lpc/lpc.c Thu Feb 29 14:29:46 1996
+++ speak_freely-6.1/lpc/lpc.c Sat Apr 13 13:14:19 1996
@@ -2,6 +2,9 @@
#include <math.h>
#include <sys/types.h>
#include <netinet/in.h>
+#ifdef LINUX
+#include <fpu_control.h>
+#endif LINUX

#include "lpc.h"
#include "../ulaw2linear.h"
@@ -203,6 +206,21 @@
}
}
#endif
+
+#ifdef LINUX
+ /* Thanks to Malcolm Beattie <mbeattie@sable.ox.ac.uk>
+ (Also the #include <fpu_control.h> above)
+ He notes that later versions (apparently of libc)
+ do this by default, I think someplace in 5.2 (I was
+ reading the ChangeLog.6 that ended with 5.2.16 and it had
+ hopeful looking remarks, including one for the m68k);
+ it should eventually be determined which libc has it right first
+ and then test for that, with a comment to remove this test
+ a few years in the future (after everyone is done upgrading
+ to the new libc(s) coupled with the new Linux 2.0 stable
+ kernel, which will be a few years) <ulmo@q.net> 1996-April-13 */
+ __setfpucw(_FPU_IEEE);
+#endif /* LINUX */

for (i = 0; i < BUFLEN; i++) {
s[i] = 0.0;
--end of patch--