OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [m68k/] [fpsp040/] [setox.S] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
|
2
|       setox.sa 3.1 12/10/90
3
|
4
|       The entry point setox computes the exponential of a value.
5
|       setoxd does the same except the input value is a denormalized
6
|       number. setoxm1 computes exp(X)-1, and setoxm1d computes
7
|       exp(X)-1 for denormalized X.
8
|
9
|       INPUT
10
|       -----
11
|       Double-extended value in memory location pointed to by address
12
|       register a0.
13
|
14
|       OUTPUT
15
|       ------
16
|       exp(X) or exp(X)-1 returned in floating-point register fp0.
17
|
18
|       ACCURACY and MONOTONICITY
19
|       -------------------------
20
|       The returned result is within 0.85 ulps in 64 significant bit, i.e.
21
|       within 0.5001 ulp to 53 bits if the result is subsequently rounded
22
|       to double precision. The result is provably monotonic in double
23
|       precision.
24
|
25
|       SPEED
26
|       -----
27
|       Two timings are measured, both in the copy-back mode. The
28
|       first one is measured when the function is invoked the first time
29
|       (so the instructions and data are not in cache), and the
30
|       second one is measured when the function is reinvoked at the same
31
|       input argument.
32
|
33
|       The program setox takes approximately 210/190 cycles for input
34
|       argument X whose magnitude is less than 16380 log2, which
35
|       is the usual situation. For the less common arguments,
36
|       depending on their values, the program may run faster or slower --
37
|       but no worse than 10% slower even in the extreme cases.
38
|
39
|       The program setoxm1 takes approximately ???/??? cycles for input
40
|       argument X, 0.25 <= |X| < 70log2. For |X| < 0.25, it takes
41
|       approximately ???/??? cycles. For the less common arguments,
42
|       depending on their values, the program may run faster or slower --
43
|       but no worse than 10% slower even in the extreme cases.
44
|
45
|       ALGORITHM and IMPLEMENTATION NOTES
46
|       ----------------------------------
47
|
48
|       setoxd
49
|       ------
50
|       Step 1. Set ans := 1.0
51
|
52
|       Step 2. Return  ans := ans + sign(X)*2^(-126). Exit.
53
|       Notes:  This will always generate one exception -- inexact.
54
|
55
|
56
|       setox
57
|       -----
58
|
59
|       Step 1. Filter out extreme cases of input argument.
60
|               1.1     If |X| >= 2^(-65), go to Step 1.3.
61
|               1.2     Go to Step 7.
62
|               1.3     If |X| < 16380 log(2), go to Step 2.
63
|               1.4     Go to Step 8.
64
|       Notes:  The usual case should take the branches 1.1 -> 1.3 -> 2.
65
|                To avoid the use of floating-point comparisons, a
66
|                compact representation of |X| is used. This format is a
67
|                32-bit integer, the upper (more significant) 16 bits are
68
|                the sign and biased exponent field of |X|; the lower 16
69
|                bits are the 16 most significant fraction (including the
70
|                explicit bit) bits of |X|. Consequently, the comparisons
71
|                in Steps 1.1 and 1.3 can be performed by integer comparison.
72
|                Note also that the constant 16380 log(2) used in Step 1.3
73
|                is also in the compact form. Thus taking the branch
74
|                to Step 2 guarantees |X| < 16380 log(2). There is no harm
75
|                to have a small number of cases where |X| is less than,
76
|                but close to, 16380 log(2) and the branch to Step 9 is
77
|                taken.
78
|
79
|       Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ).
80
|               2.1     Set AdjFlag := 0 (indicates the branch 1.3 -> 2 was taken)
81
|               2.2     N := round-to-nearest-integer( X * 64/log2 ).
82
|               2.3     Calculate       J = N mod 64; so J = 0,1,2,..., or 63.
83
|               2.4     Calculate       M = (N - J)/64; so N = 64M + J.
84
|               2.5     Calculate the address of the stored value of 2^(J/64).
85
|               2.6     Create the value Scale = 2^M.
86
|       Notes:  The calculation in 2.2 is really performed by
87
|
88
|                       Z := X * constant
89
|                       N := round-to-nearest-integer(Z)
90
|
91
|                where
92
|
93
|                       constant := single-precision( 64/log 2 ).
94
|
95
|                Using a single-precision constant avoids memory access.
96
|                Another effect of using a single-precision "constant" is
97
|                that the calculated value Z is
98
|
99
|                       Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24).
100
|
101
|                This error has to be considered later in Steps 3 and 4.
102
|
103
|       Step 3. Calculate X - N*log2/64.
104
|               3.1     R := X + N*L1, where L1 := single-precision(-log2/64).
105
|               3.2     R := R + N*L2, L2 := extended-precision(-log2/64 - L1).
106
|       Notes:  a) The way L1 and L2 are chosen ensures L1+L2 approximate
107
|                the value      -log2/64        to 88 bits of accuracy.
108
|                b) N*L1 is exact because N is no longer than 22 bits and
109
|                L1 is no longer than 24 bits.
110
|                c) The calculation X+N*L1 is also exact due to cancellation.
111
|                Thus, R is practically X+N(L1+L2) to full 64 bits.
112
|                d) It is important to estimate how large can |R| be after
113
|                Step 3.2.
114
|
115
|                       N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24)
116
|                       X*64/log2 (1+eps)       =       N + f,  |f| <= 0.5
117
|                       X*64/log2 - N   =       f - eps*X 64/log2
118
|                       X - N*log2/64   =       f*log2/64 - eps*X
119
|
120
|
121
|                Now |X| <= 16446 log2, thus
122
|
123
|                       |X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64
124
|                                       <= 0.57 log2/64.
125
|                This bound will be used in Step 4.
126
|
127
|       Step 4. Approximate exp(R)-1 by a polynomial
128
|                       p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
129
|       Notes:  a) In order to reduce memory access, the coefficients are
130
|                made as "short" as possible: A1 (which is 1/2), A4 and A5
131
|                are single precision; A2 and A3 are double precision.
132
|                b) Even with the restrictions above,
133
|                       |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062.
134
|                Note that 0.0062 is slightly bigger than 0.57 log2/64.
135
|                c) To fully utilize the pipeline, p is separated into
136
|                two independent pieces of roughly equal complexities
137
|                       p = [ R + R*S*(A2 + S*A4) ]     +
138
|                               [ S*(A1 + S*(A3 + S*A5)) ]
139
|                where S = R*R.
140
|
141
|       Step 5. Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by
142
|                               ans := T + ( T*p + t)
143
|                where T and t are the stored values for 2^(J/64).
144
|       Notes:  2^(J/64) is stored as T and t where T+t approximates
145
|                2^(J/64) to roughly 85 bits; T is in extended precision
146
|                and t is in single precision. Note also that T is rounded
147
|                to 62 bits so that the last two bits of T are zero. The
148
|                reason for such a special form is that T-1, T-2, and T-8
149
|                will all be exact --- a property that will give much
150
|                more accurate computation of the function EXPM1.
151
|
152
|       Step 6. Reconstruction of exp(X)
153
|                       exp(X) = 2^M * 2^(J/64) * exp(R).
154
|               6.1     If AdjFlag = 0, go to 6.3
155
|               6.2     ans := ans * AdjScale
156
|               6.3     Restore the user FPCR
157
|               6.4     Return ans := ans * Scale. Exit.
158
|       Notes:  If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R,
159
|                |M| <= 16380, and Scale = 2^M. Moreover, exp(X) will
160
|                neither overflow nor underflow. If AdjFlag = 1, that
161
|                means that
162
|                       X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380.
163
|                Hence, exp(X) may overflow or underflow or neither.
164
|                When that is the case, AdjScale = 2^(M1) where M1 is
165
|                approximately M. Thus 6.2 will never cause over/underflow.
166
|                Possible exception in 6.4 is overflow or underflow.
167
|                The inexact exception is not generated in 6.4. Although
168
|                one can argue that the inexact flag should always be
169
|                raised, to simulate that exception cost to much than the
170
|                flag is worth in practical uses.
171
|
172
|       Step 7. Return 1 + X.
173
|               7.1     ans := X
174
|               7.2     Restore user FPCR.
175
|               7.3     Return ans := 1 + ans. Exit
176
|       Notes:  For non-zero X, the inexact exception will always be
177
|                raised by 7.3. That is the only exception raised by 7.3.
178
|                Note also that we use the FMOVEM instruction to move X
179
|                in Step 7.1 to avoid unnecessary trapping. (Although
180
|                the FMOVEM may not seem relevant since X is normalized,
181
|                the precaution will be useful in the library version of
182
|                this code where the separate entry for denormalized inputs
183
|                will be done away with.)
184
|
185
|       Step 8. Handle exp(X) where |X| >= 16380log2.
186
|               8.1     If |X| > 16480 log2, go to Step 9.
187
|               (mimic 2.2 - 2.6)
188
|               8.2     N := round-to-integer( X * 64/log2 )
189
|               8.3     Calculate J = N mod 64, J = 0,1,...,63
190
|               8.4     K := (N-J)/64, M1 := truncate(K/2), M = K-M1, AdjFlag := 1.
191
|               8.5     Calculate the address of the stored value 2^(J/64).
192
|               8.6     Create the values Scale = 2^M, AdjScale = 2^M1.
193
|               8.7     Go to Step 3.
194
|       Notes:  Refer to notes for 2.2 - 2.6.
195
|
196
|       Step 9. Handle exp(X), |X| > 16480 log2.
197
|               9.1     If X < 0, go to 9.3
198
|               9.2     ans := Huge, go to 9.4
199
|               9.3     ans := Tiny.
200
|               9.4     Restore user FPCR.
201
|               9.5     Return ans := ans * ans. Exit.
202
|       Notes:  Exp(X) will surely overflow or underflow, depending on
203
|                X's sign. "Huge" and "Tiny" are respectively large/tiny
204
|                extended-precision numbers whose square over/underflow
205
|                with an inexact result. Thus, 9.5 always raises the
206
|                inexact together with either overflow or underflow.
207
|
208
|
209
|       setoxm1d
210
|       --------
211
|
212
|       Step 1. Set ans := 0
213
|
214
|       Step 2. Return  ans := X + ans. Exit.
215
|       Notes:  This will return X with the appropriate rounding
216
|                precision prescribed by the user FPCR.
217
|
218
|       setoxm1
219
|       -------
220
|
221
|       Step 1. Check |X|
222
|               1.1     If |X| >= 1/4, go to Step 1.3.
223
|               1.2     Go to Step 7.
224
|               1.3     If |X| < 70 log(2), go to Step 2.
225
|               1.4     Go to Step 10.
226
|       Notes:  The usual case should take the branches 1.1 -> 1.3 -> 2.
227
|                However, it is conceivable |X| can be small very often
228
|                because EXPM1 is intended to evaluate exp(X)-1 accurately
229
|                when |X| is small. For further details on the comparisons,
230
|                see the notes on Step 1 of setox.
231
|
232
|       Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ).
233
|               2.1     N := round-to-nearest-integer( X * 64/log2 ).
234
|               2.2     Calculate       J = N mod 64; so J = 0,1,2,..., or 63.
235
|               2.3     Calculate       M = (N - J)/64; so N = 64M + J.
236
|               2.4     Calculate the address of the stored value of 2^(J/64).
237
|               2.5     Create the values Sc = 2^M and OnebySc := -2^(-M).
238
|       Notes:  See the notes on Step 2 of setox.
239
|
240
|       Step 3. Calculate X - N*log2/64.
241
|               3.1     R := X + N*L1, where L1 := single-precision(-log2/64).
242
|               3.2     R := R + N*L2, L2 := extended-precision(-log2/64 - L1).
243
|       Notes:  Applying the analysis of Step 3 of setox in this case
244
|                shows that |R| <= 0.0055 (note that |X| <= 70 log2 in
245
|                this case).
246
|
247
|       Step 4. Approximate exp(R)-1 by a polynomial
248
|                       p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6)))))
249
|       Notes:  a) In order to reduce memory access, the coefficients are
250
|                made as "short" as possible: A1 (which is 1/2), A5 and A6
251
|                are single precision; A2, A3 and A4 are double precision.
252
|                b) Even with the restriction above,
253
|                       |p - (exp(R)-1)| <      |R| * 2^(-72.7)
254
|                for all |R| <= 0.0055.
255
|                c) To fully utilize the pipeline, p is separated into
256
|                two independent pieces of roughly equal complexity
257
|                       p = [ R*S*(A2 + S*(A4 + S*A6)) ]        +
258
|                               [ R + S*(A1 + S*(A3 + S*A5)) ]
259
|                where S = R*R.
260
|
261
|       Step 5. Compute 2^(J/64)*p by
262
|                               p := T*p
263
|                where T and t are the stored values for 2^(J/64).
264
|       Notes:  2^(J/64) is stored as T and t where T+t approximates
265
|                2^(J/64) to roughly 85 bits; T is in extended precision
266
|                and t is in single precision. Note also that T is rounded
267
|                to 62 bits so that the last two bits of T are zero. The
268
|                reason for such a special form is that T-1, T-2, and T-8
269
|                will all be exact --- a property that will be exploited
270
|                in Step 6 below. The total relative error in p is no
271
|                bigger than 2^(-67.7) compared to the final result.
272
|
273
|       Step 6. Reconstruction of exp(X)-1
274
|                       exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ).
275
|               6.1     If M <= 63, go to Step 6.3.
276
|               6.2     ans := T + (p + (t + OnebySc)). Go to 6.6
277
|               6.3     If M >= -3, go to 6.5.
278
|               6.4     ans := (T + (p + t)) + OnebySc. Go to 6.6
279
|               6.5     ans := (T + OnebySc) + (p + t).
280
|               6.6     Restore user FPCR.
281
|               6.7     Return ans := Sc * ans. Exit.
282
|       Notes:  The various arrangements of the expressions give accurate
283
|                evaluations.
284
|
285
|       Step 7. exp(X)-1 for |X| < 1/4.
286
|               7.1     If |X| >= 2^(-65), go to Step 9.
287
|               7.2     Go to Step 8.
288
|
289
|       Step 8. Calculate exp(X)-1, |X| < 2^(-65).
290
|               8.1     If |X| < 2^(-16312), goto 8.3
291
|               8.2     Restore FPCR; return ans := X - 2^(-16382). Exit.
292
|               8.3     X := X * 2^(140).
293
|               8.4     Restore FPCR; ans := ans - 2^(-16382).
294
|                Return ans := ans*2^(140). Exit
295
|       Notes:  The idea is to return "X - tiny" under the user
296
|                precision and rounding modes. To avoid unnecessary
297
|                inefficiency, we stay away from denormalized numbers the
298
|                best we can. For |X| >= 2^(-16312), the straightforward
299
|                8.2 generates the inexact exception as the case warrants.
300
|
301
|       Step 9. Calculate exp(X)-1, |X| < 1/4, by a polynomial
302
|                       p = X + X*X*(B1 + X*(B2 + ... + X*B12))
303
|       Notes:  a) In order to reduce memory access, the coefficients are
304
|                made as "short" as possible: B1 (which is 1/2), B9 to B12
305
|                are single precision; B3 to B8 are double precision; and
306
|                B2 is double extended.
307
|                b) Even with the restriction above,
308
|                       |p - (exp(X)-1)| < |X| 2^(-70.6)
309
|                for all |X| <= 0.251.
310
|                Note that 0.251 is slightly bigger than 1/4.
311
|                c) To fully preserve accuracy, the polynomial is computed
312
|                as     X + ( S*B1 +    Q ) where S = X*X and
313
|                       Q       =       X*S*(B2 + X*(B3 + ... + X*B12))
314
|                d) To fully utilize the pipeline, Q is separated into
315
|                two independent pieces of roughly equal complexity
316
|                       Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] +
317
|                               [ S*S*(B3 + S*(B5 + ... + S*B11)) ]
318
|
319
|       Step 10.        Calculate exp(X)-1 for |X| >= 70 log 2.
320
|               10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all practical
321
|                purposes. Therefore, go to Step 1 of setox.
322
|               10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical purposes.
323
|                ans := -1
324
|                Restore user FPCR
325
|                Return ans := ans + 2^(-126). Exit.
326
|       Notes:  10.2 will always create an inexact and return -1 + tiny
327
|                in the user rounding precision and mode.
328
|
329
|
330
 
