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/] [scale.S] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
|
2
|       scale.sa 3.3 7/30/91
3
|
4
|       The entry point sSCALE computes the destination operand
5
|       scaled by the source operand.  If the absolute value of
6
|       the source operand is (>= 2^14) an overflow or underflow
7
|       is returned.
8
|
9
|       The entry point sscale is called from do_func to emulate
10
|       the fscale unimplemented instruction.
11
|
12
|       Input: Double-extended destination operand in FPTEMP,
13
|               double-extended source operand in ETEMP.
14
|
15
|       Output: The function returns scale(X,Y) to fp0.
16
|
17
|       Modifies: fp0.
18
|
19
|       Algorithm:
20
|
21
|               Copyright (C) Motorola, Inc. 1990
22
|                       All Rights Reserved
23
|
24
|       For details on the license for this file, please see the
25
|       file, README, in this same directory.
26
 
27
|SCALE    idnt    2,1 | Motorola 040 Floating Point Software Package
28
 
29
        |section        8
30
 
31
#include "fpsp.h"
32
 
33
        |xref   t_ovfl2
34
        |xref   t_unfl
35
        |xref   round
36
        |xref   t_resdnrm
37
 
38
SRC_BNDS: .short        0x3fff,0x400c
39
 
40
|
41
| This entry point is used by the unimplemented instruction exception
42
| handler.
43
|
44
|
45
|
46
|       FSCALE
47
|
48
        .global sscale
49
sscale:
50
        fmovel          #0,%fpcr                |clr user enabled exc
51
        clrl            %d1
52
        movew           FPTEMP(%a6),%d1 |get dest exponent
53
        smi             L_SCR1(%a6)     |use L_SCR1 to hold sign
54
        andil           #0x7fff,%d1     |strip sign
55
        movew           ETEMP(%a6),%d0  |check src bounds
56
        andiw           #0x7fff,%d0     |clr sign bit
57
        cmp2w           SRC_BNDS,%d0
58
        bccs            src_in
59
        cmpiw           #0x400c,%d0     |test for too large
60
        bge             src_out
61
|
62
| The source input is below 1, so we check for denormalized numbers
63
| and set unfl.
64
|
65
src_small:
66
        moveb           DTAG(%a6),%d0
67
        andib           #0xe0,%d0
68
        tstb            %d0
69
        beqs            no_denorm
70
        st              STORE_FLG(%a6)  |dest already contains result
71
        orl             #unfl_mask,USER_FPSR(%a6) |set UNFL
72
den_done:
73
        leal            FPTEMP(%a6),%a0
74
        bra             t_resdnrm
75
no_denorm:
76
        fmovel          USER_FPCR(%a6),%FPCR
77
        fmovex          FPTEMP(%a6),%fp0        |simply return dest
78
        rts
79
 
80
 
81
|
82
| Source is within 2^14 range.  To perform the int operation,
83
| move it to d0.
84
|
85
src_in:
86
        fmovex          ETEMP(%a6),%fp0 |move in src for int
87
        fmovel          #rz_mode,%fpcr  |force rz for src conversion
88
        fmovel          %fp0,%d0                |int src to d0
89
        fmovel          #0,%FPSR                |clr status from above
90
        tstw            ETEMP(%a6)      |check src sign
91
        blt             src_neg
92
|
93
| Source is positive.  Add the src to the dest exponent.
94
| The result can be denormalized, if src = 0, or overflow,
95
| if the result of the add sets a bit in the upper word.
96
|
97
src_pos:
98
        tstw            %d1             |check for denorm
99
        beq             dst_dnrm
100
        addl            %d0,%d1         |add src to dest exp
101
        beqs            denorm          |if zero, result is denorm
102
        cmpil           #0x7fff,%d1     |test for overflow
103
        bges            ovfl
104
        tstb            L_SCR1(%a6)
105
        beqs            spos_pos
106
        orw             #0x8000,%d1
107
spos_pos:
108
        movew           %d1,FPTEMP(%a6) |result in FPTEMP
