xref: /csrg-svn/lib/libm/tahoe/support.s (revision 61316)
134128Sbostic/*
2*61316Sbostic * Copyright (c) 1987, 1993
3*61316Sbostic *	The Regents of the University of California.  All rights reserved.
434128Sbostic *
542658Sbostic * %sccs.include.redist.c%
631840Szliu */
731840Szliu	.data
831840Szliu	.align	2
931840Szliu_sccsid:
10*61316Sbostic	.asciz	"@(#)support.s	8.1	(ucb.elefunt)	06/04/93"
1131840Szliu/*
1231840Szliu * copysign(x,y),
1331840Szliu * logb(x),
1431840Szliu * scalb(x,N),
1531840Szliu * finite(x),
1631840Szliu * drem(x,y),
1731840Szliu * Coded in vax assembly language by K. C. Ng 4/9/85.
1831840Szliu * Re-coded in tahoe assembly language by Z. Alex Liu 7/13/87.
1931840Szliu */
2031840Szliu/*
2131840Szliu * double copysign(x,y)
2231840Szliu * double x,y;
2331840Szliu */
2431840Szliu	.globl	_copysign
2531840Szliu	.text
2631842Szliu	.align	2
2731840Szliu_copysign:
2831840Szliu	.word	0x0004			# save r2
2931840Szliu	movl	8(fp),r1
3031840Szliu	movl	4(fp),r0		# r0:r1 = x
3131840Szliu	andl3	$0x7f800000,r0,r2	# r2 = biased exponent of x
3231840Szliu	beql	1f			# if 0 or reserved op then return x
3331840Szliu	andl3	$0x80000000,12(fp),r2	# r2 = sign bit of y at bit-31
3431840Szliu	andl2	$0x7fffffff,r0		# replace x by |x|
3531840Szliu	orl2	r2,r0			# copy the sign bit of y to x
3631840Szliu1:	ret
3731840Szliu/*
3831840Szliu * double logb(x)
3931840Szliu * double x;
4031840Szliu */
4131840Szliu	.globl	_logb
4231840Szliu	.text
4331842Szliu	.align	2
4431840Szliu_logb:
4531842Szliu	.word	0x0000			# save nothing
4631840Szliu	andl3	$0x7f800000,4(fp),r0	# r0[b23:b30] = biased exponent of x
4731840Szliu	beql    1f
4831840Szliu	shrl	$23,r0,r0		# r0[b0:b7] = biased exponent of x
4931840Szliu	subl2	$129,r0			# r0 = unbiased exponent of x
5031840Szliu	cvld	r0			# acc = unbiased exponent of x (double)
5131840Szliu	std	r0			# r0 =  unbiased exponent of x (double)
5231840Szliu	ret
5331840Szliu1:	movl	8(fp),r1		# 8(fp) must be moved first
5431840Szliu	movl	4(fp),r0		# r0:r1 = x (zero or reserved op)
5531840Szliu	blss	2f			# simply return if reserved op
5631840Szliu	movl	$0xfe000000,r1
5731840Szliu	movl	$0xcfffffff,r0		# -2147483647.0
5831840Szliu2:	ret
5931840Szliu/*
6031840Szliu * long finite(x)
6131840Szliu * double x;
6231840Szliu */
6331840Szliu	.globl	_finite
6431840Szliu	.text
6531842Szliu	.align	2
6631840Szliu_finite:
6731842Szliu	.word	0x0000			# save nothing
6831840Szliu	andl3	$0xff800000,4(fp),r0	# r0 = sign of x & its biased exponent
6931840Szliu	cmpl	r0,$0x80000000		# is x a reserved op?
7031840Szliu	beql	1f			# if so, return FALSE (0)
7131840Szliu	movl	$1,r0			# else return TRUE (1)
7231840Szliu	ret
7331840Szliu1:	clrl	r0
7431840Szliu	ret
7531840Szliu/*
7631840Szliu * double scalb(x,N)
7731840Szliu * double x; int N;
7831840Szliu */
7931840Szliu	.globl	_scalb
8031840Szliu	.set	ERANGE,34
8131840Szliu	.text
8231842Szliu	.align	2
8331840Szliu_scalb:
8431842Szliu	.word	0x000c			# save r2-r3
8531840Szliu	movl	8(fp),r1
8631840Szliu	movl	4(fp),r0		# r0:r1 = x (-128 <= Ex <= 126)
8731840Szliu	andl3	$0x7f800000,r0,r3	# r3[b23:b30] = biased exponent of x
8831840Szliu	beql	1f			# is x a 0 or a reserved operand?
8931840Szliu	movl	12(fp),r2		# r2 = N
9031840Szliu	cmpl	r2,$0xff		# if N >= 255
9131840Szliu	bgeq	2f			# then the result must overflow
9231840Szliu	cmpl	r2,$-0xff		# if N <= -255
9331840Szliu	bleq	3f			# then the result must underflow
9431840Szliu	shrl	$23,r3,r3		# r3[b0:b7] = biased exponent of x
9531840Szliu	addl2	r2,r3			# r3 = biased exponent of the result
9631840Szliu	bleq	3f			# if <= 0 then the result underflows
9731840Szliu	cmpl	r3,$0x100		# if >= 256 then the result overflows
9831840Szliu	bgeq	2f
9931840Szliu	shll	$23,r3,r3		# r3[b23:b30] = biased exponent of res.
10031840Szliu	andl2	$0x807fffff,r0
10131840Szliu	orl2	r3,r0			# r0:r1 = x*2^N
10231840Szliu1:	ret
10331840Szliu2:	pushl	$ERANGE			# if the result would overflow
10431840Szliu	callf	$8,_infnan		# and _infnan returns
10531840Szliu	andl3	$0x80000000,4(fp),r2	# get the sign of input arg
10631840Szliu	orl2	r2,r0			# re-attach the sign to r0:r1
10731840Szliu	ret
10831840Szliu3:	clrl	r1			# if the result would underflow
10931840Szliu	clrl	r0			# then return 0
11031840Szliu	ret
11131840Szliu/*
11231840Szliu * double drem(x,y)
11331840Szliu * double x,y;
11431840Szliu * Returns x-n*y where n=[x/y] rounded (to even in the half way case).
11531840Szliu */
11631840Szliu	.globl	_drem
11731840Szliu	.set	EDOM,33
11831840Szliu	.text
11931842Szliu	.align	2
12031840Szliu_drem:
12131840Szliu	.word	0x1ffc			# save r2-r12
12231840Szliu	movl	16(fp),r3
12331840Szliu	movl	12(fp),r2		# r2:r3 = y
12431840Szliu	movl	8(fp),r1
12531840Szliu	movl	4(fp),r0		# r0:r1 = x
12631840Szliu	andl3	$0xff800000,r0,r4
12731840Szliu	cmpl	r4,$0x80000000		# is x a reserved operand?
12831840Szliu	beql	1f			# if yes then propagate x and return
12931840Szliu	andl3	$0xff800000,r2,r4
13031840Szliu	cmpl	r4,$0x80000000		# is y a reserved operand?
13131840Szliu	bneq	2f
13231840Szliu	movl	r3,r1
13331840Szliu	movl	r2,r0			# if yes then propagate y and return
13431840Szliu1:	ret
13531840Szliu
13631840Szliu2:	tstl	r4			# is y a 0?
13731840Szliu	bneq	3f
13831840Szliu	pushl	$EDOM			# if so then generate reserved op fault
13931840Szliu	callf	$8,_infnan
14031840Szliu	ret
14131840Szliu
14231840Szliu3:	andl2	$0x7fffffff,r2		# r2:r3 = y <- |y|
14331840Szliu	clrl	r12			# r12 = nx := 0
14431840Szliu	cmpl	r2,$0x1c800000		# Ey ? 57
14531840Szliu	bgtr	4f			# if Ey > 57 goto 4
14631840Szliu	addl2	$0x1c800000,r2		# scale up y by 2**57
14731840Szliu	movl	$0x1c800000,r12		# r12[b23:b30] = nx = 57
14831840Szliu4:	pushl	r12			# pushed onto stack: nf := nx
14931840Szliu	andl3	$0x80000000,r0,-(sp)	# pushed onto stack: sign of x
15031840Szliu	andl2	$0x7fffffff,r0		# r0:r1 = x <- |x|
15131840Szliu	movl	r3,r11			# r10:r11 = y1 = y w/ last 27 bits 0
15231840Szliu	andl3	$0xf8000000,r10,r11	# clear last 27 bits of y1
15331840Szliu
15431840SzliuLoop:	cmpd2	r0,r2			# x ? y
15531840Szliu	bleq	6f			# if x <= y goto 6
15631840Szliu /* 					# begin argument reduction */
15731840Szliu	movl	r3,r5
15831840Szliu	movl	r2,r4			# r4:r5 = t = y
15931840Szliu	movl	r11,r7
16031840Szliu	movl	r10,r6			# r6:r7 = t1 = y1
16131840Szliu	andl3	$0x7f800000,r0,r8	# r8[b23:b30] = Ex:biased exponent of x
16231840Szliu	andl3	$0x7f800000,r2,r9	# r9[b23:b30] = Ey:biased exponent of y
16331840Szliu	subl2	r9,r8			# r8[b23:b30] = Ex-Ey
16431840Szliu	subl2	$0x0c800000,r8		# r8[b23:b30] = k = Ex-Ey-25
16531840Szliu	blss	5f			# if k < 0 goto 5
16631840Szliu	addl2	r8,r4			# t += k
16731840Szliu	addl2	r8,r6			# t1 += k, scale up t and t1
16831840Szliu5:	ldd	r0			# acc = x
16931840Szliu	divd	r4			# acc = x/t
17031840Szliu	cvdl	r8			# r8 = n = [x/t] truncated
17131840Szliu	cvld	r8			# acc = dble(n)
17231840Szliu	std	r8			# r8:r9 = dble(n)
17331840Szliu	ldd	r4			# acc = t
17431840Szliu	subd	r6			# acc = t-t1
17531840Szliu	muld	r8			# acc = n*(t-t1)
17631840Szliu	std	r4			# r4:r5 = n*(t-t1)
17731840Szliu	ldd	r6			# acc = t1
17831840Szliu	muld	r8			# acc = n*t1
17931840Szliu	subd	r0			# acc = n*t1-x
18031840Szliu	negd				# acc = x-n*t1
18131840Szliu	subd	r4			# acc = (x-n*t1)-n*(t-t1)
18231840Szliu	std	r0			# r0:r1 = (x-n*t1)-n*(t-t1)
18331840Szliu	brb	Loop
18431840Szliu
18531840Szliu6:	movl	r12,r6			# r6 = nx
18631840Szliu	beql	7f			# if nx == 0 goto 7
18731840Szliu	addl2	r6,r0			# x <- x*2**57:scale x up by nx
18831840Szliu	clrl	r12			# clear nx
18931840Szliu	brb	Loop
19031840Szliu
19131840Szliu7:	movl	r3,r5
19231840Szliu	movl	r2,r4			# r4:r5 = y
19331840Szliu	subl2	$0x800000,r4		# r4:r5 = y/2
19431840Szliu	cmpd2	r0,r4			# x ? y/2
19531840Szliu	blss	9f			# if x < y/2 goto 9
19631840Szliu	bgtr	8f			# if x > y/2 goto 8
19731840Szliu	ldd	r8			# acc = dble(n)
19831840Szliu	cvdl	r8			# r8 = ifix(dble(n))
19931840Szliu	bbc	$0,r8,9f		# if the last bit is zero, goto 9
20031840Szliu8:	ldd	r0			# acc = x
20131840Szliu	subd	r2			# acc = x-y
20231840Szliu	std	r0			# r0:r1 = x-y
20331840Szliu9:	xorl2	(sp)+,r0		# x^sign (exclusive or)
20431840Szliu	movl	(sp)+,r6		# r6 = nf
20531840Szliu	andl3	$0x7f800000,r0,r8	# r8 = biased exponent of x
20631840Szliu	andl2	$0x807fffff,r0		# r0 = x w/ exponent zapped
20731840Szliu	subl2	r6,r8			# r8 = Ex-nf
20831840Szliu	bgtr	0f			# if Ex-nf > 0 goto 0
20931840Szliu	clrl	r8			# clear r8
21031840Szliu	clrl	r0
21131840Szliu	clrl	r1			# x underflows to zero
21231840Szliu0:	orl2	r8,r0			# put r8 into x's exponent field
21331840Szliu	ret
214