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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems/] [c/] [src/] [lib/] [libcpu/] [m68k/] [m68040/] [fpsp/] [get_op.S] - Blame information for rev 158

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

Line No. Rev Author Line
1 158 chris
//
2
//      $Id: get_op.S,v 1.1.1.1 2001-07-10 09:55:52 chris Exp $
3
//
4
//      get_op.sa 3.6 5/19/92
5
//
6
//      get_op.sa 3.5 4/26/91
7
//
8
//  Description: This routine is called by the unsupported format/data
9
// type exception handler ('unsupp' - vector 55) and the unimplemented
10
// instruction exception handler ('unimp' - vector 11).  'get_op'
11
// determines the opclass (0, 2, or 3) and branches to the
12
// opclass handler routine.  See 68881/2 User's Manual table 4-11
13
// for a description of the opclasses.
14
//
15
// For UNSUPPORTED data/format (exception vector 55) and for
16
// UNIMPLEMENTED instructions (exception vector 11) the following
17
// applies:
18
//
19
// - For unnormalized numbers (opclass 0, 2, or 3) the
20
// number(s) is normalized and the operand type tag is updated.
21
//
22
// - For a packed number (opclass 2) the number is unpacked and the
23
// operand type tag is updated.
24
//
25
// - For denormalized numbers (opclass 0 or 2) the number(s) is not
26
// changed but passed to the next module.  The next module for
27
// unimp is do_func, the next module for unsupp is res_func.
28
//
29
// For UNSUPPORTED data/format (exception vector 55) only the
30
// following applies:
31
//
32
// - If there is a move out with a packed number (opclass 3) the
33
// number is packed and written to user memory.  For the other
34
// opclasses the number(s) are written back to the fsave stack
35
// and the instruction is then restored back into the '040.  The
36
// '040 is then able to complete the instruction.
37
//
38
// For example:
39
// fadd.x fpm,fpn where the fpm contains an unnormalized number.
40
// The '040 takes an unsupported data trap and gets to this
41
// routine.  The number is normalized, put back on the stack and
42
// then an frestore is done to restore the instruction back into
43
// the '040.  The '040 then re-executes the fadd.x fpm,fpn with
44
// a normalized number in the source and the instruction is
45
// successful.
46
//
47
// Next consider if in the process of normalizing the un-
48
// normalized number it becomes a denormalized number.  The
49
// routine which converts the unnorm to a norm (called mk_norm)
50
// detects this and tags the number as a denorm.  The routine
51
// res_func sees the denorm tag and converts the denorm to a
52
// norm.  The instruction is then restored back into the '040
53
// which re_executes the instruction.
54
//
55
//
56
//              Copyright (C) Motorola, Inc. 1990
57
//                      All Rights Reserved
58
//
59
//      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
60
//      The copyright notice above does not evidence any
61
//      actual or intended publication of such source code.
62
 
63
GET_OP:    //idnt    2,1 | Motorola 040 Floating Point Software Package
64
 
65
        |section        8
66
 
67
#include "fpsp.defs"
68
 
69
        .global PIRN,PIRZRM,PIRP
70
        .global SMALRN,SMALRZRM,SMALRP
71
        .global BIGRN,BIGRZRM,BIGRP
72
 
73
PIRN:
74
        .long 0x40000000,0xc90fdaa2,0x2168c235    //pi
75
PIRZRM:
76
        .long 0x40000000,0xc90fdaa2,0x2168c234    //pi
77
PIRP:
78
        .long 0x40000000,0xc90fdaa2,0x2168c235    //pi
79
 
80
//round to nearest
81
SMALRN:
82
        .long 0x3ffd0000,0x9a209a84,0xfbcff798    //log10(2)
83
        .long 0x40000000,0xadf85458,0xa2bb4a9a    //e
84
        .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc    //log2(e)
85
        .long 0x3ffd0000,0xde5bd8a9,0x37287195    //log10(e)
86
        .long 0x00000000,0x00000000,0x00000000    //0.0
87
// round to zero;round to negative infinity
88
SMALRZRM:
89
        .long 0x3ffd0000,0x9a209a84,0xfbcff798    //log10(2)
