1/*
2 * Public domain.
3 */
4
5#include <machine/asm.h>
6#include <i386-math-asm.h>
7#include <libm-alias-finite.h>
8
9 .section .rodata
10
11 .align ALIGNARG(4)
12 .type zero_nan,@object
13zero_nan:
14 .double 0.0
15nan: .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)
19
20
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
28
29 .text
30ENTRY(__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
56
57 /* y is -inf */
581: 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
76
77 /* The result is NaN, but we must not raise an exception.
78 So use a variable. */
792: fstp %st
80 fstp %st
81#ifdef PIC
82 LOAD_PIC_REG (cx)
83#endif
84 fldl MO(nan)
85 ret
86
87 /* The first parameter is a NaN. Return it. */
883: fstp %st(1)
89 ret
90
91 /* Return NaN and raise the invalid exception. */
924: fstp %st
93 fstp %st
94 fldz
95 fdiv %st
96 ret
97END(__ieee754_scalb)
98libm_alias_finite (__ieee754_scalb, __scalb)
99

source code of glibc/sysdeps/i386/fpu/e_scalb.S