xref: /original-bsd/lib/libm/tahoe/cabs.s (revision c3e32dec)
1# Copyright (c) 1987, 1993
2#	The Regents of the University of California.  All rights reserved.
3#
4# %sccs.include.redist.sh%
5#
6#	@(#)cabs.s	8.1 (Berkeley) 06/04/93
7#
8	.data
9	.align	2
10_sccsid:
11.asciz	"@(#)cabs.s	8.1	8.1	(ucb.elefunt)	06/04/93"
12
13# double precision complex absolute value
14# CABS by W. Kahan, 9/7/80.
15# Revised for reserved operands by E. LeBlanc, 8/18/82
16# argument for complex absolute value by reference, *4(fp)
17# argument for cabs and hypot (C fcns) by value, 4(fp)
18# output is in r0:r1
19
20	.text
21	.align	2
22	.globl  _cabs
23	.globl  _hypot
24	.globl	_z_abs
25
26#	entry for c functions cabs and hypot
27_cabs:
28_hypot:
29	.word	0x807c		# save r2-r6, enable floating overflow
30	movl	16(fp),r3
31	movl	12(fp),r2	# r2:3 = y
32	movl	8(fp),r1
33	movl	4(fp),r0	# r0:1 = x
34	brb	1f
35#	entry for Fortran use, call by:   d = abs(z)
36_z_abs:
37	.word	0x807c		# save r2-r6, enable floating overflow
38	movl	4(fp),r4	# indirect addressing is necessary here
39	movl	12(r4),r3	#
40	movl	8(r4),r2	# r2:3 = y
41	movl	4(r4),r1	#
42	movl	(r4),r0		# r0:1 = x
431:	andl3	$0xff800000,r0,r4	# r4 has signed biased exp of x
44	cmpl	$0x80000000,r4
45	beql	2f		# x is a reserved operand, so return it
46	andl3	$0xff800000,r2,r5	# r5 has signed biased exp of y
47	cmpl	$0x80000000,r5
48	bneq	3f		# y isn't a reserved operand
49	movl	r3,r1
50	movl	r2,r0		# return y if it's reserved
512:	ret
52
533:	callf	$4,regs_set	# r0:1 = dsqrt(x^2+y^2)/2^r6
54	addl2	r6,r0		# unscaled cdabs in r0:1
55	jvc	2b		# unless it overflows
56	subl2	$0x800000,r0	# halve r0 to get meaningful overflow
57	ldd	r0
58	addd	r0		# overflow; r0 is half of true abs value
59	ret
60
61regs_set:
62	.word	0x0000
63	andl2	$0x7fffffff,r0	# r0:r1 = dabs(x)
64	andl2	$0x7fffffff,r2	# r2:r3 = dabs(y)
65	cmpl	r0,r2
66	bgeq	4f
67	movl	r1,r5
68	movl	r0,r4
69	movl	r3,r1
70	movl	r2,r0
71	movl	r5,r3
72	movl	r4,r2		# force y's exp <= x's exp
734:	andl3	$0xff800000,r0,r6	# r6 = exponent(x) + bias(129)
74	beql	5f		# if x = y = 0 then cdabs(x,y) = 0
75	subl2	$0x47800000,r6	# r6 = exponent(x) - 14
76	subl2	r6,r0		# 2^14 <= scaled x < 2^15
77	bitl	$0xff800000,r2
78	beql	5f		# if y = 0 return dabs(x)
79	subl2	r6,r2
80	cmpl	$0x37800000,r2	# if scaled y < 2^-18
81	bgtr	5f		#   return dabs(x)
82	ldd	r0
83	muld	r0
84	std	r0		# r0:1 = scaled x^2
85	ldd	r2
86	muld	r2		# acc = scaled y^2
87	addd	r0
88	std	r0
89	pushl	r1
90	pushl	r0
91	callf	$12,_sqrt	# r0:1 = dsqrt(x^2+y^2)/2^r6
925:	ret
93