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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 158 chris
//
2 208 chris
//      $Id: kernel_ex.S,v 1.2 2001-09-27 12:01:22 chris Exp $
3 158 chris
//
4
//      kernel_ex.sa 3.3 12/19/90
5
//
6
// This file contains routines to force exception status in the
7
// fpu for exceptional cases detected or reported within the
8
// transcendental functions.  Typically, the t_xx routine will
9
// set the appropriate bits in the USER_FPSR word on the stack.
10
// The bits are tested in gen_except.sa to determine if an exceptional
11
// situation needs to be created on return from the FPSP.
12
//
13
 
14
//              Copyright (C) Motorola, Inc. 1990
15
//                      All Rights Reserved
16
//
17
//      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
18
//      The copyright notice above does not evidence any
19
//      actual or intended publication of such source code.
20
 
21
KERNEL_EX:    //idnt    2,1 | Motorola 040 Floating Point Software Package
22
 
23
        |section    8
24
 
25
#include "fpsp.defs"
26
 
27
mns_inf:  .long 0xffff0000,0x00000000,0x00000000
28
pls_inf:  .long 0x7fff0000,0x00000000,0x00000000
29
nan:      .long 0x7fff0000,0xffffffff,0xffffffff
30
huge:     .long 0x7ffe0000,0xffffffff,0xffffffff
31
 
32
        |xref     ovf_r_k
33
        |xref     unf_sub
34
        |xref     nrm_set
35
 
36
        .global           t_dz
37
        .global      t_dz2
38
        .global      t_operr
39
        .global      t_unfl
40
        .global      t_ovfl
41
        .global      t_ovfl2
42
        .global      t_inx2
43
        .global   t_frcinx
44
        .global   t_extdnrm
45
        .global   t_resdnrm
46
        .global   dst_nan
47
        .global   src_nan
48
//
49
//      DZ exception
50
//
51
//
52
//      if dz trap disabled
53
//              store properly signed inf (use sign of etemp) into fp0
54
//              set FPSR exception status dz bit, condition code
55
//              inf bit, and accrued dz bit
56
//              return
57
//              frestore the frame into the machine (done by unimp_hd)
58
//
59
//      else dz trap enabled
60
//              set exception status bit & accrued bits in FPSR
61
//              set flag to disable sto_res from corrupting fp register
62
//              return
63
//              frestore the frame into the machine (done by unimp_hd)
64
//
65
// t_dz2 is used by monadic functions such as flogn (from do_func).
66
// t_dz is used by monadic functions such as satanh (from the
67
// transcendental function).
68
//
69
t_dz2:
70
        bsetb   #neg_bit,FPSR_CC(%a6)   //set neg bit in FPSR
71
        fmovel  #0,%FPSR                        //clr status bits (Z set)
72
        btstb   #dz_bit,FPCR_ENABLE(%a6)        //test FPCR for dz exc enabled
73
        bnes    dz_ena_end
74
        bras    m_inf                   //flogx always returns -inf
75
t_dz:
76
        fmovel  #0,%FPSR                        //clr status bits (Z set)
77
        btstb   #dz_bit,FPCR_ENABLE(%a6)        //test FPCR for dz exc enabled
78
        bnes    dz_ena
79
//
80
//      dz disabled
81
//
82
        btstb   #sign_bit,ETEMP_EX(%a6) //check sign for neg or pos
83
        beqs    p_inf                   //branch if pos sign
84
 
85
m_inf:
86
        fmovemx mns_inf,%fp0-%fp0               //load -inf
87
        bsetb   #neg_bit,FPSR_CC(%a6)   //set neg bit in FPSR
88
        bras    set_fpsr
89
p_inf:
90
        fmovemx pls_inf,%fp0-%fp0               //load +inf
91
set_fpsr:
92
        orl     #dzinf_mask,USER_FPSR(%a6) //set I,DZ,ADZ
93
        rts
94
//
95
//      dz enabled
96
//
97
dz_ena:
98
        btstb   #sign_bit,ETEMP_EX(%a6) //check sign for neg or pos
99
        beqs    dz_ena_end
100
        bsetb   #neg_bit,FPSR_CC(%a6)   //set neg bit in FPSR
101
dz_ena_end:
102
        orl     #dzinf_mask,USER_FPSR(%a6) //set I,DZ,ADZ
103
        st      STORE_FLG(%a6)
104
        rts
