OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
//
2
//      $Id: util.S,v 1.2 2001-09-27 12:01:22 chris Exp $
3
//
4
//      util.sa 3.7 7/29/91
5
//
6
//      This file contains routines used by other programs.
7
//
8
//      ovf_res: used by overflow to force the correct
9
//               result. ovf_r_k, ovf_r_x2, ovf_r_x3 are
10
//               derivatives of this routine.
11
//      get_fline: get user's opcode word
12
//      g_dfmtou: returns the destination format.
13
//      g_opcls: returns the opclass of the float instruction.
14
//      g_rndpr: returns the rounding precision.
15
//      reg_dest: write byte, word, or long data to Dn
16
//
17
//
18
//              Copyright (C) Motorola, Inc. 1990
19
//                      All Rights Reserved
20
//
21
//      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
22
//      The copyright notice above does not evidence any
23
//      actual or intended publication of such source code.
24
 
25
//UTIL  idnt    2,1 | Motorola 040 Floating Point Software Package
26
 
27
        |section        8
28
 
29
#include "fpsp.defs"
30
 
31
        |xref   mem_read
32
 
33
        .global g_dfmtou
34
        .global g_opcls
35
        .global g_rndpr
36
        .global get_fline
37
        .global reg_dest
38
 
39
//
40
// Final result table for ovf_res. Note that the negative counterparts
41
// are unnecessary as ovf_res always returns the sign separately from
42
// the exponent.
43
//                                      ;+inf
44
EXT_PINF:       .long   0x7fff0000,0x00000000,0x00000000,0x00000000
45
//                                      ;largest +ext
46
EXT_PLRG:       .long   0x7ffe0000,0xffffffff,0xffffffff,0x00000000
47
//                                      ;largest magnitude +sgl in ext
48
SGL_PLRG:       .long   0x407e0000,0xffffff00,0x00000000,0x00000000
49
//                                      ;largest magnitude +dbl in ext
50
DBL_PLRG:       .long   0x43fe0000,0xffffffff,0xfffff800,0x00000000
51
//                                      ;largest -ext
52
 
53
tblovfl:
54
        .long   EXT_RN
55
        .long   EXT_RZ
56
        .long   EXT_RM
57
        .long   EXT_RP
58
        .long   SGL_RN
59
        .long   SGL_RZ
60
        .long   SGL_RM
61
        .long   SGL_RP
62
        .long   DBL_RN
63
        .long   DBL_RZ
64
        .long   DBL_RM
65
        .long   DBL_RP
66
        .long   error
67
        .long   error
68
        .long   error
69
        .long   error
70
 
71
 
72
//
73
//      ovf_r_k --- overflow result calculation
74
//
75
// This entry point is used by kernel_ex.
76
//
77
// This forces the destination precision to be extended
78
//
79
// Input:       operand in ETEMP
80
// Output:      a result is in ETEMP (internal extended format)
81
//
82
        .global ovf_r_k
83
ovf_r_k:
84
        lea     ETEMP(%a6),%a0  //a0 points to source operand
85
        bclrb   #sign_bit,ETEMP_EX(%a6)
86
        sne     ETEMP_SGN(%a6)  //convert to internal IEEE format
87
 
88
//
89
//      ovf_r_x2 --- overflow result calculation
90
//
91
// This entry point used by x_ovfl.  (opclass 0 and 2)
92
//
93
// Input                a0  points to an operand in the internal extended format
94
// Output       a0  points to the result in the internal extended format
95
//
96
// This sets the round precision according to the user's FPCR unless the
97
// instruction is fsgldiv or fsglmul or fsadd, fdadd, fsub, fdsub, fsmul,
98
// fdmul, fsdiv, fddiv, fssqrt, fsmove, fdmove, fsabs, fdabs, fsneg, fdneg.
99
// If the instruction is fsgldiv of fsglmul, the rounding precision must be
100
// extended.  If the instruction is not fsgldiv or fsglmul but a force-
101
// precision instruction, the rounding precision is then set to the force
102
// precision.
103
 
104
        .global ovf_r_x2
105
ovf_r_x2:
106
        btstb   #E3,E_BYTE(%a6)         //check for nu exception
107
        beql    ovf_e1_exc              //it is cu exception
108
ovf_e3_exc:
109
        movew   CMDREG3B(%a6),%d0               //get the command word
