xref: /netbsd-src/sys/arch/m68k/fpsp/setox.sa (revision 81ca7445e9ef974ba8838a13051caa499883fb41)
1*81ca7445Smatt*	$NetBSD: setox.sa,v 1.5 2014/09/01 08:21:26 matt Exp $
257fb77a1Scgd
322ef5fa9Smycroft*	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
422ef5fa9Smycroft*	M68000 Hi-Performance Microprocessor Division
522ef5fa9Smycroft*	M68040 Software Package
622ef5fa9Smycroft*
722ef5fa9Smycroft*	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
822ef5fa9Smycroft*	All rights reserved.
922ef5fa9Smycroft*
1022ef5fa9Smycroft*	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
1122ef5fa9Smycroft*	To the maximum extent permitted by applicable law,
1222ef5fa9Smycroft*	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
1322ef5fa9Smycroft*	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
1422ef5fa9Smycroft*	PARTICULAR PURPOSE and any warranty against infringement with
1522ef5fa9Smycroft*	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
1622ef5fa9Smycroft*	and any accompanying written materials.
1722ef5fa9Smycroft*
1822ef5fa9Smycroft*	To the maximum extent permitted by applicable law,
1922ef5fa9Smycroft*	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
2022ef5fa9Smycroft*	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
2122ef5fa9Smycroft*	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
2222ef5fa9Smycroft*	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
2322ef5fa9Smycroft*	SOFTWARE.  Motorola assumes no responsibility for the maintenance
2422ef5fa9Smycroft*	and support of the SOFTWARE.
2522ef5fa9Smycroft*
2622ef5fa9Smycroft*	You are hereby granted a copyright license to use, modify, and
2722ef5fa9Smycroft*	distribute the SOFTWARE so long as this entire notice is retained
2822ef5fa9Smycroft*	without alteration in any modified and/or redistributed versions,
2922ef5fa9Smycroft*	and that such modified versions are clearly identified as such.
3022ef5fa9Smycroft*	No licenses are granted by implication, estoppel or otherwise
3122ef5fa9Smycroft*	under any patents or trademarks of Motorola, Inc.
3222ef5fa9Smycroft
3322ef5fa9Smycroft*
3422ef5fa9Smycroft*	setox.sa 3.1 12/10/90
3522ef5fa9Smycroft*
3622ef5fa9Smycroft*	The entry point setox computes the exponential of a value.
3722ef5fa9Smycroft*	setoxd does the same except the input value is a denormalized
3822ef5fa9Smycroft*	number.	setoxm1 computes exp(X)-1, and setoxm1d computes
3922ef5fa9Smycroft*	exp(X)-1 for denormalized X.
4022ef5fa9Smycroft*
4122ef5fa9Smycroft*	INPUT
4222ef5fa9Smycroft*	-----
4322ef5fa9Smycroft*	Double-extended value in memory location pointed to by address
4422ef5fa9Smycroft*	register a0.
4522ef5fa9Smycroft*
4622ef5fa9Smycroft*	OUTPUT
4722ef5fa9Smycroft*	------
4822ef5fa9Smycroft*	exp(X) or exp(X)-1 returned in floating-point register fp0.
4922ef5fa9Smycroft*
5022ef5fa9Smycroft*	ACCURACY and MONOTONICITY
5122ef5fa9Smycroft*	-------------------------
5222ef5fa9Smycroft*	The returned result is within 0.85 ulps in 64 significant bit, i.e.
5322ef5fa9Smycroft*	within 0.5001 ulp to 53 bits if the result is subsequently rounded
5422ef5fa9Smycroft*	to double precision. The result is provably monotonic in double
5522ef5fa9Smycroft*	precision.
5622ef5fa9Smycroft*
5722ef5fa9Smycroft*	SPEED
5822ef5fa9Smycroft*	-----
5922ef5fa9Smycroft*	Two timings are measured, both in the copy-back mode. The
6022ef5fa9Smycroft*	first one is measured when the function is invoked the first time
6122ef5fa9Smycroft*	(so the instructions and data are not in cache), and the
6222ef5fa9Smycroft*	second one is measured when the function is reinvoked at the same
6322ef5fa9Smycroft*	input argument.
6422ef5fa9Smycroft*
6522ef5fa9Smycroft*	The program setox takes approximately 210/190 cycles for input
6622ef5fa9Smycroft*	argument X whose magnitude is less than 16380 log2, which
6722ef5fa9Smycroft*	is the usual situation.	For the less common arguments,
6822ef5fa9Smycroft*	depending on their values, the program may run faster or slower --
6922ef5fa9Smycroft*	but no worse than 10% slower even in the extreme cases.
7022ef5fa9Smycroft*
7122ef5fa9Smycroft*	The program setoxm1 takes approximately ??? / ??? cycles for input
7222ef5fa9Smycroft*	argument X, 0.25 <= |X| < 70log2. For |X| < 0.25, it takes
7322ef5fa9Smycroft*	approximately ??? / ??? cycles. For the less common arguments,
7422ef5fa9Smycroft*	depending on their values, the program may run faster or slower --
7522ef5fa9Smycroft*	but no worse than 10% slower even in the extreme cases.
7622ef5fa9Smycroft*
7722ef5fa9Smycroft*	ALGORITHM and IMPLEMENTATION NOTES
7822ef5fa9Smycroft*	----------------------------------
7922ef5fa9Smycroft*
8022ef5fa9Smycroft*	setoxd
8122ef5fa9Smycroft*	------
8222ef5fa9Smycroft*	Step 1.	Set ans := 1.0
8322ef5fa9Smycroft*
8422ef5fa9Smycroft*	Step 2.	Return	ans := ans + sign(X)*2^(-126). Exit.
8522ef5fa9Smycroft*	Notes:	This will always generate one exception -- inexact.
8622ef5fa9Smycroft*
8722ef5fa9Smycroft*
8822ef5fa9Smycroft*	setox
8922ef5fa9Smycroft*	-----
9022ef5fa9Smycroft*
9122ef5fa9Smycroft*	Step 1.	Filter out extreme cases of input argument.
9222ef5fa9Smycroft*		1.1	If |X| >= 2^(-65), go to Step 1.3.
9322ef5fa9Smycroft*		1.2	Go to Step 7.
9422ef5fa9Smycroft*		1.3	If |X| < 16380 log(2), go to Step 2.
9522ef5fa9Smycroft*		1.4	Go to Step 8.
9622ef5fa9Smycroft*	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.
9722ef5fa9Smycroft*		 To avoid the use of floating-point comparisons, a
9822ef5fa9Smycroft*		 compact representation of |X| is used. This format is a
9922ef5fa9Smycroft*		 32-bit integer, the upper (more significant) 16 bits are
10022ef5fa9Smycroft*		 the sign and biased exponent field of |X|; the lower 16
10122ef5fa9Smycroft*		 bits are the 16 most significant fraction (including the
10222ef5fa9Smycroft*		 explicit bit) bits of |X|. Consequently, the comparisons
10322ef5fa9Smycroft*		 in Steps 1.1 and 1.3 can be performed by integer comparison.
10422ef5fa9Smycroft*		 Note also that the constant 16380 log(2) used in Step 1.3
10522ef5fa9Smycroft*		 is also in the compact form. Thus taking the branch
10622ef5fa9Smycroft*		 to Step 2 guarantees |X| < 16380 log(2). There is no harm
10722ef5fa9Smycroft*		 to have a small number of cases where |X| is less than,
10822ef5fa9Smycroft*		 but close to, 16380 log(2) and the branch to Step 9 is
10922ef5fa9Smycroft*		 taken.
11022ef5fa9Smycroft*
11122ef5fa9Smycroft*	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).
11222ef5fa9Smycroft*		2.1	Set AdjFlag := 0 (indicates the branch 1.3 -> 2 was taken)
11322ef5fa9Smycroft*		2.2	N := round-to-nearest-integer( X * 64/log2 ).
11422ef5fa9Smycroft*		2.3	Calculate	J = N mod 64; so J = 0,1,2,..., or 63.
11522ef5fa9Smycroft*		2.4	Calculate	M = (N - J)/64; so N = 64M + J.
11622ef5fa9Smycroft*		2.5	Calculate the address of the stored value of 2^(J/64).
11722ef5fa9Smycroft*		2.6	Create the value Scale = 2^M.
11822ef5fa9Smycroft*	Notes:	The calculation in 2.2 is really performed by
11922ef5fa9Smycroft*
12022ef5fa9Smycroft*			Z := X * constant
12122ef5fa9Smycroft*			N := round-to-nearest-integer(Z)
12222ef5fa9Smycroft*
12322ef5fa9Smycroft*		 where
12422ef5fa9Smycroft*
12522ef5fa9Smycroft*			constant := single-precision( 64/log 2 ).
12622ef5fa9Smycroft*
12722ef5fa9Smycroft*		 Using a single-precision constant avoids memory access.
12822ef5fa9Smycroft*		 Another effect of using a single-precision "constant" is
12922ef5fa9Smycroft*		 that the calculated value Z is
13022ef5fa9Smycroft*
13122ef5fa9Smycroft*			Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24).
13222ef5fa9Smycroft*
13322ef5fa9Smycroft*		 This error has to be considered later in Steps 3 and 4.
13422ef5fa9Smycroft*
13522ef5fa9Smycroft*	Step 3.	Calculate X - N*log2/64.
13622ef5fa9Smycroft*		3.1	R := X + N*L1, where L1 := single-precision(-log2/64).
13722ef5fa9Smycroft*		3.2	R := R + N*L2, L2 := extended-precision(-log2/64 - L1).
13822ef5fa9Smycroft*	Notes:	a) The way L1 and L2 are chosen ensures L1+L2 approximate
13922ef5fa9Smycroft*		 the value	-log2/64	to 88 bits of accuracy.
14022ef5fa9Smycroft*		 b) N*L1 is exact because N is no longer than 22 bits and
14122ef5fa9Smycroft*		 L1 is no longer than 24 bits.
14222ef5fa9Smycroft*		 c) The calculation X+N*L1 is also exact due to cancellation.
14322ef5fa9Smycroft*		 Thus, R is practically X+N(L1+L2) to full 64 bits.
14422ef5fa9Smycroft*		 d) It is important to estimate how large can |R| be after
14522ef5fa9Smycroft*		 Step 3.2.
14622ef5fa9Smycroft*
14722ef5fa9Smycroft*			N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24)
14822ef5fa9Smycroft*			X*64/log2 (1+eps)	=	N + f,	|f| <= 0.5
14922ef5fa9Smycroft*			X*64/log2 - N	=	f - eps*X 64/log2
15022ef5fa9Smycroft*			X - N*log2/64	=	f*log2/64 - eps*X
15122ef5fa9Smycroft*
15222ef5fa9Smycroft*
15322ef5fa9Smycroft*		 Now |X| <= 16446 log2, thus
15422ef5fa9Smycroft*
15522ef5fa9Smycroft*			|X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64
15622ef5fa9Smycroft*					<= 0.57 log2/64.
15722ef5fa9Smycroft*		 This bound will be used in Step 4.
15822ef5fa9Smycroft*
15922ef5fa9Smycroft*	Step 4.	Approximate exp(R)-1 by a polynomial
16022ef5fa9Smycroft*			p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
16122ef5fa9Smycroft*	Notes:	a) In order to reduce memory access, the coefficients are
16222ef5fa9Smycroft*		 made as "short" as possible: A1 (which is 1/2), A4 and A5
16322ef5fa9Smycroft*		 are single precision; A2 and A3 are double precision.
16422ef5fa9Smycroft*		 b) Even with the restrictions above,
16522ef5fa9Smycroft*			|p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062.
16622ef5fa9Smycroft*		 Note that 0.0062 is slightly bigger than 0.57 log2/64.
1671f4ad37fSperry*		 c) To fully use the pipeline, p is separated into
16822ef5fa9Smycroft*		 two independent pieces of roughly equal complexities
16922ef5fa9Smycroft*			p = [ R + R*S*(A2 + S*A4) ]	+
17022ef5fa9Smycroft*				[ S*(A1 + S*(A3 + S*A5)) ]
17122ef5fa9Smycroft*		 where S = R*R.
17222ef5fa9Smycroft*
17322ef5fa9Smycroft*	Step 5.	Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by
17422ef5fa9Smycroft*				ans := T + ( T*p + t)
17522ef5fa9Smycroft*		 where T and t are the stored values for 2^(J/64).
17622ef5fa9Smycroft*	Notes:	2^(J/64) is stored as T and t where T+t approximates
17722ef5fa9Smycroft*		 2^(J/64) to roughly 85 bits; T is in extended precision
17822ef5fa9Smycroft*		 and t is in single precision. Note also that T is rounded
17922ef5fa9Smycroft*		 to 62 bits so that the last two bits of T are zero. The
18022ef5fa9Smycroft*		 reason for such a special form is that T-1, T-2, and T-8
18122ef5fa9Smycroft*		 will all be exact --- a property that will give much
18222ef5fa9Smycroft*		 more accurate computation of the function EXPM1.
18322ef5fa9Smycroft*
18422ef5fa9Smycroft*	Step 6.	Reconstruction of exp(X)
18522ef5fa9Smycroft*			exp(X) = 2^M * 2^(J/64) * exp(R).
18622ef5fa9Smycroft*		6.1	If AdjFlag = 0, go to 6.3
18722ef5fa9Smycroft*		6.2	ans := ans * AdjScale
18822ef5fa9Smycroft*		6.3	Restore the user FPCR
18922ef5fa9Smycroft*		6.4	Return ans := ans * Scale. Exit.
19022ef5fa9Smycroft*	Notes:	If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R,
19122ef5fa9Smycroft*		 |M| <= 16380, and Scale = 2^M. Moreover, exp(X) will
19222ef5fa9Smycroft*		 neither overflow nor underflow. If AdjFlag = 1, that
19322ef5fa9Smycroft*		 means that
19422ef5fa9Smycroft*			X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380.
19522ef5fa9Smycroft*		 Hence, exp(X) may overflow or underflow or neither.
19622ef5fa9Smycroft*		 When that is the case, AdjScale = 2^(M1) where M1 is
19722ef5fa9Smycroft*		 approximately M. Thus 6.2 will never cause over/underflow.
19822ef5fa9Smycroft*		 Possible exception in 6.4 is overflow or underflow.
19922ef5fa9Smycroft*		 The inexact exception is not generated in 6.4. Although
20022ef5fa9Smycroft*		 one can argue that the inexact flag should always be
20122ef5fa9Smycroft*		 raised, to simulate that exception cost to much than the
20222ef5fa9Smycroft*		 flag is worth in practical uses.
20322ef5fa9Smycroft*
20422ef5fa9Smycroft*	Step 7.	Return 1 + X.
20522ef5fa9Smycroft*		7.1	ans := X
20622ef5fa9Smycroft*		7.2	Restore user FPCR.
20722ef5fa9Smycroft*		7.3	Return ans := 1 + ans. Exit
20822ef5fa9Smycroft*	Notes:	For non-zero X, the inexact exception will always be
20922ef5fa9Smycroft*		 raised by 7.3. That is the only exception raised by 7.3.
21022ef5fa9Smycroft*		 Note also that we use the FMOVEM instruction to move X
21122ef5fa9Smycroft*		 in Step 7.1 to avoid unnecessary trapping. (Although
21222ef5fa9Smycroft*		 the FMOVEM may not seem relevant since X is normalized,
21322ef5fa9Smycroft*		 the precaution will be useful in the library version of
21422ef5fa9Smycroft*		 this code where the separate entry for denormalized inputs
21522ef5fa9Smycroft*		 will be done away with.)
21622ef5fa9Smycroft*
21722ef5fa9Smycroft*	Step 8.	Handle exp(X) where |X| >= 16380log2.
21822ef5fa9Smycroft*		8.1	If |X| > 16480 log2, go to Step 9.
21922ef5fa9Smycroft*		(mimic 2.2 - 2.6)
22022ef5fa9Smycroft*		8.2	N := round-to-integer( X * 64/log2 )
22122ef5fa9Smycroft*		8.3	Calculate J = N mod 64, J = 0,1,...,63
22222ef5fa9Smycroft*		8.4	K := (N-J)/64, M1 := truncate(K/2), M = K-M1, AdjFlag := 1.
22322ef5fa9Smycroft*		8.5	Calculate the address of the stored value 2^(J/64).
22422ef5fa9Smycroft*		8.6	Create the values Scale = 2^M, AdjScale = 2^M1.
22522ef5fa9Smycroft*		8.7	Go to Step 3.
22622ef5fa9Smycroft*	Notes:	Refer to notes for 2.2 - 2.6.
22722ef5fa9Smycroft*
22822ef5fa9Smycroft*	Step 9.	Handle exp(X), |X| > 16480 log2.
22922ef5fa9Smycroft*		9.1	If X < 0, go to 9.3
23022ef5fa9Smycroft*		9.2	ans := Huge, go to 9.4
23122ef5fa9Smycroft*		9.3	ans := Tiny.
23222ef5fa9Smycroft*		9.4	Restore user FPCR.
23322ef5fa9Smycroft*		9.5	Return ans := ans * ans. Exit.
23422ef5fa9Smycroft*	Notes:	Exp(X) will surely overflow or underflow, depending on
23522ef5fa9Smycroft*		 X's sign. "Huge" and "Tiny" are respectively large/tiny
23622ef5fa9Smycroft*		 extended-precision numbers whose square over/underflow
23722ef5fa9Smycroft*		 with an inexact result. Thus, 9.5 always raises the
23822ef5fa9Smycroft*		 inexact together with either overflow or underflow.
23922ef5fa9Smycroft*
24022ef5fa9Smycroft*
24122ef5fa9Smycroft*	setoxm1d
24222ef5fa9Smycroft*	--------
24322ef5fa9Smycroft*
24422ef5fa9Smycroft*	Step 1.	Set ans := 0
24522ef5fa9Smycroft*
24622ef5fa9Smycroft*	Step 2.	Return	ans := X + ans. Exit.
24722ef5fa9Smycroft*	Notes:	This will return X with the appropriate rounding
24822ef5fa9Smycroft*		 precision prescribed by the user FPCR.
24922ef5fa9Smycroft*
25022ef5fa9Smycroft*	setoxm1
25122ef5fa9Smycroft*	-------
25222ef5fa9Smycroft*
25322ef5fa9Smycroft*	Step 1.	Check |X|
25422ef5fa9Smycroft*		1.1	If |X| >= 1/4, go to Step 1.3.
25522ef5fa9Smycroft*		1.2	Go to Step 7.
25622ef5fa9Smycroft*		1.3	If |X| < 70 log(2), go to Step 2.
25722ef5fa9Smycroft*		1.4	Go to Step 10.
25822ef5fa9Smycroft*	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.
25922ef5fa9Smycroft*		 However, it is conceivable |X| can be small very often
26022ef5fa9Smycroft*		 because EXPM1 is intended to evaluate exp(X)-1 accurately
26122ef5fa9Smycroft*		 when |X| is small. For further details on the comparisons,
26222ef5fa9Smycroft*		 see the notes on Step 1 of setox.
26322ef5fa9Smycroft*
26422ef5fa9Smycroft*	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).
26522ef5fa9Smycroft*		2.1	N := round-to-nearest-integer( X * 64/log2 ).
26622ef5fa9Smycroft*		2.2	Calculate	J = N mod 64; so J = 0,1,2,..., or 63.
26722ef5fa9Smycroft*		2.3	Calculate	M = (N - J)/64; so N = 64M + J.
26822ef5fa9Smycroft*		2.4	Calculate the address of the stored value of 2^(J/64).
26922ef5fa9Smycroft*		2.5	Create the values Sc = 2^M and OnebySc := -2^(-M).
27022ef5fa9Smycroft*	Notes:	See the notes on Step 2 of setox.
27122ef5fa9Smycroft*
27222ef5fa9Smycroft*	Step 3.	Calculate X - N*log2/64.
27322ef5fa9Smycroft*		3.1	R := X + N*L1, where L1 := single-precision(-log2/64).
27422ef5fa9Smycroft*		3.2	R := R + N*L2, L2 := extended-precision(-log2/64 - L1).
27522ef5fa9Smycroft*	Notes:	Applying the analysis of Step 3 of setox in this case
27622ef5fa9Smycroft*		 shows that |R| <= 0.0055 (note that |X| <= 70 log2 in
27722ef5fa9Smycroft*		 this case).
27822ef5fa9Smycroft*
27922ef5fa9Smycroft*	Step 4.	Approximate exp(R)-1 by a polynomial
28022ef5fa9Smycroft*			p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6)))))
28122ef5fa9Smycroft*	Notes:	a) In order to reduce memory access, the coefficients are
28222ef5fa9Smycroft*		 made as "short" as possible: A1 (which is 1/2), A5 and A6
28322ef5fa9Smycroft*		 are single precision; A2, A3 and A4 are double precision.
28422ef5fa9Smycroft*		 b) Even with the restriction above,
28522ef5fa9Smycroft*			|p - (exp(R)-1)| <	|R| * 2^(-72.7)
28622ef5fa9Smycroft*		 for all |R| <= 0.0055.
2871f4ad37fSperry*		 c) To fully use the pipeline, p is separated into
28822ef5fa9Smycroft*		 two independent pieces of roughly equal complexity
28922ef5fa9Smycroft*			p = [ R*S*(A2 + S*(A4 + S*A6)) ]	+
29022ef5fa9Smycroft*				[ R + S*(A1 + S*(A3 + S*A5)) ]
29122ef5fa9Smycroft*		 where S = R*R.
29222ef5fa9Smycroft*
29322ef5fa9Smycroft*	Step 5.	Compute 2^(J/64)*p by
29422ef5fa9Smycroft*				p := T*p
29522ef5fa9Smycroft*		 where T and t are the stored values for 2^(J/64).
29622ef5fa9Smycroft*	Notes:	2^(J/64) is stored as T and t where T+t approximates
29722ef5fa9Smycroft*		 2^(J/64) to roughly 85 bits; T is in extended precision
29822ef5fa9Smycroft*		 and t is in single precision. Note also that T is rounded
29922ef5fa9Smycroft*		 to 62 bits so that the last two bits of T are zero. The
30022ef5fa9Smycroft*		 reason for such a special form is that T-1, T-2, and T-8
30122ef5fa9Smycroft*		 will all be exact --- a property that will be exploited
30222ef5fa9Smycroft*		 in Step 6 below. The total relative error in p is no
30322ef5fa9Smycroft*		 bigger than 2^(-67.7) compared to the final result.
30422ef5fa9Smycroft*
30522ef5fa9Smycroft*	Step 6.	Reconstruction of exp(X)-1
30622ef5fa9Smycroft*			exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ).
30722ef5fa9Smycroft*		6.1	If M <= 63, go to Step 6.3.
30822ef5fa9Smycroft*		6.2	ans := T + (p + (t + OnebySc)). Go to 6.6
30922ef5fa9Smycroft*		6.3	If M >= -3, go to 6.5.
31022ef5fa9Smycroft*		6.4	ans := (T + (p + t)) + OnebySc. Go to 6.6
31122ef5fa9Smycroft*		6.5	ans := (T + OnebySc) + (p + t).
31222ef5fa9Smycroft*		6.6	Restore user FPCR.
31322ef5fa9Smycroft*		6.7	Return ans := Sc * ans. Exit.
31422ef5fa9Smycroft*	Notes:	The various arrangements of the expressions give accurate
31522ef5fa9Smycroft*		 evaluations.
31622ef5fa9Smycroft*
31722ef5fa9Smycroft*	Step 7.	exp(X)-1 for |X| < 1/4.
31822ef5fa9Smycroft*		7.1	If |X| >= 2^(-65), go to Step 9.
31922ef5fa9Smycroft*		7.2	Go to Step 8.
32022ef5fa9Smycroft*
32122ef5fa9Smycroft*	Step 8.	Calculate exp(X)-1, |X| < 2^(-65).
32222ef5fa9Smycroft*		8.1	If |X| < 2^(-16312), goto 8.3
32322ef5fa9Smycroft*		8.2	Restore FPCR; return ans := X - 2^(-16382). Exit.
32422ef5fa9Smycroft*		8.3	X := X * 2^(140).
32522ef5fa9Smycroft*		8.4	Restore FPCR; ans := ans - 2^(-16382).
32622ef5fa9Smycroft*		 Return ans := ans*2^(140). Exit
32722ef5fa9Smycroft*	Notes:	The idea is to return "X - tiny" under the user
32822ef5fa9Smycroft*		 precision and rounding modes. To avoid unnecessary
32922ef5fa9Smycroft*		 inefficiency, we stay away from denormalized numbers the
33022ef5fa9Smycroft*		 best we can. For |X| >= 2^(-16312), the straightforward
33122ef5fa9Smycroft*		 8.2 generates the inexact exception as the case warrants.
33222ef5fa9Smycroft*
33322ef5fa9Smycroft*	Step 9.	Calculate exp(X)-1, |X| < 1/4, by a polynomial
33422ef5fa9Smycroft*			p = X + X*X*(B1 + X*(B2 + ... + X*B12))
33522ef5fa9Smycroft*	Notes:	a) In order to reduce memory access, the coefficients are
33622ef5fa9Smycroft*		 made as "short" as possible: B1 (which is 1/2), B9 to B12
33722ef5fa9Smycroft*		 are single precision; B3 to B8 are double precision; and
33822ef5fa9Smycroft*		 B2 is double extended.
33922ef5fa9Smycroft*		 b) Even with the restriction above,
34022ef5fa9Smycroft*			|p - (exp(X)-1)| < |X| 2^(-70.6)
34122ef5fa9Smycroft*		 for all |X| <= 0.251.
34222ef5fa9Smycroft*		 Note that 0.251 is slightly bigger than 1/4.
34322ef5fa9Smycroft*		 c) To fully preserve accuracy, the polynomial is computed
34422ef5fa9Smycroft*		 as	X + ( S*B1 +	Q ) where S = X*X and
34522ef5fa9Smycroft*			Q	=	X*S*(B2 + X*(B3 + ... + X*B12))
3461f4ad37fSperry*		 d) To fully use the pipeline, Q is separated into
34722ef5fa9Smycroft*		 two independent pieces of roughly equal complexity
34822ef5fa9Smycroft*			Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] +
34922ef5fa9Smycroft*				[ S*S*(B3 + S*(B5 + ... + S*B11)) ]
35022ef5fa9Smycroft*
35122ef5fa9Smycroft*	Step 10.	Calculate exp(X)-1 for |X| >= 70 log 2.
35222ef5fa9Smycroft*		10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all practical
35322ef5fa9Smycroft*		 purposes. Therefore, go to Step 1 of setox.
35422ef5fa9Smycroft*		10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical purposes.
35522ef5fa9Smycroft*		 ans := -1
35622ef5fa9Smycroft*		 Restore user FPCR
35722ef5fa9Smycroft*		 Return ans := ans + 2^(-126). Exit.
35822ef5fa9Smycroft*	Notes:	10.2 will always create an inexact and return -1 + tiny
35922ef5fa9Smycroft*		 in the user rounding precision and mode.
36022ef5fa9Smycroft*
36122ef5fa9Smycroft
36222ef5fa9Smycroftsetox	IDNT	2,1 Motorola 040 Floating Point Software Package
36322ef5fa9Smycroft
36422ef5fa9Smycroft	section	8
36522ef5fa9Smycroft
36622ef5fa9Smycroft	include	fpsp.h
36722ef5fa9Smycroft
36822ef5fa9SmycroftL2	DC.L	$3FDC0000,$82E30865,$4361C4C6,$00000000
36922ef5fa9Smycroft
37022ef5fa9SmycroftEXPA3	DC.L	$3FA55555,$55554431
37122ef5fa9SmycroftEXPA2	DC.L	$3FC55555,$55554018
37222ef5fa9Smycroft
37322ef5fa9SmycroftHUGE	DC.L	$7FFE0000,$FFFFFFFF,$FFFFFFFF,$00000000
37422ef5fa9SmycroftTINY	DC.L	$00010000,$FFFFFFFF,$FFFFFFFF,$00000000
37522ef5fa9Smycroft
37622ef5fa9SmycroftEM1A4	DC.L	$3F811111,$11174385
37722ef5fa9SmycroftEM1A3	DC.L	$3FA55555,$55554F5A
37822ef5fa9Smycroft
37922ef5fa9SmycroftEM1A2	DC.L	$3FC55555,$55555555,$00000000,$00000000
38022ef5fa9Smycroft
38122ef5fa9SmycroftEM1B8	DC.L	$3EC71DE3,$A5774682
38222ef5fa9SmycroftEM1B7	DC.L	$3EFA01A0,$19D7CB68
38322ef5fa9Smycroft
38422ef5fa9SmycroftEM1B6	DC.L	$3F2A01A0,$1A019DF3
38522ef5fa9SmycroftEM1B5	DC.L	$3F56C16C,$16C170E2
38622ef5fa9Smycroft
38722ef5fa9SmycroftEM1B4	DC.L	$3F811111,$11111111
38822ef5fa9SmycroftEM1B3	DC.L	$3FA55555,$55555555
38922ef5fa9Smycroft
39022ef5fa9SmycroftEM1B2	DC.L	$3FFC0000,$AAAAAAAA,$AAAAAAAB
39122ef5fa9Smycroft	DC.L	$00000000
39222ef5fa9Smycroft
39322ef5fa9SmycroftTWO140	DC.L	$48B00000,$00000000
39422ef5fa9SmycroftTWON140	DC.L	$37300000,$00000000
39522ef5fa9Smycroft
39622ef5fa9SmycroftEXPTBL
39722ef5fa9Smycroft	DC.L	$3FFF0000,$80000000,$00000000,$00000000
39822ef5fa9Smycroft	DC.L	$3FFF0000,$8164D1F3,$BC030774,$9F841A9B
39922ef5fa9Smycroft	DC.L	$3FFF0000,$82CD8698,$AC2BA1D8,$9FC1D5B9
40022ef5fa9Smycroft	DC.L	$3FFF0000,$843A28C3,$ACDE4048,$A0728369
40122ef5fa9Smycroft	DC.L	$3FFF0000,$85AAC367,$CC487B14,$1FC5C95C
40222ef5fa9Smycroft	DC.L	$3FFF0000,$871F6196,$9E8D1010,$1EE85C9F
40322ef5fa9Smycroft	DC.L	$3FFF0000,$88980E80,$92DA8528,$9FA20729
40422ef5fa9Smycroft	DC.L	$3FFF0000,$8A14D575,$496EFD9C,$A07BF9AF
40522ef5fa9Smycroft	DC.L	$3FFF0000,$8B95C1E3,$EA8BD6E8,$A0020DCF
40622ef5fa9Smycroft	DC.L	$3FFF0000,$8D1ADF5B,$7E5BA9E4,$205A63DA
40722ef5fa9Smycroft	DC.L	$3FFF0000,$8EA4398B,$45CD53C0,$1EB70051
40822ef5fa9Smycroft	DC.L	$3FFF0000,$9031DC43,$1466B1DC,$1F6EB029
40922ef5fa9Smycroft	DC.L	$3FFF0000,$91C3D373,$AB11C338,$A0781494
41022ef5fa9Smycroft	DC.L	$3FFF0000,$935A2B2F,$13E6E92C,$9EB319B0
41122ef5fa9Smycroft	DC.L	$3FFF0000,$94F4EFA8,$FEF70960,$2017457D
41222ef5fa9Smycroft	DC.L	$3FFF0000,$96942D37,$20185A00,$1F11D537
41322ef5fa9Smycroft	DC.L	$3FFF0000,$9837F051,$8DB8A970,$9FB952DD
41422ef5fa9Smycroft	DC.L	$3FFF0000,$99E04593,$20B7FA64,$1FE43087
41522ef5fa9Smycroft	DC.L	$3FFF0000,$9B8D39B9,$D54E5538,$1FA2A818
41622ef5fa9Smycroft	DC.L	$3FFF0000,$9D3ED9A7,$2CFFB750,$1FDE494D
41722ef5fa9Smycroft	DC.L	$3FFF0000,$9EF53260,$91A111AC,$20504890
41822ef5fa9Smycroft	DC.L	$3FFF0000,$A0B0510F,$B9714FC4,$A073691C
41922ef5fa9Smycroft	DC.L	$3FFF0000,$A2704303,$0C496818,$1F9B7A05
42022ef5fa9Smycroft	DC.L	$3FFF0000,$A43515AE,$09E680A0,$A0797126
42122ef5fa9Smycroft	DC.L	$3FFF0000,$A5FED6A9,$B15138EC,$A071A140
42222ef5fa9Smycroft	DC.L	$3FFF0000,$A7CD93B4,$E9653568,$204F62DA
42322ef5fa9Smycroft	DC.L	$3FFF0000,$A9A15AB4,$EA7C0EF8,$1F283C4A
42422ef5fa9Smycroft	DC.L	$3FFF0000,$AB7A39B5,$A93ED338,$9F9A7FDC
42522ef5fa9Smycroft	DC.L	$3FFF0000,$AD583EEA,$42A14AC8,$A05B3FAC
42622ef5fa9Smycroft	DC.L	$3FFF0000,$AF3B78AD,$690A4374,$1FDF2610
42722ef5fa9Smycroft	DC.L	$3FFF0000,$B123F581,$D2AC2590,$9F705F90
42822ef5fa9Smycroft	DC.L	$3FFF0000,$B311C412,$A9112488,$201F678A
42922ef5fa9Smycroft	DC.L	$3FFF0000,$B504F333,$F9DE6484,$1F32FB13
43022ef5fa9Smycroft	DC.L	$3FFF0000,$B6FD91E3,$28D17790,$20038B30
43122ef5fa9Smycroft	DC.L	$3FFF0000,$B8FBAF47,$62FB9EE8,$200DC3CC
43222ef5fa9Smycroft	DC.L	$3FFF0000,$BAFF5AB2,$133E45FC,$9F8B2AE6
43322ef5fa9Smycroft	DC.L	$3FFF0000,$BD08A39F,$580C36C0,$A02BBF70
43422ef5fa9Smycroft	DC.L	$3FFF0000,$BF1799B6,$7A731084,$A00BF518
43522ef5fa9Smycroft	DC.L	$3FFF0000,$C12C4CCA,$66709458,$A041DD41
43622ef5fa9Smycroft	DC.L	$3FFF0000,$C346CCDA,$24976408,$9FDF137B
43722ef5fa9Smycroft	DC.L	$3FFF0000,$C5672A11,$5506DADC,$201F1568
43822ef5fa9Smycroft	DC.L	$3FFF0000,$C78D74C8,$ABB9B15C,$1FC13A2E
43922ef5fa9Smycroft	DC.L	$3FFF0000,$C9B9BD86,$6E2F27A4,$A03F8F03
44022ef5fa9Smycroft	DC.L	$3FFF0000,$CBEC14FE,$F2727C5C,$1FF4907D
44122ef5fa9Smycroft	DC.L	$3FFF0000,$CE248C15,$1F8480E4,$9E6E53E4
44222ef5fa9Smycroft	DC.L	$3FFF0000,$D06333DA,$EF2B2594,$1FD6D45C
44322ef5fa9Smycroft	DC.L	$3FFF0000,$D2A81D91,$F12AE45C,$A076EDB9
44422ef5fa9Smycroft	DC.L	$3FFF0000,$D4F35AAB,$CFEDFA20,$9FA6DE21
44522ef5fa9Smycroft	DC.L	$3FFF0000,$D744FCCA,$D69D6AF4,$1EE69A2F
44622ef5fa9Smycroft	DC.L	$3FFF0000,$D99D15C2,$78AFD7B4,$207F439F
44722ef5fa9Smycroft	DC.L	$3FFF0000,$DBFBB797,$DAF23754,$201EC207
44822ef5fa9Smycroft	DC.L	$3FFF0000,$DE60F482,$5E0E9124,$9E8BE175
44922ef5fa9Smycroft	DC.L	$3FFF0000,$E0CCDEEC,$2A94E110,$20032C4B
45022ef5fa9Smycroft	DC.L	$3FFF0000,$E33F8972,$BE8A5A50,$2004DFF5
45122ef5fa9Smycroft	DC.L	$3FFF0000,$E5B906E7,$7C8348A8,$1E72F47A
45222ef5fa9Smycroft	DC.L	$3FFF0000,$E8396A50,$3C4BDC68,$1F722F22
45322ef5fa9Smycroft	DC.L	$3FFF0000,$EAC0C6E7,$DD243930,$A017E945
45422ef5fa9Smycroft	DC.L	$3FFF0000,$ED4F301E,$D9942B84,$1F401A5B
45522ef5fa9Smycroft	DC.L	$3FFF0000,$EFE4B99B,$DCDAF5CC,$9FB9A9E3
45622ef5fa9Smycroft	DC.L	$3FFF0000,$F281773C,$59FFB138,$20744C05
45722ef5fa9Smycroft	DC.L	$3FFF0000,$F5257D15,$2486CC2C,$1F773A19
45822ef5fa9Smycroft	DC.L	$3FFF0000,$F7D0DF73,$0AD13BB8,$1FFE90D5
45922ef5fa9Smycroft	DC.L	$3FFF0000,$FA83B2DB,$722A033C,$A041ED22
46022ef5fa9Smycroft	DC.L	$3FFF0000,$FD3E0C0C,$F486C174,$1F853F3A
46122ef5fa9Smycroft
46222ef5fa9SmycroftADJFLAG	equ L_SCR2
46322ef5fa9SmycroftSCALE	equ FP_SCR1
46422ef5fa9SmycroftADJSCALE equ FP_SCR2
46522ef5fa9SmycroftSC	equ FP_SCR3
46622ef5fa9SmycroftONEBYSC	equ FP_SCR4
46722ef5fa9Smycroft
46822ef5fa9Smycroft	xref	t_frcinx
46922ef5fa9Smycroft	xref	t_extdnrm
47022ef5fa9Smycroft	xref	t_unfl
47122ef5fa9Smycroft	xref	t_ovfl
47222ef5fa9Smycroft
47322ef5fa9Smycroft	xdef	setoxd
47422ef5fa9Smycroftsetoxd:
47522ef5fa9Smycroft*--entry point for EXP(X), X is denormalized
47622ef5fa9Smycroft	MOVE.L		(a0),d0
47722ef5fa9Smycroft	ANDI.L		#$80000000,d0
47822ef5fa9Smycroft	ORI.L		#$00800000,d0		...sign(X)*2^(-126)
47922ef5fa9Smycroft	MOVE.L		d0,-(sp)
48022ef5fa9Smycroft	FMOVE.S		#:3F800000,fp0
48122ef5fa9Smycroft	fmove.l		d1,fpcr
48222ef5fa9Smycroft	FADD.S		(sp)+,fp0
48322ef5fa9Smycroft	bra		t_frcinx
48422ef5fa9Smycroft
48522ef5fa9Smycroft	xdef	setox
48622ef5fa9Smycroftsetox:
48722ef5fa9Smycroft*--entry point for EXP(X), here X is finite, non-zero, and not NaN's
48822ef5fa9Smycroft
48922ef5fa9Smycroft*--Step 1.
49022ef5fa9Smycroft	MOVE.L		(a0),d0	 ...load part of input X
49122ef5fa9Smycroft	ANDI.L		#$7FFF0000,d0	...biased expo. of X
49222ef5fa9Smycroft	CMPI.L		#$3FBE0000,d0	...2^(-65)
49322ef5fa9Smycroft	BGE.B		EXPC1		...normal case
49422ef5fa9Smycroft	BRA.W		EXPSM
49522ef5fa9Smycroft
49622ef5fa9SmycroftEXPC1:
49722ef5fa9Smycroft*--The case |X| >= 2^(-65)
49822ef5fa9Smycroft	MOVE.W		4(a0),d0	...expo. and partial sig. of |X|
49922ef5fa9Smycroft	CMPI.L		#$400CB167,d0	...16380 log2 trunc. 16 bits
50022ef5fa9Smycroft	BLT.B		EXPMAIN	 ...normal case
50122ef5fa9Smycroft	BRA.W		EXPBIG
50222ef5fa9Smycroft
50322ef5fa9SmycroftEXPMAIN:
50422ef5fa9Smycroft*--Step 2.
50522ef5fa9Smycroft*--This is the normal branch:	2^(-65) <= |X| < 16380 log2.
50622ef5fa9Smycroft	FMOVE.X		(a0),fp0	...load input from (a0)
50722ef5fa9Smycroft
50822ef5fa9Smycroft	FMOVE.X		fp0,fp1
50922ef5fa9Smycroft	FMUL.S		#:42B8AA3B,fp0	...64/log2 * X
51022ef5fa9Smycroft	fmovem.x	fp2/fp3,-(a7)		...save fp2
511eddb30abSmycroft	CLR.L		ADJFLAG(a6)
51222ef5fa9Smycroft	FMOVE.L		fp0,d0		...N = int( X * 64/log2 )
51322ef5fa9Smycroft	LEA		EXPTBL,a1
51422ef5fa9Smycroft	FMOVE.L		d0,fp0		...convert to floating-format
51522ef5fa9Smycroft
51622ef5fa9Smycroft	MOVE.L		d0,L_SCR1(a6)	...save N temporarily
51722ef5fa9Smycroft	ANDI.L		#$3F,d0		...D0 is J = N mod 64
51822ef5fa9Smycroft	LSL.L		#4,d0
51922ef5fa9Smycroft	ADDA.L		d0,a1		...address of 2^(J/64)
52022ef5fa9Smycroft	MOVE.L		L_SCR1(a6),d0
52122ef5fa9Smycroft	ASR.L		#6,d0		...D0 is M
52222ef5fa9Smycroft	ADDI.W		#$3FFF,d0	...biased expo. of 2^(M)
52322ef5fa9Smycroft	MOVE.W		L2,L_SCR1(a6)	...prefetch L2, no need in CB
52422ef5fa9Smycroft
52522ef5fa9SmycroftEXPCONT1:
52622ef5fa9Smycroft*--Step 3.
52722ef5fa9Smycroft*--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
52822ef5fa9Smycroft*--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
52922ef5fa9Smycroft	FMOVE.X		fp0,fp2
53022ef5fa9Smycroft	FMUL.S		#:BC317218,fp0	...N * L1, L1 = lead(-log2/64)
53122ef5fa9Smycroft	FMUL.X		L2,fp2		...N * L2, L1+L2 = -log2/64
53222ef5fa9Smycroft	FADD.X		fp1,fp0	 	...X + N*L1
53322ef5fa9Smycroft	FADD.X		fp2,fp0		...fp0 is R, reduced arg.
53422ef5fa9Smycroft*	MOVE.W		#$3FA5,EXPA3	...load EXPA3 in cache
53522ef5fa9Smycroft
53622ef5fa9Smycroft*--Step 4.
53722ef5fa9Smycroft*--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
53822ef5fa9Smycroft*-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
5391f4ad37fSperry*--TO FULLY USE THE PIPELINE, WE COMPUTE S = R*R
54022ef5fa9Smycroft*--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
54122ef5fa9Smycroft
54222ef5fa9Smycroft	FMOVE.X		fp0,fp1
54322ef5fa9Smycroft	FMUL.X		fp1,fp1	 	...fp1 IS S = R*R
54422ef5fa9Smycroft
54522ef5fa9Smycroft	FMOVE.S		#:3AB60B70,fp2	...fp2 IS A5
546eddb30abSmycroft*	CLR.W		2(a1)		...load 2^(J/64) in cache
54722ef5fa9Smycroft
54822ef5fa9Smycroft	FMUL.X		fp1,fp2	 	...fp2 IS S*A5
54922ef5fa9Smycroft	FMOVE.X		fp1,fp3
55022ef5fa9Smycroft	FMUL.S		#:3C088895,fp3	...fp3 IS S*A4
55122ef5fa9Smycroft
55222ef5fa9Smycroft	FADD.D		EXPA3,fp2	...fp2 IS A3+S*A5
55322ef5fa9Smycroft	FADD.D		EXPA2,fp3	...fp3 IS A2+S*A4
55422ef5fa9Smycroft
55522ef5fa9Smycroft	FMUL.X		fp1,fp2	 	...fp2 IS S*(A3+S*A5)
55622ef5fa9Smycroft	MOVE.W		d0,SCALE(a6)	...SCALE is 2^(M) in extended
55722ef5fa9Smycroft	clr.w		SCALE+2(a6)
55822ef5fa9Smycroft	move.l		#$80000000,SCALE+4(a6)
55922ef5fa9Smycroft	clr.l		SCALE+8(a6)
56022ef5fa9Smycroft
56122ef5fa9Smycroft	FMUL.X		fp1,fp3	 	...fp3 IS S*(A2+S*A4)
56222ef5fa9Smycroft
56322ef5fa9Smycroft	FADD.S		#:3F000000,fp2	...fp2 IS A1+S*(A3+S*A5)
56422ef5fa9Smycroft	FMUL.X		fp0,fp3	 	...fp3 IS R*S*(A2+S*A4)
56522ef5fa9Smycroft
56622ef5fa9Smycroft	FMUL.X		fp1,fp2	 	...fp2 IS S*(A1+S*(A3+S*A5))
56722ef5fa9Smycroft	FADD.X		fp3,fp0	 	...fp0 IS R+R*S*(A2+S*A4),
56822ef5fa9Smycroft*					...fp3 released
56922ef5fa9Smycroft
57022ef5fa9Smycroft	FMOVE.X		(a1)+,fp1	...fp1 is lead. pt. of 2^(J/64)
57122ef5fa9Smycroft	FADD.X		fp2,fp0	 	...fp0 is EXP(R) - 1
57222ef5fa9Smycroft*					...fp2 released
57322ef5fa9Smycroft
57422ef5fa9Smycroft*--Step 5
57522ef5fa9Smycroft*--final reconstruction process
57622ef5fa9Smycroft*--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
57722ef5fa9Smycroft
57822ef5fa9Smycroft	FMUL.X		fp1,fp0	 	...2^(J/64)*(Exp(R)-1)
57922ef5fa9Smycroft	fmovem.x	(a7)+,fp2/fp3	...fp2 restored
58022ef5fa9Smycroft	FADD.S		(a1),fp0	...accurate 2^(J/64)
58122ef5fa9Smycroft
58222ef5fa9Smycroft	FADD.X		fp1,fp0	 	...2^(J/64) + 2^(J/64)*...
58322ef5fa9Smycroft	MOVE.L		ADJFLAG(a6),d0
58422ef5fa9Smycroft
58522ef5fa9Smycroft*--Step 6
58622ef5fa9Smycroft	TST.L		D0
58722ef5fa9Smycroft	BEQ.B		NORMAL
58822ef5fa9SmycroftADJUST:
58922ef5fa9Smycroft	FMUL.X		ADJSCALE(a6),fp0
59022ef5fa9SmycroftNORMAL:
59122ef5fa9Smycroft	FMOVE.L		d1,FPCR	 	...restore user FPCR
59222ef5fa9Smycroft	FMUL.X		SCALE(a6),fp0	...multiply 2^(M)
59322ef5fa9Smycroft	bra		t_frcinx
59422ef5fa9Smycroft
59522ef5fa9SmycroftEXPSM:
59622ef5fa9Smycroft*--Step 7
59722ef5fa9Smycroft	FMOVEM.X	(a0),fp0	...in case X is denormalized
59822ef5fa9Smycroft	FMOVE.L		d1,FPCR
59922ef5fa9Smycroft	FADD.S		#:3F800000,fp0	...1+X in user mode
60022ef5fa9Smycroft	bra		t_frcinx
60122ef5fa9Smycroft
60222ef5fa9SmycroftEXPBIG:
60322ef5fa9Smycroft*--Step 8
60422ef5fa9Smycroft	CMPI.L		#$400CB27C,d0	...16480 log2
60522ef5fa9Smycroft	BGT.B		EXP2BIG
60622ef5fa9Smycroft*--Steps 8.2 -- 8.6
60722ef5fa9Smycroft	FMOVE.X		(a0),fp0	...load input from (a0)
60822ef5fa9Smycroft
60922ef5fa9Smycroft	FMOVE.X		fp0,fp1
61022ef5fa9Smycroft	FMUL.S		#:42B8AA3B,fp0	...64/log2 * X
61122ef5fa9Smycroft	fmovem.x	 fp2/fp3,-(a7)		...save fp2
61222ef5fa9Smycroft	MOVE.L		#1,ADJFLAG(a6)
61322ef5fa9Smycroft	FMOVE.L		fp0,d0		...N = int( X * 64/log2 )
61422ef5fa9Smycroft	LEA		EXPTBL,a1
61522ef5fa9Smycroft	FMOVE.L		d0,fp0		...convert to floating-format
61622ef5fa9Smycroft	MOVE.L		d0,L_SCR1(a6)			...save N temporarily
61722ef5fa9Smycroft	ANDI.L		#$3F,d0		 ...D0 is J = N mod 64
61822ef5fa9Smycroft	LSL.L		#4,d0
61922ef5fa9Smycroft	ADDA.L		d0,a1			...address of 2^(J/64)
62022ef5fa9Smycroft	MOVE.L		L_SCR1(a6),d0
62122ef5fa9Smycroft	ASR.L		#6,d0			...D0 is K
62222ef5fa9Smycroft	MOVE.L		d0,L_SCR1(a6)			...save K temporarily
62322ef5fa9Smycroft	ASR.L		#1,d0			...D0 is M1
62422ef5fa9Smycroft	SUB.L		d0,L_SCR1(a6)			...a1 is M
62522ef5fa9Smycroft	ADDI.W		#$3FFF,d0		...biased expo. of 2^(M1)
62622ef5fa9Smycroft	MOVE.W		d0,ADJSCALE(a6)		...ADJSCALE := 2^(M1)
62722ef5fa9Smycroft	clr.w		ADJSCALE+2(a6)
62822ef5fa9Smycroft	move.l		#$80000000,ADJSCALE+4(a6)
62922ef5fa9Smycroft	clr.l		ADJSCALE+8(a6)
63022ef5fa9Smycroft	MOVE.L		L_SCR1(a6),d0			...D0 is M
63122ef5fa9Smycroft	ADDI.W		#$3FFF,d0		...biased expo. of 2^(M)
63222ef5fa9Smycroft	BRA.W		EXPCONT1		...go back to Step 3
63322ef5fa9Smycroft
63422ef5fa9SmycroftEXP2BIG:
63522ef5fa9Smycroft*--Step 9
63622ef5fa9Smycroft	FMOVE.L		d1,FPCR
63722ef5fa9Smycroft	MOVE.L		(a0),d0
63822ef5fa9Smycroft	bclr.b		#sign_bit,(a0)		...setox always returns positive
639eddb30abSmycroft	TST.L		d0
64022ef5fa9Smycroft	BLT		t_unfl
64122ef5fa9Smycroft	BRA		t_ovfl
64222ef5fa9Smycroft
64322ef5fa9Smycroft	xdef	setoxm1d
64422ef5fa9Smycroftsetoxm1d:
64522ef5fa9Smycroft*--entry point for EXPM1(X), here X is denormalized
64622ef5fa9Smycroft*--Step 0.
64722ef5fa9Smycroft	bra		t_extdnrm
64822ef5fa9Smycroft
64922ef5fa9Smycroft
65022ef5fa9Smycroft	xdef	setoxm1
65122ef5fa9Smycroftsetoxm1:
65222ef5fa9Smycroft*--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
65322ef5fa9Smycroft
65422ef5fa9Smycroft*--Step 1.
65522ef5fa9Smycroft*--Step 1.1
65622ef5fa9Smycroft	MOVE.L		(a0),d0	 ...load part of input X
65722ef5fa9Smycroft	ANDI.L		#$7FFF0000,d0	...biased expo. of X
65822ef5fa9Smycroft	CMPI.L		#$3FFD0000,d0	...1/4
65922ef5fa9Smycroft	BGE.B		EM1CON1	 ...|X| >= 1/4
66022ef5fa9Smycroft	BRA.W		EM1SM
66122ef5fa9Smycroft
66222ef5fa9SmycroftEM1CON1:
66322ef5fa9Smycroft*--Step 1.3
66422ef5fa9Smycroft*--The case |X| >= 1/4
66522ef5fa9Smycroft	MOVE.W		4(a0),d0	...expo. and partial sig. of |X|
66622ef5fa9Smycroft	CMPI.L		#$4004C215,d0	...70log2 rounded up to 16 bits
66722ef5fa9Smycroft	BLE.B		EM1MAIN	 ...1/4 <= |X| <= 70log2
66822ef5fa9Smycroft	BRA.W		EM1BIG
66922ef5fa9Smycroft
67022ef5fa9SmycroftEM1MAIN:
67122ef5fa9Smycroft*--Step 2.
67222ef5fa9Smycroft*--This is the case:	1/4 <= |X| <= 70 log2.
67322ef5fa9Smycroft	FMOVE.X		(a0),fp0	...load input from (a0)
67422ef5fa9Smycroft
67522ef5fa9Smycroft	FMOVE.X		fp0,fp1
67622ef5fa9Smycroft	FMUL.S		#:42B8AA3B,fp0	...64/log2 * X
67722ef5fa9Smycroft	fmovem.x	fp2/fp3,-(a7)		...save fp2
67822ef5fa9Smycroft*	MOVE.W		#$3F81,EM1A4		...prefetch in CB mode
67922ef5fa9Smycroft	FMOVE.L		fp0,d0		...N = int( X * 64/log2 )
68022ef5fa9Smycroft	LEA		EXPTBL,a1
68122ef5fa9Smycroft	FMOVE.L		d0,fp0		...convert to floating-format
68222ef5fa9Smycroft
68322ef5fa9Smycroft	MOVE.L		d0,L_SCR1(a6)			...save N temporarily
68422ef5fa9Smycroft	ANDI.L		#$3F,d0		 ...D0 is J = N mod 64
68522ef5fa9Smycroft	LSL.L		#4,d0
68622ef5fa9Smycroft	ADDA.L		d0,a1			...address of 2^(J/64)
68722ef5fa9Smycroft	MOVE.L		L_SCR1(a6),d0
68822ef5fa9Smycroft	ASR.L		#6,d0			...D0 is M
68922ef5fa9Smycroft	MOVE.L		d0,L_SCR1(a6)			...save a copy of M
69022ef5fa9Smycroft*	MOVE.W		#$3FDC,L2		...prefetch L2 in CB mode
69122ef5fa9Smycroft
69222ef5fa9Smycroft*--Step 3.
69322ef5fa9Smycroft*--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
69422ef5fa9Smycroft*--a0 points to 2^(J/64), D0 and a1 both contain M
69522ef5fa9Smycroft	FMOVE.X		fp0,fp2
69622ef5fa9Smycroft	FMUL.S		#:BC317218,fp0	...N * L1, L1 = lead(-log2/64)
69722ef5fa9Smycroft	FMUL.X		L2,fp2		...N * L2, L1+L2 = -log2/64
69822ef5fa9Smycroft	FADD.X		fp1,fp0	 ...X + N*L1
69922ef5fa9Smycroft	FADD.X		fp2,fp0	 ...fp0 is R, reduced arg.
70022ef5fa9Smycroft*	MOVE.W		#$3FC5,EM1A2		...load EM1A2 in cache
70122ef5fa9Smycroft	ADDI.W		#$3FFF,d0		...D0 is biased expo. of 2^M
70222ef5fa9Smycroft
70322ef5fa9Smycroft*--Step 4.
70422ef5fa9Smycroft*--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
70522ef5fa9Smycroft*-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
7061f4ad37fSperry*--TO FULLY USE THE PIPELINE, WE COMPUTE S = R*R
70722ef5fa9Smycroft*--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
70822ef5fa9Smycroft
70922ef5fa9Smycroft	FMOVE.X		fp0,fp1
71022ef5fa9Smycroft	FMUL.X		fp1,fp1		...fp1 IS S = R*R
71122ef5fa9Smycroft
71222ef5fa9Smycroft	FMOVE.S		#:3950097B,fp2	...fp2 IS a6
713eddb30abSmycroft*	CLR.W		2(a1)		...load 2^(J/64) in cache
71422ef5fa9Smycroft
71522ef5fa9Smycroft	FMUL.X		fp1,fp2		...fp2 IS S*A6
71622ef5fa9Smycroft	FMOVE.X		fp1,fp3
71722ef5fa9Smycroft	FMUL.S		#:3AB60B6A,fp3	...fp3 IS S*A5
71822ef5fa9Smycroft
71922ef5fa9Smycroft	FADD.D		EM1A4,fp2	...fp2 IS A4+S*A6
72022ef5fa9Smycroft	FADD.D		EM1A3,fp3	...fp3 IS A3+S*A5
72122ef5fa9Smycroft	MOVE.W		d0,SC(a6)		...SC is 2^(M) in extended
72222ef5fa9Smycroft	clr.w		SC+2(a6)
72322ef5fa9Smycroft	move.l		#$80000000,SC+4(a6)
72422ef5fa9Smycroft	clr.l		SC+8(a6)
72522ef5fa9Smycroft
72622ef5fa9Smycroft	FMUL.X		fp1,fp2		...fp2 IS S*(A4+S*A6)
72722ef5fa9Smycroft	MOVE.L		L_SCR1(a6),d0		...D0 is	M
72822ef5fa9Smycroft	NEG.W		D0		...D0 is -M
72922ef5fa9Smycroft	FMUL.X		fp1,fp3		...fp3 IS S*(A3+S*A5)
73022ef5fa9Smycroft	ADDI.W		#$3FFF,d0	...biased expo. of 2^(-M)
73122ef5fa9Smycroft	FADD.D		EM1A2,fp2	...fp2 IS A2+S*(A4+S*A6)
73222ef5fa9Smycroft	FADD.S		#:3F000000,fp3	...fp3 IS A1+S*(A3+S*A5)
73322ef5fa9Smycroft
73422ef5fa9Smycroft	FMUL.X		fp1,fp2		...fp2 IS S*(A2+S*(A4+S*A6))
73522ef5fa9Smycroft	ORI.W		#$8000,d0	...signed/expo. of -2^(-M)
73622ef5fa9Smycroft	MOVE.W		d0,ONEBYSC(a6)	...OnebySc is -2^(-M)
73722ef5fa9Smycroft	clr.w		ONEBYSC+2(a6)
73822ef5fa9Smycroft	move.l		#$80000000,ONEBYSC+4(a6)
73922ef5fa9Smycroft	clr.l		ONEBYSC+8(a6)
74022ef5fa9Smycroft	FMUL.X		fp3,fp1		...fp1 IS S*(A1+S*(A3+S*A5))
74122ef5fa9Smycroft*					...fp3 released
74222ef5fa9Smycroft
74322ef5fa9Smycroft	FMUL.X		fp0,fp2		...fp2 IS R*S*(A2+S*(A4+S*A6))
74422ef5fa9Smycroft	FADD.X		fp1,fp0		...fp0 IS R+S*(A1+S*(A3+S*A5))
74522ef5fa9Smycroft*					...fp1 released
74622ef5fa9Smycroft
74722ef5fa9Smycroft	FADD.X		fp2,fp0		...fp0 IS EXP(R)-1
74822ef5fa9Smycroft*					...fp2 released
74922ef5fa9Smycroft	fmovem.x	(a7)+,fp2/fp3	...fp2 restored
75022ef5fa9Smycroft
75122ef5fa9Smycroft*--Step 5
75222ef5fa9Smycroft*--Compute 2^(J/64)*p
75322ef5fa9Smycroft
75422ef5fa9Smycroft	FMUL.X		(a1),fp0	...2^(J/64)*(Exp(R)-1)
75522ef5fa9Smycroft
75622ef5fa9Smycroft*--Step 6
75722ef5fa9Smycroft*--Step 6.1
75822ef5fa9Smycroft	MOVE.L		L_SCR1(a6),d0		...retrieve M
75922ef5fa9Smycroft	CMPI.L		#63,d0
76022ef5fa9Smycroft	BLE.B		MLE63
76122ef5fa9Smycroft*--Step 6.2	M >= 64
76222ef5fa9Smycroft	FMOVE.S		12(a1),fp1	...fp1 is t
76322ef5fa9Smycroft	FADD.X		ONEBYSC(a6),fp1	...fp1 is t+OnebySc
76422ef5fa9Smycroft	FADD.X		fp1,fp0		...p+(t+OnebySc), fp1 released
76522ef5fa9Smycroft	FADD.X		(a1),fp0	...T+(p+(t+OnebySc))
76622ef5fa9Smycroft	BRA.B		EM1SCALE
76722ef5fa9SmycroftMLE63:
76822ef5fa9Smycroft*--Step 6.3	M <= 63
76922ef5fa9Smycroft	CMPI.L		#-3,d0
77022ef5fa9Smycroft	BGE.B		MGEN3
77122ef5fa9SmycroftMLTN3:
77222ef5fa9Smycroft*--Step 6.4	M <= -4
77322ef5fa9Smycroft	FADD.S		12(a1),fp0	...p+t
77422ef5fa9Smycroft	FADD.X		(a1),fp0	...T+(p+t)
77522ef5fa9Smycroft	FADD.X		ONEBYSC(a6),fp0	...OnebySc + (T+(p+t))
77622ef5fa9Smycroft	BRA.B		EM1SCALE
77722ef5fa9SmycroftMGEN3:
77822ef5fa9Smycroft*--Step 6.5	-3 <= M <= 63
77922ef5fa9Smycroft	FMOVE.X		(a1)+,fp1	...fp1 is T
78022ef5fa9Smycroft	FADD.S		(a1),fp0	...fp0 is p+t
78122ef5fa9Smycroft	FADD.X		ONEBYSC(a6),fp1	...fp1 is T+OnebySc
78222ef5fa9Smycroft	FADD.X		fp1,fp0		...(T+OnebySc)+(p+t)
78322ef5fa9Smycroft
78422ef5fa9SmycroftEM1SCALE:
78522ef5fa9Smycroft*--Step 6.6
78622ef5fa9Smycroft	FMOVE.L		d1,FPCR
78722ef5fa9Smycroft	FMUL.X		SC(a6),fp0
78822ef5fa9Smycroft
78922ef5fa9Smycroft	bra		t_frcinx
79022ef5fa9Smycroft
79122ef5fa9SmycroftEM1SM:
79222ef5fa9Smycroft*--Step 7	|X| < 1/4.
79322ef5fa9Smycroft	CMPI.L		#$3FBE0000,d0	...2^(-65)
79422ef5fa9Smycroft	BGE.B		EM1POLY
79522ef5fa9Smycroft
79622ef5fa9SmycroftEM1TINY:
79722ef5fa9Smycroft*--Step 8	|X| < 2^(-65)
79822ef5fa9Smycroft	CMPI.L		#$00330000,d0	...2^(-16312)
79922ef5fa9Smycroft	BLT.B		EM12TINY
80022ef5fa9Smycroft*--Step 8.2
80122ef5fa9Smycroft	MOVE.L		#$80010000,SC(a6)	...SC is -2^(-16382)
80222ef5fa9Smycroft	move.l		#$80000000,SC+4(a6)
80322ef5fa9Smycroft	clr.l		SC+8(a6)
80422ef5fa9Smycroft	FMOVE.X		(a0),fp0
80522ef5fa9Smycroft	FMOVE.L		d1,FPCR
80622ef5fa9Smycroft	FADD.X		SC(a6),fp0
80722ef5fa9Smycroft
80822ef5fa9Smycroft	bra		t_frcinx
80922ef5fa9Smycroft
81022ef5fa9SmycroftEM12TINY:
81122ef5fa9Smycroft*--Step 8.3
81222ef5fa9Smycroft	FMOVE.X		(a0),fp0
81322ef5fa9Smycroft	FMUL.D		TWO140,fp0
81422ef5fa9Smycroft	MOVE.L		#$80010000,SC(a6)
81522ef5fa9Smycroft	move.l		#$80000000,SC+4(a6)
81622ef5fa9Smycroft	clr.l		SC+8(a6)
81722ef5fa9Smycroft	FADD.X		SC(a6),fp0
81822ef5fa9Smycroft	FMOVE.L		d1,FPCR
81922ef5fa9Smycroft	FMUL.D		TWON140,fp0
82022ef5fa9Smycroft
82122ef5fa9Smycroft	bra		t_frcinx
82222ef5fa9Smycroft
82322ef5fa9SmycroftEM1POLY:
82422ef5fa9Smycroft*--Step 9	exp(X)-1 by a simple polynomial
82522ef5fa9Smycroft	FMOVE.X		(a0),fp0	...fp0 is X
82622ef5fa9Smycroft	FMUL.X		fp0,fp0		...fp0 is S := X*X
82722ef5fa9Smycroft	fmovem.x	fp2/fp3,-(a7)	...save fp2
82822ef5fa9Smycroft	FMOVE.S		#:2F30CAA8,fp1	...fp1 is B12
82922ef5fa9Smycroft	FMUL.X		fp0,fp1		...fp1 is S*B12
83022ef5fa9Smycroft	FMOVE.S		#:310F8290,fp2	...fp2 is B11
83122ef5fa9Smycroft	FADD.S		#:32D73220,fp1	...fp1 is B10+S*B12
83222ef5fa9Smycroft
83322ef5fa9Smycroft	FMUL.X		fp0,fp2		...fp2 is S*B11
83422ef5fa9Smycroft	FMUL.X		fp0,fp1		...fp1 is S*(B10 + ...
83522ef5fa9Smycroft
83622ef5fa9Smycroft	FADD.S		#:3493F281,fp2	...fp2 is B9+S*...
83722ef5fa9Smycroft	FADD.D		EM1B8,fp1	...fp1 is B8+S*...
83822ef5fa9Smycroft
83922ef5fa9Smycroft	FMUL.X		fp0,fp2		...fp2 is S*(B9+...
84022ef5fa9Smycroft	FMUL.X		fp0,fp1		...fp1 is S*(B8+...
84122ef5fa9Smycroft
84222ef5fa9Smycroft	FADD.D		EM1B7,fp2	...fp2 is B7+S*...
84322ef5fa9Smycroft	FADD.D		EM1B6,fp1	...fp1 is B6+S*...
84422ef5fa9Smycroft
84522ef5fa9Smycroft	FMUL.X		fp0,fp2		...fp2 is S*(B7+...
84622ef5fa9Smycroft	FMUL.X		fp0,fp1		...fp1 is S*(B6+...
84722ef5fa9Smycroft
84822ef5fa9Smycroft	FADD.D		EM1B5,fp2	...fp2 is B5+S*...
84922ef5fa9Smycroft	FADD.D		EM1B4,fp1	...fp1 is B4+S*...
85022ef5fa9Smycroft
85122ef5fa9Smycroft	FMUL.X		fp0,fp2		...fp2 is S*(B5+...
85222ef5fa9Smycroft	FMUL.X		fp0,fp1		...fp1 is S*(B4+...
85322ef5fa9Smycroft
85422ef5fa9Smycroft	FADD.D		EM1B3,fp2	...fp2 is B3+S*...
85522ef5fa9Smycroft	FADD.X		EM1B2,fp1	...fp1 is B2+S*...
85622ef5fa9Smycroft
85722ef5fa9Smycroft	FMUL.X		fp0,fp2		...fp2 is S*(B3+...
85822ef5fa9Smycroft	FMUL.X		fp0,fp1		...fp1 is S*(B2+...
85922ef5fa9Smycroft
86022ef5fa9Smycroft	FMUL.X		fp0,fp2		...fp2 is S*S*(B3+...)
86122ef5fa9Smycroft	FMUL.X		(a0),fp1	...fp1 is X*S*(B2...
86222ef5fa9Smycroft
86322ef5fa9Smycroft	FMUL.S		#:3F000000,fp0	...fp0 is S*B1
86422ef5fa9Smycroft	FADD.X		fp2,fp1		...fp1 is Q
86522ef5fa9Smycroft*					...fp2 released
86622ef5fa9Smycroft
86722ef5fa9Smycroft	fmovem.x	(a7)+,fp2/fp3	...fp2 restored
86822ef5fa9Smycroft
86922ef5fa9Smycroft	FADD.X		fp1,fp0		...fp0 is S*B1+Q
87022ef5fa9Smycroft*					...fp1 released
87122ef5fa9Smycroft
87222ef5fa9Smycroft	FMOVE.L		d1,FPCR
87322ef5fa9Smycroft	FADD.X		(a0),fp0
87422ef5fa9Smycroft
87522ef5fa9Smycroft	bra		t_frcinx
87622ef5fa9Smycroft
87722ef5fa9SmycroftEM1BIG:
87822ef5fa9Smycroft*--Step 10	|X| > 70 log2
87922ef5fa9Smycroft	MOVE.L		(a0),d0
880eddb30abSmycroft	TST.L		d0
88122ef5fa9Smycroft	BGT.W		EXPC1
88222ef5fa9Smycroft*--Step 10.2
88322ef5fa9Smycroft	FMOVE.S		#:BF800000,fp0	...fp0 is -1
88422ef5fa9Smycroft	FMOVE.L		d1,FPCR
88522ef5fa9Smycroft	FADD.S		#:00800000,fp0	...-1 + 2^(-126)
88622ef5fa9Smycroft
88722ef5fa9Smycroft	bra		t_frcinx
88822ef5fa9Smycroft
88922ef5fa9Smycroft	end
890