xref: /openbmc/linux/arch/m68k/fpsp040/ssinh.S (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus Torvalds|
2*1da177e4SLinus Torvalds|	ssinh.sa 3.1 12/10/90
3*1da177e4SLinus Torvalds|
4*1da177e4SLinus Torvalds|       The entry point sSinh computes the hyperbolic sine of
5*1da177e4SLinus Torvalds|       an input argument; sSinhd does the same except for denormalized
6*1da177e4SLinus Torvalds|       input.
7*1da177e4SLinus Torvalds|
8*1da177e4SLinus Torvalds|       Input: Double-extended number X in location pointed to
9*1da177e4SLinus Torvalds|		by address register a0.
10*1da177e4SLinus Torvalds|
11*1da177e4SLinus Torvalds|       Output: The value sinh(X) returned in floating-point register Fp0.
12*1da177e4SLinus Torvalds|
13*1da177e4SLinus Torvalds|       Accuracy and Monotonicity: The returned result is within 3 ulps in
14*1da177e4SLinus Torvalds|               64 significant bit, i.e. within 0.5001 ulp to 53 bits if the
15*1da177e4SLinus Torvalds|               result is subsequently rounded to double precision. The
16*1da177e4SLinus Torvalds|               result is provably monotonic in double precision.
17*1da177e4SLinus Torvalds|
18*1da177e4SLinus Torvalds|       Speed: The program sSINH takes approximately 280 cycles.
19*1da177e4SLinus Torvalds|
20*1da177e4SLinus Torvalds|       Algorithm:
21*1da177e4SLinus Torvalds|
22*1da177e4SLinus Torvalds|       SINH
23*1da177e4SLinus Torvalds|       1. If |X| > 16380 log2, go to 3.
24*1da177e4SLinus Torvalds|
25*1da177e4SLinus Torvalds|       2. (|X| <= 16380 log2) Sinh(X) is obtained by the formulae
26*1da177e4SLinus Torvalds|               y = |X|, sgn = sign(X), and z = expm1(Y),
27*1da177e4SLinus Torvalds|               sinh(X) = sgn*(1/2)*( z + z/(1+z) ).
28*1da177e4SLinus Torvalds|          Exit.
29*1da177e4SLinus Torvalds|
30*1da177e4SLinus Torvalds|       3. If |X| > 16480 log2, go to 5.
31*1da177e4SLinus Torvalds|
32*1da177e4SLinus Torvalds|       4. (16380 log2 < |X| <= 16480 log2)
33*1da177e4SLinus Torvalds|               sinh(X) = sign(X) * exp(|X|)/2.
34*1da177e4SLinus Torvalds|          However, invoking exp(|X|) may cause premature overflow.
35*1da177e4SLinus Torvalds|          Thus, we calculate sinh(X) as follows:
36*1da177e4SLinus Torvalds|             Y       := |X|
37*1da177e4SLinus Torvalds|             sgn     := sign(X)
38*1da177e4SLinus Torvalds|             sgnFact := sgn * 2**(16380)
39*1da177e4SLinus Torvalds|             Y'      := Y - 16381 log2
40*1da177e4SLinus Torvalds|             sinh(X) := sgnFact * exp(Y').
41*1da177e4SLinus Torvalds|          Exit.
42*1da177e4SLinus Torvalds|
43*1da177e4SLinus Torvalds|       5. (|X| > 16480 log2) sinh(X) must overflow. Return
44*1da177e4SLinus Torvalds|          sign(X)*Huge*Huge to generate overflow and an infinity with
45*1da177e4SLinus Torvalds|          the appropriate sign. Huge is the largest finite number in
46*1da177e4SLinus Torvalds|          extended format. Exit.
47*1da177e4SLinus Torvalds|
48*1da177e4SLinus Torvalds
49*1da177e4SLinus Torvalds|		Copyright (C) Motorola, Inc. 1990
50*1da177e4SLinus Torvalds|			All Rights Reserved
51*1da177e4SLinus Torvalds|
52*1da177e4SLinus Torvalds|	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
53*1da177e4SLinus Torvalds|	The copyright notice above does not evidence any
54*1da177e4SLinus Torvalds|	actual or intended publication of such source code.
55*1da177e4SLinus Torvalds
56*1da177e4SLinus Torvalds|SSINH	idnt	2,1 | Motorola 040 Floating Point Software Package
57*1da177e4SLinus Torvalds
58*1da177e4SLinus Torvalds	|section	8
59*1da177e4SLinus Torvalds
60*1da177e4SLinus TorvaldsT1:	.long 0x40C62D38,0xD3D64634 | ... 16381 LOG2 LEAD
61*1da177e4SLinus TorvaldsT2:	.long 0x3D6F90AE,0xB1E75CC7 | ... 16381 LOG2 TRAIL
62*1da177e4SLinus Torvalds
63*1da177e4SLinus Torvalds	|xref	t_frcinx
64*1da177e4SLinus Torvalds	|xref	t_ovfl
65*1da177e4SLinus Torvalds	|xref	t_extdnrm
66*1da177e4SLinus Torvalds	|xref	setox
67*1da177e4SLinus Torvalds	|xref	setoxm1
68*1da177e4SLinus Torvalds
69*1da177e4SLinus Torvalds	.global	ssinhd
70*1da177e4SLinus Torvaldsssinhd:
71*1da177e4SLinus Torvalds|--SINH(X) = X FOR DENORMALIZED X
72*1da177e4SLinus Torvalds
73*1da177e4SLinus Torvalds	bra	t_extdnrm
74*1da177e4SLinus Torvalds
75*1da177e4SLinus Torvalds	.global	ssinh
76*1da177e4SLinus Torvaldsssinh:
77*1da177e4SLinus Torvalds	fmovex	(%a0),%fp0	| ...LOAD INPUT
78*1da177e4SLinus Torvalds
79*1da177e4SLinus Torvalds	movel	(%a0),%d0
80*1da177e4SLinus Torvalds	movew	4(%a0),%d0
81*1da177e4SLinus Torvalds	movel	%d0,%a1		| save a copy of original (compacted) operand
82*1da177e4SLinus Torvalds	andl	#0x7FFFFFFF,%d0
83*1da177e4SLinus Torvalds	cmpl	#0x400CB167,%d0
84*1da177e4SLinus Torvalds	bgts	SINHBIG
85*1da177e4SLinus Torvalds
86*1da177e4SLinus Torvalds|--THIS IS THE USUAL CASE, |X| < 16380 LOG2
87*1da177e4SLinus Torvalds|--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
88*1da177e4SLinus Torvalds
89*1da177e4SLinus Torvalds	fabsx	%fp0		| ...Y = |X|
90*1da177e4SLinus Torvalds
91*1da177e4SLinus Torvalds	moveml	%a1/%d1,-(%sp)
92*1da177e4SLinus Torvalds	fmovemx %fp0-%fp0,(%a0)
93*1da177e4SLinus Torvalds	clrl	%d1
94*1da177e4SLinus Torvalds	bsr	setoxm1		| ...FP0 IS Z = EXPM1(Y)
95*1da177e4SLinus Torvalds	fmovel	#0,%fpcr
96*1da177e4SLinus Torvalds	moveml	(%sp)+,%a1/%d1
97*1da177e4SLinus Torvalds
98*1da177e4SLinus Torvalds	fmovex	%fp0,%fp1
99*1da177e4SLinus Torvalds	fadds	#0x3F800000,%fp1	| ...1+Z
100*1da177e4SLinus Torvalds	fmovex	%fp0,-(%sp)
101*1da177e4SLinus Torvalds	fdivx	%fp1,%fp0		| ...Z/(1+Z)
102*1da177e4SLinus Torvalds	movel	%a1,%d0
103*1da177e4SLinus Torvalds	andl	#0x80000000,%d0
104*1da177e4SLinus Torvalds	orl	#0x3F000000,%d0
105*1da177e4SLinus Torvalds	faddx	(%sp)+,%fp0
106*1da177e4SLinus Torvalds	movel	%d0,-(%sp)
107*1da177e4SLinus Torvalds
108*1da177e4SLinus Torvalds	fmovel	%d1,%fpcr
109*1da177e4SLinus Torvalds	fmuls	(%sp)+,%fp0	|last fp inst - possible exceptions set
110*1da177e4SLinus Torvalds
111*1da177e4SLinus Torvalds	bra	t_frcinx
112*1da177e4SLinus Torvalds
113*1da177e4SLinus TorvaldsSINHBIG:
114*1da177e4SLinus Torvalds	cmpl	#0x400CB2B3,%d0
115*1da177e4SLinus Torvalds	bgt	t_ovfl
116*1da177e4SLinus Torvalds	fabsx	%fp0
117*1da177e4SLinus Torvalds	fsubd	T1(%pc),%fp0	| ...(|X|-16381LOG2_LEAD)
118*1da177e4SLinus Torvalds	movel	#0,-(%sp)
119*1da177e4SLinus Torvalds	movel	#0x80000000,-(%sp)
120*1da177e4SLinus Torvalds	movel	%a1,%d0
121*1da177e4SLinus Torvalds	andl	#0x80000000,%d0
122*1da177e4SLinus Torvalds	orl	#0x7FFB0000,%d0
123*1da177e4SLinus Torvalds	movel	%d0,-(%sp)	| ...EXTENDED FMT
124*1da177e4SLinus Torvalds	fsubd	T2(%pc),%fp0	| ...|X| - 16381 LOG2, ACCURATE
125*1da177e4SLinus Torvalds
126*1da177e4SLinus Torvalds	movel	%d1,-(%sp)
127*1da177e4SLinus Torvalds	clrl	%d1
128*1da177e4SLinus Torvalds	fmovemx %fp0-%fp0,(%a0)
129*1da177e4SLinus Torvalds	bsr	setox
130*1da177e4SLinus Torvalds	fmovel	(%sp)+,%fpcr
131*1da177e4SLinus Torvalds
132*1da177e4SLinus Torvalds	fmulx	(%sp)+,%fp0	|possible exception
133*1da177e4SLinus Torvalds	bra	t_frcinx
134*1da177e4SLinus Torvalds
135*1da177e4SLinus Torvalds	|end
136