109
        fmovel          USER_FPCR(%a6),%FPCR
110
        fmovex          FPTEMP(%a6),%fp0        |write result to fp0
111
        rts
112
ovfl:
113
        tstb            L_SCR1(%a6)
114
        beqs            sovl_pos
115
        orw             #0x8000,%d1
116
sovl_pos:
117
        movew           FPTEMP(%a6),ETEMP(%a6)  |result in ETEMP
118
        movel           FPTEMP_HI(%a6),ETEMP_HI(%a6)
119
        movel           FPTEMP_LO(%a6),ETEMP_LO(%a6)
120
        bra             t_ovfl2
121
 
122
denorm:
123
        tstb            L_SCR1(%a6)
124
        beqs            den_pos
125
        orw             #0x8000,%d1
126
den_pos:
127
        tstl            FPTEMP_HI(%a6)  |check j bit
128
        blts            nden_exit       |if set, not denorm
129
        movew           %d1,ETEMP(%a6)  |input expected in ETEMP
130
        movel           FPTEMP_HI(%a6),ETEMP_HI(%a6)
131
        movel           FPTEMP_LO(%a6),ETEMP_LO(%a6)
132
        orl             #unfl_bit,USER_FPSR(%a6)        |set unfl
133
        leal            ETEMP(%a6),%a0
134
        bra             t_resdnrm
135
nden_exit:
136
        movew           %d1,FPTEMP(%a6) |result in FPTEMP
137
        fmovel          USER_FPCR(%a6),%FPCR
138
        fmovex          FPTEMP(%a6),%fp0        |write result to fp0
139
        rts
140
 
141
|
142
| Source is negative.  Add the src to the dest exponent.
143
| (The result exponent will be reduced).  The result can be
144
| denormalized.
145
|
146
src_neg:
147
        addl            %d0,%d1         |add src to dest
148
        beqs            denorm          |if zero, result is denorm
149
        blts            fix_dnrm        |if negative, result is
150
|                                       ;needing denormalization
151
        tstb            L_SCR1(%a6)
152
        beqs            sneg_pos
153
        orw             #0x8000,%d1
154
sneg_pos:
155
        movew           %d1,FPTEMP(%a6) |result in FPTEMP
156
        fmovel          USER_FPCR(%a6),%FPCR
157
        fmovex          FPTEMP(%a6),%fp0        |write result to fp0
158
        rts
159
 
160
 
161
|
162
| The result exponent is below denorm value.  Test for catastrophic
163
| underflow and force zero if true.  If not, try to shift the
164
| mantissa right until a zero exponent exists.
165
|
166
fix_dnrm:
167
        cmpiw           #0xffc0,%d1     |lower bound for normalization
168
        blt             fix_unfl        |if lower, catastrophic unfl
169
        movew           %d1,%d0         |use d0 for exp
170
        movel           %d2,-(%a7)      |free d2 for norm
171
        movel           FPTEMP_HI(%a6),%d1
172
        movel           FPTEMP_LO(%a6),%d2
173
        clrl            L_SCR2(%a6)
174
fix_loop:
175
        addw            #1,%d0          |drive d0 to 0
176
        lsrl            #1,%d1          |while shifting the
177
        roxrl           #1,%d2          |mantissa to the right
178
        bccs            no_carry
179
        st              L_SCR2(%a6)     |use L_SCR2 to capture inex
180
no_carry:
181
        tstw            %d0             |it is finished when
182
        blts            fix_loop        |d0 is zero or the mantissa
183
        tstb            L_SCR2(%a6)
184
        beqs            tst_zero
185
        orl             #unfl_inx_mask,USER_FPSR(%a6)
186
|                                       ;set unfl, aunfl, ainex
187
|
188
| Test for zero. If zero, simply use fmove to return +/- zero
189
| to the fpu.
190
|
191
tst_zero:
192
        clrw            FPTEMP_EX(%a6)
193
        tstb            L_SCR1(%a6)     |test for sign