331
|               Copyright (C) Motorola, Inc. 1990
332
|                       All Rights Reserved
333
|
334
|       For details on the license for this file, please see the
335
|       file, README, in this same directory.
336
 
337
|setox  idnt    2,1 | Motorola 040 Floating Point Software Package
338
 
339
        |section        8
340
 
341
#include "fpsp.h"
342
 
343
L2:     .long   0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
344
 
345
EXPA3:  .long   0x3FA55555,0x55554431
346
EXPA2:  .long   0x3FC55555,0x55554018
347
 
348
HUGE:   .long   0x7FFE0000,0xFFFFFFFF,0xFFFFFFFF,0x00000000
349
TINY:   .long   0x00010000,0xFFFFFFFF,0xFFFFFFFF,0x00000000
350
 
351
EM1A4:  .long   0x3F811111,0x11174385
352
EM1A3:  .long   0x3FA55555,0x55554F5A
353
 
354
EM1A2:  .long   0x3FC55555,0x55555555,0x00000000,0x00000000
355
 
356
EM1B8:  .long   0x3EC71DE3,0xA5774682
357
EM1B7:  .long   0x3EFA01A0,0x19D7CB68
358
 
359
EM1B6:  .long   0x3F2A01A0,0x1A019DF3
360
EM1B5:  .long   0x3F56C16C,0x16C170E2
361
 
