(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / sysdeps / i386 / fpu / e_scalbl.S
blob65644f8f0ecb2c4e3d0585a9eead8131cd065ef4
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  *
7  * Correct handling of y==-inf <drepper@gnu>
8  */
10 #include <machine/asm.h>
12 RCSID("$NetBSD: $")
14 #ifdef __ELF__
15         .section .rodata
16 #else
17         .text
18 #endif
20         .align ALIGNARG(4)
21         ASM_TYPE_DIRECTIVE(zero_nan,@object)
22 zero_nan:
23         .double 0.0
24 nan:    .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
25 minus_zero:
26         .byte 0, 0, 0, 0, 0, 0, 0, 0x80
27         .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
28         ASM_SIZE_DIRECTIVE(zero_nan)
31 #ifdef PIC
32 #define MO(op) op##@GOTOFF(%ecx)
33 #define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
34 #else
35 #define MO(op) op
36 #define MOX(op,x,f) op(,x,f)
37 #endif
39         .text
40 ENTRY(__ieee754_scalbl)
41         fldt    16(%esp)
42         fxam
43         fnstsw
44         fldt    4(%esp)
45         andl    $0x4700, %eax
46         cmpl    $0x0700, %eax
47         je      1f
48         andl    $0x4500, %eax
49         cmpl    $0x0100, %eax
50         je      2f
51         fxam
52         fnstsw
53         andl    $0x4500, %eax
54         cmpl    $0x0100, %eax
55         je      3f
56         fld     %st(1)
57         frndint
58         fcomp   %st(2)
59         fnstsw
60         sahf
61         jne     4f
62         fscale
63         fstp    %st(1)
64         ret
66         /* y is -inf */
67 1:      fxam
68 #ifdef  PIC
69         call    1f
70 1:      popl    %ecx
71         addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
72 #endif
73         fnstsw
74         movl    12(%esp), %edx
75         shrl    $5, %eax
76         fstp    %st
77         fstp    %st
78         andl    $0x8000, %edx
79         andl    $8, %eax
80         jnz     4f
81         shrl    $11, %edx
82         addl    %edx, %eax
83         fldl    MOX(zero_nan, %eax, 1)
84         ret
86         /* The result is NaN, but we must not raise an exception.
87            So use a variable.  */
88 2:      fstp    %st
89         fstp    %st
90 #ifdef  PIC
91         call    1f
92 1:      popl    %ecx
93         addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
94 #endif
95         fldl    MO(nan)
96         ret
98         /* The first parameter is a NaN.  Return it.  */
99 3:      fstp    %st(1)
100         ret
102         /* Return NaN and raise the invalid exception.  */
103 4:      fstp    %st
104         fstp    %st
105         fldz
106         fdiv    %st
107         ret
108 END(__ieee754_scalbl)