math: move i386 sqrt to C with inline asm
authorAlexander Monakov <amonakov@ispras.ru>
Tue, 7 Jan 2020 12:53:03 +0000 (15:53 +0300)
committerRich Felker <dalias@aerifal.cx>
Tue, 24 Mar 2020 20:31:36 +0000 (16:31 -0400)
src/math/i386/sqrt.c [new file with mode: 0644]
src/math/i386/sqrt.s [deleted file]

diff --git a/src/math/i386/sqrt.c b/src/math/i386/sqrt.c
new file mode 100644 (file)
index 0000000..934fbcc
--- /dev/null
@@ -0,0 +1,15 @@
+#include "libm.h"
+
+double sqrt(double x)
+{
+       union ldshape ux;
+       unsigned fpsr;
+       __asm__ ("fsqrt; fnstsw %%ax": "=t"(ux.f), "=a"(fpsr) : "0"(x));
+       if ((ux.i.m & 0x7ff) != 0x400)
+               return (double)ux.f;
+       /* Rounding to double would have encountered an exact halfway case.
+          Adjust mantissa downwards if fsqrt rounded up, else upwards.
+          (result of fsqrt could not have been exact) */
+       ux.i.m ^= (fpsr & 0x200) + 0x300;
+       return (double)ux.f;
+}
diff --git a/src/math/i386/sqrt.s b/src/math/i386/sqrt.s
deleted file mode 100644 (file)
index 57837e2..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-.global sqrt
-.type sqrt,@function
-sqrt:  fldl 4(%esp)
-       fsqrt
-       fnstsw %ax
-       sub $12,%esp
-       fld %st(0)
-       fstpt (%esp)
-       mov (%esp),%ecx
-       and $0x7ff,%ecx
-       cmp $0x400,%ecx
-       jnz 1f
-       and $0x200,%eax
-       sub $0x100,%eax
-       sub %eax,(%esp)
-       fstp %st(0)
-       fldt (%esp)
-1:     add $12,%esp
-       fstpl 4(%esp)
-       fldl 4(%esp)
-       ret