(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / sysdeps / i386 / fpu / e_scalbf.S
blobd41c29327d7a1e37b8cb07d1061b78290621155e
1 /*
2  * Written by J.T. Conklin <jtc@netbsd.org>.
3  * Public domain.
4  * Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
5  *
6  * Correct handling of y==-inf <drepper@gnu>
7  */
9 #include <machine/asm.h>
11 RCSID("$NetBSD: $")
13 #ifdef __ELF__
14         .section .rodata
15 #else
16         .text
17 #endif
19         .align ALIGNARG(4)
20         ASM_TYPE_DIRECTIVE(zero_nan,@object)
21 zero_nan:
22         .double 0.0
23 nan:    .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
24 minus_zero:
25         .byte 0, 0, 0, 0, 0, 0, 0, 0x80
26         .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
27         ASM_SIZE_DIRECTIVE(zero_nan)
30 #ifdef PIC
31 #define MO(op) op##@GOTOFF(%ecx)
32 #define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
33 #else
34 #define MO(op) op
35 #define MOX(op,x,f) op(,x,f)
36 #endif
39         .text
40 ENTRY(__ieee754_scalbf)
41         flds    8(%esp)
42         fxam
43         fnstsw
44         flds    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    4(%esp), %edx
75         shrl    $5, %eax
76         fstp    %st
77         fstp    %st
78         andl    $0x80000000, %edx
79         andl    $8, %eax
80         jnz     4f
81         shrl    $27, %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_scalbf)