362
EM1B4:  .long   0x3F811111,0x11111111
363
EM1B3:  .long   0x3FA55555,0x55555555
364
 
365
EM1B2:  .long   0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
366
        .long   0x00000000
367
 
368
TWO140: .long   0x48B00000,0x00000000
369
TWON140:        .long   0x37300000,0x00000000
370
 
371
EXPTBL:
372
        .long   0x3FFF0000,0x80000000,0x00000000,0x00000000
373
        .long   0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
374
        .long   0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
375
        .long   0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
376
        .long   0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
377
        .long   0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
378
        .long   0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
379
        .long   0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
380
        .long   0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
381
        .long   0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
382
        .long   0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
383
        .long   0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
384
        .long   0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
385
        .long   0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
386
        .long   0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
387
        .long   0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
388
        .long   0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
389
        .long   0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
390
        .long   0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
391
        .long   0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
392
        .long   0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
393
        .long   0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
394
        .long   0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
395
        .long   0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
396
        .long   0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
397
        .long   0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
398
        .long   0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
399
        .long   0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
400
        .long   0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
401
        .long   0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
402
        .long   0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
403
        .long   0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
404
        .long   0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
405
        .long   0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
406
        .long   0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
407
        .long   0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
408
        .long   0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
409
        .long   0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
