Skip to content

Commit

Permalink
math: Fix sqrt calc on IA32
Browse files Browse the repository at this point in the history
This change assumes that the `fsqrt` calculation is performed
for double precision FP and rounded to the nearest (even) value.
To achieve this, the FPU control word is set accordingly at
the sqrt computation time. All exceptions are enabled:
any underflow, overflow, /0, invalid precission, etc
during sqrt calculation will throw an exception.

JIRA: RTOS-562
  • Loading branch information
gerard5 committed Aug 19, 2023
1 parent bea8eb5 commit 71504c7
Showing 1 changed file with 12 additions and 16 deletions.
28 changes: 12 additions & 16 deletions include/arch/ia32/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,22 @@

static inline double __ieee754_sqrt(double x)
{
double result;
/* 0x27f means default rounding, use 53bit (double precision), all exceptions */
static const unsigned short newcw = 0x27f;
unsigned short savecw;

/* clang-format off */
__asm__ volatile ("fldl %1\n\t" /* put value */
"fsqrt\n\t" /* calc sqrt */
"fxtract\n\t" /* extract exponent */
"fisttp %0\n\t" /* round the exponent */
"fld %0\n\t" /* load the rounded exponent */
"fcomp\n\t" /* compare with the original exponent */
"fstsw %%ax\n\t" /* save FPU status to AX register */
"sahf\n\t" /* copy status to CPU flags */
"jp 1f\n\t" /* jump if the result was exact */
"fsubrp\n" /* adjust mantissa down */
"1:\n\t"
"fstpl %0" /* get the result */
: "=m"(result)
: "m"(x));
__asm__ volatile (
// "fclex\n\t" /* clear pending exceptions */
"fstcw %[savecw]\n\t" /* save control word */
"fldcw %[newcw]\n\t" /* set double precision */
"fsqrt\n\t" /* calculate double precision sqrt */
"fldcw %[savecw]" /* restore control word */
: "+t" (x)
: [newcw] "m" (newcw), [savecw] "m" (savecw));
/* clang-format on */

return result;
return x;
}

#endif
Expand Down

0 comments on commit 71504c7

Please sign in to comment.