Mail Archives: djgpp-workers/1998/11/04/04:05:26
On Tue, 3 Nov 1998 Kbwms AT aol DOT com wrote:
> L10:
> fldl -8(%ebp)
> fsqrt
> fucom %st(0)
> fnstsw %ax
> andb $69,%ah
> cmpb $64,%ah
> je L11
> fstp %st(0)
> pushl -4(%ebp)
> pushl -8(%ebp)
> fstpt -32(%ebp)
> call _sqrt
> addl $8,%esp
> fldt -32(%ebp)
> fxch %st(1)
>
> I am not familiar with this brand of assembler code but, in the version of
> the assembler code that was optimized, it appears that the compiler checks
> the output of `fsqrt' and calls the library version of `sqrt' if something
> looks amiss.
Clever! What that code does is this:
1. Call FSQRT.
2. FUCOM compares ST with the operand, in this case ST(0) is
compared to itself. Depending on the result of FSQRT in
ST(0), this sets certain SW_Ci bits in the status word
(see below).
3. It then retrieves the FPU status word into AX and looks at
its high 8 bits.
4. AH is ANDed with 45h (69 decimal). This masks off any
bits but SW_C0, SW_C2 and SW_C3 (see the docs of
`_status87' in libc.inf).
5. Next, if only SW_C3 is set, meaning that ST(0) is equal to
itself, everything's okay and it accepts the result of
FSQRT.
6. If not, this means SW_C0 and SW_C2 are also set, which can
only happen if ST(0) cannot be compared with itself, which
in turn means ST(0) is either a NaN or an Infinity, and
the code then falls back to the library function.
This is all perfectly okay, except that if some of the exceptions are
not masked, sqrt(-1) should trigger an FP exception and crash the
program before all this cleverness has a chance to execute. v2.02
startup code masks all exceptions, but what if an application unmasks
some of them?
Can you modify this program to unmask exceptions (by a call to
`_control87') before the call to `sqrt', and see what happens?
If it does crash, I wonder if we should do anything about it. At
least some comment in the docs seems to be due.
- Raw text -