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