xref: /csrg-svn/lib/libm/vax/cabs.s (revision 24729)
1#
2# Copyright (c) 1985 Regents of the University of California.
3#
4# Use and reproduction of this software are granted  in  accordance  with
5# the terms and conditions specified in  the  Berkeley  Software  License
6# Agreement (in particular, this entails acknowledgement of the programs'
7# source, and inclusion of this notice) with the additional understanding
8# that  all  recipients  should regard themselves as participants  in  an
9# ongoing  research  project and hence should  feel  obligated  to report
10# their  experiences (good or bad) with these elementary function  codes,
11# using "sendbug 4bsd-bugs@BERKELEY", to the authors.
12#
13	.data
14	.align	2
15_sccsid:
16.asciz	"@(#)cabs.s	1.2 (Berkeley) 8/21/85; 1.3 (ucb.elefunt) 09/12/85"
17
18# double precision complex absolute value
19# CABS by W. Kahan, 9/7/80.
20# Revised for reserved operands by E. LeBlanc, 8/18/82
21# argument for complex absolute value by reference, *4(ap)
22# argument for cabs and hypot (C fcns) by value, 4(ap)
23# output is in r0:r1 (error less than 0.86 ulps)
24
25	.text
26	.align	1
27	.globl  _cabs
28	.globl  _hypot
29	.globl	_z_abs
30	.globl	libm$cdabs_r6
31	.globl	libm$dsqrt_r5
32
33#	entry for c functions cabs and hypot
34_cabs:
35_hypot:
36	.word	0x807c		# save r2-r6, enable floating overflow
37	movq	4(ap),r0	# r0:1 = x
38	movq	12(ap),r2	# r2:3 = y
39	jmp	cabs2
40#	entry for Fortran use, call by:   d = abs(z)
41_z_abs:
42	.word	0x807c		# save r2-r6, enable floating overflow
43	movl	4(ap),r2	# indirect addressing is necessary here
44	movq	(r2)+,r0	# r0:1 = x
45	movq	(r2),r2		# r2:3 = y
46
47cabs2:
48	bicw3	$0x7f,r0,r4	# r4 has signed biased exp of x
49	cmpw	$0x8000,r4
50	jeql	return		# x is a reserved operand, so return it
51	bicw3	$0x7f,r2,r5	# r5 has signed biased exp of y
52	cmpw	$0x8000,r5
53	jneq	cont		# y isn't a reserved operand
54	movq	r2,r0		# return y if it's reserved
55	ret
56
57cont:
58	bsbb	regs_set	# r0:1 = dsqrt(x^2+y^2)/2^r6
59	addw2	r6,r0		# unscaled cdabs in r0:1
60	jvc	return		# unless it overflows
61	subw2	$0x80,r0	# halve r0 to get meaningful overflow
62	addd2	r0,r0		# overflow; r0 is half of true abs value
63return:
64	ret
65
66libm$cdabs_r6:			# ENTRY POINT for cdsqrt
67				# calculates a scaled (factor in r6)
68				# complex absolute value
69
70	movq	(r4)+,r0	# r0:r1 = x via indirect addressing
71	movq	(r4),r2		# r2:r3 = y via indirect addressing
72
73	bicw3	$0x7f,r0,r5	# r5 has signed biased exp of x
74	cmpw	$0x8000,r5
75	jeql	cdreserved	# x is a reserved operand
76	bicw3	$0x7f,r2,r5	# r5 has signed biased exp of y
77	cmpw	$0x8000,r5
78	jneq	regs_set	# y isn't a reserved operand either?
79
80cdreserved:
81	movl	*4(ap),r4	# r4 -> (u,v), if x or y is reserved
82	movq	r0,(r4)+	# copy u and v as is and return
83	movq	r2,(r4)		# (again addressing is indirect)
84	ret
85
86regs_set:
87	bicw2	$0x8000,r0	# r0:r1 = dabs(x)
88	bicw2	$0x8000,r2	# r2:r3 = dabs(y)
89	cmpw	r0,r2
90	jgeq	ordered
91	movq	r0,r4
92	movq	r2,r0
93	movq	r4,r2		# force y's exp <= x's exp
94ordered:
95	bicw3	$0x7f,r0,r6	# r6 = exponent(x) + bias(129)
96	jeql	retsb		# if x = y = 0 then cdabs(x,y) = 0
97	subw2	$0x4780,r6	# r6 = exponent(x) - 14
98	subw2	r6,r0		# 2^14 <= scaled x < 2^15
99	bitw	$0xff80,r2
100	jeql	retsb		# if y = 0 return dabs(x)
101	subw2	r6,r2
102	cmpw	$0x3780,r2	# if scaled y < 2^-18
103	jgtr	retsb		#   return dabs(x)
104	emodd	r0,$0,r0,r4,r0	# r4 + r0:1 = scaled x^2
105	emodd	r2,$0,r2,r5,r2	# r5 + r2:3 = scaled y^2
106	addd2	r2,r0
107	addl2	r5,r4
108	cvtld	r4,r2
109	addd2	r2,r0		# r0:1 = scaled x^2 + y^2
110	jmp	libm$dsqrt_r5	# r0:1 = dsqrt(x^2+y^2)/2^r6
111retsb:
112	rsb			# error < 0.86 ulp
113