diff options
Diffstat (limited to 'sysdeps/libm-i387')
-rw-r--r-- | sysdeps/libm-i387/e_exp.S | 21 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_expf.S | 19 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_expl.S | 19 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_log.S | 2 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_log10.S | 2 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_log10f.S | 2 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_log10l.S | 2 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_logf.S | 2 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_logl.S | 2 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_pow.S | 120 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_powf.S | 120 | ||||
-rw-r--r-- | sysdeps/libm-i387/e_powl.S | 120 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_asinh.S | 2 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_asinhf.S | 2 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_asinhl.S | 2 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_ceil.S | 20 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_ceilf.S | 20 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_ceill.S | 20 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_expm1.S | 83 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_expm1f.S | 83 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_expm1l.S | 83 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_floor.S | 26 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_floorf.S | 26 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_floorl.S | 26 | ||||
-rw-r--r-- | sysdeps/libm-i387/s_significandl.S | 2 |
25 files changed, 716 insertions, 110 deletions
diff --git a/sysdeps/libm-i387/e_exp.S b/sysdeps/libm-i387/e_exp.S index 4505ebd309..3c9d45b746 100644 --- a/sysdeps/libm-i387/e_exp.S +++ b/sysdeps/libm-i387/e_exp.S @@ -5,7 +5,7 @@ #include <machine/asm.h> -RCSID("$NetBSD: e_exp.S,v 1.4 1995/05/08 23:47:04 jtc Exp $") +RCSID("$NetBSD: e_exp.S,v 1.7 1996/07/03 17:31:28 jtc Exp $") /* e^x = 2^(x * log2(e)) */ ENTRY(__ieee754_exp) @@ -16,16 +16,16 @@ ENTRY(__ieee754_exp) -- drepper@cygnus.com. */ fxam /* Is NaN or +-Inf? */ fstsw %ax - sahf - jnc .LnoInfNaN /* No, jump. */ - jp .LisInf /* Is +-Inf, jump. */ -.LnoInfNaN: + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 1f /* Is +-Inf, jump. */ fldl2e fmulp /* x * log2(e) */ fstl %st(1) frndint /* int(x * log2(e)) */ - fstl %st(2) - fsubrp /* fract(x * log2(e)) */ + fsub %st,%st(1) /* fract(x * log2(e)) */ + fxch f2xm1 /* 2^(fract(x * log2(e))) - 1 */ fld1 faddp /* 2^(fract(x * log2(e))) */ @@ -33,9 +33,8 @@ ENTRY(__ieee754_exp) fstp %st(1) ret -.LisInf: - andb $2, %ah /* Test sign. */ - jz .LpInf /* If positive, jump. */ +1: testl $0x200, %eax /* Test sign. */ + jz 2f /* If positive, jump. */ fldz /* Set result to 0. */ -.LpInf: ret +2: ret END (__ieee754_exp) diff --git a/sysdeps/libm-i387/e_expf.S b/sysdeps/libm-i387/e_expf.S index c8233eba50..cd8dc7f0b9 100644 --- a/sysdeps/libm-i387/e_expf.S +++ b/sysdeps/libm-i387/e_expf.S @@ -17,16 +17,16 @@ ENTRY(__ieee754_expf) -- drepper@cygnus.com. */ fxam /* Is NaN or +-Inf? */ fstsw %ax - sahf - jnc .LnoInfNaN /* No, jump. */ - jp .LisInf /* Is +-Inf, jump. */ -.LnoInfNaN: + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 1f /* Is +-Inf, jump. */ fldl2e fmulp /* x * log2(e) */ fstl %st(1) frndint /* int(x * log2(e)) */ - fstl %st(2) - fsubrp /* fract(x * log2(e)) */ + fsub %st,%st(1) /* fract(x * log2(e)) */ + fxch f2xm1 /* 2^(fract(x * log2(e))) - 1 */ fld1 faddp /* 2^(fract(x * log2(e))) */ @@ -34,9 +34,8 @@ ENTRY(__ieee754_expf) fstp %st(1) ret -.LisInf: - andb $2, %ah /* Test sign. */ - jz .LpInf /* If positive, jump. */ +1: testl $0x200, %eax /* Test sign. */ + jz 2f /* If positive, jump. */ fldz /* Set result to 0. */ -.LpInf: ret +2: ret END (__ieee754_expf) diff --git a/sysdeps/libm-i387/e_expl.S b/sysdeps/libm-i387/e_expl.S index 9103a923aa..e398a90ef6 100644 --- a/sysdeps/libm-i387/e_expl.S +++ b/sysdeps/libm-i387/e_expl.S @@ -18,16 +18,16 @@ ENTRY(__ieee754_expl) -- drepper@cygnus.com. */ fxam /* Is NaN or +-Inf? */ fstsw %ax - sahf - jnc .LnoInfNaN /* No, jump. */ - jp .LisInf /* Is +-Inf, jump. */ -.LnoInfNaN: + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 1f /* Is +-Inf, jump. */ fldl2e fmulp /* x * log2(e) */ fstl %st(1) frndint /* int(x * log2(e)) */ - fstl %st(2) - fsubrp /* fract(x * log2(e)) */ + fsub %st,%st(1) /* fract(x * log2(e)) */ + fxch f2xm1 /* 2^(fract(x * log2(e))) - 1 */ fld1 faddp /* 2^(fract(x * log2(e))) */ @@ -35,9 +35,8 @@ ENTRY(__ieee754_expl) fstp %st(1) ret -.LisInf: - andb $2, %ah /* Test sign. */ - jz .LpInf /* If positive, jump. */ +1: testl $0x200, %eax /* Test sign. */ + jz 2f /* If positive, jump. */ fldz /* Set result to 0. */ -.LpInf: ret +2: ret END (__ieee754_expl) diff --git a/sysdeps/libm-i387/e_log.S b/sysdeps/libm-i387/e_log.S index 43d430332c..e7f567d950 100644 --- a/sysdeps/libm-i387/e_log.S +++ b/sysdeps/libm-i387/e_log.S @@ -53,7 +53,7 @@ ENTRY(__ieee754_log) fyl2xp1 // log(x) ret -2: fincstp // x : log(2) +2: fstp %st(0) // x : log(2) fyl2x // log(x) ret END (__ieee754_log) diff --git a/sysdeps/libm-i387/e_log10.S b/sysdeps/libm-i387/e_log10.S index 95efc8f7a2..ecb691b905 100644 --- a/sysdeps/libm-i387/e_log10.S +++ b/sysdeps/libm-i387/e_log10.S @@ -53,7 +53,7 @@ ENTRY(__ieee754_log10) fyl2xp1 // log10(x) ret -2: fincstp // x : log10(2) +2: fstp %st(0) // x : log10(2) fyl2x // log10(x) ret END (__ieee754_log10) diff --git a/sysdeps/libm-i387/e_log10f.S b/sysdeps/libm-i387/e_log10f.S index bddb5011bc..aac58d0293 100644 --- a/sysdeps/libm-i387/e_log10f.S +++ b/sysdeps/libm-i387/e_log10f.S @@ -54,7 +54,7 @@ ENTRY(__ieee754_log10f) fyl2xp1 // log10(x) ret -2: fincstp // x : log10(2) +2: fstp %st(0) // x : log10(2) fyl2x // log10(x) ret END (__ieee754_log10f) diff --git a/sysdeps/libm-i387/e_log10l.S b/sysdeps/libm-i387/e_log10l.S index f0b8f325a7..4f51818bdd 100644 --- a/sysdeps/libm-i387/e_log10l.S +++ b/sysdeps/libm-i387/e_log10l.S @@ -55,7 +55,7 @@ ENTRY(__ieee754_log10l) fyl2xp1 // log10(x) ret -2: fincstp // x : log10(2) +2: fstp %st(0) // x : log10(2) fyl2x // log10(x) ret END(__ieee754_log10l) diff --git a/sysdeps/libm-i387/e_logf.S b/sysdeps/libm-i387/e_logf.S index b79f478cdf..4459b7fc08 100644 --- a/sysdeps/libm-i387/e_logf.S +++ b/sysdeps/libm-i387/e_logf.S @@ -54,7 +54,7 @@ ENTRY(__ieee754_logf) fyl2xp1 // log(x) ret -2: fincstp // x : log(2) +2: fstp %st(0) // x : log(2) fyl2x // log(x) ret END (__ieee754_logf) diff --git a/sysdeps/libm-i387/e_logl.S b/sysdeps/libm-i387/e_logl.S index 1657dfd5fb..08447a27e7 100644 --- a/sysdeps/libm-i387/e_logl.S +++ b/sysdeps/libm-i387/e_logl.S @@ -54,7 +54,7 @@ ENTRY(__ieee754_logl) fyl2xp1 // log(x) ret -2: fincstp // x : log(2) +2: fstp %st(0) // x : log(2) fyl2x // log(x) ret END (__ieee754_logl) diff --git a/sysdeps/libm-i387/e_pow.S b/sysdeps/libm-i387/e_pow.S new file mode 100644 index 0000000000..f6c7562d9c --- /dev/null +++ b/sysdeps/libm-i387/e_pow.S @@ -0,0 +1,120 @@ +/* ix87 specific implementation of pow function. + Copyright (C) 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#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) + ASM_TYPE_DIRECTIVE(limit,@object) +limit: .double 0.29 + ASM_SIZE_DIRECTIVE(limit) + +#ifdef PIC +#define MO(op) op##@GOTOFF(%ecx) +#else +#define MO(op) op +#endif + + .text +ENTRY(__ieee754_pow) + fldl 4(%esp) // x + fldl 12(%esp) // y : x + +#ifdef PIC + call 1f +1: popl %ecx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx +#endif + subl $8,%esp + + /* First see whether `y' is a natural number. In this case we + can use a more precise algorithm. */ + fld %st // y : y : x + fistpll (%esp) // y : x + fildll (%esp) // int(y) : y : x + fucomp %st(1) // y : x + fnstsw + sahf + jne 2f + + /* OK, we have an integer value for y. */ + ftst // y : x + fstp %st(0) // x + fnstsw + sahf + popl %eax + popl %edx + jnc 4f // y >= 0, jump + fdivrl MO(one) // 1/x (now referred to as x) + negl %eax + adcl $0, %edx + negl %edx +4: fldl MO(one) // 1 : x + fxch + +6: shrdl $1, %edx, %eax + jnc 5f + fxch + fmul %st(1) // x : ST*x + fxch +5: fmul %st(0), %st // x*x : ST*x + movl %eax, %ecx + orl %edx, %ecx + jnz 6b + fstp %st(0) // ST*x + ret + + .align ALIGNARG(4) +2: /* y is a real number. */ + fxch // x : y + fldl MO(one) // 1.0 : x : y + fld %st(1) // x : 1.0 : x : y + fsub %st(1) // x-1 : 1.0 : x : y + fabs // |x-1| : 1.0 : x : y + fcompl MO(limit) // 1.0 : x : y + fnstsw + fxch // x : 1.0 : y + sahf + ja 7f + fsub %st(1) // x-1 : 1.0 : y + fyl2xp1 // log2(x) : y + jmp 8f + +7: fyl2x // log2(x) : y +8: fmul %st(1) // y*log2(x) : y + fst %st(1) // y*log2(x) : y*log2(x) + frndint // int(y*log2(x)) : y*log2(x) + fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x)) + fxch // fract(y*log2(x)) : int(y*log2(x)) + f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x)) + faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x)) + fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x)) + addl $8, %esp + fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x)) + ret +END(__ieee754_pow) diff --git a/sysdeps/libm-i387/e_powf.S b/sysdeps/libm-i387/e_powf.S new file mode 100644 index 0000000000..9d6bc510b6 --- /dev/null +++ b/sysdeps/libm-i387/e_powf.S @@ -0,0 +1,120 @@ +/* ix87 specific implementation of pow function. + Copyright (C) 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#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) + ASM_TYPE_DIRECTIVE(limit,@object) +limit: .double 0.29 + ASM_SIZE_DIRECTIVE(limit) + +#ifdef PIC +#define MO(op) op##@GOTOFF(%ecx) +#else +#define MO(op) op +#endif + + .text +ENTRY(__ieee754_powf) + flds 4(%esp) // x + flds 8(%esp) // y : x + +#ifdef PIC + call 1f +1: popl %ecx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx +#endif + subl $8,%esp + + /* First see whether `y' is a natural number. In this case we + can use a more precise algorithm. */ + fld %st // y : y : x + fistpll (%esp) // y : x + fildll (%esp) // int(y) : y : x + fucomp %st(1) // y : x + fnstsw + sahf + jne 2f + + /* OK, we have an integer value for y. */ + ftst // y : x + fstp %st(0) // x + fnstsw + sahf + popl %eax + popl %edx + jnc 4f // y >= 0, jump + fdivrl MO(one) // 1/x (now referred to as x) + negl %eax + adcl $0, %edx + negl %edx +4: fldl MO(one) // 1 : x + fxch + +6: shrdl $1, %edx, %eax + jnc 5f + fxch + fmul %st(1) // x : ST*x + fxch +5: fmul %st(0), %st // x*x : ST*x + movl %eax, %ecx + orl %edx, %ecx + jnz 6b + fstp %st(0) // ST*x + ret + + .align ALIGNARG(4) +2: /* y is a real number. */ + fxch // x : y + fldl MO(one) // 1.0 : x : y + fld %st(1) // x : 1.0 : x : y + fsub %st(1) // x-1 : 1.0 : x : y + fabs // |x-1| : 1.0 : x : y + fcompl MO(limit) // 1.0 : x : y + fnstsw + fxch // x : 1.0 : y + sahf + ja 7f + fsub %st(1) // x-1 : 1.0 : y + fyl2xp1 // log2(x) : y + jmp 8f + +7: fyl2x // log2(x) : y +8: fmul %st(1) // y*log2(x) : y + fst %st(1) // y*log2(x) : y*log2(x) + frndint // int(y*log2(x)) : y*log2(x) + fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x)) + fxch // fract(y*log2(x)) : int(y*log2(x)) + f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x)) + faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x)) + fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x)) + addl $8, %esp + fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x)) + ret +END(__ieee754_powf) diff --git a/sysdeps/libm-i387/e_powl.S b/sysdeps/libm-i387/e_powl.S new file mode 100644 index 0000000000..ea445804f0 --- /dev/null +++ b/sysdeps/libm-i387/e_powl.S @@ -0,0 +1,120 @@ +/* ix87 specific implementation of pow function. + Copyright (C) 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#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) + ASM_TYPE_DIRECTIVE(limit,@object) +limit: .double 0.29 + ASM_SIZE_DIRECTIVE(limit) + +#ifdef PIC +#define MO(op) op##@GOTOFF(%ecx) +#else +#define MO(op) op +#endif + + .text +ENTRY(__ieee754_powl) + fldt 4(%esp) // x + fldt 16(%esp) // y : x + +#ifdef PIC + call 1f +1: popl %ecx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx +#endif + subl $8,%esp + + /* First see whether `y' is a natural number. In this case we + can use a more precise algorithm. */ + fld %st // y : y : x + fistpll (%esp) // y : x + fildll (%esp) // int(y) : y : x + fucomp %st(1) // y : x + fnstsw + sahf + jne 2f + + /* OK, we have an integer value for y. */ + ftst // y : x + fstp %st(0) // x + fnstsw + sahf + popl %eax + popl %edx + jnc 4f // y >= 0, jump + fdivrl MO(one) // 1/x (now referred to as x) + negl %eax + adcl $0, %edx + negl %edx +4: fldl MO(one) // 1 : x + fxch + +6: shrdl $1, %edx, %eax + jnc 5f + fxch + fmul %st(1) // x : ST*x + fxch +5: fmul %st(0), %st // x*x : ST*x + movl %eax, %ecx + orl %edx, %ecx + jnz 6b + fstp %st(0) // ST*x + ret + + .align ALIGNARG(4) +2: /* y is a real number. */ + fxch // x : y + fldl MO(one) // 1.0 : x : y + fld %st(1) // x : 1.0 : x : y + fsub %st(1) // x-1 : 1.0 : x : y + fabs // |x-1| : 1.0 : x : y + fcompl MO(limit) // 1.0 : x : y + fnstsw + fxch // x : 1.0 : y + sahf + ja 7f + fsub %st(1) // x-1 : 1.0 : y + fyl2xp1 // log2(x) : y + jmp 8f + +7: fyl2x // log2(x) : y +8: fmul %st(1) // y*log2(x) : y + fst %st(1) // y*log2(x) : y*log2(x) + frndint // int(y*log2(x)) : y*log2(x) + fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x)) + fxch // fract(y*log2(x)) : int(y*log2(x)) + f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x)) + faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x)) + fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*log2(x)) + addl $8, %esp + fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x)) + ret +END(__ieee754_powl) diff --git a/sysdeps/libm-i387/s_asinh.S b/sysdeps/libm-i387/s_asinh.S index 9b58eaa424..a71d0b66f4 100644 --- a/sysdeps/libm-i387/s_asinh.S +++ b/sysdeps/libm-i387/s_asinh.S @@ -101,7 +101,7 @@ ENTRY(__asinh) fchs // x 4: fld %st // x : x faddl MO(huge) // huge+x : x - fincstp // x + fstp %st(0) // x ret // |x| > 2^28 => y = sign(x) * (log(|x|) + log(2)) diff --git a/sysdeps/libm-i387/s_asinhf.S b/sysdeps/libm-i387/s_asinhf.S index d0a99a9461..f47bc9e0ac 100644 --- a/sysdeps/libm-i387/s_asinhf.S +++ b/sysdeps/libm-i387/s_asinhf.S @@ -101,7 +101,7 @@ ENTRY(__asinhf) fchs // x 4: fld %st // x : x faddl MO(huge) // huge+x : x - fincstp // x + fstp %st(0) // x ret // |x| > 2^14 => y = sign(x) * (log(|x|) + log(2)) diff --git a/sysdeps/libm-i387/s_asinhl.S b/sysdeps/libm-i387/s_asinhl.S index 28f76c2649..e112244908 100644 --- a/sysdeps/libm-i387/s_asinhl.S +++ b/sysdeps/libm-i387/s_asinhl.S @@ -109,7 +109,7 @@ ENTRY(__asinhl) 4: fld %st // x : x fldt MO(huge) // huge : x : x faddp // huge+x : x - fincstp // x + fstp %st(0) // x ret // |x| > 2^34 => y = sign(x) * (log(|x|) + log(2)) diff --git a/sysdeps/libm-i387/s_ceil.S b/sysdeps/libm-i387/s_ceil.S index 309fe882f8..b0159128aa 100644 --- a/sysdeps/libm-i387/s_ceil.S +++ b/sysdeps/libm-i387/s_ceil.S @@ -8,27 +8,25 @@ RCSID("$NetBSD: s_ceil.S,v 1.4 1995/05/08 23:52:13 jtc Exp $") ENTRY(__ceil) - pushl %ebp - movl %esp,%ebp + fldl 4(%esp) subl $8,%esp - fstcw -4(%ebp) /* store fpu control word */ + fstcw 4(%esp) /* store fpu control word */ /* We use here %edx although only the low 1 bits are defined. But none of the operations should care and they are faster than the 16 bit operations. */ - movl -4(%ebp),%edx - orl $0x0800,%edx /* round towards +oo */ + movl $0x0800,%edx /* round towards +oo */ + orl 4(%esp),%edx andl $0xfbff,%edx - movl %edx,-8(%ebp) - fldcw -8(%ebp) /* load modified control word */ + movl %edx,(%esp) + fldcw (%esp) /* load modified control word */ - fldl 8(%ebp); /* round */ - frndint + frndint /* round */ - fldcw -4(%ebp) /* restore original control word */ + fldcw 4(%esp) /* restore original control word */ - leave + addl $8,%esp ret END (__ceil) weak_alias (__ceil, ceil) diff --git a/sysdeps/libm-i387/s_ceilf.S b/sysdeps/libm-i387/s_ceilf.S index 768d117021..352d40d7ce 100644 --- a/sysdeps/libm-i387/s_ceilf.S +++ b/sysdeps/libm-i387/s_ceilf.S @@ -8,27 +8,25 @@ RCSID("$NetBSD: s_ceilf.S,v 1.3 1995/05/08 23:52:44 jtc Exp $") ENTRY(__ceilf) - pushl %ebp - movl %esp,%ebp + flds 4(%esp) subl $8,%esp - fstcw -4(%ebp) /* store fpu control word */ + fstcw 4(%esp) /* store fpu control word */ /* We use here %edx although only the low 1 bits are defined. But none of the operations should care and they are faster than the 16 bit operations. */ - movl -4(%ebp),%edx - orl $0x0800,%edx /* round towards +oo */ + movl $0x0800,%edx /* round towards +oo */ + orl 4(%esp),%edx andl $0xfbff,%edx - movl %edx,-8(%ebp) - fldcw -8(%ebp) /* load modified control word */ + movl %edx,(%esp) + fldcw (%esp) /* load modified control word */ - flds 8(%ebp); /* round */ - frndint + frndint /* round */ - fldcw -4(%ebp) /* restore original control word */ + fldcw 4(%esp) /* restore original control word */ - leave + addl $8,%esp ret END (__ceilf) weak_alias (__ceilf, ceilf) diff --git a/sysdeps/libm-i387/s_ceill.S b/sysdeps/libm-i387/s_ceill.S index dcf8719af3..0128966ebe 100644 --- a/sysdeps/libm-i387/s_ceill.S +++ b/sysdeps/libm-i387/s_ceill.S @@ -9,27 +9,25 @@ RCSID("$NetBSD: $") ENTRY(__ceill) - pushl %ebp - movl %esp,%ebp + fldt 4(%esp) subl $8,%esp - fstcw -4(%ebp) /* store fpu control word */ + fstcw 4(%esp) /* store fpu control word */ /* We use here %edx although only the low 1 bits are defined. But none of the operations should care and they are faster than the 16 bit operations. */ - movl -4(%ebp),%edx - orl $0x0800,%edx /* round towards +oo */ + movl $0x0800,%edx /* round towards +oo */ + orl 4(%esp),%edx andl $0xfbff,%edx - movl %edx,-8(%ebp) - fldcw -8(%ebp) /* load modified control word */ + movl %edx,(%esp) + fldcw (%esp) /* load modified control word */ - fldt 8(%ebp); /* round */ - frndint + frndint /* round */ - fldcw -4(%ebp) /* restore original control word */ + fldcw 4(%esp) /* restore original control word */ - leave + addl $8,%esp ret END (__ceill) weak_alias (__ceill, ceill) diff --git a/sysdeps/libm-i387/s_expm1.S b/sysdeps/libm-i387/s_expm1.S new file mode 100644 index 0000000000..2685d6e770 --- /dev/null +++ b/sysdeps/libm-i387/s_expm1.S @@ -0,0 +1,83 @@ +/* ix87 specific implementation of exp(x)-1. + Copyright (C) 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + /* Using: e^x - 1 = 2^(x * log2(e)) - 1 */ + +#include <machine/asm.h> + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(zero,@object) +zero: .double 0.0 + ASM_SIZE_DIRECTIVE(zero) + ASM_TYPE_DIRECTIVE(one,@object) +one: .double 1.0 + ASM_SIZE_DIRECTIVE(one) + ASM_TYPE_DIRECTIVE(l2e,@object) +l2e: .tfloat 1.442695040888963407359924681002 + ASM_SIZE_DIRECTIVE(l2e) + +#ifdef PIC +#define MO(op) op##@GOTOFF(%edx) +#else +#define MO(op) op +#endif + + .text +ENTRY(__expm1) + fldl 4(%esp) // x + fxam // Is NaN or +-Inf? + fstsw %ax +#ifdef PIC + call 1f +1: popl %edx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx +#endif + movb $0x45, %ch + andb %ah, %ch + cmpb $0x05, %ch + je 2f // Is +-Inf, jump. + + fldt MO(l2e) // log2(e) : x + fmulp // log2(e)*x + fld %st // log2(e)*x : log2(e)*x + frndint // int(log2(e)*x) : log2(e)*x + fsub %st, %st(1) // int(log2(e)*x) : fract(log2(e)*x) + fxch // fract(log2(e)*x) : int(log2(e)*x) + f2xm1 // 2^fract(log2(e)*x)-1 : int(log2(e)*x) + fscale // 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x) + fxch // int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fldl MO(one) // 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fscale // 2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + faddp // 2^(log2(e)*x) + fsubl MO(one) + ret + +2: testl $0x200, %eax // Test sign. + jz 3f // If positive, jump. + fldl MO(zero) // Set result to 0. +3: ret +END(__expm1) +weak_alias (__expm1, expm1) diff --git a/sysdeps/libm-i387/s_expm1f.S b/sysdeps/libm-i387/s_expm1f.S new file mode 100644 index 0000000000..85c3c849f1 --- /dev/null +++ b/sysdeps/libm-i387/s_expm1f.S @@ -0,0 +1,83 @@ +/* ix87 specific implementation of exp(x)-1. + Copyright (C) 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + /* Using: e^x - 1 = 2^(x * log2(e)) - 1 */ + +#include <machine/asm.h> + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(zero,@object) +zero: .double 0.0 + ASM_SIZE_DIRECTIVE(zero) + ASM_TYPE_DIRECTIVE(one,@object) +one: .double 1.0 + ASM_SIZE_DIRECTIVE(one) + ASM_TYPE_DIRECTIVE(l2e,@object) +l2e: .tfloat 1.442695040888963407359924681002 + ASM_SIZE_DIRECTIVE(l2e) + +#ifdef PIC +#define MO(op) op##@GOTOFF(%edx) +#else +#define MO(op) op +#endif + + .text +ENTRY(__expm1f) + flds 4(%esp) // x + fxam // Is NaN or +-Inf? + fstsw %ax +#ifdef PIC + call 1f +1: popl %edx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx +#endif + movb $0x45, %ch + andb %ah, %ch + cmpb $0x05, %ch + je 2f // Is +-Inf, jump. + + fldt MO(l2e) // log2(e) : x + fmulp // log2(e)*x + fld %st // log2(e)*x : log2(e)*x + frndint // int(log2(e)*x) : log2(e)*x + fsub %st, %st(1) // int(log2(e)*x) : fract(log2(e)*x) + fxch // fract(log2(e)*x) : int(log2(e)*x) + f2xm1 // 2^fract(log2(e)*x)-1 : int(log2(e)*x) + fscale // 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x) + fxch // int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fldl MO(one) // 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fscale // 2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + faddp // 2^(log2(e)*x) + fsubl MO(one) + ret + +2: testl $0x200, %eax // Test sign. + jz 3f // If positive, jump. + fldl MO(zero) // Set result to 0. +3: ret +END(__expm1f) +weak_alias (__expm1f, expm1f) diff --git a/sysdeps/libm-i387/s_expm1l.S b/sysdeps/libm-i387/s_expm1l.S new file mode 100644 index 0000000000..45aa753094 --- /dev/null +++ b/sysdeps/libm-i387/s_expm1l.S @@ -0,0 +1,83 @@ +/* ix87 specific implementation of exp(x)-1. + Copyright (C) 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + Based on code by John C. Bowman <bowman@ipp-garching.mpg.de>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + + /* Using: e^x - 1 = 2^(x * log2(e)) - 1 */ + +#include <machine/asm.h> + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(zero,@object) +zero: .double 0.0 + ASM_SIZE_DIRECTIVE(zero) + ASM_TYPE_DIRECTIVE(one,@object) +one: .double 1.0 + ASM_SIZE_DIRECTIVE(one) + ASM_TYPE_DIRECTIVE(l2e,@object) +l2e: .tfloat 1.442695040888963407359924681002 + ASM_SIZE_DIRECTIVE(l2e) + +#ifdef PIC +#define MO(op) op##@GOTOFF(%edx) +#else +#define MO(op) op +#endif + + .text +ENTRY(__expm1l) + fldt 4(%esp) // x + fxam // Is NaN or +-Inf? + fstsw %ax +#ifdef PIC + call 1f +1: popl %edx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx +#endif + movb $0x45, %ch + andb %ah, %ch + cmpb $0x05, %ch + je 2f // Is +-Inf, jump. + + fldt MO(l2e) // log2(e) : x + fmulp // log2(e)*x + fld %st // log2(e)*x : log2(e)*x + frndint // int(log2(e)*x) : log2(e)*x + fsub %st, %st(1) // int(log2(e)*x) : fract(log2(e)*x) + fxch // fract(log2(e)*x) : int(log2(e)*x) + f2xm1 // 2^fract(log2(e)*x)-1 : int(log2(e)*x) + fscale // 2^(log2(e)*x)-2^int(log2(e)*x) : int(log2(e)*x) + fxch // int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fldl MO(one) // 1 : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + fscale // 2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x) + faddp // 2^(log2(e)*x) + fsubl MO(one) + ret + +2: testl $0x200, %eax // Test sign. + jz 3f // If positive, jump. + fldl MO(zero) // Set result to 0. +3: ret +END(__expm1l) +weak_alias (__expm1l, expm1l) diff --git a/sysdeps/libm-i387/s_floor.S b/sysdeps/libm-i387/s_floor.S index 561f83d98a..20a8660424 100644 --- a/sysdeps/libm-i387/s_floor.S +++ b/sysdeps/libm-i387/s_floor.S @@ -8,23 +8,25 @@ RCSID("$NetBSD: s_floor.S,v 1.4 1995/05/09 00:01:59 jtc Exp $") ENTRY(__floor) - pushl %ebp - movl %esp,%ebp + fldl 4(%esp) subl $8,%esp - fstcw -4(%ebp) /* store fpu control word */ - movw -4(%ebp),%dx - orw $0x0400,%dx /* round towards -oo */ - andw $0xf7ff,%dx - movw %dx,-8(%ebp) - fldcw -8(%ebp) /* load modified control word */ + fstcw 4(%esp) /* store fpu control word */ - fldl 8(%ebp); /* round */ - frndint + /* We use here %edx although only the low 1 bits are defined. + But none of the operations should care and they are faster + than the 16 bit operations. */ + movl $0x400,%edx /* round towards -oo */ + orl 4(%esp),%edx + andl $0xf7ff,%edx + movl %edx,(%esp) + fldcw (%esp) /* load modified control word */ - fldcw -4(%ebp) /* restore original control word */ + frndint /* round */ - leave + fldcw 4(%esp) /* restore original control word */ + + addl $8,%esp ret END (__floor) weak_alias (__floor, floor) diff --git a/sysdeps/libm-i387/s_floorf.S b/sysdeps/libm-i387/s_floorf.S index 059f4f3a15..eca93a2aa3 100644 --- a/sysdeps/libm-i387/s_floorf.S +++ b/sysdeps/libm-i387/s_floorf.S @@ -8,23 +8,25 @@ RCSID("$NetBSD: s_floorf.S,v 1.3 1995/05/09 00:04:32 jtc Exp $") ENTRY(__floorf) - pushl %ebp - movl %esp,%ebp + flds 4(%esp) subl $8,%esp - fstcw -4(%ebp) /* store fpu control word */ - movw -4(%ebp),%dx - orw $0x0400,%dx /* round towards -oo */ - andw $0xf7ff,%dx - movw %dx,-8(%ebp) - fldcw -8(%ebp) /* load modified control word */ + fstcw 4(%esp) /* store fpu control word */ - flds 8(%ebp); /* round */ - frndint + /* We use here %edx although only the low 1 bits are defined. + But none of the operations should care and they are faster + than the 16 bit operations. */ + movl $0x400,%edx /* round towards -oo */ + orl 4(%esp),%edx + andl $0xf7ff,%edx + movl %edx,(%esp) + fldcw (%esp) /* load modified control word */ - fldcw -4(%ebp) /* restore original control word */ + frndint /* round */ - leave + fldcw 4(%esp) /* restore original control word */ + + addl $8,%esp ret END (__floorf) weak_alias (__floorf, floorf) diff --git a/sysdeps/libm-i387/s_floorl.S b/sysdeps/libm-i387/s_floorl.S index 7b7cff777a..c2bf091d73 100644 --- a/sysdeps/libm-i387/s_floorl.S +++ b/sysdeps/libm-i387/s_floorl.S @@ -9,23 +9,25 @@ RCSID("$NetBSD: $") ENTRY(__floorl) - pushl %ebp - movl %esp,%ebp + fldt 4(%esp) subl $8,%esp - fstcw -4(%ebp) /* store fpu control word */ - movw -4(%ebp),%dx - orw $0x0400,%dx /* round towards -oo */ - andw $0xf7ff,%dx - movw %dx,-8(%ebp) - fldcw -8(%ebp) /* load modified control word */ + fstcw 4(%esp) /* store fpu control word */ - fldt 8(%ebp) /* round */ - frndint + /* We use here %edx although only the low 1 bits are defined. + But none of the operations should care and they are faster + than the 16 bit operations. */ + movl $0x400,%edx /* round towards -oo */ + orl 4(%esp),%edx + andl $0xf7ff,%edx + movl %edx,(%esp) + fldcw (%esp) /* load modified control word */ - fldcw -4(%ebp) /* restore original control word */ + frndint /* round */ - leave + fldcw 4(%esp) /* restore original control word */ + + addl $8,%esp ret END (__floorl) weak_alias (__floorl, floorl) diff --git a/sysdeps/libm-i387/s_significandl.S b/sysdeps/libm-i387/s_significandl.S index 1d5f4a3f6a..e3a69cba73 100644 --- a/sysdeps/libm-i387/s_significandl.S +++ b/sysdeps/libm-i387/s_significandl.S @@ -11,7 +11,7 @@ RCSID("$NetBSD: $") ENTRY(__significandl) fldt 4(%esp) fxtract - fincstp + fstp %st(0) ret END (__significandl) weak_alias (__significandl, significandl) |