105
//
106
//      OPERR exception
107
//
108
//      if (operr trap disabled)
109
//              set FPSR exception status operr bit, condition code
110
//              nan bit; Store default NAN into fp0
111
//              frestore the frame into the machine (done by unimp_hd)
112
//
113
//      else (operr trap enabled)
114
//              set FPSR exception status operr bit, accrued operr bit
115
//              set flag to disable sto_res from corrupting fp register
116
//              frestore the frame into the machine (done by unimp_hd)
117
//
118
t_operr:
119
        orl     #opnan_mask,USER_FPSR(%a6) //set NaN, OPERR, AIOP
120
 
121
        btstb   #operr_bit,FPCR_ENABLE(%a6) //test FPCR for operr enabled
122
        bnes    op_ena
123
 
124
        fmovemx nan,%fp0-%fp0           //load default nan
125
        rts
126
op_ena:
127
        st      STORE_FLG(%a6)          //do not corrupt destination
128
        rts
129
 
130
//
131
//      t_unfl --- UNFL exception
132
//
133
// This entry point is used by all routines requiring unfl, inex2,
134
// aunfl, and ainex to be set on exit.
135
//
136
// On entry, a0 points to the exceptional operand.  The final exceptional
137
// operand is built in FP_SCR1 and only the sign from the original operand
138
// is used.
139
//
140
t_unfl:
141
        clrl    FP_SCR1(%a6)            //set exceptional operand to zero
142
        clrl    FP_SCR1+4(%a6)
143
        clrl    FP_SCR1+8(%a6)
144
        tstb    (%a0)                   //extract sign from caller's exop
145
        bpls    unfl_signok
146
        bset    #sign_bit,FP_SCR1(%a6)
147
unfl_signok:
148
        leal    FP_SCR1(%a6),%a0
149
        orl     #unfinx_mask,USER_FPSR(%a6)
150
//                                      ;set UNFL, INEX2, AUNFL, AINEX
151
unfl_con:
152
        btstb   #unfl_bit,FPCR_ENABLE(%a6)
153
        beqs    unfl_dis
154
 