410
        .long   0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
411
        .long   0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
412
        .long   0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
413
        .long   0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
414
        .long   0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
415
        .long   0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
416
        .long   0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
417
        .long   0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
418
        .long   0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
419
        .long   0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
420
        .long   0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
421
        .long   0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
422
        .long   0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
423
        .long   0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
424
        .long   0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
425
        .long   0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
426
        .long   0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
427
        .long   0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
428
        .long   0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
429
        .long   0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
430
        .long   0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
431
        .long   0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
432
        .long   0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
433
        .long   0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
434
        .long   0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
435
        .long   0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
436
 
437
        .set    ADJFLAG,L_SCR2
438
        .set    SCALE,FP_SCR1
439
        .set    ADJSCALE,FP_SCR2
440
        .set    SC,FP_SCR3
441
        .set    ONEBYSC,FP_SCR4
442
 
443
        | xref  t_frcinx
444
        |xref   t_extdnrm
445
        |xref   t_unfl
446
        |xref   t_ovfl
447
 
448
        .global setoxd
449
setoxd:
450
|--entry point for EXP(X), X is denormalized
451
        movel           (%a0),%d0
452
        andil           #0x80000000,%d0
453
        oril            #0x00800000,%d0         | ...sign(X)*2^(-126)
454
        movel           %d0,-(%sp)
455
        fmoves          #0x3F800000,%fp0
456
        fmovel          %d1,%fpcr
457
        fadds           (%sp)+,%fp0
458
        bra             t_frcinx
459
 
460
        .global setox