194
        beqs            tst_con
195
        orw             #0x8000,FPTEMP_EX(%a6) |set sign bit
196
tst_con:
197
        movel           %d1,FPTEMP_HI(%a6)
198
        movel           %d2,FPTEMP_LO(%a6)
199
        movel           (%a7)+,%d2
200
        tstl            %d1
201
        bnes            not_zero
202
        tstl            FPTEMP_LO(%a6)
203
        bnes            not_zero
204
|
205
| Result is zero.  Check for rounding mode to set lsb.  If the
206
| mode is rp, and the zero is positive, return smallest denorm.
207
| If the mode is rm, and the zero is negative, return smallest
208
| negative denorm.
209
|
210
        btstb           #5,FPCR_MODE(%a6) |test if rm or rp
211
        beqs            no_dir
212
        btstb           #4,FPCR_MODE(%a6) |check which one
213
        beqs            zer_rm
214
zer_rp:
215
        tstb            L_SCR1(%a6)     |check sign
216
        bnes            no_dir          |if set, neg op, no inc
217
        movel           #1,FPTEMP_LO(%a6) |set lsb
218
        bras            sm_dnrm
219
zer_rm:
220
        tstb            L_SCR1(%a6)     |check sign
221
        beqs            no_dir          |if clr, neg op, no inc
222
        movel           #1,FPTEMP_LO(%a6) |set lsb
223
        orl             #neg_mask,USER_FPSR(%a6) |set N
224
        bras            sm_dnrm
225
no_dir:
226
        fmovel          USER_FPCR(%a6),%FPCR
227
        fmovex          FPTEMP(%a6),%fp0        |use fmove to set cc's
228
        rts
229
 
230
|
231
| The rounding mode changed the zero to a smallest denorm. Call
232
| t_resdnrm with exceptional operand in ETEMP.
233
|
234
sm_dnrm:
235
        movel           FPTEMP_EX(%a6),ETEMP_EX(%a6)
236
        movel           FPTEMP_HI(%a6),ETEMP_HI(%a6)
237
        movel           FPTEMP_LO(%a6),ETEMP_LO(%a6)
238
        leal            ETEMP(%a6),%a0
239
        bra             t_resdnrm
240
 
241
|
242
| Result is still denormalized.
243
|
244
not_zero:
245
        orl             #unfl_mask,USER_FPSR(%a6) |set unfl
246
        tstb            L_SCR1(%a6)     |check for sign
247
        beqs            fix_exit
248
        orl             #neg_mask,USER_FPSR(%a6) |set N
249
fix_exit:
250
        bras            sm_dnrm
251
 
252
 
253
|
254
| The result has underflowed to zero. Return zero and set
255
| unfl, aunfl, and ainex.
256
|
257
fix_unfl:
258
        orl             #unfl_inx_mask,USER_FPSR(%a6)
259
        btstb           #5,FPCR_MODE(%a6) |test if rm or rp
260
        beqs            no_dir2
261
        btstb           #4,FPCR_MODE(%a6) |check which one
262
        beqs            zer_rm2
263
zer_rp2:
264
        tstb            L_SCR1(%a6)     |check sign
265
        bnes            no_dir2         |if set, neg op, no inc
266
        clrl            FPTEMP_EX(%a6)
267
        clrl            FPTEMP_HI(%a6)
268
        movel           #1,FPTEMP_LO(%a6) |set lsb
269
        bras            sm_dnrm         |return smallest denorm
270
zer_rm2:
271
        tstb            L_SCR1(%a6)     |check sign
272
        beqs            no_dir2         |if clr, neg op, no inc
273
        movew           #0x8000,FPTEMP_EX(%a6)
274
        clrl            FPTEMP_HI(%a6)
275
        movel           #1,FPTEMP_LO(%a6) |set lsb
276
        orl             #neg_mask,USER_FPSR(%a6) |set N
277
        bra             sm_dnrm         |return smallest denorm
278
 
