summaryrefslogtreecommitdiff
path: root/src/math
diff options
context:
space:
mode:
authorAlexander Monakov <amonakov@ispras.ru>2020-01-07 15:53:03 +0300
committerRich Felker <dalias@aerifal.cx>2020-03-24 16:31:36 -0400
commitacfe6d033eafe12d61ad91f496850b1bf58c6f98 (patch)
tree7c448f0aeee5bee6241b4ac291ce57ffb35db0ee /src/math
parent29adaeb2c0e795e75044a9b678b8cc66570f7e95 (diff)
downloadmusl-acfe6d033eafe12d61ad91f496850b1bf58c6f98.tar.gz
math: move i386 sqrt to C with inline asm
Diffstat (limited to 'src/math')
-rw-r--r--src/math/i386/sqrt.c15
-rw-r--r--src/math/i386/sqrt.s21
2 files changed, 15 insertions, 21 deletions
diff --git a/src/math/i386/sqrt.c b/src/math/i386/sqrt.c
new file mode 100644
index 00000000..934fbcca
--- /dev/null
+++ b/src/math/i386/sqrt.c
@@ -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
index 57837e25..00000000
--- a/src/math/i386/sqrt.s
+++ /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