461
setox:
462
|--entry point for EXP(X), here X is finite, non-zero, and not NaN's
463
 
464
|--Step 1.
465
        movel           (%a0),%d0        | ...load part of input X
466
        andil           #0x7FFF0000,%d0 | ...biased expo. of X
467
        cmpil           #0x3FBE0000,%d0 | ...2^(-65)
468
        bges            EXPC1           | ...normal case
469
        bra             EXPSM
470
 
471
EXPC1:
472
|--The case |X| >= 2^(-65)
473
        movew           4(%a0),%d0      | ...expo. and partial sig. of |X|
474
        cmpil           #0x400CB167,%d0 | ...16380 log2 trunc. 16 bits
475
        blts            EXPMAIN  | ...normal case
476
        bra             EXPBIG
477
 
478
EXPMAIN:
479
|--Step 2.
480
|--This is the normal branch:   2^(-65) <= |X| < 16380 log2.
481
        fmovex          (%a0),%fp0      | ...load input from (a0)
482
 
483
        fmovex          %fp0,%fp1
484
        fmuls           #0x42B8AA3B,%fp0        | ...64/log2 * X
485
        fmovemx %fp2-%fp2/%fp3,-(%a7)           | ...save fp2
486
        movel           #0,ADJFLAG(%a6)
487
        fmovel          %fp0,%d0                | ...N = int( X * 64/log2 )
488
        lea             EXPTBL,%a1
489
        fmovel          %d0,%fp0                | ...convert to floating-format
490
 
491
        movel           %d0,L_SCR1(%a6) | ...save N temporarily
492
        andil           #0x3F,%d0               | ...D0 is J = N mod 64
493
        lsll            #4,%d0
494
        addal           %d0,%a1         | ...address of 2^(J/64)
495
        movel           L_SCR1(%a6),%d0
496
        asrl            #6,%d0          | ...D0 is M
497
        addiw           #0x3FFF,%d0     | ...biased expo. of 2^(M)
498
        movew           L2,L_SCR1(%a6)  | ...prefetch L2, no need in CB
499
 
500
EXPCONT1:
501
|--Step 3.
502
|--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
503
|--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
504
        fmovex          %fp0,%fp2
505
        fmuls           #0xBC317218,%fp0        | ...N * L1, L1 = lead(-log2/64)
506
        fmulx           L2,%fp2         | ...N * L2, L1+L2 = -log2/64
507
        faddx           %fp1,%fp0               | ...X + N*L1
508
        faddx           %fp2,%fp0               | ...fp0 is R, reduced arg.
509
|       MOVE.W          #$3FA5,EXPA3    ...load EXPA3 in cache
510
 
511
|--Step 4.
512
|--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
513
|-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
514
|--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
515
|--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
516
 
517
        fmovex          %fp0,%fp1
518
        fmulx           %fp1,%fp1               | ...fp1 IS S = R*R
519
 
520
        fmoves          #0x3AB60B70,%fp2        | ...fp2 IS A5
521
|       MOVE.W          #0,2(%a1)       ...load 2^(J/64) in cache
522
 
523
        fmulx           %fp1,%fp2               | ...fp2 IS S*A5
524
        fmovex          %fp1,%fp3
525
        fmuls           #0x3C088895,%fp3        | ...fp3 IS S*A4
526
 
527
        faddd           EXPA3,%fp2      | ...fp2 IS A3+S*A5
528
        faddd           EXPA2,%fp3      | ...fp3 IS A2+S*A4
529
 
530
        fmulx           %fp1,%fp2               | ...fp2 IS S*(A3+S*A5)
531
        movew           %d0,SCALE(%a6)  | ...SCALE is 2^(M) in extended
532
        clrw            SCALE+2(%a6)
533
        movel           #0x80000000,SCALE+4(%a6)
534
        clrl            SCALE+8(%a6)
535
 
536
        fmulx           %fp1,%fp3               | ...fp3 IS S*(A2+S*A4)
537
 
538
        fadds           #0x3F000000,%fp2        | ...fp2 IS A1+S*(A3+S*A5)
539
        fmulx           %fp0,%fp3               | ...fp3 IS R*S*(A2+S*A4)
540
 
541
        fmulx           %fp1,%fp2               | ...fp2 IS S*(A1+S*(A3+S*A5))
542
        faddx           %fp3,%fp0               | ...fp0 IS R+R*S*(A2+S*A4),
543
|                                       ...fp3 released
544
 
545
        fmovex          (%a1)+,%fp1     | ...fp1 is lead. pt. of 2^(J/64)
546
        faddx           %fp2,%fp0               | ...fp0 is EXP(R) - 1
547
|                                       ...fp2 released
548
 
549
|--Step 5
550
|--final reconstruction process
551
|--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
552
 
553
        fmulx           %fp1,%fp0               | ...2^(J/64)*(Exp(R)-1)
554
        fmovemx (%a7)+,%fp2-%fp2/%fp3   | ...fp2 restored
555
        fadds           (%a1),%fp0      | ...accurate 2^(J/64)
556
 
557
        faddx           %fp1,%fp0               | ...2^(J/64) + 2^(J/64)*...
558
        movel           ADJFLAG(%a6),%d0
559
 
