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