1901f3990SIngo Weinhold/*
2901f3990SIngo Weinhold * Written by J.T. Conklin <jtc@netbsd.org>.
3901f3990SIngo Weinhold * Public domain.
4901f3990SIngo Weinhold */
5901f3990SIngo Weinhold
6901f3990SIngo Weinhold#include <machine/asm.h>
7901f3990SIngo Weinhold
8901f3990SIngo WeinholdRCSID("$NetBSD: e_exp.S,v 1.7 1996/07/03 17:31:28 jtc Exp $")
9901f3990SIngo Weinhold
10901f3990SIngo Weinhold/* e^x = 2^(x * log2(e)) */
11901f3990SIngo WeinholdENTRY(__ieee754_exp)
12901f3990SIngo Weinhold	fldl	4(%esp)
13901f3990SIngo Weinhold/* I added the following ugly construct because exp(+-Inf) resulted
14901f3990SIngo Weinhold   in NaN.  The ugliness results from the bright minds at Intel.
15901f3990SIngo Weinhold   For the i686 the code can be written better.
16901f3990SIngo Weinhold   -- drepper@cygnus.com.  */
17901f3990SIngo Weinhold	fxam				/* Is NaN or +-Inf?  */
18901f3990SIngo Weinhold	fstsw	%ax
19901f3990SIngo Weinhold	movb	$0x45, %dh
20901f3990SIngo Weinhold	andb	%ah, %dh
21901f3990SIngo Weinhold	cmpb	$0x05, %dh
22901f3990SIngo Weinhold	je	1f			/* Is +-Inf, jump.  */
23901f3990SIngo Weinhold	fldl2e
24901f3990SIngo Weinhold	fmulp				/* x * log2(e) */
25901f3990SIngo Weinhold	fld	%st
26901f3990SIngo Weinhold	frndint				/* int(x * log2(e)) */
27901f3990SIngo Weinhold	fsubr	%st,%st(1)		/* fract(x * log2(e)) */
28901f3990SIngo Weinhold	fxch
29901f3990SIngo Weinhold	f2xm1				/* 2^(fract(x * log2(e))) - 1 */
30901f3990SIngo Weinhold	fld1
31901f3990SIngo Weinhold	faddp				/* 2^(fract(x * log2(e))) */
32901f3990SIngo Weinhold	fscale				/* e^x */
33901f3990SIngo Weinhold	fstp	%st(1)
34901f3990SIngo Weinhold	ret
35901f3990SIngo Weinhold
36901f3990SIngo Weinhold1:	testl	$0x200, %eax		/* Test sign.  */
37901f3990SIngo Weinhold	jz	2f			/* If positive, jump.  */
38901f3990SIngo Weinhold	fstp	%st
39901f3990SIngo Weinhold	fldz				/* Set result to 0.  */
40901f3990SIngo Weinhold2:	ret
41901f3990SIngo WeinholdEND (__ieee754_exp)