110
        andiw   #0x00000060,%d0         //clear all bits except 6 and 5
111
        cmpil   #0x00000040,%d0
112
        beql    ovff_sgl                //force precision is single
113
        cmpil   #0x00000060,%d0
114
        beql    ovff_dbl                //force precision is double
115
        movew   CMDREG3B(%a6),%d0               //get the command word again
116
        andil   #0x7f,%d0                       //clear all except operation
117
        cmpil   #0x33,%d0
118
        beql    ovf_fsgl                //fsglmul or fsgldiv
119
        cmpil   #0x30,%d0
120
        beql    ovf_fsgl
121
        bra     ovf_fpcr                //instruction is none of the above
122
//                                      ;use FPCR
123
ovf_e1_exc:
124
        movew   CMDREG1B(%a6),%d0               //get command word
125
        andil   #0x00000044,%d0         //clear all bits except 6 and 2
126
        cmpil   #0x00000040,%d0
127
        beql    ovff_sgl                //the instruction is force single
128
        cmpil   #0x00000044,%d0
129
        beql    ovff_dbl                //the instruction is force double
130
        movew   CMDREG1B(%a6),%d0               //again get the command word
131
        andil   #0x0000007f,%d0         //clear all except the op code
132
        cmpil   #0x00000027,%d0
133
        beql    ovf_fsgl                //fsglmul
134
        cmpil   #0x00000024,%d0
135
        beql    ovf_fsgl                //fsgldiv
136
        bra     ovf_fpcr                //none of the above, use FPCR
137
//
138
//
139
// Inst is either fsgldiv or fsglmul.  Force extended precision.
140
//
141
ovf_fsgl:
142
        clrl    %d0
143
        bra     ovf_res
144
 
145
ovff_sgl:
146
        movel   #0x00000001,%d0         //set single
147
        bra     ovf_res
148
ovff_dbl:
149
        movel   #0x00000002,%d0         //set double
150
        bra     ovf_res
