[Rd] i386 floating point tweaking

Duncan Murdoch murdoch@stats.uwo.ca
Mon, 18 Nov 2002 13:33:23 -0500


On Mon, 18 Nov 2002 17:57:47 +0000, you wrote in message
<3DD92A1B.1020707@lancaster.ac.uk>:

>Just been trying to get the polygon triangulation code from this 
>package: http://www-2.cs.cmu.edu/~quake/triangle.html to dyn.load into 
>R. Uh oh. Floating point exceptions.
>
>Track it down to some FPU diddling that the author deems is necessary. 
>Here's my minimal code that breaks:
>
>flipme.c:
>
>#include <fpu_control.h>
>void flipme(){
>   int cword;
>   cword=4210;
>   _FPU_SETCW(cword);
>   printf("%f\n",sqrt(2.0));
>}
>
>  Compile with "R SHLIB flipme.c", then dyn.load and run:
>
> > dyn.load("flipme.so")
> > .C("flipme")
>
>Process R floating point exception at Mon Nov 18 17:41:50 2002

Dynamic code that changes the floating point word should change it
back when it returns.  R depends on it being correct.

The value you're using is hex 1072, which means among other things
that calculations should be done to 24 bit precision, and various
exceptions should not be masked.  This won't work for R, which assumes
full precision and masking of various things. The safe thing to do
would be to save the CW on entry to each of these routines, set it to
1072 for the duration, then on exit clear any pending exceptions, and
restore the R setting.

I don't know how to do that in C.  In assembler it would be

    fstcw   saved_cw

    do some stuff

    fclex
    fldcw   saved_cw

Duncan Murdoch