Update copyright notices with scripts/update-copyrights.
[glibc.git] / sysdeps / x86_64 / fpu / e_scalbl.S
blobc422d53b1c994b7cccf03ed61a2c97f347c2e64a
1 /*
2  * Written by J.T. Conklin <jtc@netbsd.org>.
3  * Public domain.
4  *
5  * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
6  * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>
7  *
8  * Correct handling of y==-inf <drepper@gnu>
9  */
11 #include <machine/asm.h>
13         .section .rodata
15         .align ALIGNARG(4)
16         .type zero_nan,@object
17 zero_nan:
18         .double 0.0
19 nan:    .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
20         .byte 0, 0, 0, 0, 0, 0, 0, 0x80
21         .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
22         ASM_SIZE_DIRECTIVE(zero_nan)
25 #ifdef PIC
26 # define MO(op) op##(%rip)
27 #else
28 # define MO(op) op
29 #endif
31         .text
32 ENTRY(__ieee754_scalbl)
33         fldt    24(%rsp)
34         fxam
35         fnstsw
36         fldt    8(%rsp)
37         andl    $0x4700, %eax
38         cmpl    $0x0700, %eax
39         je      1f
40         andl    $0x4500, %eax
41         cmpl    $0x0100, %eax
42         je      2f
43         fxam
44         fnstsw
45         andl    $0x4500, %eax
46         cmpl    $0x0100, %eax
47         je      3f
48         fld     %st(1)
49         frndint
50         fcomip  %st(2), %st
51         jne     4f
52         fscale
53         fstp    %st(1)
54         ret
56         /* y is -inf */
57 1:      fxam
58         fnstsw
59         movl    16(%rsp), %edx
60         shrl    $5, %eax
61         fstp    %st
62         fstp    %st
63         andl    $0x8000, %edx
64         andl    $8, %eax
65         jnz     4f
66         shrl    $11, %edx
67         addl    %edx, %eax
68 #ifdef PIC
69         lea     zero_nan(%rip),%rdx
70         fldl    (%rdx,%rax,1)
71 #else
72         fldl    zero_nan(%rax, 1)
73 #endif
74         ret
76         /* The result is NaN, but we must not raise an exception.
77            So use a variable.  */
78 2:      fstp    %st
79         fstp    %st
80         fldl    MO(nan)
81         ret
83         /* The first parameter is a NaN.  Return it.  */
84 3:      fstp    %st(1)
85         ret
87         /* Return NaN and raise the invalid exception.  */
88 4:      fstp    %st
89         fstp    %st
90         fldz
91         fdiv    %st
92         ret
93 END(__ieee754_scalbl)
94 strong_alias (__ieee754_scalbl, __scalbl_finite)