90
        .long 0x40000000,0xadf85458,0xa2bb4a9a    //e
91
        .long 0x3fff0000,0xb8aa3b29,0x5c17f0bb    //log2(e)
92
        .long 0x3ffd0000,0xde5bd8a9,0x37287195    //log10(e)
93
        .long 0x00000000,0x00000000,0x00000000    //0.0
94
// round to positive infinity
95
SMALRP:
96
        .long 0x3ffd0000,0x9a209a84,0xfbcff799    //log10(2)
97
        .long 0x40000000,0xadf85458,0xa2bb4a9b    //e
98
        .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc    //log2(e)
99
        .long 0x3ffd0000,0xde5bd8a9,0x37287195    //log10(e)
100
        .long 0x00000000,0x00000000,0x00000000    //0.0
101
 
102
//round to nearest
103
BIGRN:
104
        .long 0x3ffe0000,0xb17217f7,0xd1cf79ac    //ln(2)
105
        .long 0x40000000,0x935d8ddd,0xaaa8ac17    //ln(10)
106
        .long 0x3fff0000,0x80000000,0x00000000    //10 ^ 0
107
 
108
        .global PTENRN
109
PTENRN:
110
        .long 0x40020000,0xA0000000,0x00000000    //10 ^ 1
111
        .long 0x40050000,0xC8000000,0x00000000    //10 ^ 2
112
        .long 0x400C0000,0x9C400000,0x00000000    //10 ^ 4
113
        .long 0x40190000,0xBEBC2000,0x00000000    //10 ^ 8
114
        .long 0x40340000,0x8E1BC9BF,0x04000000    //10 ^ 16
115
        .long 0x40690000,0x9DC5ADA8,0x2B70B59E    //10 ^ 32
116
        .long 0x40D30000,0xC2781F49,0xFFCFA6D5    //10 ^ 64
117
        .long 0x41A80000,0x93BA47C9,0x80E98CE0    //10 ^ 128
118
        .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E    //10 ^ 256
119
        .long 0x46A30000,0xE319A0AE,0xA60E91C7    //10 ^ 512
120
        .long 0x4D480000,0xC9767586,0x81750C17    //10 ^ 1024
121
        .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5    //10 ^ 2048
122
        .long 0x75250000,0xC4605202,0x8A20979B    //10 ^ 4096
123
//round to minus infinity
124
BIGRZRM:
125
        .long 0x3ffe0000,0xb17217f7,0xd1cf79ab    //ln(2)
126
        .long 0x40000000,0x935d8ddd,0xaaa8ac16    //ln(10)
127
        .long 0x3fff0000,0x80000000,0x00000000    //10 ^ 0
128
 
129
        .global PTENRM
130
PTENRM:
131
        .long 0x40020000,0xA0000000,0x00000000    //10 ^ 1
132
        .long 0x40050000,0xC8000000,0x00000000    //10 ^ 2
133
        .long 0x400C0000,0x9C400000,0x00000000    //10 ^ 4
134
        .long 0x40190000,0xBEBC2000,0x00000000    //10 ^ 8
135
        .long 0x40340000,0x8E1BC9BF,0x04000000    //10 ^ 16
136
        .long 0x40690000,0x9DC5ADA8,0x2B70B59D    //10 ^ 32
137
        .long 0x40D30000,0xC2781F49,0xFFCFA6D5    //10 ^ 64
138
        .long 0x41A80000,0x93BA47C9,0x80E98CDF    //10 ^ 128
139
        .long 0x43510000,0xAA7EEBFB,0x9DF9DE8D    //10 ^ 256
140
        .long 0x46A30000,0xE319A0AE,0xA60E91C6    //10 ^ 512
141
        .long 0x4D480000,0xC9767586,0x81750C17    //10 ^ 1024
142
        .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5    //10 ^ 2048
143
        .long 0x75250000,0xC4605202,0x8A20979A    //10 ^ 4096
144
//round to positive infinity
145
BIGRP:
146
        .long 0x3ffe0000,0xb17217f7,0xd1cf79ac    //ln(2)
147
        .long 0x40000000,0x935d8ddd,0xaaa8ac17    //ln(10)
