summaryrefslogtreecommitdiff
path: root/sysdeps/libm-i387
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/libm-i387')
-rw-r--r--sysdeps/libm-i387/s_exp2.S38
-rw-r--r--sysdeps/libm-i387/s_exp2f.S38
-rw-r--r--sysdeps/libm-i387/s_exp2l.S38
-rw-r--r--sysdeps/libm-i387/s_log2.S59
-rw-r--r--sysdeps/libm-i387/s_log2f.S59
-rw-r--r--sysdeps/libm-i387/s_log2l.S59
6 files changed, 291 insertions, 0 deletions
diff --git a/sysdeps/libm-i387/s_exp2.S b/sysdeps/libm-i387/s_exp2.S
new file mode 100644
index 0000000000..1afacf58cd
--- /dev/null
+++ b/sysdeps/libm-i387/s_exp2.S
@@ -0,0 +1,38 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__exp2)
+ fldl 4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fld %st
+ frndint /* int(x) */
+ fsubr %st,%st(1) /* fract(x) */
+ fxch
+ f2xm1 /* 2^(fract(x)) - 1 */
+ fld1
+ faddp /* 2^(fract(x)) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__exp2)
+weak_alias (__exp2, exp2)
diff --git a/sysdeps/libm-i387/s_exp2f.S b/sysdeps/libm-i387/s_exp2f.S
new file mode 100644
index 0000000000..896583bf83
--- /dev/null
+++ b/sysdeps/libm-i387/s_exp2f.S
@@ -0,0 +1,38 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__exp2f)
+ flds 4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fld %st
+ frndint /* int(x) */
+ fsubr %st,%st(1) /* fract(x) */
+ fxch
+ f2xm1 /* 2^(fract(x)) - 1 */
+ fld1
+ faddp /* 2^(fract(x)) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__exp2f)
+weak_alias (__exp2f, exp2f)
diff --git a/sysdeps/libm-i387/s_exp2l.S b/sysdeps/libm-i387/s_exp2l.S
new file mode 100644
index 0000000000..4b543d06f8
--- /dev/null
+++ b/sysdeps/libm-i387/s_exp2l.S
@@ -0,0 +1,38 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+ENTRY(__exp2l)
+ fldt 4(%esp)
+/* I added the following ugly construct because exp(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ fxam /* Is NaN or +-Inf? */
+ fstsw %ax
+ movb $0x45, %dh
+ andb %ah, %dh
+ cmpb $0x05, %dh
+ je 1f /* Is +-Inf, jump. */
+ fld %st
+ frndint /* int(x) */
+ fsubr %st,%st(1) /* fract(x) */
+ fxch
+ f2xm1 /* 2^(fract(x)) - 1 */
+ fld1
+ faddp /* 2^(fract(x)) */
+ fscale /* e^x */
+ fstp %st(1)
+ ret
+
+1: testl $0x200, %eax /* Test sign. */
+ jz 2f /* If positive, jump. */
+ fstp %st
+ fldz /* Set result to 0. */
+2: ret
+END (__exp2l)
+weak_alias (__exp2l, exp2l)
diff --git a/sysdeps/libm-i387/s_log2.S b/sysdeps/libm-i387/s_log2.S
new file mode 100644
index 0000000000..4632c96f67
--- /dev/null
+++ b/sysdeps/libm-i387/s_log2.S
@@ -0,0 +1,59 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__log2)
+#ifdef PIC
+ call 1f
+1: popl %edx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+ fldl MO(one)
+ fldl 4(%esp) // x : 1
+ fld %st // x : x : 1
+ fsub %st(2), %st // x-1 : x : 1
+ fld %st // x-1 : x-1 : x : 1
+ fabs // |x-1| : x-1 : x : 1
+ fcompl MO(limit) // x-1 : x : 1
+ fnstsw // x-1 : x : 1
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : 1
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : 1
+ fyl2x // log(x)
+ ret
+END (__log2)
+weak_alias (__log2, log2)
diff --git a/sysdeps/libm-i387/s_log2f.S b/sysdeps/libm-i387/s_log2f.S
new file mode 100644
index 0000000000..bfdd0ef88e
--- /dev/null
+++ b/sysdeps/libm-i387/s_log2f.S
@@ -0,0 +1,59 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__log2f)
+#ifdef PIC
+ call 1f
+1: popl %edx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+ fldl MO(one)
+ flds 4(%esp) // x : 1
+ fld %st // x : x : 1
+ fsub %st(2), %st // x-1 : x : 1
+ fld %st // x-1 : x-1 : x : 1
+ fabs // |x-1| : x-1 : x : 1
+ fcompl MO(limit) // x-1 : x : 1
+ fnstsw // x-1 : x : 1
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : 1
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : 1
+ fyl2x // log(x)
+ ret
+END (__log2f)
+weak_alias (__log2f, log2f)
diff --git a/sysdeps/libm-i387/s_log2l.S b/sysdeps/libm-i387/s_log2l.S
new file mode 100644
index 0000000000..184981c4bb
--- /dev/null
+++ b/sysdeps/libm-i387/s_log2l.S
@@ -0,0 +1,59 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
+ * Public domain.
+ *
+ * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
+ */
+
+#include <machine/asm.h>
+
+#ifdef __ELF__
+ .section .rodata
+#else
+ .text
+#endif
+ .align ALIGNARG(4)
+ ASM_TYPE_DIRECTIVE(one,@object)
+one: .double 1.0
+ ASM_SIZE_DIRECTIVE(one)
+ /* It is not important that this constant is precise. It is only
+ a value which is known to be on the safe side for using the
+ fyl2xp1 instruction. */
+ ASM_TYPE_DIRECTIVE(limit,@object)
+limit: .double 0.29
+ ASM_SIZE_DIRECTIVE(limit)
+
+
+#ifdef PIC
+#define MO(op) op##@GOTOFF(%edx)
+#else
+#define MO(op) op
+#endif
+
+ .text
+ENTRY(__log2l)
+#ifdef PIC
+ call 1f
+1: popl %edx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
+#endif
+ fldl MO(one)
+ fldt 4(%esp) // x : 1
+ fld %st // x : x : 1
+ fsub %st(2), %st // x-1 : x : 1
+ fld %st // x-1 : x-1 : x : 1
+ fabs // |x-1| : x-1 : x : 1
+ fcompl MO(limit) // x-1 : x : 1
+ fnstsw // x-1 : x : 1
+ andb $0x45, %ah
+ jz 2f
+ fstp %st(1) // x-1 : 1
+ fyl2xp1 // log(x)
+ ret
+
+2: fstp %st(0) // x : 1
+ fyl2x // log(x)
+ ret
+END (__log2l)
+weak_alias (__log2l, log2l)