560
|--Step 6
561
        tstl            %d0
562
        beqs            NORMAL
563
ADJUST:
564
        fmulx           ADJSCALE(%a6),%fp0
565
NORMAL:
566
        fmovel          %d1,%FPCR               | ...restore user FPCR
567
        fmulx           SCALE(%a6),%fp0 | ...multiply 2^(M)
568
        bra             t_frcinx
569
 
570
EXPSM:
571
|--Step 7
572
        fmovemx (%a0),%fp0-%fp0 | ...in case X is denormalized
573
        fmovel          %d1,%FPCR
574
        fadds           #0x3F800000,%fp0        | ...1+X in user mode
575
        bra             t_frcinx
576
 
577
EXPBIG:
578
|--Step 8
579
        cmpil           #0x400CB27C,%d0 | ...16480 log2
580
        bgts            EXP2BIG
581
|--Steps 8.2 -- 8.6
582
        fmovex          (%a0),%fp0      | ...load input from (a0)
583
 
584
        fmovex          %fp0,%fp1
585
        fmuls           #0x42B8AA3B,%fp0        | ...64/log2 * X
586
        fmovemx  %fp2-%fp2/%fp3,-(%a7)          | ...save fp2
587
        movel           #1,ADJFLAG(%a6)
588
        fmovel          %fp0,%d0                | ...N = int( X * 64/log2 )
589
        lea             EXPTBL,%a1
590
        fmovel          %d0,%fp0                | ...convert to floating-format
591
        movel           %d0,L_SCR1(%a6)                 | ...save N temporarily
592
        andil           #0x3F,%d0                | ...D0 is J = N mod 64
593
        lsll            #4,%d0
594
        addal           %d0,%a1                 | ...address of 2^(J/64)
595
        movel           L_SCR1(%a6),%d0
596
        asrl            #6,%d0                  | ...D0 is K
597
        movel           %d0,L_SCR1(%a6)                 | ...save K temporarily
598
        asrl            #1,%d0                  | ...D0 is M1
599
        subl            %d0,L_SCR1(%a6)                 | ...a1 is M
600
        addiw           #0x3FFF,%d0             | ...biased expo. of 2^(M1)
601
        movew           %d0,ADJSCALE(%a6)               | ...ADJSCALE := 2^(M1)
602
        clrw            ADJSCALE+2(%a6)
603
        movel           #0x80000000,ADJSCALE+4(%a6)
604
        clrl            ADJSCALE+8(%a6)
605
        movel           L_SCR1(%a6),%d0                 | ...D0 is M
606
        addiw           #0x3FFF,%d0             | ...biased expo. of 2^(M)
607
        bra             EXPCONT1                | ...go back to Step 3
608
 
609
EXP2BIG:
610
|--Step 9
611
        fmovel          %d1,%FPCR
612
        movel           (%a0),%d0
613
        bclrb           #sign_bit,(%a0)         | ...setox always returns positive
614
        cmpil           #0,%d0
615
        blt             t_unfl
616
        bra             t_ovfl
617
 
618
        .global setoxm1d
619
setoxm1d:
620
|--entry point for EXPM1(X), here X is denormalized
621
|--Step 0.
622
        bra             t_extdnrm
623
 
624
 
625
        .global setoxm1
626
setoxm1:
627
|--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
628
 
629
|--Step 1.
630
|--Step 1.1
631
        movel           (%a0),%d0        | ...load part of input X
632
        andil           #0x7FFF0000,%d0 | ...biased expo. of X
633
        cmpil           #0x3FFD0000,%d0 | ...1/4
634
        bges            EM1CON1  | ...|X| >= 1/4
635
        bra             EM1SM
636
 
637
EM1CON1:
638
|--Step 1.3
639
|--The case |X| >= 1/4
640
        movew           4(%a0),%d0      | ...expo. and partial sig. of |X|
641
        cmpil           #0x4004C215,%d0 | ...70log2 rounded up to 16 bits
642
        bles            EM1MAIN  | ...1/4 <= |X| <= 70log2
643
        bra             EM1BIG
644
 
645
EM1MAIN:
646
|--Step 2.
647
|--This is the case:    1/4 <= |X| <= 70 log2.
648
        fmovex          (%a0),%fp0      | ...load input from (a0)
649
 
650
        fmovex          %fp0,%fp1
651
        fmuls           #0x42B8AA3B,%fp0        | ...64/log2 * X
652
        fmovemx %fp2-%fp2/%fp3,-(%a7)           | ...save fp2
653
|       MOVE.W          #$3F81,EM1A4            ...prefetch in CB mode
654
        fmovel          %fp0,%d0                | ...N = int( X * 64/log2 )
655
        lea             EXPTBL,%a1
656
        fmovel          %d0,%fp0                | ...convert to floating-format
657
 
658
        movel           %d0,L_SCR1(%a6)                 | ...save N temporarily
659
        andil           #0x3F,%d0                | ...D0 is J = N mod 64
660
        lsll            #4,%d0
661
        addal           %d0,%a1                 | ...address of 2^(J/64)
662
        movel           L_SCR1(%a6),%d0
663
        asrl            #6,%d0                  | ...D0 is M
664
        movel           %d0,L_SCR1(%a6)                 | ...save a copy of M