148
        .long 0x3fff0000,0x80000000,0x00000000    //10 ^ 0
149
 
150
        .global PTENRP
151
PTENRP:
152
        .long 0x40020000,0xA0000000,0x00000000    //10 ^ 1
153
        .long 0x40050000,0xC8000000,0x00000000    //10 ^ 2
154
        .long 0x400C0000,0x9C400000,0x00000000    //10 ^ 4
155
        .long 0x40190000,0xBEBC2000,0x00000000    //10 ^ 8
156
        .long 0x40340000,0x8E1BC9BF,0x04000000    //10 ^ 16
157
        .long 0x40690000,0x9DC5ADA8,0x2B70B59E    //10 ^ 32
158
        .long 0x40D30000,0xC2781F49,0xFFCFA6D6    //10 ^ 64
159
        .long 0x41A80000,0x93BA47C9,0x80E98CE0    //10 ^ 128
160
        .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E    //10 ^ 256
161
        .long 0x46A30000,0xE319A0AE,0xA60E91C7    //10 ^ 512
162
        .long 0x4D480000,0xC9767586,0x81750C18    //10 ^ 1024
163
        .long 0x5A920000,0x9E8B3B5D,0xC53D5DE6    //10 ^ 2048
164
        .long 0x75250000,0xC4605202,0x8A20979B    //10 ^ 4096
165
 
166
        |xref   nrm_zero
167
        |xref   decbin
168
        |xref   round
169
 
170
        .global    get_op
171
        .global    uns_getop
172
        .global    uni_getop
173
get_op:
174
        clrb    DY_MO_FLG(%a6)
175
        tstb    UFLG_TMP(%a6)   //test flag for unsupp/unimp state
176
        beq     uni_getop
177
 
178
uns_getop:
179
        btstb   #direction_bit,CMDREG1B(%a6)
180
        bne     opclass3        //branch if a fmove out (any kind)
181
        btstb   #6,CMDREG1B(%a6)
182
        beqs    uns_notpacked
183
 
