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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [m68k/] [m68040/] [fpsp/] [scale.S] - Blame information for rev 594

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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