665
|       MOVE.W          #$3FDC,L2               ...prefetch L2 in CB mode
666
 
667
|--Step 3.
668
|--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
669
|--a0 points to 2^(J/64), D0 and a1 both contain M
670
        fmovex          %fp0,%fp2
671
        fmuls           #0xBC317218,%fp0        | ...N * L1, L1 = lead(-log2/64)
672
        fmulx           L2,%fp2         | ...N * L2, L1+L2 = -log2/64
673
        faddx           %fp1,%fp0        | ...X + N*L1
674
        faddx           %fp2,%fp0        | ...fp0 is R, reduced arg.
675
|       MOVE.W          #$3FC5,EM1A2            ...load EM1A2 in cache
676
        addiw           #0x3FFF,%d0             | ...D0 is biased expo. of 2^M
677
 
678
|--Step 4.
679
|--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
680
|-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
681
|--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
682
|--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
683
 
684
        fmovex          %fp0,%fp1
685
        fmulx           %fp1,%fp1               | ...fp1 IS S = R*R
686
 
687
        fmoves          #0x3950097B,%fp2        | ...fp2 IS a6
688
|       MOVE.W          #0,2(%a1)       ...load 2^(J/64) in cache
689
 
690
        fmulx           %fp1,%fp2               | ...fp2 IS S*A6
691
        fmovex          %fp1,%fp3
692
        fmuls           #0x3AB60B6A,%fp3        | ...fp3 IS S*A5
693
 
694
        faddd           EM1A4,%fp2      | ...fp2 IS A4+S*A6
695
        faddd           EM1A3,%fp3      | ...fp3 IS A3+S*A5
696
        movew           %d0,SC(%a6)             | ...SC is 2^(M) in extended
697
        clrw            SC+2(%a6)
698
        movel           #0x80000000,SC+4(%a6)
699
        clrl            SC+8(%a6)
700
 
701
        fmulx           %fp1,%fp2               | ...fp2 IS S*(A4+S*A6)
702
        movel           L_SCR1(%a6),%d0         | ...D0 is      M
703
        negw            %d0             | ...D0 is -M
704
        fmulx           %fp1,%fp3               | ...fp3 IS S*(A3+S*A5)
705
        addiw           #0x3FFF,%d0     | ...biased expo. of 2^(-M)
706
        faddd           EM1A2,%fp2      | ...fp2 IS A2+S*(A4+S*A6)
707
        fadds           #0x3F000000,%fp3        | ...fp3 IS A1+S*(A3+S*A5)
708
 
709
        fmulx           %fp1,%fp2               | ...fp2 IS S*(A2+S*(A4+S*A6))
710
        oriw            #0x8000,%d0     | ...signed/expo. of -2^(-M)
711
        movew           %d0,ONEBYSC(%a6)        | ...OnebySc is -2^(-M)
712
        clrw            ONEBYSC+2(%a6)
713
        movel           #0x80000000,ONEBYSC+4(%a6)
714
        clrl            ONEBYSC+8(%a6)
715
        fmulx           %fp3,%fp1               | ...fp1 IS S*(A1+S*(A3+S*A5))
716
|                                       ...fp3 released
717
 
718
        fmulx           %fp0,%fp2               | ...fp2 IS R*S*(A2+S*(A4+S*A6))
719
        faddx           %fp1,%fp0               | ...fp0 IS R+S*(A1+S*(A3+S*A5))
720
|                                       ...fp1 released
721
 
722
        faddx           %fp2,%fp0               | ...fp0 IS EXP(R)-1
723
|                                       ...fp2 released
724
        fmovemx (%a7)+,%fp2-%fp2/%fp3   | ...fp2 restored
725
 
726
|--Step 5
727
|--Compute 2^(J/64)*p
728
 
729
        fmulx           (%a1),%fp0      | ...2^(J/64)*(Exp(R)-1)
730
 
731
|--Step 6
732
|--Step 6.1
733
        movel           L_SCR1(%a6),%d0         | ...retrieve M
734
        cmpil           #63,%d0
735
        bles            MLE63
736
|--Step 6.2     M >= 64
737
        fmoves          12(%a1),%fp1    | ...fp1 is t
738
        faddx           ONEBYSC(%a6),%fp1       | ...fp1 is t+OnebySc
739
        faddx           %fp1,%fp0               | ...p+(t+OnebySc), fp1 released
740
        faddx           (%a1),%fp0      | ...T+(p+(t+OnebySc))
741
        bras            EM1SCALE
742
MLE63:
743
|--Step 6.3     M <= 63
744
        cmpil           #-3,%d0
745
        bges            MGEN3
746
MLTN3:
747
|--Step 6.4     M <= -4
748
        fadds           12(%a1),%fp0    | ...p+t
749
        faddx           (%a1),%fp0      | ...T+(p+t)
750
        faddx           ONEBYSC(%a6),%fp0       | ...OnebySc + (T+(p+t))
751
        bras            EM1SCALE
752
MGEN3:
753
|--Step 6.5     -3 <= M <= 63
754
        fmovex          (%a1)+,%fp1     | ...fp1 is T
755
        fadds           (%a1),%fp0      | ...fp0 is p+t