184
        bfextu  CMDREG1B(%a6){#3:#3},%d0
185
        cmpb    #3,%d0
186
        beq     pack_source     //check for a packed src op, branch if so
187
uns_notpacked:
188
        bsr     chk_dy_mo       //set the dyadic/monadic flag
189
        tstb    DY_MO_FLG(%a6)
190
        beqs    src_op_ck       //if monadic, go check src op
191
//                              ;else, check dst op (fall through)
192
 
193
        btstb   #7,DTAG(%a6)
194
        beqs    src_op_ck       //if dst op is norm, check src op
195
        bras    dst_ex_dnrm     //else, handle destination unnorm/dnrm
196
 
197
uni_getop:
198
        bfextu  CMDREG1B(%a6){#0:#6},%d0 //get opclass and src fields
199
        cmpil   #0x17,%d0               //if op class and size fields are $17,
200
//                              ;it is FMOVECR; if not, continue
201
//
202
// If the instruction is fmovecr, exit get_op.  It is handled
203
// in do_func and smovecr.sa.
204
//
205
        bne     not_fmovecr     //handle fmovecr as an unimplemented inst
206
        rts
207
 
208
not_fmovecr:
209
        btstb   #E1,E_BYTE(%a6) //if set, there is a packed operand
210
        bne     pack_source     //check for packed src op, branch if so
211
 
212
// The following lines of are coded to optimize on normalized operands
213
        moveb   STAG(%a6),%d0
214
        orb     DTAG(%a6),%d0   //check if either of STAG/DTAG msb set
215
        bmis    dest_op_ck      //if so, some op needs to be fixed
216
        rts
217
 
218
dest_op_ck:
219
        btstb   #7,DTAG(%a6)    //check for unsupported data types in
220
        beqs    src_op_ck       //the destination, if not, check src op
221
        bsr     chk_dy_mo       //set dyadic/monadic flag
222
        tstb    DY_MO_FLG(%a6)  //
223
        beqs    src_op_ck       //if monadic, check src op
224
//
225
// At this point, destination has an extended denorm or unnorm.
226
//
227
dst_ex_dnrm:
228
        movew   FPTEMP_EX(%a6),%d0 //get destination exponent
229
        andiw   #0x7fff,%d0     //mask sign, check if exp = 0000
230
        beqs    src_op_ck       //if denorm then check source op.
231
//                              ;denorms are taken care of in res_func
232
//                              ;(unsupp) or do_func (unimp)
233
//                              ;else unnorm fall through
234
        leal    FPTEMP(%a6),%a0 //point a0 to dop - used in mk_norm
235
        bsr     mk_norm         //go normalize - mk_norm returns:
236
//                              ;L_SCR1{7:5} = operand tag
237
//                              ;       (000 = norm, 100 = denorm)
238
//                              ;L_SCR1{4} = fpte15 or ete15
239
//                              ;       0 = exp >  $3fff
240
//                              ;       1 = exp <= $3fff
241
//                              ;and puts the normalized num back
242
//                              ;on the fsave stack
243
//
244
        moveb L_SCR1(%a6),DTAG(%a6) //write the new tag & fpte15
245
//                              ;to the fsave stack and fall
246
//                              ;through to check source operand
247
//
248
src_op_ck:
249
        btstb   #7,STAG(%a6)
250
        beq     end_getop       //check for unsupported data types on the
251
//                              ;source operand
252
        btstb   #5,STAG(%a6)
253
        bnes    src_sd_dnrm     //if bit 5 set, handle sgl/dbl denorms
254
//
255
// At this point only unnorms or extended denorms are possible.
256
//
257
src_ex_dnrm:
258
        movew   ETEMP_EX(%a6),%d0 //get source exponent
259
        andiw   #0x7fff,%d0     //mask sign, check if exp = 0000
260
        beq     end_getop       //if denorm then exit, denorms are
261
//                              ;handled in do_func
262
        leal    ETEMP(%a6),%a0  //point a0 to sop - used in mk_norm
263
        bsr     mk_norm         //go normalize - mk_norm returns:
264
//                              ;L_SCR1{7:5} = operand tag
265
//                              ;       (000 = norm, 100 = denorm)
266
//                              ;L_SCR1{4} = fpte15 or ete15
267
//                              ;       0 = exp >  $3fff
268
//                              ;       1 = exp <= $3fff
269
//                              ;and puts the normalized num back
270
//                              ;on the fsave stack
271
//
272
        moveb   L_SCR1(%a6),STAG(%a6) //write the new tag & ete15
273
        rts                     //end_getop
274
 
275
//
276
// At this point, only single or double denorms are possible.
277
// If the inst is not fmove, normalize the source.  If it is,
278
// do nothing to the input.
279
//
280
src_sd_dnrm:
281
        btstb   #4,CMDREG1B(%a6)        //differentiate between sgl/dbl denorm
282
        bnes    is_double
283
is_single:
284
        movew   #0x3f81,%d1     //write bias for sgl denorm
285
        bras    common          //goto the common code
286
is_double:
287
        movew   #0x3c01,%d1     //write the bias for a dbl denorm
288
common:
289
        btstb   #sign_bit,ETEMP_EX(%a6) //grab sign bit of mantissa
290
        beqs    pos
291
        bset    #15,%d1         //set sign bit because it is negative
292
pos:
293
        movew   %d1,ETEMP_EX(%a6)
294
//                              ;put exponent on stack
295
 
296
        movew   CMDREG1B(%a6),%d1
297
        andw    #0xe3ff,%d1     //clear out source specifier
298
        orw     #0x0800,%d1     //set source specifier to extended prec
299
        movew   %d1,CMDREG1B(%a6)       //write back to the command word in stack
300
//                              ;this is needed to fix unsupp data stack
301
        leal    ETEMP(%a6),%a0  //point a0 to sop
302
 
303
        bsr     mk_norm         //convert sgl/dbl denorm to norm
304
        moveb   L_SCR1(%a6),STAG(%a6) //put tag into source tag reg - d0
305
        rts                     //end_getop
306
//
307
// At this point, the source is definitely packed, whether
308
// instruction is dyadic or monadic is still unknown
309
//
310
pack_source:
311
        movel   FPTEMP_LO(%a6),ETEMP(%a6)       //write ms part of packed
312
//                              ;number to etemp slot
313
        bsr     chk_dy_mo       //set dyadic/monadic flag
314
        bsr     unpack
315
 
316
        tstb    DY_MO_FLG(%a6)
317
        beqs    end_getop       //if monadic, exit
318
//                              ;else, fix FPTEMP
319
pack_dya:
320
        bfextu  CMDREG1B(%a6){#6:#3},%d0 //extract dest fp reg
321
        movel   #7,%d1
322
        subl    %d0,%d1
323
        clrl    %d0
324
        bsetl   %d1,%d0         //set up d0 as a dynamic register mask
325
        fmovemx %d0,FPTEMP(%a6) //write to FPTEMP
326
 
327
        btstb   #7,DTAG(%a6)    //check dest tag for unnorm or denorm
328
        bne     dst_ex_dnrm     //else, handle the unnorm or ext denorm
329
//
330
// Dest is not denormalized.  Check for norm, and set fpte15
331
// accordingly.
332
//
333
        moveb   DTAG(%a6),%d0
334
        andib   #0xf0,%d0               //strip to only dtag:fpte15
335
        tstb    %d0             //check for normalized value
336
        bnes    end_getop       //if inf/nan/zero leave get_op
337
        movew   FPTEMP_EX(%a6),%d0
338
        andiw   #0x7fff,%d0
339
        cmpiw   #0x3fff,%d0     //check if fpte15 needs setting
340
        bges    end_getop       //if >= $3fff, leave fpte15=0
341
        orb     #0x10,DTAG(%a6)
342
        bras    end_getop
343
 
344
//
345
// At this point, it is either an fmoveout packed, unnorm or denorm
346
//
347
opclass3:
348
        clrb    DY_MO_FLG(%a6)  //set dyadic/monadic flag to monadic
349
        bfextu  CMDREG1B(%a6){#4:#2},%d0
350
        cmpib   #3,%d0
351
        bne     src_ex_dnrm     //if not equal, must be unnorm or denorm
352
//                              ;else it is a packed move out
353
//                              ;exit
354
end_getop:
355
        rts
356
 
357
//
358
// Sets the DY_MO_FLG correctly. This is used only on if it is an
359
// unsupported data type exception.  Set if dyadic.
360
//
361
chk_dy_mo:
362
        movew   CMDREG1B(%a6),%d0
363
        btstl   #5,%d0          //testing extension command word
364
        beqs    set_mon         //if bit 5 = 0 then monadic
365
        btstl   #4,%d0          //know that bit 5 = 1
366
        beqs    set_dya         //if bit 4 = 0 then dyadic
367
        andiw   #0x007f,%d0     //get rid of all but extension bits {6:0}
368
        cmpiw   #0x0038,%d0     //if extension = $38 then fcmp (dyadic)
369
        bnes    set_mon
370
set_dya:
371
        st      DY_MO_FLG(%a6)  //set the inst flag type to dyadic
372
        rts
373
set_mon:
374
        clrb    DY_MO_FLG(%a6)  //set the inst flag type to monadic
375
        rts
376
//
377
//      MK_NORM
378
//
379
// Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
380
// exception if denorm.
381
//
382
// CASE opclass 0x0 unsupp
383
//      mk_norm till msb set
384
//      set tag = norm
385
//
386
// CASE opclass 0x0 unimp
387
//      mk_norm till msb set or exp = 0
388
//      if integer bit = 0
389
//         tag = denorm
390
//      else
391
//         tag = norm
392
//
393
// CASE opclass 011 unsupp
394
//      mk_norm till msb set or exp = 0
395
//      if integer bit = 0
396
//         tag = denorm
397
//         set unfl_nmcexe = 1
398
//      else
399
//         tag = norm
400
//
401
// if exp <= $3fff
402
//   set ete15 or fpte15 = 1
403
// else set ete15 or fpte15 = 0
404
 
405
// input:
406
//      a0 = points to operand to be normalized
407
// output:
408
//      L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm)
409
//      L_SCR1{4}   = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff)
410
//      the normalized operand is placed back on the fsave stack
411
mk_norm:
412
        clrl    L_SCR1(%a6)
413
        bclrb   #sign_bit,LOCAL_EX(%a0)
414
        sne     LOCAL_SGN(%a0)  //transform into internal extended format
415
 
416
        cmpib   #0x2c,1+EXC_VEC(%a6) //check if unimp
417
        bnes    uns_data        //branch if unsupp
418
        bsr     uni_inst        //call if unimp (opclass 0x0)
419
        bras    reload
420
uns_data:
421
        btstb   #direction_bit,CMDREG1B(%a6) //check transfer direction
422
        bnes    bit_set         //branch if set (opclass 011)
423
        bsr     uns_opx         //call if opclass 0x0
424
        bras    reload
425
bit_set:
426
        bsr     uns_op3         //opclass 011
427
reload:
428
        cmpw    #0x3fff,LOCAL_EX(%a0) //if exp > $3fff
429
        bgts    end_mk          //   fpte15/ete15 already set to 0
430
        bsetb   #4,L_SCR1(%a6)  //else set fpte15/ete15 to 1
431
//                              ;calling routine actually sets the
432
//                              ;value on the stack (along with the
433
//                              ;tag), since this routine doesn't
434
//                              ;know if it should set ete15 or fpte15
435
//                              ;ie, it doesn't know if this is the
436
//                              ;src op or dest op.
437
end_mk:
438
        bfclr   LOCAL_SGN(%a0){#0:#8}
439
        beqs    end_mk_pos
440
        bsetb   #sign_bit,LOCAL_EX(%a0) //convert back to IEEE format
441
end_mk_pos:
442
        rts
443
//
444
//     CASE opclass 011 unsupp
445
//
446
uns_op3:
447
        bsr     nrm_zero        //normalize till msb = 1 or exp = zero
448
        btstb   #7,LOCAL_HI(%a0)        //if msb = 1
449
        bnes    no_unfl         //then branch
450
set_unfl:
451
        orw     #dnrm_tag,L_SCR1(%a6) //set denorm tag
452
        bsetb   #unfl_bit,FPSR_EXCEPT(%a6) //set unfl exception bit
453
no_unfl:
454
        rts
455
//
456
//     CASE opclass 0x0 unsupp
457
//
458
uns_opx:
459
        bsr     nrm_zero        //normalize the number
460
        btstb   #7,LOCAL_HI(%a0)        //check if integer bit (j-bit) is set
461
        beqs    uns_den         //if clear then now have a denorm
462
uns_nrm:
463
        orb     #norm_tag,L_SCR1(%a6) //set tag to norm
464
        rts
465
uns_den:
466
        orb     #dnrm_tag,L_SCR1(%a6) //set tag to denorm
467
        rts
468
//
469
//     CASE opclass 0x0 unimp
470
//
471
uni_inst:
472
        bsr     nrm_zero
473
        btstb   #7,LOCAL_HI(%a0)        //check if integer bit (j-bit) is set
474
        beqs    uni_den         //if clear then now have a denorm
475
uni_nrm:
476
        orb     #norm_tag,L_SCR1(%a6) //set tag to norm
477
        rts
478
uni_den:
479
        orb     #dnrm_tag,L_SCR1(%a6) //set tag to denorm
480
        rts
481
 
482
//
483
//      Decimal to binary conversion
484
//
485
// Special cases of inf and NaNs are completed outside of decbin.
486
// If the input is an snan, the snan bit is not set.
487
//
488
// input:
489
//      ETEMP(a6)       - points to packed decimal string in memory
490
// output:
491
//      fp0     - contains packed string converted to extended precision
492
//      ETEMP   - same as fp0
493
unpack:
494
        movew   CMDREG1B(%a6),%d0       //examine command word, looking for fmove's
495
        andw    #0x3b,%d0
496
        beq     move_unpack     //special handling for fmove: must set FPSR_CC
497
 
498
        movew   ETEMP(%a6),%d0  //get word with inf information
499
        bfextu  %d0{#20:#12},%d1        //get exponent into d1
500
        cmpiw   #0x0fff,%d1     //test for inf or NaN
501
        bnes    try_zero        //if not equal, it is not special
502
        bfextu  %d0{#17:#3},%d1 //get SE and y bits into d1
503
        cmpiw   #7,%d1          //SE and y bits must be on for special
504
        bnes    try_zero        //if not on, it is not special
505
//input is of the special cases of inf and NaN
506
        tstl    ETEMP_HI(%a6)   //check ms mantissa
507
        bnes    fix_nan         //if non-zero, it is a NaN
508
        tstl    ETEMP_LO(%a6)   //check ls mantissa
509
        bnes    fix_nan         //if non-zero, it is a NaN
510
        bra     finish          //special already on stack
511
fix_nan:
512
        btstb   #signan_bit,ETEMP_HI(%a6) //test for snan
513
        bne     finish
514
        orl     #snaniop_mask,USER_FPSR(%a6) //always set snan if it is so
515
        bra     finish
516
try_zero:
517
        movew   ETEMP_EX+2(%a6),%d0 //get word 4
518
        andiw   #0x000f,%d0     //clear all but last ni(y)bble
519
        tstw    %d0             //check for zero.
520
        bne     not_spec
521
        tstl    ETEMP_HI(%a6)   //check words 3 and 2
522
        bne     not_spec
523
        tstl    ETEMP_LO(%a6)   //check words 1 and 0
524
        bne     not_spec
525
        tstl    ETEMP(%a6)      //test sign of the zero
526
        bges    pos_zero
527
        movel   #0x80000000,ETEMP(%a6) //write neg zero to etemp
528
        clrl    ETEMP_HI(%a6)
529
        clrl    ETEMP_LO(%a6)
530
        bra     finish
531
pos_zero:
532
        clrl    ETEMP(%a6)
533
        clrl    ETEMP_HI(%a6)
534
        clrl    ETEMP_LO(%a6)
535
        bra     finish
536
 
537
not_spec:
538
        fmovemx %fp0-%fp1,-(%a7)        //save fp0 - decbin returns in it
539
        bsr     decbin
540
        fmovex %fp0,ETEMP(%a6)  //put the unpacked sop in the fsave stack
541
        fmovemx (%a7)+,%fp0-%fp1
542
        fmovel  #0,%FPSR                //clr fpsr from decbin
543
        bra     finish
544
 
545
//
546
// Special handling for packed move in:  Same results as all other
547
// packed cases, but we must set the FPSR condition codes properly.
548
//
549
move_unpack:
550
        movew   ETEMP(%a6),%d0  //get word with inf information
551
        bfextu  %d0{#20:#12},%d1        //get exponent into d1
552
        cmpiw   #0x0fff,%d1     //test for inf or NaN
553
        bnes    mtry_zero       //if not equal, it is not special
554
        bfextu  %d0{#17:#3},%d1 //get SE and y bits into d1
555
        cmpiw   #7,%d1          //SE and y bits must be on for special
556
        bnes    mtry_zero       //if not on, it is not special
557
//input is of the special cases of inf and NaN
558
        tstl    ETEMP_HI(%a6)   //check ms mantissa
559
        bnes    mfix_nan                //if non-zero, it is a NaN
560
        tstl    ETEMP_LO(%a6)   //check ls mantissa
561
        bnes    mfix_nan                //if non-zero, it is a NaN
562
//input is inf
563
        orl     #inf_mask,USER_FPSR(%a6) //set I bit
564
        tstl    ETEMP(%a6)      //check sign
565
        bge     finish
566
        orl     #neg_mask,USER_FPSR(%a6) //set N bit
567
        bra     finish          //special already on stack
568
mfix_nan:
569
        orl     #nan_mask,USER_FPSR(%a6) //set NaN bit
570
        moveb   #nan_tag,STAG(%a6)      //set stag to NaN
571
        btstb   #signan_bit,ETEMP_HI(%a6) //test for snan
572
        bnes    mn_snan
573
        orl     #snaniop_mask,USER_FPSR(%a6) //set snan bit
574
        btstb   #snan_bit,FPCR_ENABLE(%a6) //test for snan enabled
575
        bnes    mn_snan
576
        bsetb   #signan_bit,ETEMP_HI(%a6) //force snans to qnans
577
mn_snan:
578
        tstl    ETEMP(%a6)      //check for sign
579
        bge     finish          //if clr, go on
580
        orl     #neg_mask,USER_FPSR(%a6) //set N bit
581
        bra     finish
582
 
583
mtry_zero:
584
        movew   ETEMP_EX+2(%a6),%d0 //get word 4
585
        andiw   #0x000f,%d0     //clear all but last ni(y)bble
586
        tstw    %d0             //check for zero.
587
        bnes    mnot_spec
588
        tstl    ETEMP_HI(%a6)   //check words 3 and 2
589
        bnes    mnot_spec
590
        tstl    ETEMP_LO(%a6)   //check words 1 and 0
591
        bnes    mnot_spec
592
        tstl    ETEMP(%a6)      //test sign of the zero
593
        bges    mpos_zero
594
        orl     #neg_mask+z_mask,USER_FPSR(%a6) //set N and Z
595
        movel   #0x80000000,ETEMP(%a6) //write neg zero to etemp
596
        clrl    ETEMP_HI(%a6)
597
        clrl    ETEMP_LO(%a6)
598
        bras    finish
599
mpos_zero:
600
        orl     #z_mask,USER_FPSR(%a6) //set Z
601
        clrl    ETEMP(%a6)
602
        clrl    ETEMP_HI(%a6)
603
        clrl    ETEMP_LO(%a6)
604
        bras    finish
605
 
606
mnot_spec:
607
        fmovemx %fp0-%fp1,-(%a7)        //save fp0 ,fp1 - decbin returns in fp0
608
        bsr     decbin
609
        fmovex %fp0,ETEMP(%a6)
610
//                              ;put the unpacked sop in the fsave stack
611
        fmovemx (%a7)+,%fp0-%fp1
612
 
613
finish:
614
        movew   CMDREG1B(%a6),%d0       //get the command word
615
        andw    #0xfbff,%d0     //change the source specifier field to
616
//                              ;extended (was packed).
617
        movew   %d0,CMDREG1B(%a6)       //write command word back to fsave stack
618
//                              ;we need to do this so the 040 will
619
//                              ;re-execute the inst. without taking
620
//                              ;another packed trap.
621
 
622
fix_stag:
623
//Converted result is now in etemp on fsave stack, now set the source
624
//tag (stag)
625
//      if (ete =$7fff) then INF or NAN
626
//              if (etemp = $x.0----0) then
627
//                      stag = INF
628
//              else
629
//                      stag = NAN
630
//      else
631
//              if (ete = $0000) then
632
//                      stag = ZERO
633
//              else
634
//                      stag = NORM
635
//
636
// Note also that the etemp_15 bit (just right of the stag) must
637
// be set accordingly.
638
//
639
        movew           ETEMP_EX(%a6),%d1
640
        andiw           #0x7fff,%d1   //strip sign
641
        cmpw            #0x7fff,%d1
642
        bnes            z_or_nrm
643
        movel           ETEMP_HI(%a6),%d1
644
        bnes            is_nan
645
        movel           ETEMP_LO(%a6),%d1
646
        bnes            is_nan
647
is_inf:
648
        moveb           #0x40,STAG(%a6)
649
        movel           #0x40,%d0
650
        rts
651
is_nan:
652
        moveb           #0x60,STAG(%a6)
653
        movel           #0x60,%d0
654
        rts
655
z_or_nrm:
656
        tstw            %d1
657
        bnes            is_nrm
658
is_zro:
659
// For a zero, set etemp_15
660
        moveb           #0x30,STAG(%a6)
661
        movel           #0x20,%d0
662
        rts
663
is_nrm:
664
// For a norm, check if the exp <= $3fff; if so, set etemp_15
665
        cmpiw           #0x3fff,%d1
666
        bles            set_bit15
667
        moveb           #0,STAG(%a6)
668
        bras            end_is_nrm
669
set_bit15:
670
        moveb           #0x10,STAG(%a6)
671
end_is_nrm:
672
        movel           #0,%d0
673
end_fix:
674
        rts
675
 
676
end_get:
677
        rts
678
        |end

powered by: WebSVN 2.1.0

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