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 */
8
9#include <machine/asm.h>
10
11RCSID("$NetBSD: $")
12
13#ifdef __ELF__
14	.section .rodata
15#else
16	.text
17#endif
18
19	.align ALIGNARG(4)
20	ASM_TYPE_DIRECTIVE(zero_nan,@object)
21zero_nan:
22	.double 0.0
23nan:	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
24minus_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)
28
29
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
37
38
39	.text
40ENTRY(__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
65
66	/* y is -inf */
671:	fxam
68#ifdef  PIC
69        call    1f
701:      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
85
86	/* The result is NaN, but we must not raise an exception.
87	   So use a variable.  */
882:	fstp	%st
89	fstp	%st
90#ifdef  PIC
91        call    1f
921:      popl    %ecx
93        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
94#endif
95	fldl	MO(nan)
96	ret
97
98	/* The first parameter is a NaN.  Return it.  */
993:	fstp	%st(1)
100	ret
101
102	/* Return NaN and raise the invalid exception.  */
1034:	fstp	%st
104	fstp	%st
105	fldz
106	fdiv	%st
107	ret
108END(__ieee754_scalbf)
109