756
        faddx           ONEBYSC(%a6),%fp1       | ...fp1 is T+OnebySc
757
        faddx           %fp1,%fp0               | ...(T+OnebySc)+(p+t)
758
 
759
EM1SCALE:
760
|--Step 6.6
761
        fmovel          %d1,%FPCR
762
        fmulx           SC(%a6),%fp0
763
 
764
        bra             t_frcinx
765
 
766
EM1SM:
767
|--Step 7       |X| < 1/4.
768
        cmpil           #0x3FBE0000,%d0 | ...2^(-65)
769
        bges            EM1POLY
770
 
771
EM1TINY:
772
|--Step 8       |X| < 2^(-65)
773
        cmpil           #0x00330000,%d0 | ...2^(-16312)
774
        blts            EM12TINY
775
|--Step 8.2
776
        movel           #0x80010000,SC(%a6)     | ...SC is -2^(-16382)
777
        movel           #0x80000000,SC+4(%a6)
778
        clrl            SC+8(%a6)
779
        fmovex          (%a0),%fp0
780
        fmovel          %d1,%FPCR
781
        faddx           SC(%a6),%fp0
782
 
783
        bra             t_frcinx
784
 
785
EM12TINY:
786
|--Step 8.3
787
        fmovex          (%a0),%fp0
788
        fmuld           TWO140,%fp0
789
        movel           #0x80010000,SC(%a6)
790
        movel           #0x80000000,SC+4(%a6)
791
        clrl            SC+8(%a6)
792
        faddx           SC(%a6),%fp0
793
        fmovel          %d1,%FPCR
794
        fmuld           TWON140,%fp0
795
 
796
        bra             t_frcinx
797
 
798
EM1POLY:
799
|--Step 9       exp(X)-1 by a simple polynomial
800
        fmovex          (%a0),%fp0      | ...fp0 is X
801
        fmulx           %fp0,%fp0               | ...fp0 is S := X*X
802
        fmovemx %fp2-%fp2/%fp3,-(%a7)   | ...save fp2
803
        fmoves          #0x2F30CAA8,%fp1        | ...fp1 is B12
804
        fmulx           %fp0,%fp1               | ...fp1 is S*B12
805
        fmoves          #0x310F8290,%fp2        | ...fp2 is B11
806
        fadds           #0x32D73220,%fp1        | ...fp1 is B10+S*B12
807
 
808
        fmulx           %fp0,%fp2               | ...fp2 is S*B11
809
        fmulx           %fp0,%fp1               | ...fp1 is S*(B10 + ...
810
 
811
        fadds           #0x3493F281,%fp2        | ...fp2 is B9+S*...
812
        faddd           EM1B8,%fp1      | ...fp1 is B8+S*...
813
 
814
        fmulx           %fp0,%fp2               | ...fp2 is S*(B9+...
815
        fmulx           %fp0,%fp1               | ...fp1 is S*(B8+...
816
 
817
        faddd           EM1B7,%fp2      | ...fp2 is B7+S*...
818
        faddd           EM1B6,%fp1      | ...fp1 is B6+S*...
819
 
820
        fmulx           %fp0,%fp2               | ...fp2 is S*(B7+...
821
        fmulx           %fp0,%fp1               | ...fp1 is S*(B6+...
822
 
823
        faddd           EM1B5,%fp2      | ...fp2 is B5+S*...
824
        faddd           EM1B4,%fp1      | ...fp1 is B4+S*...
825
 
826
        fmulx           %fp0,%fp2               | ...fp2 is S*(B5+...
827
        fmulx           %fp0,%fp1               | ...fp1 is S*(B4+...
828
 
829
        faddd           EM1B3,%fp2      | ...fp2 is B3+S*...
830
        faddx           EM1B2,%fp1      | ...fp1 is B2+S*...
831
 
832
        fmulx           %fp0,%fp2               | ...fp2 is S*(B3+...
833
        fmulx           %fp0,%fp1               | ...fp1 is S*(B2+...
834
 
835
        fmulx           %fp0,%fp2               | ...fp2 is S*S*(B3+...)
836
        fmulx           (%a0),%fp1      | ...fp1 is X*S*(B2...
837
 
838
        fmuls           #0x3F000000,%fp0        | ...fp0 is S*B1
839
        faddx           %fp2,%fp1               | ...fp1 is Q
840
|                                       ...fp2 released
841
 
842
        fmovemx (%a7)+,%fp2-%fp2/%fp3   | ...fp2 restored
843
 
844
        faddx           %fp1,%fp0               | ...fp0 is S*B1+Q
845
|                                       ...fp1 released
846
 
847
        fmovel          %d1,%FPCR
848
        faddx           (%a0),%fp0
849
 
850
        bra             t_frcinx
851
 
852
EM1BIG:
853
|--Step 10      |X| > 70 log2
854
        movel           (%a0),%d0
855
        cmpil           #0,%d0
856
        bgt             EXPC1
857
|--Step 10.2
858
        fmoves          #0xBF800000,%fp0        | ...fp0 is -1
859
        fmovel          %d1,%FPCR
860
        fadds           #0x00800000,%fp0        | ...-1 + 2^(-126)
861
 
862
        bra             t_frcinx
863
 
864
        |end

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.