xref: /openbmc/linux/arch/m68k/fpsp040/ssinh.S (revision e5451c8f8330e03ad3cfa16048b4daf961af434f)
11da177e4SLinus Torvalds|
21da177e4SLinus Torvalds|	ssinh.sa 3.1 12/10/90
31da177e4SLinus Torvalds|
41da177e4SLinus Torvalds|       The entry point sSinh computes the hyperbolic sine of
51da177e4SLinus Torvalds|       an input argument; sSinhd does the same except for denormalized
61da177e4SLinus Torvalds|       input.
71da177e4SLinus Torvalds|
81da177e4SLinus Torvalds|       Input: Double-extended number X in location pointed to
91da177e4SLinus Torvalds|		by address register a0.
101da177e4SLinus Torvalds|
111da177e4SLinus Torvalds|       Output: The value sinh(X) returned in floating-point register Fp0.
121da177e4SLinus Torvalds|
131da177e4SLinus Torvalds|       Accuracy and Monotonicity: The returned result is within 3 ulps in
141da177e4SLinus Torvalds|               64 significant bit, i.e. within 0.5001 ulp to 53 bits if the
151da177e4SLinus Torvalds|               result is subsequently rounded to double precision. The
161da177e4SLinus Torvalds|               result is provably monotonic in double precision.
171da177e4SLinus Torvalds|
181da177e4SLinus Torvalds|       Speed: The program sSINH takes approximately 280 cycles.
191da177e4SLinus Torvalds|
201da177e4SLinus Torvalds|       Algorithm:
211da177e4SLinus Torvalds|
221da177e4SLinus Torvalds|       SINH
231da177e4SLinus Torvalds|       1. If |X| > 16380 log2, go to 3.
241da177e4SLinus Torvalds|
251da177e4SLinus Torvalds|       2. (|X| <= 16380 log2) Sinh(X) is obtained by the formulae
261da177e4SLinus Torvalds|               y = |X|, sgn = sign(X), and z = expm1(Y),
271da177e4SLinus Torvalds|               sinh(X) = sgn*(1/2)*( z + z/(1+z) ).
281da177e4SLinus Torvalds|          Exit.
291da177e4SLinus Torvalds|
301da177e4SLinus Torvalds|       3. If |X| > 16480 log2, go to 5.
311da177e4SLinus Torvalds|
321da177e4SLinus Torvalds|       4. (16380 log2 < |X| <= 16480 log2)
331da177e4SLinus Torvalds|               sinh(X) = sign(X) * exp(|X|)/2.
341da177e4SLinus Torvalds|          However, invoking exp(|X|) may cause premature overflow.
351da177e4SLinus Torvalds|          Thus, we calculate sinh(X) as follows:
361da177e4SLinus Torvalds|             Y       := |X|
371da177e4SLinus Torvalds|             sgn     := sign(X)
381da177e4SLinus Torvalds|             sgnFact := sgn * 2**(16380)
391da177e4SLinus Torvalds|             Y'      := Y - 16381 log2
401da177e4SLinus Torvalds|             sinh(X) := sgnFact * exp(Y').
411da177e4SLinus Torvalds|          Exit.
421da177e4SLinus Torvalds|
431da177e4SLinus Torvalds|       5. (|X| > 16480 log2) sinh(X) must overflow. Return
441da177e4SLinus Torvalds|          sign(X)*Huge*Huge to generate overflow and an infinity with
451da177e4SLinus Torvalds|          the appropriate sign. Huge is the largest finite number in
461da177e4SLinus Torvalds|          extended format. Exit.
471da177e4SLinus Torvalds|
481da177e4SLinus Torvalds
491da177e4SLinus Torvalds|		Copyright (C) Motorola, Inc. 1990
501da177e4SLinus Torvalds|			All Rights Reserved
511da177e4SLinus Torvalds|
52*e00d82d0SMatt Waddel|       For details on the license for this file, please see the
53*e00d82d0SMatt Waddel|       file, README, in this same directory.
541da177e4SLinus Torvalds
551da177e4SLinus Torvalds|SSINH	idnt	2,1 | Motorola 040 Floating Point Software Package
561da177e4SLinus Torvalds
571da177e4SLinus Torvalds	|section	8
581da177e4SLinus Torvalds
591da177e4SLinus TorvaldsT1:	.long 0x40C62D38,0xD3D64634 | ... 16381 LOG2 LEAD
601da177e4SLinus TorvaldsT2:	.long 0x3D6F90AE,0xB1E75CC7 | ... 16381 LOG2 TRAIL
611da177e4SLinus Torvalds
621da177e4SLinus Torvalds	|xref	t_frcinx
631da177e4SLinus Torvalds	|xref	t_ovfl
641da177e4SLinus Torvalds	|xref	t_extdnrm
651da177e4SLinus Torvalds	|xref	setox
661da177e4SLinus Torvalds	|xref	setoxm1
671da177e4SLinus Torvalds
681da177e4SLinus Torvalds	.global	ssinhd
691da177e4SLinus Torvaldsssinhd:
701da177e4SLinus Torvalds|--SINH(X) = X FOR DENORMALIZED X
711da177e4SLinus Torvalds
721da177e4SLinus Torvalds	bra	t_extdnrm
731da177e4SLinus Torvalds
741da177e4SLinus Torvalds	.global	ssinh
751da177e4SLinus Torvaldsssinh:
761da177e4SLinus Torvalds	fmovex	(%a0),%fp0	| ...LOAD INPUT
771da177e4SLinus Torvalds
781da177e4SLinus Torvalds	movel	(%a0),%d0
791da177e4SLinus Torvalds	movew	4(%a0),%d0
801da177e4SLinus Torvalds	movel	%d0,%a1		| save a copy of original (compacted) operand
811da177e4SLinus Torvalds	andl	#0x7FFFFFFF,%d0
821da177e4SLinus Torvalds	cmpl	#0x400CB167,%d0
831da177e4SLinus Torvalds	bgts	SINHBIG
841da177e4SLinus Torvalds
851da177e4SLinus Torvalds|--THIS IS THE USUAL CASE, |X| < 16380 LOG2
861da177e4SLinus Torvalds|--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
871da177e4SLinus Torvalds
881da177e4SLinus Torvalds	fabsx	%fp0		| ...Y = |X|
891da177e4SLinus Torvalds
901da177e4SLinus Torvalds	moveml	%a1/%d1,-(%sp)
911da177e4SLinus Torvalds	fmovemx %fp0-%fp0,(%a0)
921da177e4SLinus Torvalds	clrl	%d1
931da177e4SLinus Torvalds	bsr	setoxm1		| ...FP0 IS Z = EXPM1(Y)
941da177e4SLinus Torvalds	fmovel	#0,%fpcr
951da177e4SLinus Torvalds	moveml	(%sp)+,%a1/%d1
961da177e4SLinus Torvalds
971da177e4SLinus Torvalds	fmovex	%fp0,%fp1
981da177e4SLinus Torvalds	fadds	#0x3F800000,%fp1	| ...1+Z
991da177e4SLinus Torvalds	fmovex	%fp0,-(%sp)
1001da177e4SLinus Torvalds	fdivx	%fp1,%fp0		| ...Z/(1+Z)
1011da177e4SLinus Torvalds	movel	%a1,%d0
1021da177e4SLinus Torvalds	andl	#0x80000000,%d0
1031da177e4SLinus Torvalds	orl	#0x3F000000,%d0
1041da177e4SLinus Torvalds	faddx	(%sp)+,%fp0
1051da177e4SLinus Torvalds	movel	%d0,-(%sp)
1061da177e4SLinus Torvalds
1071da177e4SLinus Torvalds	fmovel	%d1,%fpcr
1081da177e4SLinus Torvalds	fmuls	(%sp)+,%fp0	|last fp inst - possible exceptions set
1091da177e4SLinus Torvalds
1101da177e4SLinus Torvalds	bra	t_frcinx
1111da177e4SLinus Torvalds
1121da177e4SLinus TorvaldsSINHBIG:
1131da177e4SLinus Torvalds	cmpl	#0x400CB2B3,%d0
1141da177e4SLinus Torvalds	bgt	t_ovfl
1151da177e4SLinus Torvalds	fabsx	%fp0
1161da177e4SLinus Torvalds	fsubd	T1(%pc),%fp0	| ...(|X|-16381LOG2_LEAD)
1171da177e4SLinus Torvalds	movel	#0,-(%sp)
1181da177e4SLinus Torvalds	movel	#0x80000000,-(%sp)
1191da177e4SLinus Torvalds	movel	%a1,%d0
1201da177e4SLinus Torvalds	andl	#0x80000000,%d0
1211da177e4SLinus Torvalds	orl	#0x7FFB0000,%d0
1221da177e4SLinus Torvalds	movel	%d0,-(%sp)	| ...EXTENDED FMT
1231da177e4SLinus Torvalds	fsubd	T2(%pc),%fp0	| ...|X| - 16381 LOG2, ACCURATE
1241da177e4SLinus Torvalds
1251da177e4SLinus Torvalds	movel	%d1,-(%sp)
1261da177e4SLinus Torvalds	clrl	%d1
1271da177e4SLinus Torvalds	fmovemx %fp0-%fp0,(%a0)
1281da177e4SLinus Torvalds	bsr	setox
1291da177e4SLinus Torvalds	fmovel	(%sp)+,%fpcr
1301da177e4SLinus Torvalds
1311da177e4SLinus Torvalds	fmulx	(%sp)+,%fp0	|possible exception
1321da177e4SLinus Torvalds	bra	t_frcinx
1331da177e4SLinus Torvalds
1341da177e4SLinus Torvalds	|end
135