Linux: Consolidate typesizes.h
[glibc.git] / sysdeps / i386 / fpu / e_scalb.S
blob73685baa97501de41d8a88960209781228ecbc99
1 /*
2  * Public domain.
3  */
5 #include <machine/asm.h>
6 #include <i386-math-asm.h>
7 #include <libm-alias-finite.h>
9         .section .rodata
11         .align ALIGNARG(4)
12         .type zero_nan,@object
13 zero_nan:
14         .double 0.0
15 nan:    .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
16         .byte 0, 0, 0, 0, 0, 0, 0, 0x80
17         .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
18         ASM_SIZE_DIRECTIVE(zero_nan)
21 #ifdef PIC
22 # define MO(op) op##@GOTOFF(%ecx)
23 # define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
24 #else
25 # define MO(op) op
26 # define MOX(op,x,f) op(,x,f)
27 #endif
29         .text
30 ENTRY(__ieee754_scalb)
31         fldl    12(%esp)
32         fxam
33         fnstsw
34         fldl    4(%esp)
35         andl    $0x4700, %eax
36         cmpl    $0x0700, %eax
37         je      1f
38         andl    $0x4500, %eax
39         cmpl    $0x0100, %eax
40         je      2f
41         fxam
42         fnstsw
43         andl    $0x4500, %eax
44         cmpl    $0x0100, %eax
45         je      3f
46         fld     %st(1)
47         frndint
48         fcomp   %st(2)
49         fnstsw
50         sahf
51         jne     4f
52         fscale
53         fstp    %st(1)
54         DBL_NARROW_EVAL
55         ret
57         /* y is -inf */
58 1:      fxam
59 #ifdef  PIC
60         LOAD_PIC_REG (cx)
61 #endif
62         fnstsw
63         movl    8(%esp), %edx
64         shrl    $5, %eax
65         fstp    %st
66         fstp    %st
67         andl    $0x80000000, %edx
68         andl    $0x0228, %eax
69         cmpl    $0x0028, %eax
70         je      4f
71         andl    $8, %eax
72         shrl    $27, %edx
73         addl    %edx, %eax
74         fldl    MOX(zero_nan, %eax, 1)
75         ret
77         /* The result is NaN, but we must not raise an exception.
78            So use a variable.  */
79 2:      fstp    %st
80         fstp    %st
81 #ifdef  PIC
82         LOAD_PIC_REG (cx)
83 #endif
84         fldl    MO(nan)
85         ret
87         /* The first parameter is a NaN.  Return it.  */
88 3:      fstp    %st(1)
89         ret
91         /* Return NaN and raise the invalid exception.  */
92 4:      fstp    %st
93         fstp    %st
94         fldz
95         fdiv    %st
96         ret
97 END(__ieee754_scalb)
98 libm_alias_finite (__ieee754_scalb, __scalb)