151
//
152
// The precision is in the fpcr.
153
//
154
ovf_fpcr:
155
        bfextu  FPCR_MODE(%a6){#0:#2},%d0 //set round precision
156
        bra     ovf_res
157
 
158
//
159
//
160
//      ovf_r_x3 --- overflow result calculation
161
//
162
// This entry point used by x_ovfl. (opclass 3 only)
163
//
164
// Input                a0  points to an operand in the internal extended format
165
// Output       a0  points to the result in the internal extended format
166
//
167
// This sets the round precision according to the destination size.
168
//
169
        .global ovf_r_x3
170
ovf_r_x3:
171
        bsr     g_dfmtou        //get dest fmt in d0{1:0}
172
//                              ;for fmovout, the destination format
173
//                              ;is the rounding precision
174
 
175
//
176
//      ovf_res --- overflow result calculation
177
//
178
// Input:
179
//      a0      points to operand in internal extended format
180
// Output:
181
//      a0      points to result in internal extended format
182
//
183
        .global ovf_res
184
ovf_res:
185
        lsll    #2,%d0          //move round precision to d0{3:2}
186
        bfextu  FPCR_MODE(%a6){#2:#2},%d1 //set round mode
187
        orl     %d1,%d0         //index is fmt:mode in d0{3:0}
188
        leal    tblovfl,%a1     //load a1 with table address
189
        movel   %a1@(%d0:l:4),%a1       //use d0 as index to the table
190
        jmp     (%a1)           //go to the correct routine
191
//
192
//case DEST_FMT = EXT
193
//
194
EXT_RN:
195
        leal    EXT_PINF,%a1    //answer is +/- infinity
196
        bsetb   #inf_bit,FPSR_CC(%a6)
197
        bra     set_sign        //now go set the sign
198
EXT_RZ:
199
        leal    EXT_PLRG,%a1    //answer is +/- large number
200
        bra     set_sign        //now go set the sign
201
EXT_RM:
202
        tstb    LOCAL_SGN(%a0)  //if negative overflow
203
        beqs    e_rm_pos
204
e_rm_neg:
205
        leal    EXT_PINF,%a1    //answer is negative infinity
206
        orl     #neginf_mask,USER_FPSR(%a6)
207
        bra     end_ovfr
208
e_rm_pos:
209
        leal    EXT_PLRG,%a1    //answer is large positive number
210
        bra     end_ovfr
211
EXT_RP:
212
        tstb    LOCAL_SGN(%a0)  //if negative overflow
213
        beqs    e_rp_pos
214
e_rp_neg:
215
        leal    EXT_PLRG,%a1    //answer is large negative number
216
        bsetb   #neg_bit,FPSR_CC(%a6)
217
        bra     end_ovfr
218
e_rp_pos:
219
        leal    EXT_PINF,%a1    //answer is positive infinity
220
        bsetb   #inf_bit,FPSR_CC(%a6)
221
        bra     end_ovfr
222
//
223
//case DEST_FMT = DBL
224
//
225
DBL_RN:
226
        leal    EXT_PINF,%a1    //answer is +/- infinity
227
        bsetb   #inf_bit,FPSR_CC(%a6)
228
        bra     set_sign
229
DBL_RZ:
230
        leal    DBL_PLRG,%a1    //answer is +/- large number
231
        bra     set_sign        //now go set the sign
232
DBL_RM:
233
        tstb    LOCAL_SGN(%a0)  //if negative overflow
234
        beqs    d_rm_pos
235
d_rm_neg:
236
        leal    EXT_PINF,%a1    //answer is negative infinity
237
        orl     #neginf_mask,USER_FPSR(%a6)
238
        bra     end_ovfr        //inf is same for all precisions (ext,dbl,sgl)
239
d_rm_pos:
240
        leal    DBL_PLRG,%a1    //answer is large positive number
241
        bra     end_ovfr
242
DBL_RP:
243
        tstb    LOCAL_SGN(%a0)  //if negative overflow
244
        beqs    d_rp_pos
245
d_rp_neg:
246
        leal    DBL_PLRG,%a1    //answer is large negative number
247
        bsetb   #neg_bit,FPSR_CC(%a6)
248
        bra     end_ovfr
249
d_rp_pos:
250
        leal    EXT_PINF,%a1    //answer is positive infinity
251
        bsetb   #inf_bit,FPSR_CC(%a6)
252
        bra     end_ovfr
253
//
254
//case DEST_FMT = SGL
255
//
256
SGL_RN:
257
        leal    EXT_PINF,%a1    //answer is +/-  infinity
258
        bsetb   #inf_bit,FPSR_CC(%a6)
259
        bras    set_sign
260
SGL_RZ:
261
        leal    SGL_PLRG,%a1    //answer is +/- large number
262
        bras    set_sign
263
SGL_RM:
264
        tstb    LOCAL_SGN(%a0)  //if negative overflow
265
        beqs    s_rm_pos
266
s_rm_neg:
267
        leal    EXT_PINF,%a1    //answer is negative infinity
268
        orl     #neginf_mask,USER_FPSR(%a6)
269
        bras    end_ovfr
270
s_rm_pos:
271
        leal    SGL_PLRG,%a1    //answer is large positive number
272
        bras    end_ovfr
273
SGL_RP:
274
        tstb    LOCAL_SGN(%a0)  //if negative overflow
275
        beqs    s_rp_pos
276
s_rp_neg:
277
        leal    SGL_PLRG,%a1    //answer is large negative number
278
        bsetb   #neg_bit,FPSR_CC(%a6)
279
        bras    end_ovfr
280
s_rp_pos:
281
        leal    EXT_PINF,%a1    //answer is positive infinity
282
        bsetb   #inf_bit,FPSR_CC(%a6)
283
        bras    end_ovfr
284
 
285
set_sign:
286
        tstb    LOCAL_SGN(%a0)  //if negative overflow
287
        beqs    end_ovfr
288
neg_sign:
289
        bsetb   #neg_bit,FPSR_CC(%a6)
290
 
291
end_ovfr:
292
        movew   LOCAL_EX(%a1),LOCAL_EX(%a0) //do not overwrite sign
293
        movel   LOCAL_HI(%a1),LOCAL_HI(%a0)
294
        movel   LOCAL_LO(%a1),LOCAL_LO(%a0)
295
        rts
296
 
297
 
298
//
299
//      ERROR
300
//
301
error:
302
        rts
303
//
304
//      get_fline --- get f-line opcode of interrupted instruction
305
//
306
//      Returns opcode in the low word of d0.
307
//
308
get_fline:
309
        movel   USER_FPIAR(%a6),%a0     //opcode address
310
        movel   #0,-(%a7)       //reserve a word on the stack
311
        leal    2(%a7),%a1      //point to low word of temporary
312
        movel   #2,%d0          //count
313
        bsrl    mem_read
314
        movel   (%a7)+,%d0
315
        rts
316
//
317
//      g_rndpr --- put rounding precision in d0{1:0}
318
//
319
//      valid return codes are:
320
//              00 - extended
321
//              01 - single
322
//              10 - double
323
//
324
// begin
325
// get rounding precision (cmdreg3b{6:5})
326
// begin
327
//  case        opclass = 011 (move out)
328
//      get destination format - this is the also the rounding precision
329
//
330
//  case        opclass = 0x0
331
//      if E3
332
//          *case RndPr(from cmdreg3b{6:5} = 11  then RND_PREC = DBL
333
//          *case RndPr(from cmdreg3b{6:5} = 10  then RND_PREC = SGL
334
//           case RndPr(from cmdreg3b{6:5} = 00 | 01
335
//              use precision from FPCR{7:6}
336
//                      case 00 then RND_PREC = EXT
337
//                      case 01 then RND_PREC = SGL
338
//                      case 10 then RND_PREC = DBL
339
//      else E1
340
//           use precision in FPCR{7:6}
341
//           case 00 then RND_PREC = EXT
342
//           case 01 then RND_PREC = SGL
343
//           case 10 then RND_PREC = DBL
344
// end
345
//
346
g_rndpr:
347
        bsr     g_opcls         //get opclass in d0{2:0}
348
        cmpw    #0x0003,%d0     //check for opclass 011
349
        bnes    op_0x0
350
 
351
//
352
// For move out instructions (opclass 011) the destination format
353
// is the same as the rounding precision.  Pass results from g_dfmtou.
354
//
355
        bsr     g_dfmtou
356
        rts
357
op_0x0:
358
        btstb   #E3,E_BYTE(%a6)
359
        beql    unf_e1_exc      //branch to e1 underflow
360
unf_e3_exc:
361
        movel   CMDREG3B(%a6),%d0       //rounding precision in d0{10:9}
362
        bfextu  %d0{#9:#2},%d0  //move the rounding prec bits to d0{1:0}
363
        cmpil   #0x2,%d0
364
        beql    unff_sgl        //force precision is single
365
        cmpil   #0x3,%d0                //force precision is double
366
        beql    unff_dbl
367
        movew   CMDREG3B(%a6),%d0       //get the command word again
368
        andil   #0x7f,%d0               //clear all except operation
369
        cmpil   #0x33,%d0
370
        beql    unf_fsgl        //fsglmul or fsgldiv
371
        cmpil   #0x30,%d0
372
        beql    unf_fsgl        //fsgldiv or fsglmul
373
        bra     unf_fpcr
374
unf_e1_exc:
375
        movel   CMDREG1B(%a6),%d0       //get 32 bits off the stack, 1st 16 bits
376
//                              ;are the command word
377
        andil   #0x00440000,%d0 //clear all bits except bits 6 and 2
378
        cmpil   #0x00400000,%d0
379
        beql    unff_sgl        //force single
380
        cmpil   #0x00440000,%d0 //force double
381
        beql    unff_dbl
382
        movel   CMDREG1B(%a6),%d0       //get the command word again
383
        andil   #0x007f0000,%d0 //clear all bits except the operation
384
        cmpil   #0x00270000,%d0
385
        beql    unf_fsgl        //fsglmul
386
        cmpil   #0x00240000,%d0
387
        beql    unf_fsgl        //fsgldiv
388
        bra     unf_fpcr
389
 
390
//
391
// Convert to return format.  The values from cmdreg3b and the return
392
// values are:
393
//      cmdreg3b        return       precision
394
//      --------        ------       ---------
395
//        00,01           0             ext
396
//         10             1             sgl
397
//         11             2             dbl
398
// Force single
399
//
400
unff_sgl:
401
        movel   #1,%d0          //return 1
402
        rts
403
//
404
// Force double
405
//
406
unff_dbl:
407
        movel   #2,%d0          //return 2
408
        rts
409
//
410
// Force extended
411
//
412
unf_fsgl:
413
        movel   #0,%d0
414
        rts
415
//
416
// Get rounding precision set in FPCR{7:6}.
417
//
418
unf_fpcr:
419
        movel   USER_FPCR(%a6),%d0 //rounding precision bits in d0{7:6}
420
        bfextu  %d0{#24:#2},%d0 //move the rounding prec bits to d0{1:0}
421
        rts
422
//
423
//      g_opcls --- put opclass in d0{2:0}
424
//
425
g_opcls:
426
        btstb   #E3,E_BYTE(%a6)
427
        beqs    opc_1b          //if set, go to cmdreg1b
428
opc_3b:
429
        clrl    %d0             //if E3, only opclass 0x0 is possible
430
        rts
431
opc_1b:
432
        movel   CMDREG1B(%a6),%d0
433
        bfextu  %d0{#0:#3},%d0  //shift opclass bits d0{31:29} to d0{2:0}
434
        rts
435
//
436
//      g_dfmtou --- put destination format in d0{1:0}
437
//
438
//      If E1, the format is from cmdreg1b{12:10}
439
//      If E3, the format is extended.
440
//
441
//      Dest. Fmt.
442
//              extended  010 -> 00
443
//              single    001 -> 01
444
//              double    101 -> 10
445
//
446
g_dfmtou:
447
        btstb   #E3,E_BYTE(%a6)
448
        beqs    op011
449
        clrl    %d0             //if E1, size is always ext
450
        rts
451
op011:
452
        movel   CMDREG1B(%a6),%d0
453
        bfextu  %d0{#3:#3},%d0  //dest fmt from cmdreg1b{12:10}
454
        cmpb    #1,%d0          //check for single
455
        bnes    not_sgl
456
        movel   #1,%d0
457
        rts
458
not_sgl:
459
        cmpb    #5,%d0          //check for double
460
        bnes    not_dbl
461
        movel   #2,%d0
462
        rts
463
not_dbl:
464
        clrl    %d0             //must be extended
465
        rts
466
 
467
//
468
//
469
// Final result table for unf_sub. Note that the negative counterparts
470
// are unnecessary as unf_sub always returns the sign separately from
471
// the exponent.
472
//                                      ;+zero
473
EXT_PZRO:       .long   0x00000000,0x00000000,0x00000000,0x00000000
474
//                                      ;+zero
475
SGL_PZRO:       .long   0x3f810000,0x00000000,0x00000000,0x00000000
476
//                                      ;+zero
477
DBL_PZRO:       .long   0x3c010000,0x00000000,0x00000000,0x00000000
478
//                                      ;smallest +ext denorm
479
EXT_PSML:       .long   0x00000000,0x00000000,0x00000001,0x00000000
480
//                                      ;smallest +sgl denorm
481
SGL_PSML:       .long   0x3f810000,0x00000100,0x00000000,0x00000000
482
//                                      ;smallest +dbl denorm
483
DBL_PSML:       .long   0x3c010000,0x00000000,0x00000800,0x00000000
484
//
485
//      UNF_SUB --- underflow result calculation
486
//
487
// Input:
488
//      d0      contains round precision
489
//      a0      points to input operand in the internal extended format
490
//
491
// Output:
492
//      a0      points to correct internal extended precision result.
493
//
494
 
495
tblunf:
496
        .long   uEXT_RN
497
        .long   uEXT_RZ
498
        .long   uEXT_RM
499
        .long   uEXT_RP
500
        .long   uSGL_RN
501
        .long   uSGL_RZ
502
        .long   uSGL_RM
503
        .long   uSGL_RP
504
        .long   uDBL_RN
505
        .long   uDBL_RZ
506
        .long   uDBL_RM
507
        .long   uDBL_RP
508
        .long   uDBL_RN
509
        .long   uDBL_RZ
510
        .long   uDBL_RM
511
        .long   uDBL_RP
512
 
513
        .global unf_sub
514
unf_sub:
515
        lsll    #2,%d0          //move round precision to d0{3:2}
516
        bfextu  FPCR_MODE(%a6){#2:#2},%d1 //set round mode
517
        orl     %d1,%d0         //index is fmt:mode in d0{3:0}
518
        leal    tblunf,%a1      //load a1 with table address
519
        movel   %a1@(%d0:l:4),%a1       //use d0 as index to the table
520
        jmp     (%a1)           //go to the correct routine
521
//
522
//case DEST_FMT = EXT
523
//
524
uEXT_RN:
525
        leal    EXT_PZRO,%a1    //answer is +/- zero
526
        bsetb   #z_bit,FPSR_CC(%a6)
527
        bra     uset_sign       //now go set the sign
528
uEXT_RZ:
529
        leal    EXT_PZRO,%a1    //answer is +/- zero
530
        bsetb   #z_bit,FPSR_CC(%a6)
531
        bra     uset_sign       //now go set the sign
532
uEXT_RM:
533
        tstb    LOCAL_SGN(%a0)  //if negative underflow
534
        beqs    ue_rm_pos
535
ue_rm_neg:
536
        leal    EXT_PSML,%a1    //answer is negative smallest denorm
537
        bsetb   #neg_bit,FPSR_CC(%a6)
538
        bra     end_unfr
539
ue_rm_pos:
540
        leal    EXT_PZRO,%a1    //answer is positive zero
541
        bsetb   #z_bit,FPSR_CC(%a6)
542
        bra     end_unfr
543
uEXT_RP:
544
        tstb    LOCAL_SGN(%a0)  //if negative underflow
545
        beqs    ue_rp_pos
546
ue_rp_neg:
547
        leal    EXT_PZRO,%a1    //answer is negative zero
548
        oril    #negz_mask,USER_FPSR(%a6)
549
        bra     end_unfr
550
ue_rp_pos:
551
        leal    EXT_PSML,%a1    //answer is positive smallest denorm
552
        bra     end_unfr
553
//
554
//case DEST_FMT = DBL
555
//
556
uDBL_RN:
557
        leal    DBL_PZRO,%a1    //answer is +/- zero
558
        bsetb   #z_bit,FPSR_CC(%a6)
559
        bra     uset_sign
560
uDBL_RZ:
561
        leal    DBL_PZRO,%a1    //answer is +/- zero
562
        bsetb   #z_bit,FPSR_CC(%a6)
563
        bra     uset_sign       //now go set the sign
564
uDBL_RM:
565
        tstb    LOCAL_SGN(%a0)  //if negative overflow
566
        beqs    ud_rm_pos
567
ud_rm_neg:
568
        leal    DBL_PSML,%a1    //answer is smallest denormalized negative
569
        bsetb   #neg_bit,FPSR_CC(%a6)
570
        bra     end_unfr
571
ud_rm_pos:
572
        leal    DBL_PZRO,%a1    //answer is positive zero
573
        bsetb   #z_bit,FPSR_CC(%a6)
574
        bra     end_unfr
575
uDBL_RP:
576
        tstb    LOCAL_SGN(%a0)  //if negative overflow
577
        beqs    ud_rp_pos
578
ud_rp_neg:
579
        leal    DBL_PZRO,%a1    //answer is negative zero
580
        oril    #negz_mask,USER_FPSR(%a6)
581
        bra     end_unfr
582
ud_rp_pos:
583
        leal    DBL_PSML,%a1    //answer is smallest denormalized negative
584
        bra     end_unfr
585
//
586
//case DEST_FMT = SGL
587
//
588
uSGL_RN:
589
        leal    SGL_PZRO,%a1    //answer is +/- zero
590
        bsetb   #z_bit,FPSR_CC(%a6)
591
        bras    uset_sign
592
uSGL_RZ:
593
        leal    SGL_PZRO,%a1    //answer is +/- zero
594
        bsetb   #z_bit,FPSR_CC(%a6)
595
        bras    uset_sign
596
uSGL_RM:
597
        tstb    LOCAL_SGN(%a0)  //if negative overflow
598
        beqs    us_rm_pos
599
us_rm_neg:
600
        leal    SGL_PSML,%a1    //answer is smallest denormalized negative
601
        bsetb   #neg_bit,FPSR_CC(%a6)
602
        bras    end_unfr
603
us_rm_pos:
604
        leal    SGL_PZRO,%a1    //answer is positive zero
605
        bsetb   #z_bit,FPSR_CC(%a6)
606
        bras    end_unfr
607
uSGL_RP:
608
        tstb    LOCAL_SGN(%a0)  //if negative overflow
609
        beqs    us_rp_pos
610
us_rp_neg:
611
        leal    SGL_PZRO,%a1    //answer is negative zero
612
        oril    #negz_mask,USER_FPSR(%a6)
613
        bras    end_unfr
614
us_rp_pos:
615
        leal    SGL_PSML,%a1    //answer is smallest denormalized positive
616
        bras    end_unfr
617
 
618
uset_sign:
619
        tstb    LOCAL_SGN(%a0)  //if negative overflow
620
        beqs    end_unfr
621
uneg_sign:
622
        bsetb   #neg_bit,FPSR_CC(%a6)
623
 
624
end_unfr:
625
        movew   LOCAL_EX(%a1),LOCAL_EX(%a0) //be careful not to overwrite sign
626
        movel   LOCAL_HI(%a1),LOCAL_HI(%a0)
627
        movel   LOCAL_LO(%a1),LOCAL_LO(%a0)
628
        rts
629
//
630
//      reg_dest --- write byte, word, or long data to Dn
631
//
632
//
633
// Input:
634
//      L_SCR1: Data
635
//      d1:     data size and dest register number formatted as:
636
//
637
//      32              5    4     3     2     1     0
638
//       -----------------------------------------------
639
//       |        0        |    Size   |  Dest Reg #   |
640
//       -----------------------------------------------
641
//
642
//      Size is:
643
//              0 - Byte
644
//              1 - Word
645
//              2 - Long/Single
646
//
647
pregdst:
648
        .long   byte_d0
649
        .long   byte_d1
650
        .long   byte_d2
651
        .long   byte_d3
652
        .long   byte_d4
653
        .long   byte_d5
654
        .long   byte_d6
655
        .long   byte_d7
656
        .long   word_d0
657
        .long   word_d1
658
        .long   word_d2
659
        .long   word_d3
660
        .long   word_d4
661
        .long   word_d5
662
        .long   word_d6
663
        .long   word_d7
664
        .long   long_d0
665
        .long   long_d1
666
        .long   long_d2
667
        .long   long_d3
668
        .long   long_d4
669
        .long   long_d5
670
        .long   long_d6
671
        .long   long_d7
672
 
673
reg_dest:
674
        leal    pregdst,%a0
675
        movel   %a0@(%d1:l:4),%a0
676
        jmp     (%a0)
677
 
678
byte_d0:
679
        moveb   L_SCR1(%a6),USER_D0+3(%a6)
680
        rts
681
byte_d1:
682
        moveb   L_SCR1(%a6),USER_D1+3(%a6)
683
        rts
684
byte_d2:
685
        moveb   L_SCR1(%a6),%d2
686
        rts
687
byte_d3:
688
        moveb   L_SCR1(%a6),%d3
689
        rts
690
byte_d4:
691
        moveb   L_SCR1(%a6),%d4
692
        rts
693
byte_d5:
694
        moveb   L_SCR1(%a6),%d5
695
        rts
696
byte_d6:
697
        moveb   L_SCR1(%a6),%d6
698
        rts
699
byte_d7:
700
        moveb   L_SCR1(%a6),%d7
701
        rts
702
word_d0:
703
        movew   L_SCR1(%a6),USER_D0+2(%a6)
704
        rts
705
word_d1:
706
        movew   L_SCR1(%a6),USER_D1+2(%a6)
707
        rts
708
word_d2:
709
        movew   L_SCR1(%a6),%d2
710
        rts
711
word_d3:
712
        movew   L_SCR1(%a6),%d3
713
        rts
714
word_d4:
715
        movew   L_SCR1(%a6),%d4
716
        rts
717
word_d5:
718
        movew   L_SCR1(%a6),%d5
719
        rts
720
word_d6:
721
        movew   L_SCR1(%a6),%d6
722
        rts
723
word_d7:
724
        movew   L_SCR1(%a6),%d7
725
        rts
726
long_d0:
727
        movel   L_SCR1(%a6),USER_D0(%a6)
728
        rts
729
long_d1:
730
        movel   L_SCR1(%a6),USER_D1(%a6)
731
        rts
732
long_d2:
733
        movel   L_SCR1(%a6),%d2
734
        rts
735
long_d3:
736
        movel   L_SCR1(%a6),%d3
737
        rts
738
long_d4:
739
        movel   L_SCR1(%a6),%d4
740
        rts
741
long_d5:
742
        movel   L_SCR1(%a6),%d5
743
        rts
744
long_d6:
745
        movel   L_SCR1(%a6),%d6
746
        rts
747
long_d7:
748
        movel   L_SCR1(%a6),%d7
749
        rts
750
        |end

powered by: WebSVN 2.1.0

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