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