xref: /original-bsd/lib/libm/tahoe/support.s (revision 1b4ef7de)
1/*
2 * Copyright (c) 1987, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7	.data
8	.align	2
9_sccsid:
10	.asciz	"@(#)support.s	8.1	(ucb.elefunt)	06/04/93"
11/*
12 * copysign(x,y),
13 * logb(x),
14 * scalb(x,N),
15 * finite(x),
16 * drem(x,y),
17 * Coded in vax assembly language by K. C. Ng 4/9/85.
18 * Re-coded in tahoe assembly language by Z. Alex Liu 7/13/87.
19 */
20/*
21 * double copysign(x,y)
22 * double x,y;
23 */
24	.globl	_copysign
25	.text
26	.align	2
27_copysign:
28	.word	0x0004			# save r2
29	movl	8(fp),r1
30	movl	4(fp),r0		# r0:r1 = x
31	andl3	$0x7f800000,r0,r2	# r2 = biased exponent of x
32	beql	1f			# if 0 or reserved op then return x
33	andl3	$0x80000000,12(fp),r2	# r2 = sign bit of y at bit-31
34	andl2	$0x7fffffff,r0		# replace x by |x|
35	orl2	r2,r0			# copy the sign bit of y to x
361:	ret
37/*
38 * double logb(x)
39 * double x;
40 */
41	.globl	_logb
42	.text
43	.align	2
44_logb:
45	.word	0x0000			# save nothing
46	andl3	$0x7f800000,4(fp),r0	# r0[b23:b30] = biased exponent of x
47	beql    1f
48	shrl	$23,r0,r0		# r0[b0:b7] = biased exponent of x
49	subl2	$129,r0			# r0 = unbiased exponent of x
50	cvld	r0			# acc = unbiased exponent of x (double)
51	std	r0			# r0 =  unbiased exponent of x (double)
52	ret
531:	movl	8(fp),r1		# 8(fp) must be moved first
54	movl	4(fp),r0		# r0:r1 = x (zero or reserved op)
55	blss	2f			# simply return if reserved op
56	movl	$0xfe000000,r1
57	movl	$0xcfffffff,r0		# -2147483647.0
582:	ret
59/*
60 * long finite(x)
61 * double x;
62 */
63	.globl	_finite
64	.text
65	.align	2
66_finite:
67	.word	0x0000			# save nothing
68	andl3	$0xff800000,4(fp),r0	# r0 = sign of x & its biased exponent
69	cmpl	r0,$0x80000000		# is x a reserved op?
70	beql	1f			# if so, return FALSE (0)
71	movl	$1,r0			# else return TRUE (1)
72	ret
731:	clrl	r0
74	ret
75/*
76 * double scalb(x,N)
77 * double x; int N;
78 */
79	.globl	_scalb
80	.set	ERANGE,34
81	.text
82	.align	2
83_scalb:
84	.word	0x000c			# save r2-r3
85	movl	8(fp),r1
86	movl	4(fp),r0		# r0:r1 = x (-128 <= Ex <= 126)
87	andl3	$0x7f800000,r0,r3	# r3[b23:b30] = biased exponent of x
88	beql	1f			# is x a 0 or a reserved operand?
89	movl	12(fp),r2		# r2 = N
90	cmpl	r2,$0xff		# if N >= 255
91	bgeq	2f			# then the result must overflow
92	cmpl	r2,$-0xff		# if N <= -255
93	bleq	3f			# then the result must underflow
94	shrl	$23,r3,r3		# r3[b0:b7] = biased exponent of x
95	addl2	r2,r3			# r3 = biased exponent of the result
96	bleq	3f			# if <= 0 then the result underflows
97	cmpl	r3,$0x100		# if >= 256 then the result overflows
98	bgeq	2f
99	shll	$23,r3,r3		# r3[b23:b30] = biased exponent of res.
100	andl2	$0x807fffff,r0
101	orl2	r3,r0			# r0:r1 = x*2^N
1021:	ret
1032:	pushl	$ERANGE			# if the result would overflow
104	callf	$8,_infnan		# and _infnan returns
105	andl3	$0x80000000,4(fp),r2	# get the sign of input arg
106	orl2	r2,r0			# re-attach the sign to r0:r1
107	ret
1083:	clrl	r1			# if the result would underflow
109	clrl	r0			# then return 0
110	ret
111/*
112 * double drem(x,y)
113 * double x,y;
114 * Returns x-n*y where n=[x/y] rounded (to even in the half way case).
115 */
116	.globl	_drem
117	.set	EDOM,33
118	.text
119	.align	2
120_drem:
121	.word	0x1ffc			# save r2-r12
122	movl	16(fp),r3
123	movl	12(fp),r2		# r2:r3 = y
124	movl	8(fp),r1
125	movl	4(fp),r0		# r0:r1 = x
126	andl3	$0xff800000,r0,r4
127	cmpl	r4,$0x80000000		# is x a reserved operand?
128	beql	1f			# if yes then propagate x and return
129	andl3	$0xff800000,r2,r4
130	cmpl	r4,$0x80000000		# is y a reserved operand?
131	bneq	2f
132	movl	r3,r1
133	movl	r2,r0			# if yes then propagate y and return
1341:	ret
135
1362:	tstl	r4			# is y a 0?
137	bneq	3f
138	pushl	$EDOM			# if so then generate reserved op fault
139	callf	$8,_infnan
140	ret
141
1423:	andl2	$0x7fffffff,r2		# r2:r3 = y <- |y|
143	clrl	r12			# r12 = nx := 0
144	cmpl	r2,$0x1c800000		# Ey ? 57
145	bgtr	4f			# if Ey > 57 goto 4
146	addl2	$0x1c800000,r2		# scale up y by 2**57
147	movl	$0x1c800000,r12		# r12[b23:b30] = nx = 57
1484:	pushl	r12			# pushed onto stack: nf := nx
149	andl3	$0x80000000,r0,-(sp)	# pushed onto stack: sign of x
150	andl2	$0x7fffffff,r0		# r0:r1 = x <- |x|
151	movl	r3,r11			# r10:r11 = y1 = y w/ last 27 bits 0
152	andl3	$0xf8000000,r10,r11	# clear last 27 bits of y1
153
154Loop:	cmpd2	r0,r2			# x ? y
155	bleq	6f			# if x <= y goto 6
156 /* 					# begin argument reduction */
157	movl	r3,r5
158	movl	r2,r4			# r4:r5 = t = y
159	movl	r11,r7
160	movl	r10,r6			# r6:r7 = t1 = y1
161	andl3	$0x7f800000,r0,r8	# r8[b23:b30] = Ex:biased exponent of x
162	andl3	$0x7f800000,r2,r9	# r9[b23:b30] = Ey:biased exponent of y
163	subl2	r9,r8			# r8[b23:b30] = Ex-Ey
164	subl2	$0x0c800000,r8		# r8[b23:b30] = k = Ex-Ey-25
165	blss	5f			# if k < 0 goto 5
166	addl2	r8,r4			# t += k
167	addl2	r8,r6			# t1 += k, scale up t and t1
1685:	ldd	r0			# acc = x
169	divd	r4			# acc = x/t
170	cvdl	r8			# r8 = n = [x/t] truncated
171	cvld	r8			# acc = dble(n)
172	std	r8			# r8:r9 = dble(n)
173	ldd	r4			# acc = t
174	subd	r6			# acc = t-t1
175	muld	r8			# acc = n*(t-t1)
176	std	r4			# r4:r5 = n*(t-t1)
177	ldd	r6			# acc = t1
178	muld	r8			# acc = n*t1
179	subd	r0			# acc = n*t1-x
180	negd				# acc = x-n*t1
181	subd	r4			# acc = (x-n*t1)-n*(t-t1)
182	std	r0			# r0:r1 = (x-n*t1)-n*(t-t1)
183	brb	Loop
184
1856:	movl	r12,r6			# r6 = nx
186	beql	7f			# if nx == 0 goto 7
187	addl2	r6,r0			# x <- x*2**57:scale x up by nx
188	clrl	r12			# clear nx
189	brb	Loop
190
1917:	movl	r3,r5
192	movl	r2,r4			# r4:r5 = y
193	subl2	$0x800000,r4		# r4:r5 = y/2
194	cmpd2	r0,r4			# x ? y/2
195	blss	9f			# if x < y/2 goto 9
196	bgtr	8f			# if x > y/2 goto 8
197	ldd	r8			# acc = dble(n)
198	cvdl	r8			# r8 = ifix(dble(n))
199	bbc	$0,r8,9f		# if the last bit is zero, goto 9
2008:	ldd	r0			# acc = x
201	subd	r2			# acc = x-y
202	std	r0			# r0:r1 = x-y
2039:	xorl2	(sp)+,r0		# x^sign (exclusive or)
204	movl	(sp)+,r6		# r6 = nf
205	andl3	$0x7f800000,r0,r8	# r8 = biased exponent of x
206	andl2	$0x807fffff,r0		# r0 = x w/ exponent zapped
207	subl2	r6,r8			# r8 = Ex-nf
208	bgtr	0f			# if Ex-nf > 0 goto 0
209	clrl	r8			# clear r8
210	clrl	r0
211	clrl	r1			# x underflows to zero
2120:	orl2	r8,r0			# put r8 into x's exponent field
213	ret
214