xref: /original-bsd/lib/libm/tahoe/cbrt.s (revision 3839ed90)
1# Copyright (c) 1987 Regents of the University of California.
2# All rights reserved.
3#
4# %sccs.include.redist.sh%
5#
6#	@(#)cbrt.s	5.5 (Berkeley) 10/09/90
7#
8	.data
9	.align	2
10_sccsid:
11.asciz	"@(#)cbrt.s	5.5	(ucb.elefunt) 10/09/90"
12
13# double cbrt(double arg)
14# W. Kahan, 10/13/80. revised 1/13/84 for keeping sign symmetry
15# Re-coded in tahoe assembly language by Z. Alex Liu (7/13/87)
16# Max error less than 0.667 ULPs _if_ +,-,*,/ were all correctly rounded...
17	.globl	_cbrt
18	.globl	_d_cbrt
19	.globl	_dcbrt_
20	.text
21	.align	2
22_cbrt:
23_d_cbrt:
24	.word	0x01fc		# save r2-r8
25	movl	4(fp),r0	# r0:r1 = x
26	movl	8(fp),r1
27	brb	1f
28_dcbrt_:
29	.word	0x01fc		# save r2-r8
30	movl	4(fp),r8
31	movl	(r8),r0
32	movl	4(r8),r1	# r0:r1 = x
33
341:	andl3	$0x7f800000,r0,r2	# biased exponent of x
35	beql	return		# dcbrt(0)=0  dcbrt(res)=res. operand
36	andl3	$0x80000000,r0,r8	# r8 has sign(x)
37	xorl2	r8,r0		# r0 is abs(x)
38	movl	r0,r2		# r2 has abs(x)
39	divl2	$3,r2		# rough dcbrt with bias/3
40	addl2	B,r2		# restore bias, diminish fraction
41	ldf	r2		# acc = |q|=|dcbrt| to 5 bits
42	mulf	r2		# acc = qq
43	divf	r0		# acc = qq/|x|
44	mulf	r2		# acc = qqq/|x|
45	addf	C		# acc = C+qqq/|x|
46	stf	r3		# r3 = s = C+qqq/|x|
47	ldf	D		# acc = D
48	divf	r3		# acc = D/s
49	addf	E		# acc = E+D/s
50	addf	r3		# acc = s+E+D/s
51	stf	r3		# r3 = s+E+D/s
52	ldf	F		# acc = F
53	divf	r3		# acc = F/(s+E+D/s)
54	addf	G		# acc = G+F/(s+E+D/s)
55	mulf	r2		# acc = q*(G+F/(s+E+D/s)) = new q to 23 bits
56	stf	r2		# r2 = q*(G+F/(s+E+D/s)) = new q to 23 bits
57	clrl	r3		# r2:r3 = q as double float
58	ldd	r2		# acc = q as double float
59	muld	r2		# acc = qq exactly
60	std	r4		# r4:r5 = qq exactly
61	ldd	r0		# acc = |x|
62	divd	r4		# acc = |x|/(q*q) rounded
63	std	r0		# r0:r1 = |x|/(q*q) rounded
64	subd	r2		# acc = |x|/(q*q)-q exactly
65	std	r6		# r6:r7 = |x|/(q*q)-q exactly
66	movl    r2,r4
67	clrl	r5		# r4:r5 = q as double float
68	addl2	$0x800000,r4	# r4:r5 = 2*q
69	ldd	r4		# acc = 2*q
70	addd	r0		# acc = 2*q+|x|/(q*q)
71	std	r4		# r4:r5 = 2*q+|x|/(q*q)
72	ldd	r6		# acc = |x|/(q*q)-q
73	divd	r4		# acc = (|x|/(q*q)-q)/(2*q+|x|/(q*q))
74	muld	r2		# acc = q*(|x|/(q*q)-q)/(2*q+|x|/(q*q))
75	addd	r2		# acc = q+q*(|x|/(q*q)-q)/(2*q+|x|/(q*q))
76	std	r0		# r0:r1 = |result|
77	orl2	r8,r0		# restore the sign bit
78return: ret			# error less than 0.667ULPs?
79
80	.data
81	.align	2
82B :	.long	721142941	#(86-0.03306235651)*(2^23)
83	.align	2
84C:	.long	0x400af8b0	#.float	0f0.5428571429	# 19/35
85	.align	2
86D:	.long	0xc0348ef1	#.float	0f-0.7053061224	# -864/1225
87	.align	2
88E:	.long	0x40b50750	#.float	0f1.414285714	# 99/70
89	.align	2
90F:	.long	0x40cdb6db	#.float	0f1.607142857	# 45/28
91	.align	2
92G:	.long	0x3fb6db6e	#.float	0f0.3571428571	# 5/14
93