Update.
[jlayton/glibc.git] / sysdeps / libm-i387 / e_scalb.S
1 /*
2  * Written by J.T. Conklin <jtc@netbsd.org>.
3  * Public domain.
4  *
5  * Correct handling of y==-inf <drepper@gnu>
6  */
7
8 #include <machine/asm.h>
9
10 RCSID("$NetBSD: e_scalb.S,v 1.4 1995/05/08 23:49:52 jtc Exp $")
11
12 #ifdef __ELF__
13         .section .rodata
14 #else
15         .text
16 #endif
17
18         .align ALIGNARG(4)
19         ASM_TYPE_DIRECTIVE(zero_nan,@object)
20 zero_nan:
21         .double 0.0
22 nan:    .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
23 minus_zero:
24         .byte 0, 0, 0, 0, 0, 0, 0, 0x80
25         .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
26         ASM_SIZE_DIRECTIVE(zero_nan)
27
28
29 #ifdef PIC
30 #define MO(op) op##@GOTOFF(%ecx)
31 #define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
32 #else
33 #define MO(op) op
34 #define MOX(op,x,f) op(,x,f)
35 #endif
36
37         .text
38 ENTRY(__ieee754_scalb)
39         fldl    12(%esp)
40         fxam
41         fnstsw
42         fldl    4(%esp)
43         andl    $0x4700, %eax
44         cmpl    $0x0700, %eax
45         je      1f
46         andl    $0x4500, %eax
47         cmpl    $0x0100, %eax
48         je      2f
49         fxam
50         fnstsw
51         andl    $0x4500, %eax
52         cmpl    $0x0100, %eax
53         je      2f
54         fld     %st(1)
55         frndint
56         fcomp   %st(2)
57         fnstsw
58         sahf
59         jne     2f
60         fscale
61         fstp    %st(1)
62         ret
63
64         /* y is -inf */
65 1:      fxam
66 #ifdef  PIC
67         call    1f
68 1:      popl    %ecx
69         addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
70 #endif
71         fnstsw
72         movl    8(%esp), %edx
73         shrl    $5, %eax
74         fstp    %st
75         fstp    %st
76         andl    $0x80000000, %edx
77         andl    $8, %eax
78         shrl    $27, %edx
79         addl    %edx, %eax
80         fldl    MOX(zero_nan, %eax, 1)
81         ret
82
83         /* The result is NaN, but we must not raise an exception.
84            So use a variable.  */
85 2:      fstp    %st
86         fstp    %st
87 #ifdef  PIC
88         call    1f
89 1:      popl    %ecx
90         addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
91 #endif
92         fldl    MO(nan)
93         ret
94 END(__ieee754_scalb)