xref: /openbmc/linux/arch/m68k/fpsp040/satanh.S (revision e00d82d0)
11da177e4SLinus Torvalds|
21da177e4SLinus Torvalds|	satanh.sa 3.3 12/19/90
31da177e4SLinus Torvalds|
41da177e4SLinus Torvalds|	The entry point satanh computes the inverse
51da177e4SLinus Torvalds|	hyperbolic tangent of
61da177e4SLinus Torvalds|	an input argument; satanhd does the same except for denormalized
71da177e4SLinus Torvalds|	input.
81da177e4SLinus Torvalds|
91da177e4SLinus Torvalds|	Input: Double-extended number X in location pointed to
101da177e4SLinus Torvalds|		by address register a0.
111da177e4SLinus Torvalds|
121da177e4SLinus Torvalds|	Output: The value arctanh(X) returned in floating-point register Fp0.
131da177e4SLinus Torvalds|
141da177e4SLinus Torvalds|	Accuracy and Monotonicity: The returned result is within 3 ulps in
151da177e4SLinus Torvalds|		64 significant bit, i.e. within 0.5001 ulp to 53 bits if the
161da177e4SLinus Torvalds|		result is subsequently rounded to double precision. The
171da177e4SLinus Torvalds|		result is provably monotonic in double precision.
181da177e4SLinus Torvalds|
191da177e4SLinus Torvalds|	Speed: The program satanh takes approximately 270 cycles.
201da177e4SLinus Torvalds|
211da177e4SLinus Torvalds|	Algorithm:
221da177e4SLinus Torvalds|
231da177e4SLinus Torvalds|	ATANH
241da177e4SLinus Torvalds|	1. If |X| >= 1, go to 3.
251da177e4SLinus Torvalds|
261da177e4SLinus Torvalds|	2. (|X| < 1) Calculate atanh(X) by
271da177e4SLinus Torvalds|		sgn := sign(X)
281da177e4SLinus Torvalds|		y := |X|
291da177e4SLinus Torvalds|		z := 2y/(1-y)
301da177e4SLinus Torvalds|		atanh(X) := sgn * (1/2) * logp1(z)
311da177e4SLinus Torvalds|		Exit.
321da177e4SLinus Torvalds|
331da177e4SLinus Torvalds|	3. If |X| > 1, go to 5.
341da177e4SLinus Torvalds|
351da177e4SLinus Torvalds|	4. (|X| = 1) Generate infinity with an appropriate sign and
361da177e4SLinus Torvalds|		divide-by-zero by
371da177e4SLinus Torvalds|		sgn := sign(X)
381da177e4SLinus Torvalds|		atan(X) := sgn / (+0).
391da177e4SLinus Torvalds|		Exit.
401da177e4SLinus Torvalds|
411da177e4SLinus Torvalds|	5. (|X| > 1) Generate an invalid operation by 0 * infinity.
421da177e4SLinus Torvalds|		Exit.
431da177e4SLinus Torvalds|
441da177e4SLinus Torvalds
451da177e4SLinus Torvalds|		Copyright (C) Motorola, Inc. 1990
461da177e4SLinus Torvalds|			All Rights Reserved
471da177e4SLinus Torvalds|
48e00d82d0SMatt Waddel|       For details on the license for this file, please see the
49e00d82d0SMatt Waddel|       file, README, in this same directory.
501da177e4SLinus Torvalds
511da177e4SLinus Torvalds|satanh	idnt	2,1 | Motorola 040 Floating Point Software Package
521da177e4SLinus Torvalds
531da177e4SLinus Torvalds	|section	8
541da177e4SLinus Torvalds
551da177e4SLinus Torvalds	|xref	t_dz
561da177e4SLinus Torvalds	|xref	t_operr
571da177e4SLinus Torvalds	|xref	t_frcinx
581da177e4SLinus Torvalds	|xref	t_extdnrm
591da177e4SLinus Torvalds	|xref	slognp1
601da177e4SLinus Torvalds
611da177e4SLinus Torvalds	.global	satanhd
621da177e4SLinus Torvaldssatanhd:
631da177e4SLinus Torvalds|--ATANH(X) = X FOR DENORMALIZED X
641da177e4SLinus Torvalds
651da177e4SLinus Torvalds	bra		t_extdnrm
661da177e4SLinus Torvalds
671da177e4SLinus Torvalds	.global	satanh
681da177e4SLinus Torvaldssatanh:
691da177e4SLinus Torvalds	movel		(%a0),%d0
701da177e4SLinus Torvalds	movew		4(%a0),%d0
711da177e4SLinus Torvalds	andil		#0x7FFFFFFF,%d0
721da177e4SLinus Torvalds	cmpil		#0x3FFF8000,%d0
731da177e4SLinus Torvalds	bges		ATANHBIG
741da177e4SLinus Torvalds
751da177e4SLinus Torvalds|--THIS IS THE USUAL CASE, |X| < 1
761da177e4SLinus Torvalds|--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
771da177e4SLinus Torvalds
781da177e4SLinus Torvalds	fabsx		(%a0),%fp0	| ...Y = |X|
791da177e4SLinus Torvalds	fmovex		%fp0,%fp1
801da177e4SLinus Torvalds	fnegx		%fp1		| ...-Y
811da177e4SLinus Torvalds	faddx		%fp0,%fp0		| ...2Y
821da177e4SLinus Torvalds	fadds		#0x3F800000,%fp1	| ...1-Y
831da177e4SLinus Torvalds	fdivx		%fp1,%fp0		| ...2Y/(1-Y)
841da177e4SLinus Torvalds	movel		(%a0),%d0
851da177e4SLinus Torvalds	andil		#0x80000000,%d0
861da177e4SLinus Torvalds	oril		#0x3F000000,%d0	| ...SIGN(X)*HALF
871da177e4SLinus Torvalds	movel		%d0,-(%sp)
881da177e4SLinus Torvalds
891da177e4SLinus Torvalds	fmovemx	%fp0-%fp0,(%a0)	| ...overwrite input
901da177e4SLinus Torvalds	movel		%d1,-(%sp)
911da177e4SLinus Torvalds	clrl		%d1
921da177e4SLinus Torvalds	bsr		slognp1		| ...LOG1P(Z)
931da177e4SLinus Torvalds	fmovel		(%sp)+,%fpcr
941da177e4SLinus Torvalds	fmuls		(%sp)+,%fp0
951da177e4SLinus Torvalds	bra		t_frcinx
961da177e4SLinus Torvalds
971da177e4SLinus TorvaldsATANHBIG:
981da177e4SLinus Torvalds	fabsx		(%a0),%fp0	| ...|X|
991da177e4SLinus Torvalds	fcmps		#0x3F800000,%fp0
1001da177e4SLinus Torvalds	fbgt		t_operr
1011da177e4SLinus Torvalds	bra		t_dz
1021da177e4SLinus Torvalds
1031da177e4SLinus Torvalds	|end
104