diff options
author | Ulrich Drepper <drepper@redhat.com> | 1999-07-14 00:54:57 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1999-07-14 00:54:57 +0000 |
commit | abfbdde177c3a7155070dda1b2cdc8292054cc26 (patch) | |
tree | e021306b596381fbf8311d2b7eb294e918ff17c8 /sysdeps/i386/fpu/e_scalb.S | |
parent | 86421aa57ecfd70963ae66848bd6a6dd3b8e0fe6 (diff) | |
download | glibc-abfbdde177c3a7155070dda1b2cdc8292054cc26.tar.gz |
Update.
Diffstat (limited to 'sysdeps/i386/fpu/e_scalb.S')
-rw-r--r-- | sysdeps/i386/fpu/e_scalb.S | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/sysdeps/i386/fpu/e_scalb.S b/sysdeps/i386/fpu/e_scalb.S new file mode 100644 index 0000000000..7ff5541e2f --- /dev/null +++ b/sysdeps/i386/fpu/e_scalb.S @@ -0,0 +1,94 @@ +/* + * Written by J.T. Conklin <jtc@netbsd.org>. + * Public domain. + * + * Correct handling of y==-inf <drepper@gnu> + */ + +#include <machine/asm.h> + +RCSID("$NetBSD: e_scalb.S,v 1.4 1995/05/08 23:49:52 jtc Exp $") + +#ifdef __ELF__ + .section .rodata +#else + .text +#endif + + .align ALIGNARG(4) + ASM_TYPE_DIRECTIVE(zero_nan,@object) +zero_nan: + .double 0.0 +nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f +minus_zero: + .byte 0, 0, 0, 0, 0, 0, 0, 0x80 + .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f + ASM_SIZE_DIRECTIVE(zero_nan) + + +#ifdef PIC +#define MO(op) op##@GOTOFF(%ecx) +#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f) +#else +#define MO(op) op +#define MOX(op,x,f) op(,x,f) +#endif + + .text +ENTRY(__ieee754_scalb) + fldl 12(%esp) + fxam + fnstsw + fldl 4(%esp) + andl $0x4700, %eax + cmpl $0x0700, %eax + je 1f + andl $0x4500, %eax + cmpl $0x0100, %eax + je 2f + fxam + fnstsw + andl $0x4500, %eax + cmpl $0x0100, %eax + je 2f + fld %st(1) + frndint + fcomp %st(2) + fnstsw + sahf + jne 2f + fscale + fstp %st(1) + ret + + /* y is -inf */ +1: fxam +#ifdef PIC + call 1f +1: popl %ecx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx +#endif + fnstsw + movl 8(%esp), %edx + shrl $5, %eax + fstp %st + fstp %st + andl $0x80000000, %edx + andl $8, %eax + shrl $27, %edx + addl %edx, %eax + fldl MOX(zero_nan, %eax, 1) + ret + + /* The result is NaN, but we must not raise an exception. + So use a variable. */ +2: fstp %st + fstp %st +#ifdef PIC + call 1f +1: popl %ecx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx +#endif + fldl MO(nan) + ret +END(__ieee754_scalb) |