xref: /original-bsd/lib/libm/tahoe/cabs.s (revision 648cab2a)
1#
2# Copyright (c) 1987 Regents of the University of California.
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms are permitted
6# provided that this notice is preserved and that due credit is given
7# to the University of California at Berkeley. The name of the University
8# may not be used to endorse or promote products derived from this
9# software without specific prior written permission. This software
10# is provided ``as is'' without express or implied warranty.
11#
12# All recipients should regard themselves as participants in an ongoing
13# research project and hence should feel obligated to report their
14# experiences (good or bad) with these elementary function codes, using
15# the sendbug(8) program, to the authors.
16#
17#	@(#)cabs.s	5.3 (Berkeley) 04/29/88
18#
19	.data
20	.align	2
21_sccsid:
22.asciz	"@(#)cabs.s	5.3	5.3	(ucb.elefunt)	04/29/88"
23
24# double precision complex absolute value
25# CABS by W. Kahan, 9/7/80.
26# Revised for reserved operands by E. LeBlanc, 8/18/82
27# argument for complex absolute value by reference, *4(fp)
28# argument for cabs and hypot (C fcns) by value, 4(fp)
29# output is in r0:r1
30
31	.text
32	.align	2
33	.globl  _cabs
34	.globl  _hypot
35	.globl	_z_abs
36
37#	entry for c functions cabs and hypot
38_cabs:
39_hypot:
40	.word	0x807c		# save r2-r6, enable floating overflow
41	movl	16(fp),r3
42	movl	12(fp),r2	# r2:3 = y
43	movl	8(fp),r1
44	movl	4(fp),r0	# r0:1 = x
45	brb	1f
46#	entry for Fortran use, call by:   d = abs(z)
47_z_abs:
48	.word	0x807c		# save r2-r6, enable floating overflow
49	movl	4(fp),r4	# indirect addressing is necessary here
50	movl	12(r4),r3	#
51	movl	8(r4),r2	# r2:3 = y
52	movl	4(r4),r1	#
53	movl	(r4),r0		# r0:1 = x
541:	andl3	$0xff800000,r0,r4	# r4 has signed biased exp of x
55	cmpl	$0x80000000,r4
56	beql	2f		# x is a reserved operand, so return it
57	andl3	$0xff800000,r2,r5	# r5 has signed biased exp of y
58	cmpl	$0x80000000,r5
59	bneq	3f		# y isn't a reserved operand
60	movl	r3,r1
61	movl	r2,r0		# return y if it's reserved
622:	ret
63
643:	callf	$4,regs_set	# r0:1 = dsqrt(x^2+y^2)/2^r6
65	addl2	r6,r0		# unscaled cdabs in r0:1
66	jvc	2b		# unless it overflows
67	subl2	$0x800000,r0	# halve r0 to get meaningful overflow
68	ldd	r0
69	addd	r0		# overflow; r0 is half of true abs value
70	ret
71
72regs_set:
73	.word	0x0000
74	andl2	$0x7fffffff,r0	# r0:r1 = dabs(x)
75	andl2	$0x7fffffff,r2	# r2:r3 = dabs(y)
76	cmpl	r0,r2
77	bgeq	4f
78	movl	r1,r5
79	movl	r0,r4
80	movl	r3,r1
81	movl	r2,r0
82	movl	r5,r3
83	movl	r4,r2		# force y's exp <= x's exp
844:	andl3	$0xff800000,r0,r6	# r6 = exponent(x) + bias(129)
85	beql	5f		# if x = y = 0 then cdabs(x,y) = 0
86	subl2	$0x47800000,r6	# r6 = exponent(x) - 14
87	subl2	r6,r0		# 2^14 <= scaled x < 2^15
88	bitl	$0xff800000,r2
89	beql	5f		# if y = 0 return dabs(x)
90	subl2	r6,r2
91	cmpl	$0x37800000,r2	# if scaled y < 2^-18
92	bgtr	5f		#   return dabs(x)
93	ldd	r0
94	muld	r0
95	std	r0		# r0:1 = scaled x^2
96	ldd	r2
97	muld	r2		# acc = scaled y^2
98	addd	r0
99	std	r0
100	pushl	r1
101	pushl	r0
102	callf	$12,_sqrt	# r0:1 = dsqrt(x^2+y^2)/2^r6
1035:	ret
104