xref: /csrg-svn/lib/libm/vax/support.s (revision 61319)
134125Sbostic/*
2*61319Sbostic * Copyright (c) 1985, 1993
3*61319Sbostic *	The Regents of the University of California.  All rights reserved.
434125Sbostic *
542658Sbostic * %sccs.include.redist.c%
634125Sbostic *
7*61319Sbostic *	@(#)support.s	8.1 (Berkeley) 06/04/93
824729Selefunt */
924729Selefunt	.data
1024729Selefunt	.align	2
1124729Selefunt_sccsid:
12*61319Sbostic.asciz	"@(#)support.s	1.3 (Berkeley) 8/21/85; 8.1 (ucb.elefunt) 06/04/93"
1324729Selefunt
1424729Selefunt/*
1524572Szliu * copysign(x,y),
1624572Szliu * logb(x),
1724572Szliu * scalb(x,N),
1824572Szliu * finite(x),
1924572Szliu * drem(x,y),
2024572Szliu * Coded in vax assembly language by K.C. Ng,  3/14/85.
2124572Szliu * Revised by K.C. Ng on 4/9/85.
2224572Szliu */
2324572Szliu
2424572Szliu/*
2524572Szliu * double copysign(x,y)
2624572Szliu * double x,y;
2724572Szliu */
2824572Szliu	.globl	_copysign
2924572Szliu	.text
3024572Szliu	.align	1
3124572Szliu_copysign:
3224572Szliu	.word	0x4
3324572Szliu	movq	4(ap),r0		# load x into r0
3424572Szliu	bicw3	$0x807f,r0,r2		# mask off the exponent of x
3524572Szliu	beql	Lz			# if zero or reserved op then return x
3624572Szliu	bicw3	$0x7fff,12(ap),r2	# copy the sign bit of y into r2
3724572Szliu	bicw2	$0x8000,r0		# replace x by |x|
3824572Szliu	bisw2	r2,r0			# copy the sign bit of y to x
3924572SzliuLz:	ret
4024572Szliu
4124572Szliu/*
4224572Szliu * double logb(x)
4324572Szliu * double x;
4424572Szliu */
4524572Szliu	.globl	_logb
4624572Szliu	.text
4724572Szliu	.align	1
4824572Szliu_logb:
4924572Szliu	.word	0x0
5024572Szliu	bicl3	$0xffff807f,4(ap),r0	# mask off the exponent of x
5124572Szliu	beql    Ln
5224572Szliu	ashl	$-7,r0,r0		# get the bias exponent
5324572Szliu	subl2	$129,r0			# get the unbias exponent
5424572Szliu	cvtld	r0,r0			# return the answer in double
5524572Szliu	ret
5624572SzliuLn:	movq	4(ap),r0		# r0:1 = x (zero or reserved op)
5724572Szliu	bneq	1f			# simply return if reserved op
5824572Szliu	movq 	$0x0000fe00ffffcfff,r0  # -2147483647.0
5924572Szliu1:	ret
6024572Szliu
6124572Szliu/*
6224572Szliu * long finite(x)
6324572Szliu * double x;
6424572Szliu */
6524572Szliu	.globl	_finite
6624572Szliu	.text
6724572Szliu	.align	1
6824572Szliu_finite:
6924572Szliu	.word	0x0000
7024572Szliu	bicw3	$0x7f,4(ap),r0		# mask off the mantissa
7124572Szliu	cmpw	r0,$0x8000		# to see if x is the reserved op
7224572Szliu	beql	1f			# if so, return FALSE (0)
7324572Szliu	movl	$1,r0			# else return TRUE (1)
7424572Szliu	ret
7524572Szliu1:	clrl	r0
7624572Szliu	ret
7724572Szliu
7824572Szliu/*
7924572Szliu * double scalb(x,N)
8024572Szliu * double x; int N;
8124572Szliu */
8224572Szliu	.globl	_scalb
8324572Szliu	.set	ERANGE,34
8424572Szliu	.text
8524572Szliu	.align	1
8624572Szliu_scalb:
8724572Szliu	.word	0xc
8824572Szliu	movq	4(ap),r0
8924572Szliu	bicl3	$0xffff807f,r0,r3
9024572Szliu	beql	ret1			# 0 or reserved operand
9124572Szliu	movl	12(ap),r2
9224572Szliu	cmpl	r2,$0x12c
9324572Szliu	bgeq	ovfl
9424572Szliu	cmpl	r2,$-0x12c
9524572Szliu	bleq	unfl
9624572Szliu	ashl	$7,r2,r2
9724572Szliu	addl2	r2,r3
9824572Szliu	bleq	unfl
9924572Szliu	cmpl	r3,$0x8000
10024572Szliu	bgeq	ovfl
10124572Szliu	addl2	r2,r0
10224572Szliu	ret
10324572Szliuovfl:	pushl	$ERANGE
10424572Szliu	calls	$1,_infnan		# if it returns
10524572Szliu	bicw3	$0x7fff,4(ap),r2	# get the sign of input arg
10624572Szliu	bisw2	r2,r0			# re-attach the sign to r0/1
10724572Szliu	ret
10824572Szliuunfl:	movq	$0,r0
10924572Szliuret1:	ret
11024572Szliu
11124572Szliu/*
11224572Szliu * DREM(X,Y)
11324572Szliu * RETURN X REM Y =X-N*Y, N=[X/Y] ROUNDED (ROUNDED TO EVEN IN THE HALF WAY CASE)
11424572Szliu * DOUBLE PRECISION (VAX D format 56 bits)
11524572Szliu * CODED IN VAX ASSEMBLY LANGUAGE BY K.C. NG, 4/8/85.
11624572Szliu */
11724572Szliu	.globl	_drem
11824572Szliu	.set	EDOM,33
11924572Szliu	.text
12024572Szliu	.align	1
12124572Szliu_drem:
12224572Szliu	.word	0xffc
12324572Szliu	subl2	$12,sp
12424572Szliu	movq	4(ap),r0		#r0=x
12524572Szliu	movq	12(ap),r2		#r2=y
12624572Szliu	jeql	Rop			#if y=0 then generate reserved op fault
12724572Szliu	bicw3	$0x007f,r0,r4		#check if x is Rop
12824572Szliu	cmpw	r4,$0x8000
12924572Szliu	jeql	Ret			#if x is Rop then return Rop
13024572Szliu	bicl3	$0x007f,r2,r4		#check if y is Rop
13124572Szliu	cmpw	r4,$0x8000
13224572Szliu	jeql	Ret			#if y is Rop then return Rop
13324572Szliu	bicw2	$0x8000,r2		#y  := |y|
13424572Szliu	movw	$0,-4(fp)		#-4(fp) = nx := 0
13524572Szliu	cmpw	r2,$0x1c80		#yexp ? 57
13624572Szliu	bgtr	C1			#if yexp > 57 goto C1
13724572Szliu	addw2	$0x1c80,r2		#scale up y by 2**57
13824572Szliu	movw	$0x1c80,-4(fp)		#nx := 57 (exponent field)
13924572SzliuC1:
14024572Szliu	movw	-4(fp),-8(fp)		#-8(fp) = nf := nx
14124572Szliu	bicw3	$0x7fff,r0,-12(fp)	#-12(fp) = sign of x
14224572Szliu	bicw2	$0x8000,r0		#x  := |x|
14324572Szliu	movq	r2,r10			#y1 := y
14424572Szliu	bicl2	$0xffff07ff,r11		#clear the last 27 bits of y1
14524572Szliuloop:
14624572Szliu	cmpd	r0,r2			#x ? y
14724572Szliu	bleq	E1			#if x <= y goto E1
14824572Szliu /* begin argument reduction */
14924572Szliu	movq	r2,r4			#t =y
15024572Szliu	movq	r10,r6			#t1=y1
15124572Szliu	bicw3	$0x807f,r0,r8		#xexp= exponent of x
15224572Szliu	bicw3	$0x807f,r2,r9		#yexp= exponent fo y
15324572Szliu	subw2	r9,r8			#xexp-yexp
15424572Szliu	subw2	$0x0c80,r8		#k=xexp-yexp-25(exponent bit field)
15524572Szliu	blss	C2			#if k<0 goto C2
15624572Szliu	addw2	r8,r4			#t +=k
15724572Szliu	addw2	r8,r6			#t1+=k, scale up t and t1
15824572SzliuC2:
15924572Szliu	divd3	r4,r0,r8		#x/t
16024572Szliu	cvtdl	r8,r8			#n=[x/t] truncated
16124572Szliu	cvtld	r8,r8			#float(n)
16224572Szliu	subd2	r6,r4			#t:=t-t1
16324572Szliu	muld2	r8,r4			#n*(t-t1)
16424572Szliu	muld2	r8,r6			#n*t1
16524572Szliu	subd2	r6,r0			#x-n*t1
16624572Szliu	subd2	r4,r0			#(x-n*t1)-n*(t-t1)
16724572Szliu	brb	loop
16824572SzliuE1:
16924572Szliu	movw	-4(fp),r6		#r6=nx
17024572Szliu	beql	C3			#if nx=0 goto C3
17124572Szliu	addw2	r6,r0			#x:=x*2**57 scale up x by nx
17224572Szliu	movw	$0,-4(fp)		#clear nx
17324572Szliu	brb	loop
17424572SzliuC3:
17524572Szliu	movq	r2,r4			#r4 = y
17624572Szliu	subw2	$0x80,r4		#r4 = y/2
17724572Szliu	cmpd	r0,r4			#x:y/2
17824572Szliu	blss	E2			#if x < y/2 goto E2
17924572Szliu	bgtr	C4			#if x > y/2 goto C4
18024572Szliu	cvtdl	r8,r8			#ifix(float(n))
18124572Szliu	blbc	r8,E2			#if the last bit is zero, goto E2
18224572SzliuC4:
18324572Szliu	subd2	r2,r0			#x-y
18424572SzliuE2:
18524572Szliu	xorw2	-12(fp),r0		#x^sign (exclusive or)
18624572Szliu	movw	-8(fp),r6		#r6=nf
18724572Szliu	bicw3	$0x807f,r0,r8		#r8=exponent of x
18824572Szliu	bicw2	$0x7f80,r0		#clear the exponent of x
18924572Szliu	subw2	r6,r8			#r8=xexp-nf
19024572Szliu	bgtr	C5			#if xexp-nf is positive goto C5
19124572Szliu	movw	$0,r8			#clear r8
19224572Szliu	movq	$0,r0			#x underflow to zero
19324572SzliuC5:
19424572Szliu	bisw2	r8,r0			#put r8 into x's exponent field
19524572Szliu	ret
19624572SzliuRop:					#Reserved operand
19724572Szliu	pushl	$EDOM
19824572Szliu	calls	$1,_infnan		#generate reserved op fault
19924572Szliu	ret
20024572SzliuRet:
20124572Szliu	movq	$0x8000,r0		#propagate reserved op
20224572Szliu	ret
203