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