279
no_dir2:
280
        tstb            L_SCR1(%a6)
281
        bges            pos_zero
282
neg_zero:
283
        clrl            FP_SCR1(%a6)    |clear the exceptional operand
284
        clrl            FP_SCR1+4(%a6)  |for gen_except.
285
        clrl            FP_SCR1+8(%a6)
286
        fmoves          #0x80000000,%fp0
287
        rts
288
pos_zero:
289
        clrl            FP_SCR1(%a6)    |clear the exceptional operand
290
        clrl            FP_SCR1+4(%a6)  |for gen_except.
291
        clrl            FP_SCR1+8(%a6)
292
        fmoves          #0x00000000,%fp0
293
        rts
294
 
295
|
296
| The destination is a denormalized number.  It must be handled
297
| by first shifting the bits in the mantissa until it is normalized,
298
| then adding the remainder of the source to the exponent.
299
|
300
dst_dnrm:
301
        moveml          %d2/%d3,-(%a7)
302
        movew           FPTEMP_EX(%a6),%d1
303
        movel           FPTEMP_HI(%a6),%d2
304
        movel           FPTEMP_LO(%a6),%d3
305
dst_loop:
306
        tstl            %d2             |test for normalized result
307
        blts            dst_norm        |exit loop if so
308
        tstl            %d0             |otherwise, test shift count
309
        beqs            dst_fin         |if zero, shifting is done
310
        subil           #1,%d0          |dec src
311
        lsll            #1,%d3
312
        roxll           #1,%d2
313
        bras            dst_loop
314
|
315
| Destination became normalized.  Simply add the remaining
316
| portion of the src to the exponent.
317
|
318
dst_norm:
319
        addw            %d0,%d1         |dst is normalized; add src
320
        tstb            L_SCR1(%a6)
321
        beqs            dnrm_pos
322
        orl             #0x8000,%d1
323
dnrm_pos:
324
        movemw          %d1,FPTEMP_EX(%a6)
325
        moveml          %d2,FPTEMP_HI(%a6)
326
        moveml          %d3,FPTEMP_LO(%a6)
327
        fmovel          USER_FPCR(%a6),%FPCR
328
        fmovex          FPTEMP(%a6),%fp0
329
        moveml          (%a7)+,%d2/%d3
330
        rts
331
 
332
|
333
| Destination remained denormalized.  Call t_excdnrm with
334
| exceptional operand in ETEMP.
335
|
336
dst_fin:
337
        tstb            L_SCR1(%a6)     |check for sign
338
        beqs            dst_exit
339
        orl             #neg_mask,USER_FPSR(%a6) |set N
340
        orl             #0x8000,%d1
341
dst_exit:
342
        movemw          %d1,ETEMP_EX(%a6)
343
        moveml          %d2,ETEMP_HI(%a6)
344
        moveml          %d3,ETEMP_LO(%a6)
345
        orl             #unfl_mask,USER_FPSR(%a6) |set unfl
346
        moveml          (%a7)+,%d2/%d3
347
        leal            ETEMP(%a6),%a0
348
        bra             t_resdnrm
349
 
350
|
351
| Source is outside of 2^14 range.  Test the sign and branch
352
| to the appropriate exception handler.
353
|
354
src_out:
355
        tstb            L_SCR1(%a6)
356
        beqs            scro_pos
357
        orl             #0x8000,%d1
358
scro_pos:
359
        movel           FPTEMP_HI(%a6),ETEMP_HI(%a6)
360
        movel           FPTEMP_LO(%a6),ETEMP_LO(%a6)
361
        tstw            ETEMP(%a6)
362
        blts            res_neg
363
res_pos:
364
        movew           %d1,ETEMP(%a6)  |result in ETEMP
365
        bra             t_ovfl2
366
res_neg:
367
        movew           %d1,ETEMP(%a6)  |result in ETEMP
368
        leal            ETEMP(%a6),%a0
369
        bra             t_unfl
370
        |end

powered by: WebSVN 2.1.0

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