xref: /original-bsd/lib/libm/mc68881/support.s (revision c3e32dec)
1/*-
2 * Copyright (c) 1990, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * the Systems Programming Group of the University of Utah Computer
7 * Science Department.
8 *
9 * %sccs.include.redist.c%
10 *
11 *	@(#)support.s	8.1 (Berkeley) 06/04/93
12 */
13
14	.text
15	.globl	_copysign, _finite, _scalb, _logb, _drem, _pow_P, _atan2__A
16
17| copysign(x,y)
18| returns x with the sign of y.
19_copysign:
20	movl	sp@(4),d0
21	movl	sp@(8),d1
22	tstw	sp@(12)
23	jmi	Lneg
24	bclr	#31,d0
25	rts
26Lneg:
27	bset	#31,d0
28	rts
29
30| finite(x)
31| returns the value TRUE if -INF < x < +INF and returns FALSE otherwise.
32_finite:
33	movw	#0x7FF0,d0
34	movw	sp@(4),d1
35	andw	d0,d1
36	cmpw	d0,d1
37	beq	Lnotfin
38	moveq	#1,d0
39	rts
40Lnotfin:
41	clrl	d0
42	rts
43
44| scalb(x, N)
45| returns  x * (2**N), for integer values N.
46_scalb:
47	fmoved	sp@(4),fp0
48	fbeq	Ldone
49	fscalel	sp@(12),fp0
50Ldone:
51	fmoved	fp0,sp@-
52	movel	sp@+,d0
53	movel	sp@+,d1
54	rts
55
56| logb(x)
57| returns the unbiased exponent of x, a signed integer in double precision,
58| except that logb(0) is -INF, logb(INF) is +INF, and logb(NAN) is that NAN.
59_logb:
60	movw	sp@(4),d0
61	movw	#0x7FF0,d1	| exponent bits
62	andw	d1,d0		| mask off all else
63	cmpw	d1,d0		| max exponent?
64	bne	Lfinite		| no, is finite
65	fmoved	sp@(4),fp0	| yes, infinite or NaN
66	fbun	Ldone		| NaN returns NaN
67	fabsx	fp0		| +-inf returns inf
68	jra	Ldone
69Lfinite:
70	fmoved	sp@(4),fp0	| get entire number
71	fbne	Lnonz		| zero?
72	flog2x	fp0		| yes, log(0) a convenient source of -inf
73	jra	Ldone
74Lnonz:
75	fgetexpx	fp0	| get exponent
76	jra	Ldone
77
78| drem(x,y)
79| returns  x REM y  =  x - [x/y]*y , where [x/y] is the integer nearest x/y;
80| in half way case, choose the even one.
81_drem:
82	fmoved	sp@(4),fp0
83	fremd	sp@(12),fp0
84	fmoved	fp0,sp@-
85	movel	sp@+,d0
86	movel	sp@+,d1
87	rts
88
89| pow_P(x,y)
90| return x**y for x with sign=1 and finite y
91_pow_P:
92	flognd	sp@(4),fp0
93	fmuld	sp@(12),fp0
94	fetoxx	fp0
95	fmoved	fp0,sp@-
96	movel	sp@+,d0
97	movel	sp@+,d1
98	rts
99
100| atan2__A(y,x)
101| compute atan2(y,x) where x,y are finite and non-zero
102| called by atan2() after weeding out all the special cases
103_atan2__A:
104	moveq	#0,d0		| sign of result
105	fmoved	sp@(4),fp0	| get y
106	fboge	Lypos		| <0?
107	moveq	#1,d0		| yes, result is neg
108	fnegx	fp0		| make y pos
109Lypos:
110	fmoved	sp@(12),fp1	| get x
111	fboge	Lxpos		| <0?
112	fnegx	fp1		| yes, make x pos
113	fdivx	fp1,fp0		| y/x
114	fatanx	fp0,fp1		| atan(y/x)
115	fmovecr	#0,fp0		| get pi
116	fsubx	fp1,fp0		| pi - atan(y/x)
117	jra	Lsetsign
118Lxpos:
119	fdivx	fp1,fp0		| y/x
120	fatanx	fp0		| atan(y/x)
121Lsetsign:
122	tstl	d0		| should be neg?
123	jeq	Lrpos		| no, all done
124	fnegx	fp0		| yes, negate
125Lrpos:
126	fmoved	fp0,sp@-
127	movel	sp@+,d0
128	movel	sp@+,d1
129	rts
130