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