Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4973 right-hear 1
/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
2
#include
3
pinf:
4
	.long	0x7F800000
5
 
6
NaN:
7
	.long	0xFFC00000
8
 
9
 
10
MK_C_SYM(expm1)
11
	movl	8(%esp), %eax		/* Test for special cases. */
12
	andl	$0x7FFFFFFF, %eax
13
	cmpl	$0x40862E42, %eax
14
	jge	bigarg			/* normal args: */
15
					/* 0 < |x| <= log(DBL_MAX) */
16
argok:					/* N.B. */
17
					/* log(DBL_MAX) = 0x40862E42FEFA39EF */
18
	fldl	4(%esp)
19
	fldl2e				/* log2(e)  x			   */
20
	fmulp				/* xs				   */
21
	fld	%st			/* xs	    xs			   */
22
	frndint				/* nint(xs) xs			   */
23
	fxch	%st(1)			/* xs	    nint		   */
24
	fsub	%st(1),%st		/* fract    nint		   */
25
	f2xm1				/* exps-1   nint		   */
26
	fxch	%st(1)			/* nint	    exps-1		   */
27
	fld1				/* 1	    nint    exps-1	   */
28
	fscale				/* scale    nint    exps-1	   */
29
	fld1				/* 1	    scale   nint    exps-1 */
30
	/* Should be fsubp %st,%st(1) (gas bug) */
31
	.byte	0xDE, 0xE9		/* scale-1  nint    exps-1	   */
32
	fxch	%st(2)			/* exps-1   nint    scale-1	   */
33
	fscale				/* expm	    nint    scale-1	   */
34
	fstp	%st(1)			/* exp	    scale-1		   */
35
	faddp				/* exp-1			   */
36
	ret
37
 
38
bigarg:
39
	je	edge
40
	andl	$0x7FF00000, %eax	/* |x| > log(DBL_MAX) */
41
	cmpl	$0x7FF00000, %eax
42
	je	abarg
43
 
44
posneg:
45
	testl	$0x80000000, 8(%esp)
46
	jnz	argok			/* Large negative -- OK */
47
	movl	$2, C_SYM(errno)	/* |x| is really big, but finite */
48
	jmp	argok
49
 
50
edge:					/* |x| is nearly log(DBL_MAX) */
51
	cmpl	$0xFEFA39EF, 4(%esp)
52
	jbe	argok
53
	jmp	posneg
54
 
55
abarg:					/* x = +/-inf, or +NaN */
56
	testl	$0x000FFFFF, 8(%esp)
57
	jnz	badarg
58
	movl	4(%esp), %eax
59
	testl	%eax, %eax
60
	jnz	badarg
61
 
62
infarg:					/* |x| = inf */
63
	testl	$0x80000000, 8(%esp)
64
	jz	posinf
65
 
66
neginf:
67
	fld1
68
	fchs
69
	ret
70
 
71
posinf:
72
	movl	$2, C_SYM(errno)
73
	flds	pinf
74
	ret
75
 
76
badarg:					/* arg is NaN */
77
	movl	$1, C_SYM(errno)
78
	flds	NaN
79
	ret