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