155
unfl_ena:
156
        bfclr   STAG(%a6){#5:#3}                //clear wbtm66,wbtm1,wbtm0
157
        bsetb   #wbtemp15_bit,WB_BYTE(%a6) //set wbtemp15
158
        bsetb   #sticky_bit,STICKY(%a6) //set sticky bit
159
 
160
        bclrb   #E1,E_BYTE(%a6)
161
 
162
unfl_dis:
163
        bfextu  FPCR_MODE(%a6){#0:#2},%d0       //get round precision
164
 
165
        bclrb   #sign_bit,LOCAL_EX(%a0)
166
        sne     LOCAL_SGN(%a0)          //convert to internal ext format
167
 
168
        bsr     unf_sub                 //returns IEEE result at a0
169
//                                      ;and sets FPSR_CC accordingly
170
 
171
        bfclr   LOCAL_SGN(%a0){#0:#8}   //convert back to IEEE ext format
172
        beqs    unfl_fin
173
 
174
        bsetb   #sign_bit,LOCAL_EX(%a0)
175
        bsetb   #sign_bit,FP_SCR1(%a6)  //set sign bit of exc operand
176
 
177
unfl_fin:
178
        fmovemx (%a0),%fp0-%fp0         //store result in fp0
179
        rts
180
 
181
 
182
//
183
//      t_ovfl2 --- OVFL exception (without inex2 returned)
184
//
185
// This entry is used by scale to force catastrophic overflow.  The
186
// ovfl, aovfl, and ainex bits are set, but not the inex2 bit.
187
//
188
t_ovfl2:
189
        orl     #ovfl_inx_mask,USER_FPSR(%a6)
190
        movel   ETEMP(%a6),FP_SCR1(%a6)
191
        movel   ETEMP_HI(%a6),FP_SCR1+4(%a6)
192
        movel   ETEMP_LO(%a6),FP_SCR1+8(%a6)
193
//
194
// Check for single or double round precision.  If single, check if
195
// the lower 40 bits of ETEMP are zero; if not, set inex2.  If double,
196
// check if the lower 21 bits are zero; if not, set inex2.
197
//
198
        moveb   FPCR_MODE(%a6),%d0
199
        andib   #0xc0,%d0
200
        beq     t_work          //if extended, finish ovfl processing
201
        cmpib   #0x40,%d0               //test for single
202
        bnes    t_dbl
203
t_sgl:
204
        tstb    ETEMP_LO(%a6)
205
        bnes    t_setinx2
206
        movel   ETEMP_HI(%a6),%d0
207
        andil   #0xff,%d0               //look at only lower 8 bits
208
        bnes    t_setinx2
209
        bra     t_work
210
t_dbl:
211
        movel   ETEMP_LO(%a6),%d0
212
        andil   #0x7ff,%d0      //look at only lower 11 bits
213
        beq     t_work
214
t_setinx2:
215
        orl     #inex2_mask,USER_FPSR(%a6)
216
        bras    t_work
217
//
218
//      t_ovfl --- OVFL exception
219
//
220
//** Note: the exc operand is returned in ETEMP.
221
//
222
t_ovfl:
223
        orl     #ovfinx_mask,USER_FPSR(%a6)
224
t_work:
225
        btstb   #ovfl_bit,FPCR_ENABLE(%a6) //test FPCR for ovfl enabled
226
        beqs    ovf_dis
227
 
228
ovf_ena:
229
        clrl    FP_SCR1(%a6)            //set exceptional operand
230
        clrl    FP_SCR1+4(%a6)
231
        clrl    FP_SCR1+8(%a6)
232
 
233
        bfclr   STAG(%a6){#5:#3}                //clear wbtm66,wbtm1,wbtm0
234
        bclrb   #wbtemp15_bit,WB_BYTE(%a6) //clear wbtemp15
235
        bsetb   #sticky_bit,STICKY(%a6) //set sticky bit
236
 
237
        bclrb   #E1,E_BYTE(%a6)
238
//                                      ;fall through to disabled case
239
 
240
// For disabled overflow call 'ovf_r_k'.  This routine loads the
241
// correct result based on the rounding precision, destination
242
// format, rounding mode and sign.
243
//
244
ovf_dis:
245
        bsr     ovf_r_k                 //returns unsigned ETEMP_EX
246
//                                      ;and sets FPSR_CC accordingly.
247
        bfclr   ETEMP_SGN(%a6){#0:#8}   //fix sign
248
        beqs    ovf_pos
249
        bsetb   #sign_bit,ETEMP_EX(%a6)
250
        bsetb   #sign_bit,FP_SCR1(%a6)  //set exceptional operand sign
251
ovf_pos:
252
        fmovemx ETEMP(%a6),%fp0-%fp0            //move the result to fp0
253
        rts
254
 
255
 
256
//
257
//      INEX2 exception
258
//
259
// The inex2 and ainex bits are set.
260
//
261
t_inx2:
262
        orl     #inx2a_mask,USER_FPSR(%a6) //set INEX2, AINEX
263
        rts
264
 
265
//
266
//      Force Inex2
267
//
268
// This routine is called by the transcendental routines to force
269
// the inex2 exception bits set in the FPSR.  If the underflow bit
270
// is set, but the underflow trap was not taken, the aunfl bit in
271
// the FPSR must be set.
272
//
273
t_frcinx:
274
        orl     #inx2a_mask,USER_FPSR(%a6) //set INEX2, AINEX
275
        btstb   #unfl_bit,FPSR_EXCEPT(%a6) //test for unfl bit set
276
        beqs    no_uacc1                //if clear, do not set aunfl
277
        bsetb   #aunfl_bit,FPSR_AEXCEPT(%a6)
278
no_uacc1:
279
        rts
280
 
281
//
282
//      DST_NAN
283
//
284
// Determine if the destination nan is signalling or non-signalling,
285
// and set the FPSR bits accordingly.  See the MC68040 User's Manual
286
// section 3.2.2.5 NOT-A-NUMBERS.
287
//
288
dst_nan:
289
        btstb   #sign_bit,FPTEMP_EX(%a6) //test sign of nan
290
        beqs    dst_pos                 //if clr, it was positive
291
        bsetb   #neg_bit,FPSR_CC(%a6)   //set N bit
292
dst_pos:
293
        btstb   #signan_bit,FPTEMP_HI(%a6) //check if signalling
294
        beqs    dst_snan                //branch if signalling
295
 
296
        fmovel  %d1,%fpcr                       //restore user's rmode/prec
297
        fmovex FPTEMP(%a6),%fp0         //return the non-signalling nan
298
//
299
// Check the source nan.  If it is signalling, snan will be reported.
300
//
301
        moveb   STAG(%a6),%d0
302
        andib   #0xe0,%d0
303
        cmpib   #0x60,%d0
304
        bnes    no_snan
305
        btstb   #signan_bit,ETEMP_HI(%a6) //check if signalling
306
        bnes    no_snan
307
        orl     #snaniop_mask,USER_FPSR(%a6) //set NAN, SNAN, AIOP
308
no_snan:
309
        rts
310
 
311
dst_snan:
312
        btstb   #snan_bit,FPCR_ENABLE(%a6) //check if trap enabled
313
        beqs    dst_dis                 //branch if disabled
314
 
315
        orb     #nan_tag,DTAG(%a6)      //set up dtag for nan
316
        st      STORE_FLG(%a6)          //do not store a result
317
        orl     #snaniop_mask,USER_FPSR(%a6) //set NAN, SNAN, AIOP
318
        rts
319
 
320
dst_dis:
321
        bsetb   #signan_bit,FPTEMP_HI(%a6) //set SNAN bit in sop
322
        fmovel  %d1,%fpcr                       //restore user's rmode/prec
323
        fmovex FPTEMP(%a6),%fp0         //load non-sign. nan
324
        orl     #snaniop_mask,USER_FPSR(%a6) //set NAN, SNAN, AIOP
325
        rts
326
 
327
//
328
//      SRC_NAN
329
//
330
// Determine if the source nan is signalling or non-signalling,
331
// and set the FPSR bits accordingly.  See the MC68040 User's Manual
332
// section 3.2.2.5 NOT-A-NUMBERS.
333
//
334
src_nan:
335
        btstb   #sign_bit,ETEMP_EX(%a6) //test sign of nan
336
        beqs    src_pos                 //if clr, it was positive
337
        bsetb   #neg_bit,FPSR_CC(%a6)   //set N bit
338
src_pos:
339
        btstb   #signan_bit,ETEMP_HI(%a6) //check if signalling
340
        beqs    src_snan                //branch if signalling
341
        fmovel  %d1,%fpcr                       //restore user's rmode/prec
342
        fmovex ETEMP(%a6),%fp0          //return the non-signalling nan
343
        rts
344
 
345
src_snan:
346
        btstb   #snan_bit,FPCR_ENABLE(%a6) //check if trap enabled
347
        beqs    src_dis                 //branch if disabled
348
        bsetb   #signan_bit,ETEMP_HI(%a6) //set SNAN bit in sop
349
        orb     #norm_tag,DTAG(%a6)     //set up dtag for norm
350
        orb     #nan_tag,STAG(%a6)      //set up stag for nan
351
        st      STORE_FLG(%a6)          //do not store a result
352
        orl     #snaniop_mask,USER_FPSR(%a6) //set NAN, SNAN, AIOP
353
        rts
354
 
355
src_dis:
356
        bsetb   #signan_bit,ETEMP_HI(%a6) //set SNAN bit in sop
357
        fmovel  %d1,%fpcr                       //restore user's rmode/prec
358
        fmovex ETEMP(%a6),%fp0          //load non-sign. nan
359
        orl     #snaniop_mask,USER_FPSR(%a6) //set NAN, SNAN, AIOP
360
        rts
361
 
362
//
363
// For all functions that have a denormalized input and that f(x)=x,
364
// this is the entry point
365
//
366
t_extdnrm:
367
        orl     #unfinx_mask,USER_FPSR(%a6)
368
//                                      ;set UNFL, INEX2, AUNFL, AINEX
369
        bras    xdnrm_con
370
//
371
// Entry point for scale with extended denorm.  The function does
372
// not set inex2, aunfl, or ainex.
373
//
374
t_resdnrm:
375
        orl     #unfl_mask,USER_FPSR(%a6)
376
 
377
xdnrm_con:
378
        btstb   #unfl_bit,FPCR_ENABLE(%a6)
379
        beqs    xdnrm_dis
380
 
381
//
382
// If exceptions are enabled, the additional task of setting up WBTEMP
383
// is needed so that when the underflow exception handler is entered,
384
// the user perceives no difference between what the 040 provides vs.
385
// what the FPSP provides.
386
//
387
xdnrm_ena:
388
        movel   %a0,-(%a7)
389
 
390
        movel   LOCAL_EX(%a0),FP_SCR1(%a6)
391
        movel   LOCAL_HI(%a0),FP_SCR1+4(%a6)
392
        movel   LOCAL_LO(%a0),FP_SCR1+8(%a6)
393
 
394
        lea     FP_SCR1(%a6),%a0
395
 
396
        bclrb   #sign_bit,LOCAL_EX(%a0)
397
        sne     LOCAL_SGN(%a0)          //convert to internal ext format
398
        tstw    LOCAL_EX(%a0)           //check if input is denorm
399
        beqs    xdnrm_dn                //if so, skip nrm_set
400
        bsr     nrm_set                 //normalize the result (exponent
401
//                                      ;will be negative
402
xdnrm_dn:
403
        bclrb   #sign_bit,LOCAL_EX(%a0) //take off false sign
404
        bfclr   LOCAL_SGN(%a0){#0:#8}   //change back to IEEE ext format
405
        beqs    xdep
406
        bsetb   #sign_bit,LOCAL_EX(%a0)
407
xdep:
408
        bfclr   STAG(%a6){#5:#3}                //clear wbtm66,wbtm1,wbtm0
409
        bsetb   #wbtemp15_bit,WB_BYTE(%a6) //set wbtemp15
410
        bclrb   #sticky_bit,STICKY(%a6) //clear sticky bit
411
        bclrb   #E1,E_BYTE(%a6)
412
        movel   (%a7)+,%a0
413
xdnrm_dis:
414
        bfextu  FPCR_MODE(%a6){#0:#2},%d0       //get round precision
415
        bnes    not_ext                 //if not round extended, store
416
//                                      ;IEEE defaults
417
is_ext:
418
        btstb   #sign_bit,LOCAL_EX(%a0)
419
        beqs    xdnrm_store
420
 
421
        bsetb   #neg_bit,FPSR_CC(%a6)   //set N bit in FPSR_CC
422
 
423
        bras    xdnrm_store
424
 
425
not_ext:
426
        bclrb   #sign_bit,LOCAL_EX(%a0)
427
        sne     LOCAL_SGN(%a0)          //convert to internal ext format
428
        bsr     unf_sub                 //returns IEEE result pointed by
429
//                                      ;a0; sets FPSR_CC accordingly
430
        bfclr   LOCAL_SGN(%a0){#0:#8}   //convert back to IEEE ext format
431
        beqs    xdnrm_store
432
        bsetb   #sign_bit,LOCAL_EX(%a0)
433
xdnrm_store:
434
        fmovemx (%a0),%fp0-%fp0         //store result in fp0
435
        rts
436
 
437
//
438
// This subroutine is used for dyadic operations that use an extended
439
// denorm within the kernel. The approach used is to capture the frame,
440
// fix/restore.
441
//
442
        .global t_avoid_unsupp
443
t_avoid_unsupp:
444
        link    %a2,#-LOCAL_SIZE                //so that a2 fpsp.h negative
445
//                                      ;offsets may be used
446
        fsave   -(%a7)
447
        tstb    1(%a7)                  //check if idle, exit if so
448
        beq     idle_end
449
        btstb   #E1,E_BYTE(%a2)         //check for an E1 exception if
450
//                                      ;enabled, there is an unsupp
451
        beq     end_avun                //else, exit
452
        btstb   #7,DTAG(%a2)            //check for denorm destination
453
        beqs    src_den                 //else, must be a source denorm
454
//
455
// handle destination denorm
456
//
457
        lea     FPTEMP(%a2),%a0
458
        btstb   #sign_bit,LOCAL_EX(%a0)
459
        sne     LOCAL_SGN(%a0)          //convert to internal ext format
460
        bclrb   #7,DTAG(%a2)            //set DTAG to norm
461
        bsr     nrm_set                 //normalize result, exponent
462
//                                      ;will become negative
463
        bclrb   #sign_bit,LOCAL_EX(%a0) //get rid of fake sign
464
        bfclr   LOCAL_SGN(%a0){#0:#8}   //convert back to IEEE ext format
465
        beqs    ck_src_den              //check if source is also denorm
466
        bsetb   #sign_bit,LOCAL_EX(%a0)
467
ck_src_den:
468
        btstb   #7,STAG(%a2)
469
        beqs    end_avun
470
src_den:
471
        lea     ETEMP(%a2),%a0
472
        btstb   #sign_bit,LOCAL_EX(%a0)
473
        sne     LOCAL_SGN(%a0)          //convert to internal ext format
474
        bclrb   #7,STAG(%a2)            //set STAG to norm
475
        bsr     nrm_set                 //normalize result, exponent
476
//                                      ;will become negative
477
        bclrb   #sign_bit,LOCAL_EX(%a0) //get rid of fake sign
478
        bfclr   LOCAL_SGN(%a0){#0:#8}   //convert back to IEEE ext format
479
        beqs    den_com
480
        bsetb   #sign_bit,LOCAL_EX(%a0)
481
den_com:
482
        moveb   #0xfe,CU_SAVEPC(%a2)    //set continue frame
483
        clrw    NMNEXC(%a2)             //clear NMNEXC
484
        bclrb   #E1,E_BYTE(%a2)
485
//      fmove.l %FPSR,FPSR_SHADOW(%a2)
486
//      bset.b  #SFLAG,E_BYTE(%a2)
487
//      bset.b  #XFLAG,T_BYTE(%a2)
488
end_avun:
489
        frestore (%a7)+
490
        unlk    %a2
491
        rts
492
idle_end:
493
        addl    #4,%a7
494
        unlk    %a2
495
        rts
496
        |end

powered by: WebSVN 2.1.0

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