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