xref: /csrg-svn/lib/libm/tahoe/cabs.s (revision 32004)
1*32004Szliu#
2*32004Szliu# Copyright (c) 1987 Regents of the University of California.
3*32004Szliu#
4*32004Szliu# Use and reproduction of this software are granted  in  accordance  with
5*32004Szliu# the terms and conditions specified in  the  Berkeley  Software  License
6*32004Szliu# Agreement (in particular, this entails acknowledgement of the programs'
7*32004Szliu# source, and inclusion of this notice) with the additional understanding
8*32004Szliu# that  all  recipients  should regard themselves as participants  in  an
9*32004Szliu# ongoing  research  project and hence should  feel  obligated  to report
10*32004Szliu# their  experiences (good or bad) with these elementary function  codes,
11*32004Szliu# using "sendbug 4bsd-bugs@BERKELEY", to the authors.
12*32004Szliu#
13*32004Szliu	.data
14*32004Szliu	.align	2
15*32004Szliu_sccsid:
16*32004Szliu.asciz	"@(#)cabs.s	1.1	1.1	(ucb.elefunt)	08/04/87"
17*32004Szliu
18*32004Szliu# double precision complex absolute value
19*32004Szliu# CABS by W. Kahan, 9/7/80.
20*32004Szliu# Revised for reserved operands by E. LeBlanc, 8/18/82
21*32004Szliu# argument for complex absolute value by reference, *4(fp)
22*32004Szliu# argument for cabs and hypot (C fcns) by value, 4(fp)
23*32004Szliu# output is in r0:r1
24*32004Szliu
25*32004Szliu	.text
26*32004Szliu	.align	2
27*32004Szliu	.globl  _cabs
28*32004Szliu	.globl  _hypot
29*32004Szliu	.globl	_z_abs
30*32004Szliu
31*32004Szliu#	entry for c functions cabs and hypot
32*32004Szliu_cabs:
33*32004Szliu_hypot:
34*32004Szliu	.word	0x807c		# save r2-r6, enable floating overflow
35*32004Szliu	movl	16(fp),r3
36*32004Szliu	movl	12(fp),r2	# r2:3 = y
37*32004Szliu	movl	8(fp),r1
38*32004Szliu	movl	4(fp),r0	# r0:1 = x
39*32004Szliu	brb	1f
40*32004Szliu#	entry for Fortran use, call by:   d = abs(z)
41*32004Szliu_z_abs:
42*32004Szliu	.word	0x807c		# save r2-r6, enable floating overflow
43*32004Szliu	movl	4(fp),r4	# indirect addressing is necessary here
44*32004Szliu	movl	12(r4),r3	#
45*32004Szliu	movl	8(r4),r2	# r2:3 = y
46*32004Szliu	movl	4(r4),r1	#
47*32004Szliu	movl	(r4),r0		# r0:1 = x
48*32004Szliu1:	andl3	$0xff800000,r0,r4	# r4 has signed biased exp of x
49*32004Szliu	cmpl	$0x80000000,r4
50*32004Szliu	beql	2f		# x is a reserved operand, so return it
51*32004Szliu	andl3	$0xff800000,r2,r5	# r5 has signed biased exp of y
52*32004Szliu	cmpl	$0x80000000,r5
53*32004Szliu	bneq	3f		# y isn't a reserved operand
54*32004Szliu	movl	r3,r1
55*32004Szliu	movl	r2,r0		# return y if it's reserved
56*32004Szliu2:	ret
57*32004Szliu
58*32004Szliu3:	callf	$4,regs_set	# r0:1 = dsqrt(x^2+y^2)/2^r6
59*32004Szliu	addl2	r6,r0		# unscaled cdabs in r0:1
60*32004Szliu	jvc	2b		# unless it overflows
61*32004Szliu	subl2	$0x800000,r0	# halve r0 to get meaningful overflow
62*32004Szliu	ldd	r0
63*32004Szliu	addd	r0		# overflow; r0 is half of true abs value
64*32004Szliu	ret
65*32004Szliu
66*32004Szliuregs_set:
67*32004Szliu	.word	0x0000
68*32004Szliu	andl2	$0x7fffffff,r0	# r0:r1 = dabs(x)
69*32004Szliu	andl2	$0x7fffffff,r2	# r2:r3 = dabs(y)
70*32004Szliu	cmpl	r0,r2
71*32004Szliu	bgeq	4f
72*32004Szliu	movl	r1,r5
73*32004Szliu	movl	r0,r4
74*32004Szliu	movl	r3,r1
75*32004Szliu	movl	r2,r0
76*32004Szliu	movl	r5,r3
77*32004Szliu	movl	r4,r2		# force y's exp <= x's exp
78*32004Szliu4:	andl3	$0xff800000,r0,r6	# r6 = exponent(x) + bias(129)
79*32004Szliu	beql	5f		# if x = y = 0 then cdabs(x,y) = 0
80*32004Szliu	subl2	$0x47800000,r6	# r6 = exponent(x) - 14
81*32004Szliu	subl2	r6,r0		# 2^14 <= scaled x < 2^15
82*32004Szliu	bitl	$0xff800000,r2
83*32004Szliu	beql	5f		# if y = 0 return dabs(x)
84*32004Szliu	subl2	r6,r2
85*32004Szliu	cmpl	$0x37800000,r2	# if scaled y < 2^-18
86*32004Szliu	bgtr	5f		#   return dabs(x)
87*32004Szliu	ldd	r0
88*32004Szliu	muld	r0
89*32004Szliu	std	r0		# r0:1 = scaled x^2
90*32004Szliu	ldd	r2
91*32004Szliu	muld	r2		# acc = scaled y^2
92*32004Szliu	addd	r0
93*32004Szliu	std	r0
94*32004Szliu	pushl	r1
95*32004Szliu	pushl	r0
96*32004Szliu	callf	$12,_sqrt	# r0:1 = dsqrt(x^2+y^2)/2^r6
97*32004Szliu5:	ret
98