source: rtems/c/src/lib/libcpu/m68k/m68040/fpsp/kernel_ex.S @ 5321250

4.104.114.84.95
Last change on this file since 5321250 was 0162910, checked in by Joel Sherrill <joel.sherrill@…>, on 12/14/98 at 23:15:38

Patch from Ralf Corsepius <corsepiu@…> to rename all
.s files to .S in conformance with GNU conventions. This is a
minor step along the way to supporting automake.

  • Property mode set to 100644
File size: 13.4 KB
Line 
1//
2//      $Id$
3//
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
21KERNEL_EX:    //idnt    2,1 | Motorola 040 Floating Point Software Package
22
23        |section    8
24
25#include "fpsp.defs"
26
27mns_inf:  .long 0xffff0000,0x00000000,0x00000000
28pls_inf:  .long 0x7fff0000,0x00000000,0x00000000
29nan:      .long 0x7fff0000,0xffffffff,0xffffffff
30huge:     .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//
69t_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
75t_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
85m_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
89p_inf:
90        fmovemx pls_inf,%fp0-%fp0               //load +inf
91set_fpsr:
92        orl     #dzinf_mask,USER_FPSR(%a6) //set I,DZ,ADZ
93        rts
94//
95//      dz enabled
96//
97dz_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
101dz_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//
118t_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
126op_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//
140t_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)
147unfl_signok:
148        leal    FP_SCR1(%a6),%a0
149        orl     #unfinx_mask,USER_FPSR(%a6)
150//                                      ;set UNFL, INEX2, AUNFL, AINEX
151unfl_con:
152        btstb   #unfl_bit,FPCR_ENABLE(%a6)
153        beqs    unfl_dis
154
155unfl_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
162unfl_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
177unfl_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//
188t_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
203t_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
210t_dbl:
211        movel   ETEMP_LO(%a6),%d0
212        andil   #0x7ff,%d0      //look at only lower 11 bits
213        beq     t_work
214t_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//
222t_ovfl:
223        orl     #ovfinx_mask,USER_FPSR(%a6)
224t_work:
225        btstb   #ovfl_bit,FPCR_ENABLE(%a6) //test FPCR for ovfl enabled
226        beqs    ovf_dis
227
228ovf_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//
244ovf_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
251ovf_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//
261t_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//
273t_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)
278no_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//
288dst_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
292dst_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
308no_snan:
309        rts     
310
311dst_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
320dst_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//
334src_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
338src_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
345src_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
355src_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//
366t_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//
374t_resdnrm:
375        orl     #unfl_mask,USER_FPSR(%a6)
376
377xdnrm_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//
387xdnrm_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
402xdnrm_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)
407xdep:   
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
413xdnrm_dis:
414        bfextu  FPCR_MODE(%a6){#0:#2},%d0       //get round precision
415        bnes    not_ext                 //if not round extended, store
416//                                      ;IEEE defaults
417is_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
425not_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)
433xdnrm_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
443t_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)
467ck_src_den:
468        btstb   #7,STAG(%a2)
469        beqs    end_avun
470src_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)
481den_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)
488end_avun:
489        frestore (%a7)+
490        unlk    %a2
491        rts
492idle_end:
493        addl    #4,%a7
494        unlk    %a2
495        rts
496        |end
Note: See TracBrowser for help on using the repository browser.