1/*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Public domain.
4 *
5 * Correct handling of y==-inf <drepper@gnu>
6 */
7
8#include <machine/asm.h>
9
10RCSID("$NetBSD: e_scalb.S,v 1.4 1995/05/08 23:49:52 jtc Exp $")
11
12#ifdef __ELF__
13	.section .rodata
14#else
15	.text
16#endif
17
18	.align ALIGNARG(4)
19	ASM_TYPE_DIRECTIVE(zero_nan,@object)
20zero_nan:
21	.double 0.0
22nan:	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
23minus_zero:
24	.byte 0, 0, 0, 0, 0, 0, 0, 0x80
25	.byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f
26	ASM_SIZE_DIRECTIVE(zero_nan)
27
28
29#ifdef PIC
30#define MO(op) op##@GOTOFF(%ecx)
31#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f)
32#else
33#define MO(op) op
34#define MOX(op,x,f) op(,x,f)
35#endif
36
37	.text
38ENTRY(__ieee754_scalb)
39	fldl	12(%esp)
40	fxam
41	fnstsw
42	fldl	4(%esp)
43	andl	$0x4700, %eax
44	cmpl	$0x0700, %eax
45	je	1f
46	andl	$0x4500, %eax
47	cmpl	$0x0100, %eax
48	je	2f
49	fxam
50	fnstsw
51	andl	$0x4500, %eax
52	cmpl	$0x0100, %eax
53	je	3f
54	fld	%st(1)
55	frndint
56	fcomp	%st(2)
57	fnstsw
58	sahf
59	jne	4f
60	fscale
61	fstp	%st(1)
62	ret
63
64	/* y is -inf */
651:	fxam
66#ifdef  PIC
67        call    1f
681:      popl    %ecx
69        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
70#endif
71	fnstsw
72	movl	8(%esp), %edx
73	shrl	$5, %eax
74	fstp	%st
75	fstp	%st
76	andl	$0x80000000, %edx
77	andl	$8, %eax
78	jnz	4f
79	shrl	$27, %edx
80	addl	%edx, %eax
81	fldl	MOX(zero_nan, %eax, 1)
82	ret
83
84	/* The result is NaN, but we must not raise an exception.
85	   So use a variable.  */
862:	fstp	%st
87	fstp	%st
88#ifdef  PIC
89        call    1f
901:      popl    %ecx
91        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
92#endif
93	fldl	MO(nan)
94	ret
95
96	/* The first parameter is a NaN.  Return it.  */
973:	fstp	%st(1)
98	ret
99
100	/* Return NaN and raise the invalid exception.  */
1014:	fstp	%st
102	fstp	%st
103	fldz
104	fdiv	%st
105	ret
106END(__ieee754_scalb)
107