xref: /linux/arch/m68k/fpsp040/satanh.S (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus Torvalds|
2*1da177e4SLinus Torvalds|	satanh.sa 3.3 12/19/90
3*1da177e4SLinus Torvalds|
4*1da177e4SLinus Torvalds|	The entry point satanh computes the inverse
5*1da177e4SLinus Torvalds|	hyperbolic tangent of
6*1da177e4SLinus Torvalds|	an input argument; satanhd does the same except for denormalized
7*1da177e4SLinus Torvalds|	input.
8*1da177e4SLinus Torvalds|
9*1da177e4SLinus Torvalds|	Input: Double-extended number X in location pointed to
10*1da177e4SLinus Torvalds|		by address register a0.
11*1da177e4SLinus Torvalds|
12*1da177e4SLinus Torvalds|	Output: The value arctanh(X) returned in floating-point register Fp0.
13*1da177e4SLinus Torvalds|
14*1da177e4SLinus Torvalds|	Accuracy and Monotonicity: The returned result is within 3 ulps in
15*1da177e4SLinus Torvalds|		64 significant bit, i.e. within 0.5001 ulp to 53 bits if the
16*1da177e4SLinus Torvalds|		result is subsequently rounded to double precision. The
17*1da177e4SLinus Torvalds|		result is provably monotonic in double precision.
18*1da177e4SLinus Torvalds|
19*1da177e4SLinus Torvalds|	Speed: The program satanh takes approximately 270 cycles.
20*1da177e4SLinus Torvalds|
21*1da177e4SLinus Torvalds|	Algorithm:
22*1da177e4SLinus Torvalds|
23*1da177e4SLinus Torvalds|	ATANH
24*1da177e4SLinus Torvalds|	1. If |X| >= 1, go to 3.
25*1da177e4SLinus Torvalds|
26*1da177e4SLinus Torvalds|	2. (|X| < 1) Calculate atanh(X) by
27*1da177e4SLinus Torvalds|		sgn := sign(X)
28*1da177e4SLinus Torvalds|		y := |X|
29*1da177e4SLinus Torvalds|		z := 2y/(1-y)
30*1da177e4SLinus Torvalds|		atanh(X) := sgn * (1/2) * logp1(z)
31*1da177e4SLinus Torvalds|		Exit.
32*1da177e4SLinus Torvalds|
33*1da177e4SLinus Torvalds|	3. If |X| > 1, go to 5.
34*1da177e4SLinus Torvalds|
35*1da177e4SLinus Torvalds|	4. (|X| = 1) Generate infinity with an appropriate sign and
36*1da177e4SLinus Torvalds|		divide-by-zero by
37*1da177e4SLinus Torvalds|		sgn := sign(X)
38*1da177e4SLinus Torvalds|		atan(X) := sgn / (+0).
39*1da177e4SLinus Torvalds|		Exit.
40*1da177e4SLinus Torvalds|
41*1da177e4SLinus Torvalds|	5. (|X| > 1) Generate an invalid operation by 0 * infinity.
42*1da177e4SLinus Torvalds|		Exit.
43*1da177e4SLinus Torvalds|
44*1da177e4SLinus Torvalds
45*1da177e4SLinus Torvalds|		Copyright (C) Motorola, Inc. 1990
46*1da177e4SLinus Torvalds|			All Rights Reserved
47*1da177e4SLinus Torvalds|
48*1da177e4SLinus Torvalds|	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
49*1da177e4SLinus Torvalds|	The copyright notice above does not evidence any
50*1da177e4SLinus Torvalds|	actual or intended publication of such source code.
51*1da177e4SLinus Torvalds
52*1da177e4SLinus Torvalds|satanh	idnt	2,1 | Motorola 040 Floating Point Software Package
53*1da177e4SLinus Torvalds
54*1da177e4SLinus Torvalds	|section	8
55*1da177e4SLinus Torvalds
56*1da177e4SLinus Torvalds	|xref	t_dz
57*1da177e4SLinus Torvalds	|xref	t_operr
58*1da177e4SLinus Torvalds	|xref	t_frcinx
59*1da177e4SLinus Torvalds	|xref	t_extdnrm
60*1da177e4SLinus Torvalds	|xref	slognp1
61*1da177e4SLinus Torvalds
62*1da177e4SLinus Torvalds	.global	satanhd
63*1da177e4SLinus Torvaldssatanhd:
64*1da177e4SLinus Torvalds|--ATANH(X) = X FOR DENORMALIZED X
65*1da177e4SLinus Torvalds
66*1da177e4SLinus Torvalds	bra		t_extdnrm
67*1da177e4SLinus Torvalds
68*1da177e4SLinus Torvalds	.global	satanh
69*1da177e4SLinus Torvaldssatanh:
70*1da177e4SLinus Torvalds	movel		(%a0),%d0
71*1da177e4SLinus Torvalds	movew		4(%a0),%d0
72*1da177e4SLinus Torvalds	andil		#0x7FFFFFFF,%d0
73*1da177e4SLinus Torvalds	cmpil		#0x3FFF8000,%d0
74*1da177e4SLinus Torvalds	bges		ATANHBIG
75*1da177e4SLinus Torvalds
76*1da177e4SLinus Torvalds|--THIS IS THE USUAL CASE, |X| < 1
77*1da177e4SLinus Torvalds|--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
78*1da177e4SLinus Torvalds
79*1da177e4SLinus Torvalds	fabsx		(%a0),%fp0	| ...Y = |X|
80*1da177e4SLinus Torvalds	fmovex		%fp0,%fp1
81*1da177e4SLinus Torvalds	fnegx		%fp1		| ...-Y
82*1da177e4SLinus Torvalds	faddx		%fp0,%fp0		| ...2Y
83*1da177e4SLinus Torvalds	fadds		#0x3F800000,%fp1	| ...1-Y
84*1da177e4SLinus Torvalds	fdivx		%fp1,%fp0		| ...2Y/(1-Y)
85*1da177e4SLinus Torvalds	movel		(%a0),%d0
86*1da177e4SLinus Torvalds	andil		#0x80000000,%d0
87*1da177e4SLinus Torvalds	oril		#0x3F000000,%d0	| ...SIGN(X)*HALF
88*1da177e4SLinus Torvalds	movel		%d0,-(%sp)
89*1da177e4SLinus Torvalds
90*1da177e4SLinus Torvalds	fmovemx	%fp0-%fp0,(%a0)	| ...overwrite input
91*1da177e4SLinus Torvalds	movel		%d1,-(%sp)
92*1da177e4SLinus Torvalds	clrl		%d1
93*1da177e4SLinus Torvalds	bsr		slognp1		| ...LOG1P(Z)
94*1da177e4SLinus Torvalds	fmovel		(%sp)+,%fpcr
95*1da177e4SLinus Torvalds	fmuls		(%sp)+,%fp0
96*1da177e4SLinus Torvalds	bra		t_frcinx
97*1da177e4SLinus Torvalds
98*1da177e4SLinus TorvaldsATANHBIG:
99*1da177e4SLinus Torvalds	fabsx		(%a0),%fp0	| ...|X|
100*1da177e4SLinus Torvalds	fcmps		#0x3F800000,%fp0
101*1da177e4SLinus Torvalds	fbgt		t_operr
102*1da177e4SLinus Torvalds	bra		t_dz
103*1da177e4SLinus Torvalds
104*1da177e4SLinus Torvalds	|end
105