source: rtems/c/src/lib/libcpu/m68k/m68040/fpsp/gen_except.S @ 9b4422a2

4.115
Last change on this file since 9b4422a2 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on 05/03/12 at 15:09:24

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 13.2 KB
Line 
1//
2//
3//      gen_except.sa 3.7 1/16/92
4//
5//      gen_except --- FPSP routine to detect reportable exceptions
6//
7//      This routine compares the exception enable byte of the
8//      user_fpcr on the stack with the exception status byte
9//      of the user_fpsr.
10//
11//      Any routine which may report an exceptions must load
12//      the stack frame in memory with the exceptional operand(s).
13//
14//      Priority for exceptions is:
15//
16//      Highest:        bsun
17//                      snan
18//                      operr
19//                      ovfl
20//                      unfl
21//                      dz
22//                      inex2
23//      Lowest:         inex1
24//
25//      Note: The IEEE standard specifies that inex2 is to be
26//      reported if ovfl occurs and the ovfl enable bit is not
27//      set but the inex2 enable bit is.
28//
29//
30//              Copyright (C) Motorola, Inc. 1990
31//                      All Rights Reserved
32//
33//      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
34//      The copyright notice above does not evidence any
35//      actual or intended publication of such source code.
36
37GEN_EXCEPT:    //idnt    2,1 | Motorola 040 Floating Point Software Package
38
39        |section 8
40
41#include "fpsp.defs"
42
43        |xref   real_trace
44        |xref   fpsp_done
45        |xref   fpsp_fmt_error
46
47exc_tbl:
48        .long   bsun_exc
49        .long   commonE1
50        .long   commonE1
51        .long   ovfl_unfl
52        .long   ovfl_unfl
53        .long   commonE1
54        .long   commonE3
55        .long   commonE3
56        .long   no_match
57
58        .global gen_except
59gen_except:
60        cmpib   #IDLE_SIZE-4,1(%a7)     //test for idle frame
61        beq     do_check                //go handle idle frame
62        cmpib   #UNIMP_40_SIZE-4,1(%a7) //test for orig unimp frame
63        beqs    unimp_x                 //go handle unimp frame
64        cmpib   #UNIMP_41_SIZE-4,1(%a7) //test for rev unimp frame
65        beqs    unimp_x                 //go handle unimp frame
66        cmpib   #BUSY_SIZE-4,1(%a7)     //if size <> $60, fmt error
67        bnel    fpsp_fmt_error
68        leal    BUSY_SIZE+LOCAL_SIZE(%a7),%a1 //init a1 so fpsp.h
69//                                      ;equates will work
70// Fix up the new busy frame with entries from the unimp frame
71//
72        movel   ETEMP_EX(%a6),ETEMP_EX(%a1) //copy etemp from unimp
73        movel   ETEMP_HI(%a6),ETEMP_HI(%a1) //frame to busy frame
74        movel   ETEMP_LO(%a6),ETEMP_LO(%a1)
75        movel   CMDREG1B(%a6),CMDREG1B(%a1) //set inst in frame to unimp
76        movel   CMDREG1B(%a6),%d0               //fix cmd1b to make it
77        andl    #0x03c30000,%d0         //work for cmd3b
78        bfextu  CMDREG1B(%a6){#13:#1},%d1       //extract bit 2
79        lsll    #5,%d1
80        swap    %d1
81        orl     %d1,%d0                 //put it in the right place
82        bfextu  CMDREG1B(%a6){#10:#3},%d1       //extract bit 3,4,5
83        lsll    #2,%d1
84        swap    %d1
85        orl     %d1,%d0                 //put them in the right place
86        movel   %d0,CMDREG3B(%a1)               //in the busy frame
87//
88// Or in the FPSR from the emulation with the USER_FPSR on the stack.
89//
90        fmovel  %FPSR,%d0
91        orl     %d0,USER_FPSR(%a6)
92        movel   USER_FPSR(%a6),FPSR_SHADOW(%a1) //set exc bits
93        orl     #sx_mask,E_BYTE(%a1)
94        bra     do_clean
95
96//
97// Frame is an unimp frame possible resulting from an fmove <ea>,fp0
98// that caused an exception
99//
100// a1 is modified to point into the new frame allowing fpsp equates
101// to be valid.
102//
103unimp_x:
104        cmpib   #UNIMP_40_SIZE-4,1(%a7) //test for orig unimp frame
105        bnes    test_rev
106        leal    UNIMP_40_SIZE+LOCAL_SIZE(%a7),%a1
107        bras    unimp_con
108test_rev:
109        cmpib   #UNIMP_41_SIZE-4,1(%a7) //test for rev unimp frame
110        bnel    fpsp_fmt_error          //if not $28 or $30
111        leal    UNIMP_41_SIZE+LOCAL_SIZE(%a7),%a1
112
113unimp_con:
114//
115// Fix up the new unimp frame with entries from the old unimp frame
116//
117        movel   CMDREG1B(%a6),CMDREG1B(%a1) //set inst in frame to unimp
118//
119// Or in the FPSR from the emulation with the USER_FPSR on the stack.
120//
121        fmovel  %FPSR,%d0
122        orl     %d0,USER_FPSR(%a6)
123        bra     do_clean
124
125//
126// Frame is idle, so check for exceptions reported through
127// USER_FPSR and set the unimp frame accordingly.
128// A7 must be incremented to the point before the
129// idle fsave vector to the unimp vector.
130//
131
132do_check:
133        addl    #4,%a7                  //point A7 back to unimp frame
134//
135// Or in the FPSR from the emulation with the USER_FPSR on the stack.
136//
137        fmovel  %FPSR,%d0
138        orl     %d0,USER_FPSR(%a6)
139//
140// On a busy frame, we must clear the nmnexc bits.
141//
142        cmpib   #BUSY_SIZE-4,1(%a7)     //check frame type
143        bnes    check_fr                //if busy, clr nmnexc
144        clrw    NMNEXC(%a6)             //clr nmnexc & nmcexc
145        btstb   #5,CMDREG1B(%a6)                //test for fmove out
146        bnes    frame_com
147        movel   USER_FPSR(%a6),FPSR_SHADOW(%a6) //set exc bits
148        orl     #sx_mask,E_BYTE(%a6)
149        bras    frame_com
150check_fr:
151        cmpb    #UNIMP_40_SIZE-4,1(%a7)
152        beqs    frame_com
153        clrw    NMNEXC(%a6)
154frame_com:
155        moveb   FPCR_ENABLE(%a6),%d0    //get fpcr enable byte
156        andb    FPSR_EXCEPT(%a6),%d0    //and in the fpsr exc byte
157        bfffo   %d0{#24:#8},%d1         //test for first set bit
158        leal    exc_tbl,%a0             //load jmp table address
159        subib   #24,%d1                 //normalize bit offset to 0-8
160        movel   (%a0,%d1.w*4),%a0               //load routine address based
161//                                      ;based on first enabled exc
162        jmp     (%a0)                   //jump to routine
163//
164// Bsun is not possible in unimp or unsupp
165//
166bsun_exc:
167        bra     do_clean
168//
169// The typical work to be done to the unimp frame to report an
170// exception is to set the E1/E3 byte and clr the U flag.
171// commonE1 does this for E1 exceptions, which are snan,
172// operr, and dz.  commonE3 does this for E3 exceptions, which
173// are inex2 and inex1, and also clears the E1 exception bit
174// left over from the unimp exception.
175//
176commonE1:
177        bsetb   #E1,E_BYTE(%a6)         //set E1 flag
178        bra     commonE                 //go clean and exit
179
180commonE3:
181        tstb    UFLG_TMP(%a6)           //test flag for unsup/unimp state
182        bnes    unsE3
183uniE3:
184        bsetb   #E3,E_BYTE(%a6)         //set E3 flag
185        bclrb   #E1,E_BYTE(%a6)         //clr E1 from unimp
186        bra     commonE
187
188unsE3:
189        tstb    RES_FLG(%a6)
190        bnes    unsE3_0
191unsE3_1:
192        bsetb   #E3,E_BYTE(%a6)         //set E3 flag
193unsE3_0:
194        bclrb   #E1,E_BYTE(%a6)         //clr E1 flag
195        movel   CMDREG1B(%a6),%d0
196        andl    #0x03c30000,%d0         //work for cmd3b
197        bfextu  CMDREG1B(%a6){#13:#1},%d1       //extract bit 2
198        lsll    #5,%d1
199        swap    %d1
200        orl     %d1,%d0                 //put it in the right place
201        bfextu  CMDREG1B(%a6){#10:#3},%d1       //extract bit 3,4,5
202        lsll    #2,%d1
203        swap    %d1
204        orl     %d1,%d0                 //put them in the right place
205        movel   %d0,CMDREG3B(%a6)               //in the busy frame
206
207commonE:
208        bclrb   #UFLAG,T_BYTE(%a6)      //clr U flag from unimp
209        bra     do_clean                //go clean and exit
210//
211// No bits in the enable byte match existing exceptions.  Check for
212// the case of the ovfl exc without the ovfl enabled, but with
213// inex2 enabled.
214//
215no_match:
216        btstb   #inex2_bit,FPCR_ENABLE(%a6) //check for ovfl/inex2 case
217        beqs    no_exc                  //if clear, exit
218        btstb   #ovfl_bit,FPSR_EXCEPT(%a6) //now check ovfl
219        beqs    no_exc                  //if clear, exit
220        bras    ovfl_unfl               //go to unfl_ovfl to determine if
221//                                      ;it is an unsupp or unimp exc
222
223// No exceptions are to be reported.  If the instruction was
224// unimplemented, no FPU restore is necessary.  If it was
225// unsupported, we must perform the restore.
226no_exc:
227        tstb    UFLG_TMP(%a6)   //test flag for unsupp/unimp state
228        beqs    uni_no_exc
229uns_no_exc:
230        tstb    RES_FLG(%a6)    //check if frestore is needed
231        bne     do_clean        //if clear, no frestore needed
232uni_no_exc:
233        moveml  USER_DA(%a6),%d0-%d1/%a0-%a1
234        fmovemx USER_FP0(%a6),%fp0-%fp3
235        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
236        unlk    %a6
237        bra     finish_up
238//
239// Unsupported Data Type Handler:
240// Ovfl:
241//   An fmoveout that results in an overflow is reported this way.
242// Unfl:
243//   An fmoveout that results in an underflow is reported this way.
244//
245// Unimplemented Instruction Handler:
246// Ovfl:
247//   Only scosh, setox, ssinh, stwotox, and scale can set overflow in
248//   this manner.
249// Unfl:
250//   Stwotox, setox, and scale can set underflow in this manner.
251//   Any of the other Library Routines such that f(x)=x in which
252//   x is an extended denorm can report an underflow exception.
253//   It is the responsibility of the exception-causing exception
254//   to make sure that WBTEMP is correct.
255//
256//   The exceptional operand is in FP_SCR1.
257//
258ovfl_unfl:
259        tstb    UFLG_TMP(%a6)   //test flag for unsupp/unimp state
260        beqs    ofuf_con
261//
262// The caller was from an unsupported data type trap.  Test if the
263// caller set CU_ONLY.  If so, the exceptional operand is expected in
264// FPTEMP, rather than WBTEMP.
265//
266        tstb    CU_ONLY(%a6)            //test if inst is cu-only
267        beq     unsE3
268//      move.w  #$fe,CU_SAVEPC(%a6)
269        clrb    CU_SAVEPC(%a6)
270        bsetb   #E1,E_BYTE(%a6)         //set E1 exception flag
271        movew   ETEMP_EX(%a6),FPTEMP_EX(%a6)
272        movel   ETEMP_HI(%a6),FPTEMP_HI(%a6)
273        movel   ETEMP_LO(%a6),FPTEMP_LO(%a6)
274        bsetb   #fptemp15_bit,DTAG(%a6) //set fpte15
275        bclrb   #UFLAG,T_BYTE(%a6)      //clr U flag from unimp
276        bra     do_clean                //go clean and exit
277
278ofuf_con:
279        moveb   (%a7),VER_TMP(%a6)      //save version number
280        cmpib   #BUSY_SIZE-4,1(%a7)     //check for busy frame
281        beqs    busy_fr                 //if unimp, grow to busy
282        cmpib   #VER_40,(%a7)           //test for orig unimp frame
283        bnes    try_41                  //if not, test for rev frame
284        moveql  #13,%d0                 //need to zero 14 lwords
285        bras    ofuf_fin
286try_41:
287        cmpib   #VER_41,(%a7)           //test for rev unimp frame
288        bnel    fpsp_fmt_error          //if neither, exit with error
289        moveql  #11,%d0                 //need to zero 12 lwords
290
291ofuf_fin:
292        clrl    (%a7)
293loop1:
294        clrl    -(%a7)                  //clear and dec a7
295        dbra    %d0,loop1
296        moveb   VER_TMP(%a6),(%a7)
297        moveb   #BUSY_SIZE-4,1(%a7)             //write busy fmt word.
298busy_fr:
299        movel   FP_SCR1(%a6),WBTEMP_EX(%a6)     //write
300        movel   FP_SCR1+4(%a6),WBTEMP_HI(%a6)   //exceptional op to
301        movel   FP_SCR1+8(%a6),WBTEMP_LO(%a6)   //wbtemp
302        bsetb   #E3,E_BYTE(%a6)                 //set E3 flag
303        bclrb   #E1,E_BYTE(%a6)                 //make sure E1 is clear
304        bclrb   #UFLAG,T_BYTE(%a6)              //clr U flag
305        movel   USER_FPSR(%a6),FPSR_SHADOW(%a6)
306        orl     #sx_mask,E_BYTE(%a6)
307        movel   CMDREG1B(%a6),%d0               //fix cmd1b to make it
308        andl    #0x03c30000,%d0         //work for cmd3b
309        bfextu  CMDREG1B(%a6){#13:#1},%d1       //extract bit 2
310        lsll    #5,%d1
311        swap    %d1
312        orl     %d1,%d0                 //put it in the right place
313        bfextu  CMDREG1B(%a6){#10:#3},%d1       //extract bit 3,4,5
314        lsll    #2,%d1
315        swap    %d1
316        orl     %d1,%d0                 //put them in the right place
317        movel   %d0,CMDREG3B(%a6)               //in the busy frame
318
319//
320// Check if the frame to be restored is busy or unimp.
321//** NOTE *** Bug fix for errata (0d43b #3)
322// If the frame is unimp, we must create a busy frame to
323// fix the bug with the nmnexc bits in cases in which they
324// are set by a previous instruction and not cleared by
325// the save. The frame will be unimp only if the final
326// instruction in an emulation routine caused the exception
327// by doing an fmove <ea>,fp0.  The exception operand, in
328// internal format, is in fptemp.
329//
330do_clean:
331        cmpib   #UNIMP_40_SIZE-4,1(%a7)
332        bnes    do_con
333        moveql  #13,%d0                 //in orig, need to zero 14 lwords
334        bras    do_build
335do_con:
336        cmpib   #UNIMP_41_SIZE-4,1(%a7)
337        bnes    do_restore              //frame must be busy
338        moveql  #11,%d0                 //in rev, need to zero 12 lwords
339
340do_build:
341        moveb   (%a7),VER_TMP(%a6)
342        clrl    (%a7)
343loop2:
344        clrl    -(%a7)                  //clear and dec a7
345        dbra    %d0,loop2
346//
347// Use a1 as pointer into new frame.  a6 is not correct if an unimp or
348// busy frame was created as the result of an exception on the final
349// instruction of an emulation routine.
350//
351// We need to set the nmcexc bits if the exception is E1. Otherwise,
352// the exc taken will be inex2.
353//
354        leal    BUSY_SIZE+LOCAL_SIZE(%a7),%a1   //init a1 for new frame
355        moveb   VER_TMP(%a6),(%a7)      //write busy fmt word
356        moveb   #BUSY_SIZE-4,1(%a7)
357        movel   FP_SCR1(%a6),WBTEMP_EX(%a1)     //write
358        movel   FP_SCR1+4(%a6),WBTEMP_HI(%a1)   //exceptional op to
359        movel   FP_SCR1+8(%a6),WBTEMP_LO(%a1)   //wbtemp
360//      btst.b  #E1,E_BYTE(%a1)
361//      beq.b   do_restore
362        bfextu  USER_FPSR(%a6){#17:#4},%d0      //get snan/operr/ovfl/unfl bits
363        bfins   %d0,NMCEXC(%a1){#4:#4}  //and insert them in nmcexc
364        movel   USER_FPSR(%a6),FPSR_SHADOW(%a1) //set exc bits
365        orl     #sx_mask,E_BYTE(%a1)
366
367do_restore:
368        moveml  USER_DA(%a6),%d0-%d1/%a0-%a1
369        fmovemx USER_FP0(%a6),%fp0-%fp3
370        fmoveml USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
371        frestore (%a7)+
372        tstb    RES_FLG(%a6)    //RES_FLG indicates a "continuation" frame
373        beq     cont
374        bsr     bug1384
375cont:
376        unlk    %a6
377//
378// If trace mode enabled, then go to trace handler.  This handler
379// cannot have any fp instructions.  If there are fp inst's and an
380// exception has been restored into the machine then the exception
381// will occur upon execution of the fp inst.  This is not desirable
382// in the kernel (supervisor mode).  See MC68040 manual Section 9.3.8.
383//
384finish_up:
385        btstb   #7,(%a7)                //test T1 in SR
386        bnes    g_trace
387        btstb   #6,(%a7)                //test T0 in SR
388        bnes    g_trace
389        bral    fpsp_done
390//
391// Change integer stack to look like trace stack
392// The address of the instruction that caused the
393// exception is already in the integer stack (is
394// the same as the saved friar)
395//
396// If the current frame is already a 6-word stack then all
397// that needs to be done is to change the vector# to TRACE.
398// If the frame is only a 4-word stack (meaning we got here
399// on an Unsupported data type exception), then we need to grow
400// the stack an extra 2 words and get the FPIAR from the FPU.
401//
402g_trace:
403        bftst   EXC_VEC-4(%sp){#0:#4}
404        bne     g_easy
405
406        subw    #4,%sp          // make room
407        movel   4(%sp),(%sp)
408        movel   8(%sp),4(%sp)
409        subw    #BUSY_SIZE,%sp
410        fsave   (%sp)
411        fmovel  %fpiar,BUSY_SIZE+EXC_EA-4(%sp)
412        frestore (%sp)
413        addw    #BUSY_SIZE,%sp
414
415g_easy:
416        movew   #TRACE_VEC,EXC_VEC-4(%a7)
417        bral    real_trace
418//
419//  This is a work-around for hardware bug 1384.
420//
421bug1384:
422        link    %a5,#0
423        fsave   -(%sp)
424        cmpib   #0x41,(%sp)     // check for correct frame
425        beq     frame_41
426        bgt     nofix           // if more advanced mask, do nada
427
428frame_40:
429        tstb    1(%sp)          // check to see if idle
430        bne     notidle
431idle40:
432        clrl    (%sp)           // get rid of old fsave frame
433        movel  %d1,USER_D1(%a6)  // save d1
434        movew   #8,%d1          // place unimp frame instead
435loop40: clrl    -(%sp)
436        dbra    %d1,loop40
437        movel  USER_D1(%a6),%d1  // restore d1
438        movel   #0x40280000,-(%sp)
439        frestore (%sp)+
440        unlk    %a5
441        rts
442
443frame_41:
444        tstb    1(%sp)          // check to see if idle
445        bne     notidle
446idle41:
447        clrl    (%sp)           // get rid of old fsave frame
448        movel  %d1,USER_D1(%a6)  // save d1
449        movew   #10,%d1         // place unimp frame instead
450loop41: clrl    -(%sp)
451        dbra    %d1,loop41
452        movel  USER_D1(%a6),%d1  // restore d1
453        movel   #0x41300000,-(%sp)
454        frestore (%sp)+
455        unlk    %a5
456        rts
457
458notidle:
459        bclrb   #etemp15_bit,-40(%a5)
460        frestore (%sp)+
461        unlk    %a5
462        rts
463
464nofix:
465        frestore (%sp)+
466        unlk    %a5
467        rts
468
469        |end
Note: See TracBrowser for help on using the repository browser.