1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GR 3 M68000 Hi-Performance Microprocessor Division 4 M68060 Software Package 5 Production Release P1.00 -- October 10, 1994 6 7 M68060 Software Package Copyright © 1993, 199 8 9 THE SOFTWARE is provided on an "AS IS" basis a 10 To the maximum extent permitted by applicable 11 MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPR 12 INCLUDING IMPLIED WARRANTIES OF MERCHANTABILIT 13 and any warranty against infringement with reg 14 (INCLUDING ANY MODIFIED VERSIONS THEREOF) and 15 16 To the maximum extent permitted by applicable 17 IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY D 18 (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOS 19 BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORM 20 ARISING OF THE USE OR INABILITY TO USE THE SOF 21 Motorola assumes no responsibility for the mai 22 23 You are hereby granted a copyright license to 24 so long as this entire notice is retained with 25 redistributed versions, and that such modified 26 No licenses are granted by implication, estopp 27 or trademarks of Motorola, Inc. 28 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 29 # freal.s: 30 # This file is appended to the top of th 31 # and contains the entry points into the packa 32 # effect, branches to one of the branch table 33 # after _060FPSP_TABLE. 34 # Also, subroutine stubs exist in this f 35 # example) that are referenced by the FPSP pac 36 # to call a given routine. The stub routine ac 37 # callout. The FPSP code does a "bsr" to the s 38 # extra layer of hierarchy adds a slight perfo 39 # it makes the FPSP code easier to read and mo 40 # 41 42 set _off_bsun, 0x00 43 set _off_snan, 0x04 44 set _off_operr, 0x08 45 set _off_ovfl, 0x0c 46 set _off_unfl, 0x10 47 set _off_dz, 0x14 48 set _off_inex, 0x18 49 set _off_fline, 0x1c 50 set _off_fpu_dis, 0x20 51 set _off_trap, 0x24 52 set _off_trace, 0x28 53 set _off_access, 0x2c 54 set _off_done, 0x30 55 56 set _off_imr, 0x40 57 set _off_dmr, 0x44 58 set _off_dmw, 0x48 59 set _off_irw, 0x4c 60 set _off_irl, 0x50 61 set _off_drb, 0x54 62 set _off_drw, 0x58 63 set _off_drl, 0x5c 64 set _off_dwb, 0x60 65 set _off_dww, 0x64 66 set _off_dwl, 0x68 67 68 _060FPSP_TABLE: 69 70 ############################################## 71 72 # Here's the table of ENTRY POINTS for those l 73 bra.l _fpsp_snan 74 short 0x0000 75 bra.l _fpsp_operr 76 short 0x0000 77 bra.l _fpsp_ovfl 78 short 0x0000 79 bra.l _fpsp_unfl 80 short 0x0000 81 bra.l _fpsp_dz 82 short 0x0000 83 bra.l _fpsp_inex 84 short 0x0000 85 bra.l _fpsp_fline 86 short 0x0000 87 bra.l _fpsp_unsupp 88 short 0x0000 89 bra.l _fpsp_effadd 90 short 0x0000 91 92 space 56 93 94 ############################################## 95 global _fpsp_done 96 _fpsp_done: 97 mov.l %d0,-(%sp) 98 mov.l (_060FPSP_TABLE-0x80+_ 99 pea.l (_060FPSP_TABLE-0x80,% 100 mov.l 0x4(%sp),%d0 101 rtd &0x4 102 103 global _real_ovfl 104 _real_ovfl: 105 mov.l %d0,-(%sp) 106 mov.l (_060FPSP_TABLE-0x80+_ 107 pea.l (_060FPSP_TABLE-0x80,% 108 mov.l 0x4(%sp),%d0 109 rtd &0x4 110 111 global _real_unfl 112 _real_unfl: 113 mov.l %d0,-(%sp) 114 mov.l (_060FPSP_TABLE-0x80+_ 115 pea.l (_060FPSP_TABLE-0x80,% 116 mov.l 0x4(%sp),%d0 117 rtd &0x4 118 119 global _real_inex 120 _real_inex: 121 mov.l %d0,-(%sp) 122 mov.l (_060FPSP_TABLE-0x80+_ 123 pea.l (_060FPSP_TABLE-0x80,% 124 mov.l 0x4(%sp),%d0 125 rtd &0x4 126 127 global _real_bsun 128 _real_bsun: 129 mov.l %d0,-(%sp) 130 mov.l (_060FPSP_TABLE-0x80+_ 131 pea.l (_060FPSP_TABLE-0x80,% 132 mov.l 0x4(%sp),%d0 133 rtd &0x4 134 135 global _real_operr 136 _real_operr: 137 mov.l %d0,-(%sp) 138 mov.l (_060FPSP_TABLE-0x80+_ 139 pea.l (_060FPSP_TABLE-0x80,% 140 mov.l 0x4(%sp),%d0 141 rtd &0x4 142 143 global _real_snan 144 _real_snan: 145 mov.l %d0,-(%sp) 146 mov.l (_060FPSP_TABLE-0x80+_ 147 pea.l (_060FPSP_TABLE-0x80,% 148 mov.l 0x4(%sp),%d0 149 rtd &0x4 150 151 global _real_dz 152 _real_dz: 153 mov.l %d0,-(%sp) 154 mov.l (_060FPSP_TABLE-0x80+_ 155 pea.l (_060FPSP_TABLE-0x80,% 156 mov.l 0x4(%sp),%d0 157 rtd &0x4 158 159 global _real_fline 160 _real_fline: 161 mov.l %d0,-(%sp) 162 mov.l (_060FPSP_TABLE-0x80+_ 163 pea.l (_060FPSP_TABLE-0x80,% 164 mov.l 0x4(%sp),%d0 165 rtd &0x4 166 167 global _real_fpu_disabled 168 _real_fpu_disabled: 169 mov.l %d0,-(%sp) 170 mov.l (_060FPSP_TABLE-0x80+_ 171 pea.l (_060FPSP_TABLE-0x80,% 172 mov.l 0x4(%sp),%d0 173 rtd &0x4 174 175 global _real_trap 176 _real_trap: 177 mov.l %d0,-(%sp) 178 mov.l (_060FPSP_TABLE-0x80+_ 179 pea.l (_060FPSP_TABLE-0x80,% 180 mov.l 0x4(%sp),%d0 181 rtd &0x4 182 183 global _real_trace 184 _real_trace: 185 mov.l %d0,-(%sp) 186 mov.l (_060FPSP_TABLE-0x80+_ 187 pea.l (_060FPSP_TABLE-0x80,% 188 mov.l 0x4(%sp),%d0 189 rtd &0x4 190 191 global _real_access 192 _real_access: 193 mov.l %d0,-(%sp) 194 mov.l (_060FPSP_TABLE-0x80+_ 195 pea.l (_060FPSP_TABLE-0x80,% 196 mov.l 0x4(%sp),%d0 197 rtd &0x4 198 199 ####################################### 200 201 global _imem_read 202 _imem_read: 203 mov.l %d0,-(%sp) 204 mov.l (_060FPSP_TABLE-0x80+_ 205 pea.l (_060FPSP_TABLE-0x80,% 206 mov.l 0x4(%sp),%d0 207 rtd &0x4 208 209 global _dmem_read 210 _dmem_read: 211 mov.l %d0,-(%sp) 212 mov.l (_060FPSP_TABLE-0x80+_ 213 pea.l (_060FPSP_TABLE-0x80,% 214 mov.l 0x4(%sp),%d0 215 rtd &0x4 216 217 global _dmem_write 218 _dmem_write: 219 mov.l %d0,-(%sp) 220 mov.l (_060FPSP_TABLE-0x80+_ 221 pea.l (_060FPSP_TABLE-0x80,% 222 mov.l 0x4(%sp),%d0 223 rtd &0x4 224 225 global _imem_read_word 226 _imem_read_word: 227 mov.l %d0,-(%sp) 228 mov.l (_060FPSP_TABLE-0x80+_ 229 pea.l (_060FPSP_TABLE-0x80,% 230 mov.l 0x4(%sp),%d0 231 rtd &0x4 232 233 global _imem_read_long 234 _imem_read_long: 235 mov.l %d0,-(%sp) 236 mov.l (_060FPSP_TABLE-0x80+_ 237 pea.l (_060FPSP_TABLE-0x80,% 238 mov.l 0x4(%sp),%d0 239 rtd &0x4 240 241 global _dmem_read_byte 242 _dmem_read_byte: 243 mov.l %d0,-(%sp) 244 mov.l (_060FPSP_TABLE-0x80+_ 245 pea.l (_060FPSP_TABLE-0x80,% 246 mov.l 0x4(%sp),%d0 247 rtd &0x4 248 249 global _dmem_read_word 250 _dmem_read_word: 251 mov.l %d0,-(%sp) 252 mov.l (_060FPSP_TABLE-0x80+_ 253 pea.l (_060FPSP_TABLE-0x80,% 254 mov.l 0x4(%sp),%d0 255 rtd &0x4 256 257 global _dmem_read_long 258 _dmem_read_long: 259 mov.l %d0,-(%sp) 260 mov.l (_060FPSP_TABLE-0x80+_ 261 pea.l (_060FPSP_TABLE-0x80,% 262 mov.l 0x4(%sp),%d0 263 rtd &0x4 264 265 global _dmem_write_byte 266 _dmem_write_byte: 267 mov.l %d0,-(%sp) 268 mov.l (_060FPSP_TABLE-0x80+_ 269 pea.l (_060FPSP_TABLE-0x80,% 270 mov.l 0x4(%sp),%d0 271 rtd &0x4 272 273 global _dmem_write_word 274 _dmem_write_word: 275 mov.l %d0,-(%sp) 276 mov.l (_060FPSP_TABLE-0x80+_ 277 pea.l (_060FPSP_TABLE-0x80,% 278 mov.l 0x4(%sp),%d0 279 rtd &0x4 280 281 global _dmem_write_long 282 _dmem_write_long: 283 mov.l %d0,-(%sp) 284 mov.l (_060FPSP_TABLE-0x80+_ 285 pea.l (_060FPSP_TABLE-0x80,% 286 mov.l 0x4(%sp),%d0 287 rtd &0x4 288 289 # 290 # This file contains a set of define statement 291 # in order to promote readability within the c 292 # 293 294 set LOCAL_SIZE, 192 295 set LV, -LOCAL_SIZE 296 297 set EXC_SR, 0x4 298 set EXC_PC, 0x6 299 set EXC_VOFF, 0xa 300 set EXC_EA, 0xc 301 302 set EXC_FP, 0x0 303 304 set EXC_AREGS, -68 305 set EXC_DREGS, -100 306 set EXC_FPREGS, -36 307 308 set EXC_A7, EXC_AREGS+(7*4) 309 set OLD_A7, EXC_AREGS+(6*4) 310 set EXC_A6, EXC_AREGS+(6*4) 311 set EXC_A5, EXC_AREGS+(5*4) 312 set EXC_A4, EXC_AREGS+(4*4) 313 set EXC_A3, EXC_AREGS+(3*4) 314 set EXC_A2, EXC_AREGS+(2*4) 315 set EXC_A1, EXC_AREGS+(1*4) 316 set EXC_A0, EXC_AREGS+(0*4) 317 set EXC_D7, EXC_DREGS+(7*4) 318 set EXC_D6, EXC_DREGS+(6*4) 319 set EXC_D5, EXC_DREGS+(5*4) 320 set EXC_D4, EXC_DREGS+(4*4) 321 set EXC_D3, EXC_DREGS+(3*4) 322 set EXC_D2, EXC_DREGS+(2*4) 323 set EXC_D1, EXC_DREGS+(1*4) 324 set EXC_D0, EXC_DREGS+(0*4) 325 326 set EXC_FP0, EXC_FPREGS+(0*12) 327 set EXC_FP1, EXC_FPREGS+(1*12) 328 set EXC_FP2, EXC_FPREGS+(2*12) 329 330 set FP_SCR1, LV+80 331 set FP_SCR1_EX, FP_SCR1+0 332 set FP_SCR1_SGN, FP_SCR1+2 333 set FP_SCR1_HI, FP_SCR1+4 334 set FP_SCR1_LO, FP_SCR1+8 335 336 set FP_SCR0, LV+68 337 set FP_SCR0_EX, FP_SCR0+0 338 set FP_SCR0_SGN, FP_SCR0+2 339 set FP_SCR0_HI, FP_SCR0+4 340 set FP_SCR0_LO, FP_SCR0+8 341 342 set FP_DST, LV+56 343 set FP_DST_EX, FP_DST+0 344 set FP_DST_SGN, FP_DST+2 345 set FP_DST_HI, FP_DST+4 346 set FP_DST_LO, FP_DST+8 347 348 set FP_SRC, LV+44 349 set FP_SRC_EX, FP_SRC+0 350 set FP_SRC_SGN, FP_SRC+2 351 set FP_SRC_HI, FP_SRC+4 352 set FP_SRC_LO, FP_SRC+8 353 354 set USER_FPIAR, LV+40 355 356 set USER_FPSR, LV+36 357 set FPSR_CC, USER_FPSR+0 358 set FPSR_QBYTE, USER_FPSR+1 359 set FPSR_EXCEPT, USER_FPSR+2 360 set FPSR_AEXCEPT, USER_FPSR+3 361 362 set USER_FPCR, LV+32 363 set FPCR_ENABLE, USER_FPCR+2 364 set FPCR_MODE, USER_FPCR+3 365 366 set L_SCR3, LV+28 367 set L_SCR2, LV+24 368 set L_SCR1, LV+20 369 370 set STORE_FLG, LV+19 371 372 set EXC_TEMP2, LV+24 373 set EXC_TEMP, LV+16 374 375 set DTAG, LV+15 376 set STAG, LV+14 377 378 set SPCOND_FLG, LV+10 379 380 set EXC_CC, LV+8 381 set EXC_EXTWPTR, LV+4 382 set EXC_EXTWORD, LV+2 383 set EXC_CMDREG, LV+2 384 set EXC_OPWORD, LV+0 385 386 ################################ 387 388 # Helpful macros 389 390 set FTEMP, 0 391 set FTEMP_EX, 0 392 set FTEMP_SGN, 2 393 set FTEMP_HI, 4 394 set FTEMP_LO, 8 395 set FTEMP_GRS, 12 396 397 set LOCAL, 0 398 set LOCAL_EX, 0 399 set LOCAL_SGN, 2 400 set LOCAL_HI, 4 401 set LOCAL_LO, 8 402 set LOCAL_GRS, 12 403 404 set DST, 0 405 set DST_EX, 0 406 set DST_HI, 4 407 set DST_LO, 8 408 409 set SRC, 0 410 set SRC_EX, 0 411 set SRC_HI, 4 412 set SRC_LO, 8 413 414 set SGL_LO, 0x3f81 415 set SGL_HI, 0x407e 416 set DBL_LO, 0x3c01 417 set DBL_HI, 0x43fe 418 set EXT_LO, 0x0 419 set EXT_HI, 0x7ffe 420 421 set EXT_BIAS, 0x3fff 422 set SGL_BIAS, 0x007f 423 set DBL_BIAS, 0x03ff 424 425 set NORM, 0x00 426 set ZERO, 0x01 427 set INF, 0x02 428 set QNAN, 0x03 429 set DENORM, 0x04 430 set SNAN, 0x05 431 set UNNORM, 0x06 432 433 ################## 434 # FPSR/FPCR bits # 435 ################## 436 set neg_bit, 0x3 437 set z_bit, 0x2 438 set inf_bit, 0x1 439 set nan_bit, 0x0 440 441 set q_sn_bit, 0x7 442 443 set bsun_bit, 7 444 set snan_bit, 6 445 set operr_bit, 5 446 set ovfl_bit, 4 447 set unfl_bit, 3 448 set dz_bit, 2 449 set inex2_bit, 1 450 set inex1_bit, 0 451 452 set aiop_bit, 7 453 set aovfl_bit, 6 454 set aunfl_bit, 5 455 set adz_bit, 4 456 set ainex_bit, 3 457 458 ############################# 459 # FPSR individual bit masks # 460 ############################# 461 set neg_mask, 0x08000000 462 set inf_mask, 0x02000000 463 set z_mask, 0x04000000 464 set nan_mask, 0x01000000 465 466 set neg_bmask, 0x08 467 set inf_bmask, 0x02 468 set z_bmask, 0x04 469 set nan_bmask, 0x01 470 471 set bsun_mask, 0x00008000 472 set snan_mask, 0x00004000 473 set operr_mask, 0x00002000 474 set ovfl_mask, 0x00001000 475 set unfl_mask, 0x00000800 476 set dz_mask, 0x00000400 477 set inex2_mask, 0x00000200 478 set inex1_mask, 0x00000100 479 480 set aiop_mask, 0x00000080 481 set aovfl_mask, 0x00000040 482 set aunfl_mask, 0x00000020 483 set adz_mask, 0x00000010 484 set ainex_mask, 0x00000008 485 486 ###################################### 487 # FPSR combinations used in the FPSP # 488 ###################################### 489 set dzinf_mask, inf_mask+dz_mask+adz_m 490 set opnan_mask, nan_mask+operr_mask+ai 491 set nzi_mask, 0x01ffffff 492 set unfinx_mask, unfl_mask+inex2_mask+a 493 set unf2inx_mask, unfl_mask+inex2_mask+a 494 set ovfinx_mask, ovfl_mask+inex2_mask+a 495 set inx1a_mask, inex1_mask+ainex_mask 496 set inx2a_mask, inex2_mask+ainex_mask 497 set snaniop_mask, nan_mask+snan_mask+aio 498 set snaniop2_mask, snan_mask+aiop_mask 499 set naniop_mask, nan_mask+aiop_mask 500 set neginf_mask, neg_mask+inf_mask 501 set infaiop_mask, inf_mask+aiop_mask 502 set negz_mask, neg_mask+z_mask 503 set opaop_mask, operr_mask+aiop_mask 504 set unfl_inx_mask, unfl_mask+aunfl_mask+a 505 set ovfl_inx_mask, ovfl_mask+aovfl_mask+a 506 507 ######### 508 # misc. # 509 ######### 510 set rnd_stky_bit, 29 511 512 set sign_bit, 0x7 513 set signan_bit, 0x6 514 515 set sgl_thresh, 0x3f81 516 set dbl_thresh, 0x3c01 517 518 set x_mode, 0x0 519 set s_mode, 0x4 520 set d_mode, 0x8 521 522 set rn_mode, 0x0 523 set rz_mode, 0x1 524 set rm_mode, 0x2 525 set rp_mode, 0x3 526 527 set mantissalen, 64 528 529 set BYTE, 1 530 set WORD, 2 531 set LONG, 4 532 533 set BSUN_VEC, 0xc0 534 set INEX_VEC, 0xc4 535 set DZ_VEC, 0xc8 536 set UNFL_VEC, 0xcc 537 set OPERR_VEC, 0xd0 538 set OVFL_VEC, 0xd4 539 set SNAN_VEC, 0xd8 540 541 ########################### 542 # SPecial CONDition FLaGs # 543 ########################### 544 set ftrapcc_flg, 0x01 545 set fbsun_flg, 0x02 546 set mia7_flg, 0x04 547 set mda7_flg, 0x08 548 set fmovm_flg, 0x40 549 set immed_flg, 0x80 550 551 set ftrapcc_bit, 0x0 552 set fbsun_bit, 0x1 553 set mia7_bit, 0x2 554 set mda7_bit, 0x3 555 set immed_bit, 0x7 556 557 ################################## 558 # TRANSCENDENTAL "LAST-OP" FLAGS # 559 ################################## 560 set FMUL_OP, 0x0 561 set FDIV_OP, 0x1 562 set FADD_OP, 0x2 563 set FMOV_OP, 0x3 564 565 ############# 566 # CONSTANTS # 567 ############# 568 T1: long 0x40C62D38,0xD3D64634 569 T2: long 0x3D6F90AE,0xB1E75CC7 570 571 PI: long 0x40000000,0xC90FDAA2, 572 PIBY2: long 0x3FFF0000,0xC90FDAA2, 573 574 TWOBYPI: 575 long 0x3FE45F30,0x6DC9C883 576 577 ############################################## 578 # XDEF *************************************** 579 # _fpsp_ovfl(): 060FPSP entry point for 580 # 581 # This handler should be the first code 582 # FP Overflow exception in an operating 583 # 584 # XREF *************************************** 585 # _imem_read_long() - read instruction l 586 # fix_skewed_ops() - adjust src operand 587 # set_tag_x() - determine optype of src/ 588 # store_fpreg() - store opclass 0 or 2 r 589 # unnorm_fix() - change UNNORM operands 590 # load_fpn2() - load dst operand from FP 591 # fout() - emulate an opclass 3 instruct 592 # tbl_unsupp - add of table of emulation 593 # _fpsp_done() - "callout" for 060FPSP e 594 # _real_ovfl() - "callout" for Overflow 595 # _real_inex() - "callout" for Inexact e 596 # _real_trace() - "callout" for Trace ex 597 # 598 # INPUT ************************************** 599 # - The system stack contains the FP Ovf 600 # - The fsave frame contains the source 601 # 602 # OUTPUT ************************************* 603 # Overflow Exception enabled: 604 # - The system stack is unchanged 605 # - The fsave frame contains the adjuste 606 # Overflow Exception disabled: 607 # - The system stack is unchanged 608 # - The "exception present" flag in the 609 # 610 # ALGORITHM ********************************** 611 # On the 060, if an FP overflow is prese 612 # instruction, the 060 will take an overflow e 613 # exception is enabled or disabled in the FPCR 614 # This handler emulates the instruction to det 615 # default result should be for the operation. 616 # then stored in either the FP regfile, data r 617 # Finally, the handler exits through the "call 618 # denoting that no exceptional conditions exis 619 # If the exception is enabled, then this 620 # exceptional operand and plave it in the fsav 621 # the default result (only if the instruction 622 # exceptions enabled, this handler must exit t 623 # _real_ovfl() so that the operating system en 624 # can handle this case. 625 # Two other conditions exist. First, if 626 # but the inexact exception was enabled, this 627 # through the "callout" _real_inex() regardles 628 # was inexact. 629 # Also, in the case of an opclass three 630 # overflow was disabled and the trace exceptio 631 # handler must exit through the "callout" _rea 632 # 633 ############################################## 634 635 global _fpsp_ovfl 636 _fpsp_ovfl: 637 638 #$# sub.l &24,%sp 639 640 link.w %a6,&-LOCAL_SIZE 641 642 fsave FP_SRC(%a6) 643 644 movm.l &0x0303,EXC_DREGS(%a6) 645 fmovm.l %fpcr,%fpsr,%fpiar,USE 646 fmovm.x &0xc0,EXC_FPREGS(%a6) 647 648 # the FPIAR holds the "current PC" of the faul 649 mov.l USER_FPIAR(%a6),EXC_EX 650 mov.l EXC_EXTWPTR(%a6),%a0 651 addq.l &0x4,EXC_EXTWPTR(%a6) 652 bsr.l _imem_read_long 653 mov.l %d0,EXC_OPWORD(%a6) 654 655 ############################################## 656 657 btst &0x5,EXC_CMDREG(%a6) 658 bne.w fovfl_out 659 660 661 lea FP_SRC(%a6),%a0 662 bsr.l fix_skewed_ops 663 664 # since, I believe, only NORMs and DENORMs can 665 # maybe we can avoid the subroutine call. 666 lea FP_SRC(%a6),%a0 667 bsr.l set_tag_x 668 mov.b %d0,STAG(%a6) 669 670 # bit five of the fp extension word separates 671 # that can pass through fpsp_ovfl(). remember 672 # will never take this exception. 673 btst &0x5,1+EXC_CMDREG(%a6) 674 beq.b fovfl_extract 675 676 bfextu EXC_CMDREG(%a6){&6:&3} 677 bsr.l load_fpn2 678 679 lea FP_DST(%a6),%a0 680 bsr.l set_tag_x 681 cmpi.b %d0,&UNNORM 682 bne.b fovfl_op2_done 683 bsr.l unnorm_fix 684 fovfl_op2_done: 685 mov.b %d0,DTAG(%a6) 686 687 fovfl_extract: 688 689 #$# mov.l FP_SRC_EX(%a6),TRAP_SR 690 #$# mov.l FP_SRC_HI(%a6),TRAP_SR 691 #$# mov.l FP_SRC_LO(%a6),TRAP_SR 692 #$# mov.l FP_DST_EX(%a6),TRAP_DS 693 #$# mov.l FP_DST_HI(%a6),TRAP_DS 694 #$# mov.l FP_DST_LO(%a6),TRAP_DS 695 696 clr.l %d0 697 mov.b FPCR_MODE(%a6),%d0 698 699 mov.b 1+EXC_CMDREG(%a6),%d1 700 andi.w &0x007f,%d1 701 702 andi.l &0x00ff01ff,USER_FPSR( 703 704 fmov.l &0x0,%fpcr 705 fmov.l &0x0,%fpsr 706 707 lea FP_SRC(%a6),%a0 708 lea FP_DST(%a6),%a1 709 710 # maybe we can make these entry points ONLY th 711 mov.l (tbl_unsupp.l,%pc,%d1. 712 jsr (tbl_unsupp.l,%pc,%d1. 713 714 # the operation has been emulated. the result 715 # the EXOP, if an exception occurred, is in fp 716 # we must save the default result regardless o 717 # traps are enabled or disabled. 718 bfextu EXC_CMDREG(%a6){&6:&3} 719 bsr.l store_fpreg 720 721 # the exceptional possibilities we have left o 722 # and inexact. and, the inexact is such that o 723 # but inexact was enabled. 724 btst &ovfl_bit,FPCR_ENABLE( 725 bne.b fovfl_ovfl_on 726 727 btst &inex2_bit,FPCR_ENABLE 728 bne.b fovfl_inex_on 729 730 fmovm.x EXC_FPREGS(%a6),&0xc0 731 fmovm.l USER_FPCR(%a6),%fpcr,% 732 movm.l EXC_DREGS(%a6),&0x0303 733 734 unlk %a6 735 #$# add.l &24,%sp 736 bra.l _fpsp_done 737 738 # overflow is enabled AND overflow, of course, 739 # in fp1. now, simply jump to _real_ovfl()! 740 fovfl_ovfl_on: 741 fmovm.x &0x40,FP_SRC(%a6) 742 743 mov.w &0xe005,2+FP_SRC(%a6) 744 745 fmovm.x EXC_FPREGS(%a6),&0xc0 746 fmovm.l USER_FPCR(%a6),%fpcr,% 747 movm.l EXC_DREGS(%a6),&0x0303 748 749 frestore FP_SRC(%a6) 750 751 unlk %a6 752 753 bra.l _real_ovfl 754 755 # overflow occurred but is disabled. meanwhile 756 # we must jump to real_inex(). 757 fovfl_inex_on: 758 759 fmovm.x &0x40,FP_SRC(%a6) 760 761 mov.b &0xc4,1+EXC_VOFF(%a6) 762 mov.w &0xe001,2+FP_SRC(%a6) 763 764 fmovm.x EXC_FPREGS(%a6),&0xc0 765 fmovm.l USER_FPCR(%a6),%fpcr,% 766 movm.l EXC_DREGS(%a6),&0x0303 767 768 frestore FP_SRC(%a6) 769 770 unlk %a6 771 772 bra.l _real_inex 773 774 ############################################## 775 fovfl_out: 776 777 778 #$# mov.l FP_SRC_EX(%a6),TRAP_SR 779 #$# mov.l FP_SRC_HI(%a6),TRAP_SR 780 #$# mov.l FP_SRC_LO(%a6),TRAP_SR 781 782 # the src operand is definitely a NORM(!), so 783 mov.b &NORM,STAG(%a6) 784 785 clr.l %d0 786 mov.b FPCR_MODE(%a6),%d0 787 788 and.l &0xffff00ff,USER_FPSR( 789 790 fmov.l &0x0,%fpcr 791 fmov.l &0x0,%fpsr 792 793 lea FP_SRC(%a6),%a0 794 795 bsr.l fout 796 797 btst &ovfl_bit,FPCR_ENABLE( 798 bne.w fovfl_ovfl_on 799 800 btst &inex2_bit,FPCR_ENABLE 801 bne.w fovfl_inex_on 802 803 fmovm.x EXC_FPREGS(%a6),&0xc0 804 fmovm.l USER_FPCR(%a6),%fpcr,% 805 movm.l EXC_DREGS(%a6),&0x0303 806 807 unlk %a6 808 #$# add.l &24,%sp 809 810 btst &0x7,(%sp) 811 beq.l _fpsp_done 812 813 fmov.l %fpiar,0x8(%sp) 814 mov.w &0x2024,0x6(%sp) 815 bra.l _real_trace 816 817 ############################################## 818 # XDEF *************************************** 819 # _fpsp_unfl(): 060FPSP entry point for 820 # 821 # This handler should be the first code 822 # FP Underflow exception in an operating 823 # 824 # XREF *************************************** 825 # _imem_read_long() - read instruction l 826 # fix_skewed_ops() - adjust src operand 827 # set_tag_x() - determine optype of src/ 828 # store_fpreg() - store opclass 0 or 2 r 829 # unnorm_fix() - change UNNORM operands 830 # load_fpn2() - load dst operand from FP 831 # fout() - emulate an opclass 3 instruct 832 # tbl_unsupp - add of table of emulation 833 # _fpsp_done() - "callout" for 060FPSP e 834 # _real_ovfl() - "callout" for Overflow 835 # _real_inex() - "callout" for Inexact e 836 # _real_trace() - "callout" for Trace ex 837 # 838 # INPUT ************************************** 839 # - The system stack contains the FP Unf 840 # - The fsave frame contains the source 841 # 842 # OUTPUT ************************************* 843 # Underflow Exception enabled: 844 # - The system stack is unchanged 845 # - The fsave frame contains the adjuste 846 # Underflow Exception disabled: 847 # - The system stack is unchanged 848 # - The "exception present" flag in the 849 # 850 # ALGORITHM ********************************** 851 # On the 060, if an FP underflow is pres 852 # instruction, the 060 will take an underflow 853 # exception is enabled or disabled in the FPCR 854 # This handler emulates the instruction to det 855 # default result should be for the operation. 856 # then stored in either the FP regfile, data r 857 # Finally, the handler exits through the "call 858 # denoting that no exceptional conditions exis 859 # If the exception is enabled, then this 860 # exceptional operand and plave it in the fsav 861 # the default result (only if the instruction 862 # exceptions enabled, this handler must exit t 863 # _real_unfl() so that the operating system en 864 # can handle this case. 865 # Two other conditions exist. First, if 866 # but the inexact exception was enabled and th 867 # this handler must exit through the "callout" 868 # was inexact. 869 # Also, in the case of an opclass three 870 # underflow was disabled and the trace excepti 871 # handler must exit through the "callout" _rea 872 # 873 ############################################## 874 875 global _fpsp_unfl 876 _fpsp_unfl: 877 878 #$# sub.l &24,%sp 879 880 link.w %a6,&-LOCAL_SIZE 881 882 fsave FP_SRC(%a6) 883 884 movm.l &0x0303,EXC_DREGS(%a6) 885 fmovm.l %fpcr,%fpsr,%fpiar,USE 886 fmovm.x &0xc0,EXC_FPREGS(%a6) 887 888 # the FPIAR holds the "current PC" of the faul 889 mov.l USER_FPIAR(%a6),EXC_EX 890 mov.l EXC_EXTWPTR(%a6),%a0 891 addq.l &0x4,EXC_EXTWPTR(%a6) 892 bsr.l _imem_read_long 893 mov.l %d0,EXC_OPWORD(%a6) 894 895 ############################################## 896 897 btst &0x5,EXC_CMDREG(%a6) 898 bne.w funfl_out 899 900 901 lea FP_SRC(%a6),%a0 902 bsr.l fix_skewed_ops 903 904 lea FP_SRC(%a6),%a0 905 bsr.l set_tag_x 906 mov.b %d0,STAG(%a6) 907 908 # bit five of the fp ext word separates the mo 909 # that can pass through fpsp_unfl(). remember 910 # will never take this exception. 911 btst &0x5,1+EXC_CMDREG(%a6) 912 beq.b funfl_extract 913 914 # now, what's left that's not dyadic is fsinco 915 # from all dyadics by the '0110xxx pattern 916 btst &0x4,1+EXC_CMDREG(%a6) 917 bne.b funfl_extract 918 919 bfextu EXC_CMDREG(%a6){&6:&3} 920 bsr.l load_fpn2 921 922 lea FP_DST(%a6),%a0 923 bsr.l set_tag_x 924 cmpi.b %d0,&UNNORM 925 bne.b funfl_op2_done 926 bsr.l unnorm_fix 927 funfl_op2_done: 928 mov.b %d0,DTAG(%a6) 929 930 funfl_extract: 931 932 #$# mov.l FP_SRC_EX(%a6),TRAP_SR 933 #$# mov.l FP_SRC_HI(%a6),TRAP_SR 934 #$# mov.l FP_SRC_LO(%a6),TRAP_SR 935 #$# mov.l FP_DST_EX(%a6),TRAP_DS 936 #$# mov.l FP_DST_HI(%a6),TRAP_DS 937 #$# mov.l FP_DST_LO(%a6),TRAP_DS 938 939 clr.l %d0 940 mov.b FPCR_MODE(%a6),%d0 941 942 mov.b 1+EXC_CMDREG(%a6),%d1 943 andi.w &0x007f,%d1 944 945 andi.l &0x00ff01ff,USER_FPSR( 946 947 fmov.l &0x0,%fpcr 948 fmov.l &0x0,%fpsr 949 950 lea FP_SRC(%a6),%a0 951 lea FP_DST(%a6),%a1 952 953 # maybe we can make these entry points ONLY th 954 mov.l (tbl_unsupp.l,%pc,%d1. 955 jsr (tbl_unsupp.l,%pc,%d1. 956 957 bfextu EXC_CMDREG(%a6){&6:&3} 958 bsr.l store_fpreg 959 960 # The `060 FPU multiplier hardware is such tha 961 # multiply operation is the smallest possible 962 # (0x00000000_80000000_00000000), then the mac 963 # underflow exception. Since this is incorrect 964 # if our emulation, after re-doing the operati 965 # no underflow was called for. We do these che 966 # funfl_{unfl,inex}_on() because w/ both excep 967 # special case will simply exit gracefully wit 968 969 # the exceptional possibilities we have left o 970 # and inexact. and, the inexact is such that o 971 # but inexact was enabled. 972 btst &unfl_bit,FPCR_ENABLE( 973 bne.b funfl_unfl_on 974 975 funfl_chkinex: 976 btst &inex2_bit,FPCR_ENABLE 977 bne.b funfl_inex_on 978 979 funfl_exit: 980 fmovm.x EXC_FPREGS(%a6),&0xc0 981 fmovm.l USER_FPCR(%a6),%fpcr,% 982 movm.l EXC_DREGS(%a6),&0x0303 983 984 unlk %a6 985 #$# add.l &24,%sp 986 bra.l _fpsp_done 987 988 # overflow is enabled AND overflow, of course, 989 # in fp1 (don't forget to save fp0). what to d 990 # well, we simply have to get to go to _real_u 991 funfl_unfl_on: 992 993 # The `060 FPU multiplier hardware is such tha 994 # multiply operation is the smallest possible 995 # (0x00000000_80000000_00000000), then the mac 996 # underflow exception. Since this is incorrect 997 # if our emulation, after re-doing the operati 998 # no underflow was called for. 999 btst &unfl_bit,FPSR_EXCEPT( 1000 beq.w funfl_chkinex 1001 1002 funfl_unfl_on2: 1003 fmovm.x &0x40,FP_SRC(%a6) 1004 1005 mov.w &0xe003,2+FP_SRC(%a6) 1006 1007 fmovm.x EXC_FPREGS(%a6),&0xc0 1008 fmovm.l USER_FPCR(%a6),%fpcr, 1009 movm.l EXC_DREGS(%a6),&0x030 1010 1011 frestore FP_SRC(%a6) 1012 1013 unlk %a6 1014 1015 bra.l _real_unfl 1016 1017 # underflow occurred but is disabled. meanwhi 1018 # we must jump to real_inex(). 1019 funfl_inex_on: 1020 1021 # The `060 FPU multiplier hardware is such th 1022 # multiply operation is the smallest possible 1023 # (0x00000000_80000000_00000000), then the ma 1024 # underflow exception. 1025 # But, whether bogus or not, if inexact is en 1026 # then we have to branch to real_inex. 1027 1028 btst &inex2_bit,FPSR_EXCEP 1029 beq.w funfl_exit 1030 1031 funfl_inex_on2: 1032 1033 fmovm.x &0x40,FP_SRC(%a6) 1034 1035 mov.b &0xc4,1+EXC_VOFF(%a6) 1036 mov.w &0xe001,2+FP_SRC(%a6) 1037 1038 fmovm.x EXC_FPREGS(%a6),&0xc0 1039 fmovm.l USER_FPCR(%a6),%fpcr, 1040 movm.l EXC_DREGS(%a6),&0x030 1041 1042 frestore FP_SRC(%a6) 1043 1044 unlk %a6 1045 1046 bra.l _real_inex 1047 1048 ############################################# 1049 funfl_out: 1050 1051 1052 #$# mov.l FP_SRC_EX(%a6),TRAP_S 1053 #$# mov.l FP_SRC_HI(%a6),TRAP_S 1054 #$# mov.l FP_SRC_LO(%a6),TRAP_S 1055 1056 # the src operand is definitely a NORM(!), so 1057 mov.b &NORM,STAG(%a6) 1058 1059 clr.l %d0 1060 mov.b FPCR_MODE(%a6),%d0 1061 1062 and.l &0xffff00ff,USER_FPSR 1063 1064 fmov.l &0x0,%fpcr 1065 fmov.l &0x0,%fpsr 1066 1067 lea FP_SRC(%a6),%a0 1068 1069 bsr.l fout 1070 1071 btst &unfl_bit,FPCR_ENABLE 1072 bne.w funfl_unfl_on2 1073 1074 btst &inex2_bit,FPCR_ENABL 1075 bne.w funfl_inex_on2 1076 1077 fmovm.x EXC_FPREGS(%a6),&0xc0 1078 fmovm.l USER_FPCR(%a6),%fpcr, 1079 movm.l EXC_DREGS(%a6),&0x030 1080 1081 unlk %a6 1082 #$# add.l &24,%sp 1083 1084 btst &0x7,(%sp) 1085 beq.l _fpsp_done 1086 1087 fmov.l %fpiar,0x8(%sp) 1088 mov.w &0x2024,0x6(%sp) 1089 bra.l _real_trace 1090 1091 ############################################# 1092 # XDEF ************************************** 1093 # _fpsp_unsupp(): 060FPSP entry point f 1094 # Data Type" exception. 1095 # 1096 # This handler should be the first code 1097 # FP Unimplemented Data Type exception 1098 # 1099 # XREF ************************************** 1100 # _imem_read_{word,long}() - read instr 1101 # fix_skewed_ops() - adjust src operand 1102 # set_tag_x() - determine optype of src 1103 # store_fpreg() - store opclass 0 or 2 1104 # unnorm_fix() - change UNNORM operands 1105 # load_fpn2() - load dst operand from F 1106 # load_fpn1() - load src operand from F 1107 # fout() - emulate an opclass 3 instruc 1108 # tbl_unsupp - add of table of emulatio 1109 # _real_inex() - "callout" to operating 1110 # _fpsp_done() - "callout" for exit; wo 1111 # _real_trace() - "callout" for Trace e 1112 # funimp_skew() - adjust fsave src ops 1113 # _real_snan() - "callout" for SNAN exc 1114 # _real_operr() - "callout" for OPERR e 1115 # _real_ovfl() - "callout" for OVFL exc 1116 # _real_unfl() - "callout" for UNFL exc 1117 # get_packed() - fetch packed operand f 1118 # 1119 # INPUT ************************************* 1120 # - The system stack contains the "Unim 1121 # - The fsave frame contains the ssrc o 1122 # 1123 # OUTPUT ************************************ 1124 # If Inexact exception (opclass 3): 1125 # - The system stack is changed to an I 1126 # If SNAN exception (opclass 3): 1127 # - The system stack is changed to an S 1128 # If OPERR exception (opclass 3): 1129 # - The system stack is changed to an O 1130 # If OVFL exception (opclass 3): 1131 # - The system stack is changed to an O 1132 # If UNFL exception (opclass 3): 1133 # - The system stack is changed to an U 1134 # If Trace exception enabled: 1135 # - The system stack is changed to a Tr 1136 # Else: (normal case) 1137 # - Correct result has been stored as a 1138 # 1139 # ALGORITHM ********************************* 1140 # Two main instruction types can enter 1141 # unimplemented data types. These can be eith 1142 # instructions, and (2) PACKED unimplemented 1143 # also of opclasses 0,2, or 3. 1144 # For UNNORM/DENORM opclass 0 and 2, th 1145 # operand from the fsave state frame and the 1146 # from the FP register file. The instruction 1147 # choosing an emulation routine from a table 1148 # instruction type. Once the instruction has 1149 # saved, then we check to see if any enabled 1150 # instruction emulation. If none, then we exi 1151 # _fpsp_done(). If there is an enabled FP exc 1152 # this exception into the FPU in the fsave st 1153 # through _fpsp_done(). 1154 # PACKED opclass 0 and 2 is similar in 1155 # emulated and exceptions handled. The differ 1156 # handler loads the packed op (by calling get 1157 # by the fact that a Trace exception could be 1158 # If a Trace exception is pending, then the c 1159 # frame is changed to a Trace exception stack 1160 # made through _real_trace(). 1161 # For UNNORM/DENORM opclass 3, the actu 1162 # performed by calling the routine fout(). If 1163 # as the result of emulation, then an exit ei 1164 # _fpsp_done() or through _real_trace() if a 1165 # (a Trace stack frame must be created here, 1166 # should occur, then we must create an except 1167 # type and jump to either _real_snan(), _real 1168 # _real_unfl(), or _real_ovfl() as appropriat 1169 # emulation is performed in a similar manner. 1170 # 1171 ############################################# 1172 1173 # 1174 # (1) DENORM and UNNORM (unimplemented) data 1175 # 1176 # post-instruct 1177 # ************* 1178 # * EA 1179 # pre-instruction * 1180 # ***************** ************* 1181 # * 0x0 * 0x0dc * * 0x3 * 0x0d 1182 # ***************** ************* 1183 # * Next * * Next 1184 # * PC * * PC 1185 # ***************** ************* 1186 # * SR * * SR 1187 # ***************** ************* 1188 # 1189 # (2) PACKED format (unsupported) opclasses t 1190 # ***************** 1191 # * EA * 1192 # * * 1193 # ***************** 1194 # * 0x2 * 0x0dc * 1195 # ***************** 1196 # * Next * 1197 # * PC * 1198 # ***************** 1199 # * SR * 1200 # ***************** 1201 # 1202 global _fpsp_unsupp 1203 _fpsp_unsupp: 1204 1205 link.w %a6,&-LOCAL_SIZE 1206 1207 fsave FP_SRC(%a6) 1208 1209 movm.l &0x0303,EXC_DREGS(%a6 1210 fmovm.l %fpcr,%fpsr,%fpiar,US 1211 fmovm.x &0xc0,EXC_FPREGS(%a6) 1212 1213 btst &0x5,EXC_SR(%a6) 1214 bne.b fu_s 1215 fu_u: 1216 mov.l %usp,%a0 1217 mov.l %a0,EXC_A7(%a6) 1218 bra.b fu_cont 1219 # if the exception is an opclass zero or two 1220 # exception, then the a7' calculated here is 1221 # stack an ea. however, we don't need an a7' 1222 fu_s: 1223 lea 0x4+EXC_EA(%a6),%a0 1224 mov.l %a0,EXC_A7(%a6) 1225 1226 fu_cont: 1227 1228 # the FPIAR holds the "current PC" of the fau 1229 # the FPIAR should be set correctly for ALL e 1230 # this point. 1231 mov.l USER_FPIAR(%a6),EXC_E 1232 mov.l EXC_EXTWPTR(%a6),%a0 1233 addq.l &0x4,EXC_EXTWPTR(%a6) 1234 bsr.l _imem_read_long 1235 mov.l %d0,EXC_OPWORD(%a6) 1236 1237 ############################ 1238 1239 clr.b SPCOND_FLG(%a6) 1240 1241 # Separate opclass three (fpn-to-mem) ops sin 1242 # stack frame and protocol. 1243 btst &0x5,EXC_CMDREG(%a6) 1244 bne.w fu_out 1245 1246 # Separate packed opclass two instructions. 1247 bfextu EXC_CMDREG(%a6){&0:&6 1248 cmpi.b %d0,&0x13 1249 beq.w fu_in_pack 1250 1251 1252 # I'm not sure at this point what FPSR bits a 1253 # so, since the emulation routines re-create 1254 andi.l &0x00ff00ff,USER_FPSR 1255 1256 fmov.l &0x0,%fpcr 1257 fmov.l &0x0,%fpsr 1258 1259 # Opclass two w/ memory-to-fpn operation will 1260 # precision format if the src format was sing 1261 # source data type was an INF, NAN, DENORM, o 1262 lea FP_SRC(%a6),%a0 1263 bsr.l fix_skewed_ops 1264 1265 # we don't know whether the src operand or th 1266 # UNNORM or DENORM. call the function that ta 1267 # input is an UNNORM, then convert it to a NO 1268 lea FP_SRC(%a6),%a0 1269 bsr.l set_tag_x 1270 cmpi.b %d0,&UNNORM 1271 bne.b fu_op2 1272 bsr.l unnorm_fix 1273 1274 fu_op2: 1275 mov.b %d0,STAG(%a6) 1276 1277 bfextu EXC_CMDREG(%a6){&6:&3 1278 1279 # bit five of the fp extension word separates 1280 # at this point 1281 btst &0x5,1+EXC_CMDREG(%a6 1282 beq.b fu_extract 1283 cmpi.b 1+EXC_CMDREG(%a6),&0x 1284 beq.b fu_extract 1285 1286 bsr.l load_fpn2 1287 1288 lea FP_DST(%a6),%a0 1289 bsr.l set_tag_x 1290 cmpi.b %d0,&UNNORM 1291 bne.b fu_op2_done 1292 bsr.l unnorm_fix 1293 fu_op2_done: 1294 mov.b %d0,DTAG(%a6) 1295 1296 fu_extract: 1297 clr.l %d0 1298 mov.b FPCR_MODE(%a6),%d0 1299 1300 bfextu 1+EXC_CMDREG(%a6){&1: 1301 1302 lea FP_SRC(%a6),%a0 1303 lea FP_DST(%a6),%a1 1304 1305 mov.l (tbl_unsupp.l,%pc,%d1 1306 jsr (tbl_unsupp.l,%pc,%d1 1307 1308 # 1309 # Exceptions in order of precedence: 1310 # BSUN : none 1311 # SNAN : all dyadic ops 1312 # OPERR : fsqrt(-NORM) 1313 # OVFL : all except ftst,fcmp 1314 # UNFL : all except ftst,fcmp 1315 # DZ : fdiv 1316 # INEX2 : all except ftst,fcmp 1317 # INEX1 : none (packed doesn't go thr 1318 # 1319 1320 # we determine the highest priority exception 1321 # emulation routine that has also been enable 1322 mov.b FPCR_ENABLE(%a6),%d0 1323 bne.b fu_in_ena 1324 1325 fu_in_cont: 1326 # fcmp and ftst do not store any result. 1327 mov.b 1+EXC_CMDREG(%a6),%d0 1328 andi.b &0x38,%d0 1329 cmpi.b %d0,&0x38 1330 beq.b fu_in_exit 1331 1332 bfextu EXC_CMDREG(%a6){&6:&3 1333 bsr.l store_fpreg 1334 1335 fu_in_exit: 1336 1337 fmovm.x EXC_FPREGS(%a6),&0xc0 1338 fmovm.l USER_FPCR(%a6),%fpcr, 1339 movm.l EXC_DREGS(%a6),&0x030 1340 1341 unlk %a6 1342 1343 bra.l _fpsp_done 1344 1345 fu_in_ena: 1346 and.b FPSR_EXCEPT(%a6),%d0 1347 bfffo %d0{&24:&8},%d0 1348 bne.b fu_in_exc 1349 1350 # 1351 # No exceptions occurred that were also enabl 1352 # 1353 # if (OVFL && ovfl_disabled && inexact_ 1354 # branch to _real_inex() (even if t 1355 # } else { 1356 # save the result in the proper fp 1357 # return; 1358 # } 1359 # 1360 btst &ovfl_bit,FPSR_EXCEPT 1361 beq.b fu_in_cont 1362 1363 fu_in_ovflchk: 1364 btst &inex2_bit,FPCR_ENABL 1365 beq.b fu_in_cont 1366 bra.w fu_in_exc_ovfl 1367 1368 # 1369 # An exception occurred and that exception wa 1370 # 1371 # shift enabled exception field into lo 1372 # if (((INEX2 || INEX1) && inex_enabled 1373 # ((INEX2 || INEX1) && inex_enabled 1374 # /* 1375 # * this is the case where we 1376 # * there will be no other way 1377 # */ 1378 # call _real_inex(); 1379 # } else { 1380 # restore exc state (SNAN||OPER 1381 # } 1382 # 1383 fu_in_exc: 1384 subi.l &24,%d0 1385 cmpi.b %d0,&0x6 1386 bne.b fu_in_exc_exit 1387 1388 # the enabled exception was inexact 1389 btst &unfl_bit,FPSR_EXCEPT 1390 bne.w fu_in_exc_unfl 1391 btst &ovfl_bit,FPSR_EXCEPT 1392 bne.w fu_in_exc_ovfl 1393 1394 # here, we insert the correct fsave status va 1395 # corresponding exception. the operand in the 1396 # src operand. 1397 fu_in_exc_exit: 1398 mov.l %d0,-(%sp) 1399 bsr.l funimp_skew 1400 mov.l (%sp)+,%d0 1401 1402 mov.w (tbl_except.b,%pc,%d0 1403 1404 fmovm.x EXC_FPREGS(%a6),&0xc0 1405 fmovm.l USER_FPCR(%a6),%fpcr, 1406 movm.l EXC_DREGS(%a6),&0x030 1407 1408 frestore FP_SRC(%a6) 1409 1410 unlk %a6 1411 1412 bra.l _fpsp_done 1413 1414 tbl_except: 1415 short 0xe000,0xe006,0xe004, 1416 short 0xe003,0xe002,0xe001, 1417 1418 fu_in_exc_unfl: 1419 mov.w &0x4,%d0 1420 bra.b fu_in_exc_exit 1421 fu_in_exc_ovfl: 1422 mov.w &0x03,%d0 1423 bra.b fu_in_exc_exit 1424 1425 # If the input operand to this operation was 1426 # or double precision denorm, inf, or nan, th 1427 # "corrected" in order to have the proper equ 1428 # number. 1429 global fix_skewed_ops 1430 fix_skewed_ops: 1431 bfextu EXC_CMDREG(%a6){&0:&6 1432 cmpi.b %d0,&0x11 1433 beq.b fso_sgl 1434 cmpi.b %d0,&0x15 1435 beq.b fso_dbl 1436 rts 1437 1438 fso_sgl: 1439 mov.w LOCAL_EX(%a0),%d0 1440 andi.w &0x7fff,%d0 1441 cmpi.w %d0,&0x3f80 1442 beq.b fso_sgl_dnrm_zero 1443 cmpi.w %d0,&0x407f 1444 beq.b fso_infnan 1445 rts 1446 1447 fso_sgl_dnrm_zero: 1448 andi.l &0x7fffffff,LOCAL_HI( 1449 beq.b fso_zero 1450 fso_sgl_dnrm: 1451 # here, we count on norm not to alter a0... 1452 bsr.l norm 1453 neg.w %d0 1454 addi.w &0x3f81,%d0 1455 andi.w &0x8000,LOCAL_EX(%a0) 1456 or.w %d0,LOCAL_EX(%a0) 1457 rts 1458 1459 fso_zero: 1460 andi.w &0x8000,LOCAL_EX(%a0) 1461 rts 1462 1463 fso_infnan: 1464 andi.b &0x7f,LOCAL_HI(%a0) 1465 ori.w &0x7fff,LOCAL_EX(%a0) 1466 rts 1467 1468 fso_dbl: 1469 mov.w LOCAL_EX(%a0),%d0 1470 andi.w &0x7fff,%d0 1471 cmpi.w %d0,&0x3c00 1472 beq.b fso_dbl_dnrm_zero 1473 cmpi.w %d0,&0x43ff 1474 beq.b fso_infnan 1475 rts 1476 1477 fso_dbl_dnrm_zero: 1478 andi.l &0x7fffffff,LOCAL_HI( 1479 bne.b fso_dbl_dnrm 1480 tst.l LOCAL_LO(%a0) 1481 beq.b fso_zero 1482 fso_dbl_dnrm: 1483 # here, we count on norm not to alter a0... 1484 bsr.l norm 1485 neg.w %d0 1486 addi.w &0x3c01,%d0 1487 andi.w &0x8000,LOCAL_EX(%a0) 1488 or.w %d0,LOCAL_EX(%a0) 1489 rts 1490 1491 ############################################# 1492 1493 # fmove out took an unimplemented data type e 1494 # the src operand is in FP_SRC. Call _fout() 1495 # to determine which exceptions, if any, to t 1496 fu_out: 1497 1498 # Separate packed move outs from the UNNORM a 1499 bfextu EXC_CMDREG(%a6){&3:&3 1500 cmpi.b %d0,&0x3 1501 beq.w fu_out_pack 1502 cmpi.b %d0,&0x7 1503 beq.w fu_out_pack 1504 1505 1506 # I'm not sure at this point what FPSR bits a 1507 # so, since the emulation routines re-create 1508 # fmove out doesn't affect ccodes. 1509 and.l &0xffff00ff,USER_FPSR 1510 1511 fmov.l &0x0,%fpcr 1512 fmov.l &0x0,%fpsr 1513 1514 # the src can ONLY be a DENORM or an UNNORM! 1515 # call here. just figure out what it is... 1516 mov.w FP_SRC_EX(%a6),%d0 1517 andi.w &0x7fff,%d0 1518 beq.b fu_out_denorm 1519 1520 lea FP_SRC(%a6),%a0 1521 bsr.l unnorm_fix 1522 1523 mov.b %d0,STAG(%a6) 1524 1525 bra.b fu_out_cont 1526 fu_out_denorm: 1527 mov.b &DENORM,STAG(%a6) 1528 fu_out_cont: 1529 1530 clr.l %d0 1531 mov.b FPCR_MODE(%a6),%d0 1532 1533 lea FP_SRC(%a6),%a0 1534 1535 mov.l (%a6),EXC_A6(%a6) 1536 bsr.l fout 1537 1538 # Exceptions in order of precedence: 1539 # BSUN : none 1540 # SNAN : none 1541 # OPERR : fmove.{b,w,l} out of large 1542 # OVFL : fmove.{s,d} 1543 # UNFL : fmove.{s,d,x} 1544 # DZ : none 1545 # INEX2 : all 1546 # INEX1 : none (packed doesn't travel 1547 1548 # determine the highest priority exception(if 1549 # emulation routine that has also been enable 1550 mov.b FPCR_ENABLE(%a6),%d0 1551 bne.w fu_out_ena 1552 1553 fu_out_done: 1554 1555 mov.l EXC_A6(%a6),(%a6) 1556 1557 # on extended precision opclass three instruc 1558 # post-increment addressing mode, the address 1559 # address register was the stack pointer used 1560 # it here. if it was used from supervisor mod 1561 # as a special case. 1562 btst &0x5,EXC_SR(%a6) 1563 bne.b fu_out_done_s 1564 1565 mov.l EXC_A7(%a6),%a0 1566 mov.l %a0,%usp 1567 1568 fu_out_done_cont: 1569 fmovm.x EXC_FPREGS(%a6),&0xc0 1570 fmovm.l USER_FPCR(%a6),%fpcr, 1571 movm.l EXC_DREGS(%a6),&0x030 1572 1573 unlk %a6 1574 1575 btst &0x7,(%sp) 1576 bne.b fu_out_trace 1577 1578 bra.l _fpsp_done 1579 1580 # is the ea mode pre-decrement of the stack p 1581 # ("fmov.x fpm,-(a7)") if so, 1582 fu_out_done_s: 1583 cmpi.b SPCOND_FLG(%a6),&mda7 1584 bne.b fu_out_done_cont 1585 1586 # the extended precision result is still in f 1587 # somewhere on the stack until we can copy it 1588 # here, we're counting on the top of the stac 1589 # for fp0/fp1 which have already been restore 1590 # over those destinations with the shifted st 1591 fmovm.x &0x80,FP_SRC(%a6) 1592 1593 fmovm.x EXC_FPREGS(%a6),&0xc0 1594 fmovm.l USER_FPCR(%a6),%fpcr, 1595 movm.l EXC_DREGS(%a6),&0x030 1596 1597 mov.l (%a6),%a6 1598 1599 mov.l LOCAL_SIZE+EXC_SR(%sp 1600 mov.l LOCAL_SIZE+2+EXC_PC(% 1601 1602 # now, copy the result to the proper place on 1603 mov.l LOCAL_SIZE+FP_SRC_EX( 1604 mov.l LOCAL_SIZE+FP_SRC_HI( 1605 mov.l LOCAL_SIZE+FP_SRC_LO( 1606 1607 add.l &LOCAL_SIZE-0x8,%sp 1608 1609 btst &0x7,(%sp) 1610 bne.b fu_out_trace 1611 1612 bra.l _fpsp_done 1613 1614 fu_out_ena: 1615 and.b FPSR_EXCEPT(%a6),%d0 1616 bfffo %d0{&24:&8},%d0 1617 bne.b fu_out_exc 1618 1619 # no exceptions were set. 1620 # if a disabled overflow occurred and inexact 1621 # was exact, then a branch to _real_inex() is 1622 btst &ovfl_bit,FPSR_EXCEPT 1623 beq.w fu_out_done 1624 1625 fu_out_ovflchk: 1626 btst &inex2_bit,FPCR_ENABL 1627 beq.w fu_out_done 1628 bra.w fu_inex 1629 1630 # 1631 # The fp move out that took the "Unimplemente 1632 # being traced. Since the stack frames are si 1633 # from FPIAR and put it in the trace stack fr 1634 # 1635 # UNSUPP FRAME TR 1636 # ***************** ***** 1637 # * EA * * 1638 # * * * 1639 # ***************** ***** 1640 # * 0x3 * 0x0dc * * 0x2 1641 # ***************** ***** 1642 # * Next * * 1643 # * PC * * 1644 # ***************** ***** 1645 # * SR * * 1646 # ***************** ***** 1647 # 1648 fu_out_trace: 1649 mov.w &0x2024,0x6(%sp) 1650 fmov.l %fpiar,0x8(%sp) 1651 bra.l _real_trace 1652 1653 # an exception occurred and that exception wa 1654 fu_out_exc: 1655 subi.l &24,%d0 1656 1657 # we don't mess with the existing fsave frame 1658 # jump to the "_real_{}()" handler... 1659 mov.w (tbl_fu_out.b,%pc,%d0 1660 jmp (tbl_fu_out.b,%pc,%d0 1661 1662 swbeg &0x8 1663 tbl_fu_out: 1664 short tbl_fu_out - tbl 1665 short tbl_fu_out - tbl 1666 short fu_operr - tbl 1667 short fu_ovfl - tbl 1668 short fu_unfl - tbl 1669 short tbl_fu_out - tbl 1670 short fu_inex - tbl 1671 short tbl_fu_out - tbl 1672 1673 # for snan,operr,ovfl,unfl, src op is still i 1674 # frestore it. 1675 fu_snan: 1676 fmovm.x EXC_FPREGS(%a6),&0xc0 1677 fmovm.l USER_FPCR(%a6),%fpcr, 1678 movm.l EXC_DREGS(%a6),&0x030 1679 1680 mov.w &0x30d8,EXC_VOFF(%a6) 1681 mov.w &0xe006,2+FP_SRC(%a6) 1682 1683 frestore FP_SRC(%a6) 1684 1685 unlk %a6 1686 1687 1688 bra.l _real_snan 1689 1690 fu_operr: 1691 fmovm.x EXC_FPREGS(%a6),&0xc0 1692 fmovm.l USER_FPCR(%a6),%fpcr, 1693 movm.l EXC_DREGS(%a6),&0x030 1694 1695 mov.w &0x30d0,EXC_VOFF(%a6) 1696 mov.w &0xe004,2+FP_SRC(%a6) 1697 1698 frestore FP_SRC(%a6) 1699 1700 unlk %a6 1701 1702 1703 bra.l _real_operr 1704 1705 fu_ovfl: 1706 fmovm.x &0x40,FP_SRC(%a6) 1707 1708 fmovm.x EXC_FPREGS(%a6),&0xc0 1709 fmovm.l USER_FPCR(%a6),%fpcr, 1710 movm.l EXC_DREGS(%a6),&0x030 1711 1712 mov.w &0x30d4,EXC_VOFF(%a6) 1713 mov.w &0xe005,2+FP_SRC(%a6) 1714 1715 frestore FP_SRC(%a6) 1716 1717 unlk %a6 1718 1719 bra.l _real_ovfl 1720 1721 # underflow can happen for extended precision 1722 # three instruction exceptions don't update t 1723 # exception occurred from user mode, then sim 1724 # if the exception occurred from supervisor m 1725 fu_unfl: 1726 mov.l EXC_A6(%a6),(%a6) 1727 1728 btst &0x5,EXC_SR(%a6) 1729 bne.w fu_unfl_s 1730 1731 mov.l EXC_A7(%a6),%a0 1732 mov.l %a0,%usp 1733 1734 fu_unfl_cont: 1735 fmovm.x &0x40,FP_SRC(%a6) 1736 1737 fmovm.x EXC_FPREGS(%a6),&0xc0 1738 fmovm.l USER_FPCR(%a6),%fpcr, 1739 movm.l EXC_DREGS(%a6),&0x030 1740 1741 mov.w &0x30cc,EXC_VOFF(%a6) 1742 mov.w &0xe003,2+FP_SRC(%a6) 1743 1744 frestore FP_SRC(%a6) 1745 1746 unlk %a6 1747 1748 bra.l _real_unfl 1749 1750 fu_unfl_s: 1751 cmpi.b SPCOND_FLG(%a6),&mda7 1752 bne.b fu_unfl_cont 1753 1754 # the extended precision result is still in f 1755 # somewhere on the stack until we can copy it 1756 # (where the exc frame is currently). make su 1757 # frame or it will get overwritten when the e 1758 fmovm.x &0x80,FP_SRC(%a6) 1759 fmovm.x &0x40,FP_DST(%a6) 1760 1761 fmovm.x EXC_FPREGS(%a6),&0xc0 1762 fmovm.l USER_FPCR(%a6),%fpcr, 1763 movm.l EXC_DREGS(%a6),&0x030 1764 1765 mov.w &0x30cc,EXC_VOFF(%a6) 1766 mov.w &0xe003,2+FP_DST(%a6) 1767 1768 frestore FP_DST(%a6) 1769 1770 mov.l (%a6),%a6 1771 1772 mov.l LOCAL_SIZE+EXC_SR(%sp 1773 mov.l LOCAL_SIZE+2+EXC_PC(% 1774 mov.l LOCAL_SIZE+EXC_EA(%sp 1775 1776 # now, copy the result to the proper place on 1777 mov.l LOCAL_SIZE+FP_SRC_EX( 1778 mov.l LOCAL_SIZE+FP_SRC_HI( 1779 mov.l LOCAL_SIZE+FP_SRC_LO( 1780 1781 add.l &LOCAL_SIZE-0x8,%sp 1782 1783 bra.l _real_unfl 1784 1785 # fmove in and out enter here. 1786 fu_inex: 1787 fmovm.x &0x40,FP_SRC(%a6) 1788 1789 fmovm.x EXC_FPREGS(%a6),&0xc0 1790 fmovm.l USER_FPCR(%a6),%fpcr, 1791 movm.l EXC_DREGS(%a6),&0x030 1792 1793 mov.w &0x30c4,EXC_VOFF(%a6) 1794 mov.w &0xe001,2+FP_SRC(%a6) 1795 1796 frestore FP_SRC(%a6) 1797 1798 unlk %a6 1799 1800 1801 bra.l _real_inex 1802 1803 ############################################# 1804 ############################################# 1805 fu_in_pack: 1806 1807 1808 # I'm not sure at this point what FPSR bits a 1809 # so, since the emulation routines re-create 1810 andi.l &0x0ff00ff,USER_FPSR( 1811 1812 fmov.l &0x0,%fpcr 1813 fmov.l &0x0,%fpsr 1814 1815 bsr.l get_packed 1816 1817 lea FP_SRC(%a6),%a0 1818 bsr.l set_tag_x 1819 1820 mov.b %d0,STAG(%a6) 1821 1822 bfextu EXC_CMDREG(%a6){&6:&3 1823 1824 # bit five of the fp extension word separates 1825 # at this point 1826 btst &0x5,1+EXC_CMDREG(%a6 1827 beq.b fu_extract_p 1828 cmpi.b 1+EXC_CMDREG(%a6),&0x 1829 beq.b fu_extract_p 1830 1831 bsr.l load_fpn2 1832 1833 lea FP_DST(%a6),%a0 1834 bsr.l set_tag_x 1835 cmpi.b %d0,&UNNORM 1836 bne.b fu_op2_done_p 1837 bsr.l unnorm_fix 1838 fu_op2_done_p: 1839 mov.b %d0,DTAG(%a6) 1840 1841 fu_extract_p: 1842 clr.l %d0 1843 mov.b FPCR_MODE(%a6),%d0 1844 1845 bfextu 1+EXC_CMDREG(%a6){&1: 1846 1847 lea FP_SRC(%a6),%a0 1848 lea FP_DST(%a6),%a1 1849 1850 mov.l (tbl_unsupp.l,%pc,%d1 1851 jsr (tbl_unsupp.l,%pc,%d1 1852 1853 # 1854 # Exceptions in order of precedence: 1855 # BSUN : none 1856 # SNAN : all dyadic ops 1857 # OPERR : fsqrt(-NORM) 1858 # OVFL : all except ftst,fcmp 1859 # UNFL : all except ftst,fcmp 1860 # DZ : fdiv 1861 # INEX2 : all except ftst,fcmp 1862 # INEX1 : all 1863 # 1864 1865 # we determine the highest priority exception 1866 # emulation routine that has also been enable 1867 mov.b FPCR_ENABLE(%a6),%d0 1868 bne.w fu_in_ena_p 1869 1870 fu_in_cont_p: 1871 # fcmp and ftst do not store any result. 1872 mov.b 1+EXC_CMDREG(%a6),%d0 1873 andi.b &0x38,%d0 1874 cmpi.b %d0,&0x38 1875 beq.b fu_in_exit_p 1876 1877 bfextu EXC_CMDREG(%a6){&6:&3 1878 bsr.l store_fpreg 1879 1880 fu_in_exit_p: 1881 1882 btst &0x5,EXC_SR(%a6) 1883 bne.w fu_in_exit_s_p 1884 1885 mov.l EXC_A7(%a6),%a0 1886 mov.l %a0,%usp 1887 1888 fu_in_exit_cont_p: 1889 fmovm.x EXC_FPREGS(%a6),&0xc0 1890 fmovm.l USER_FPCR(%a6),%fpcr, 1891 movm.l EXC_DREGS(%a6),&0x030 1892 1893 unlk %a6 1894 1895 btst &0x7,(%sp) 1896 bne.w fu_trace_p 1897 1898 bra.l _fpsp_done 1899 1900 # the exception occurred in supervisor mode. 1901 # addressing mode was (a7)+. if so, we'll nee 1902 # stack frame "up". 1903 fu_in_exit_s_p: 1904 btst &mia7_bit,SPCOND_FLG( 1905 beq.b fu_in_exit_cont_p 1906 1907 fmovm.x EXC_FPREGS(%a6),&0xc0 1908 fmovm.l USER_FPCR(%a6),%fpcr, 1909 movm.l EXC_DREGS(%a6),&0x030 1910 1911 unlk %a6 1912 1913 # shift the stack frame "up". we don't really 1914 mov.l 0x4(%sp),0x10(%sp) 1915 mov.l 0x0(%sp),0xc(%sp) 1916 add.l &0xc,%sp 1917 1918 btst &0x7,(%sp) 1919 bne.w fu_trace_p 1920 1921 bra.l _fpsp_done 1922 1923 fu_in_ena_p: 1924 and.b FPSR_EXCEPT(%a6),%d0 1925 bfffo %d0{&24:&8},%d0 1926 bne.b fu_in_exc_p 1927 1928 # 1929 # No exceptions occurred that were also enabl 1930 # 1931 # if (OVFL && ovfl_disabled && inexact_ 1932 # branch to _real_inex() (even if t 1933 # } else { 1934 # save the result in the proper fp 1935 # return; 1936 # } 1937 # 1938 btst &ovfl_bit,FPSR_EXCEPT 1939 beq.w fu_in_cont_p 1940 1941 fu_in_ovflchk_p: 1942 btst &inex2_bit,FPCR_ENABL 1943 beq.w fu_in_cont_p 1944 bra.w fu_in_exc_ovfl_p 1945 1946 # 1947 # An exception occurred and that exception wa 1948 # 1949 # shift enabled exception field into lo 1950 # if (((INEX2 || INEX1) && inex_enabled 1951 # ((INEX2 || INEX1) && inex_enabled 1952 # /* 1953 # * this is the case where we 1954 # * there will be no other way 1955 # */ 1956 # call _real_inex(); 1957 # } else { 1958 # restore exc state (SNAN||OPER 1959 # } 1960 # 1961 fu_in_exc_p: 1962 subi.l &24,%d0 1963 cmpi.b %d0,&0x6 1964 blt.b fu_in_exc_exit_p 1965 1966 # the enabled exception was inexact 1967 btst &unfl_bit,FPSR_EXCEPT 1968 bne.w fu_in_exc_unfl_p 1969 btst &ovfl_bit,FPSR_EXCEPT 1970 bne.w fu_in_exc_ovfl_p 1971 1972 # here, we insert the correct fsave status va 1973 # corresponding exception. the operand in the 1974 # src operand. 1975 # as a reminder for future predicted pain and 1976 # "non-skewed" operand for cases of sgl and d 1977 # this is INCORRECT for enabled SNAN which wo 1978 fu_in_exc_exit_p: 1979 btst &0x5,EXC_SR(%a6) 1980 bne.w fu_in_exc_exit_s_p 1981 1982 mov.l EXC_A7(%a6),%a0 1983 mov.l %a0,%usp 1984 1985 fu_in_exc_exit_cont_p: 1986 mov.w (tbl_except_p.b,%pc,% 1987 1988 fmovm.x EXC_FPREGS(%a6),&0xc0 1989 fmovm.l USER_FPCR(%a6),%fpcr, 1990 movm.l EXC_DREGS(%a6),&0x030 1991 1992 frestore FP_SRC(%a6) 1993 1994 unlk %a6 1995 1996 btst &0x7,(%sp) 1997 bne.w fu_trace_p 1998 1999 bra.l _fpsp_done 2000 2001 tbl_except_p: 2002 short 0xe000,0xe006,0xe004, 2003 short 0xe003,0xe002,0xe001, 2004 2005 fu_in_exc_ovfl_p: 2006 mov.w &0x3,%d0 2007 bra.w fu_in_exc_exit_p 2008 2009 fu_in_exc_unfl_p: 2010 mov.w &0x4,%d0 2011 bra.w fu_in_exc_exit_p 2012 2013 fu_in_exc_exit_s_p: 2014 btst &mia7_bit,SPCOND_FLG( 2015 beq.b fu_in_exc_exit_cont_p 2016 2017 mov.w (tbl_except_p.b,%pc,% 2018 2019 fmovm.x EXC_FPREGS(%a6),&0xc0 2020 fmovm.l USER_FPCR(%a6),%fpcr, 2021 movm.l EXC_DREGS(%a6),&0x030 2022 2023 frestore FP_SRC(%a6) 2024 2025 unlk %a6 2026 2027 # shift stack frame "up". who cares about <ea 2028 mov.l 0x4(%sp),0x10(%sp) 2029 mov.l 0x0(%sp),0xc(%sp) 2030 add.l &0xc,%sp 2031 2032 btst &0x7,(%sp) 2033 bne.b fu_trace_p 2034 2035 bra.l _fpsp_done 2036 2037 # 2038 # The opclass two PACKED instruction that too 2039 # exception was being traced. Make the "curre 2040 # trace stack frame then jump to _real_trace( 2041 # 2042 # UNSUPP FRAME TR 2043 # ***************** ***** 2044 # * EA * * 2045 # * * * 2046 # ***************** ***** 2047 # * 0x2 * 0x0dc * * 0x2 2048 # ***************** ***** 2049 # * Next * * 2050 # * PC * * 2051 # ***************** ***** 2052 # * SR * * 2053 # ***************** ***** 2054 fu_trace_p: 2055 mov.w &0x2024,0x6(%sp) 2056 fmov.l %fpiar,0x8(%sp) 2057 2058 bra.l _real_trace 2059 2060 ############################################# 2061 ############################################# 2062 fu_out_pack: 2063 2064 2065 # I'm not sure at this point what FPSR bits a 2066 # so, since the emulation routines re-create 2067 # fmove out doesn't affect ccodes. 2068 and.l &0xffff00ff,USER_FPSR 2069 2070 fmov.l &0x0,%fpcr 2071 fmov.l &0x0,%fpsr 2072 2073 bfextu EXC_CMDREG(%a6){&6:&3 2074 bsr.l load_fpn1 2075 2076 # unlike other opclass 3, unimplemented data 2077 # able to detect all operand types. 2078 lea FP_SRC(%a6),%a0 2079 bsr.l set_tag_x 2080 cmpi.b %d0,&UNNORM 2081 bne.b fu_op2_p 2082 bsr.l unnorm_fix 2083 2084 fu_op2_p: 2085 mov.b %d0,STAG(%a6) 2086 2087 clr.l %d0 2088 mov.b FPCR_MODE(%a6),%d0 2089 2090 lea FP_SRC(%a6),%a0 2091 2092 mov.l (%a6),EXC_A6(%a6) 2093 bsr.l fout 2094 2095 # Exceptions in order of precedence: 2096 # BSUN : no 2097 # SNAN : yes 2098 # OPERR : if ((k_factor > +17) || (de 2099 # OVFL : no 2100 # UNFL : no 2101 # DZ : no 2102 # INEX2 : yes 2103 # INEX1 : no 2104 2105 # determine the highest priority exception(if 2106 # emulation routine that has also been enable 2107 mov.b FPCR_ENABLE(%a6),%d0 2108 bne.w fu_out_ena_p 2109 2110 fu_out_exit_p: 2111 mov.l EXC_A6(%a6),(%a6) 2112 2113 btst &0x5,EXC_SR(%a6) 2114 bne.b fu_out_exit_s_p 2115 2116 mov.l EXC_A7(%a6),%a0 2117 mov.l %a0,%usp 2118 2119 fu_out_exit_cont_p: 2120 fmovm.x EXC_FPREGS(%a6),&0xc0 2121 fmovm.l USER_FPCR(%a6),%fpcr, 2122 movm.l EXC_DREGS(%a6),&0x030 2123 2124 unlk %a6 2125 2126 btst &0x7,(%sp) 2127 bne.w fu_trace_p 2128 2129 bra.l _fpsp_done 2130 2131 # the exception occurred in supervisor mode. 2132 # addressing mode was -(a7). if so, we'll nee 2133 # stack frame "down". 2134 fu_out_exit_s_p: 2135 btst &mda7_bit,SPCOND_FLG( 2136 beq.b fu_out_exit_cont_p 2137 2138 fmovm.x EXC_FPREGS(%a6),&0xc0 2139 fmovm.l USER_FPCR(%a6),%fpcr, 2140 movm.l EXC_DREGS(%a6),&0x030 2141 2142 mov.l (%a6),%a6 2143 2144 mov.l LOCAL_SIZE+EXC_SR(%sp 2145 mov.l LOCAL_SIZE+2+EXC_PC(% 2146 2147 # now, copy the result to the proper place on 2148 mov.l LOCAL_SIZE+FP_DST_EX( 2149 mov.l LOCAL_SIZE+FP_DST_HI( 2150 mov.l LOCAL_SIZE+FP_DST_LO( 2151 2152 add.l &LOCAL_SIZE-0x8,%sp 2153 2154 btst &0x7,(%sp) 2155 bne.w fu_trace_p 2156 2157 bra.l _fpsp_done 2158 2159 fu_out_ena_p: 2160 and.b FPSR_EXCEPT(%a6),%d0 2161 bfffo %d0{&24:&8},%d0 2162 beq.w fu_out_exit_p 2163 2164 mov.l EXC_A6(%a6),(%a6) 2165 2166 # an exception occurred and that exception wa 2167 # the only exception possible on packed move 2168 fu_out_exc_p: 2169 cmpi.b %d0,&0x1a 2170 bgt.w fu_inex_p2 2171 beq.w fu_operr_p 2172 2173 fu_snan_p: 2174 btst &0x5,EXC_SR(%a6) 2175 bne.b fu_snan_s_p 2176 2177 mov.l EXC_A7(%a6),%a0 2178 mov.l %a0,%usp 2179 bra.w fu_snan 2180 2181 fu_snan_s_p: 2182 cmpi.b SPCOND_FLG(%a6),&mda7 2183 bne.w fu_snan 2184 2185 # the instruction was "fmove.p fpn,-(a7)" fro 2186 # the strategy is to move the exception frame 2187 # can store the default result where the exce 2188 fmovm.x EXC_FPREGS(%a6),&0xc0 2189 fmovm.l USER_FPCR(%a6),%fpcr, 2190 movm.l EXC_DREGS(%a6),&0x030 2191 2192 mov.w &0x30d8,EXC_VOFF(%a6) 2193 mov.w &0xe006,2+FP_SRC(%a6) 2194 2195 frestore FP_SRC(%a6) 2196 2197 mov.l (%a6),%a6 2198 2199 mov.l LOCAL_SIZE+EXC_SR(%sp 2200 mov.l LOCAL_SIZE+2+EXC_PC(% 2201 mov.l LOCAL_SIZE+EXC_EA(%sp 2202 2203 # now, we copy the default result to its prop 2204 mov.l LOCAL_SIZE+FP_DST_EX( 2205 mov.l LOCAL_SIZE+FP_DST_HI( 2206 mov.l LOCAL_SIZE+FP_DST_LO( 2207 2208 add.l &LOCAL_SIZE-0x8,%sp 2209 2210 2211 bra.l _real_snan 2212 2213 fu_operr_p: 2214 btst &0x5,EXC_SR(%a6) 2215 bne.w fu_operr_p_s 2216 2217 mov.l EXC_A7(%a6),%a0 2218 mov.l %a0,%usp 2219 bra.w fu_operr 2220 2221 fu_operr_p_s: 2222 cmpi.b SPCOND_FLG(%a6),&mda7 2223 bne.w fu_operr 2224 2225 # the instruction was "fmove.p fpn,-(a7)" fro 2226 # the strategy is to move the exception frame 2227 # can store the default result where the exce 2228 fmovm.x EXC_FPREGS(%a6),&0xc0 2229 fmovm.l USER_FPCR(%a6),%fpcr, 2230 movm.l EXC_DREGS(%a6),&0x030 2231 2232 mov.w &0x30d0,EXC_VOFF(%a6) 2233 mov.w &0xe004,2+FP_SRC(%a6) 2234 2235 frestore FP_SRC(%a6) 2236 2237 mov.l (%a6),%a6 2238 2239 mov.l LOCAL_SIZE+EXC_SR(%sp 2240 mov.l LOCAL_SIZE+2+EXC_PC(% 2241 mov.l LOCAL_SIZE+EXC_EA(%sp 2242 2243 # now, we copy the default result to its prop 2244 mov.l LOCAL_SIZE+FP_DST_EX( 2245 mov.l LOCAL_SIZE+FP_DST_HI( 2246 mov.l LOCAL_SIZE+FP_DST_LO( 2247 2248 add.l &LOCAL_SIZE-0x8,%sp 2249 2250 2251 bra.l _real_operr 2252 2253 fu_inex_p2: 2254 btst &0x5,EXC_SR(%a6) 2255 bne.w fu_inex_s_p2 2256 2257 mov.l EXC_A7(%a6),%a0 2258 mov.l %a0,%usp 2259 bra.w fu_inex 2260 2261 fu_inex_s_p2: 2262 cmpi.b SPCOND_FLG(%a6),&mda7 2263 bne.w fu_inex 2264 2265 # the instruction was "fmove.p fpn,-(a7)" fro 2266 # the strategy is to move the exception frame 2267 # can store the default result where the exce 2268 fmovm.x EXC_FPREGS(%a6),&0xc0 2269 fmovm.l USER_FPCR(%a6),%fpcr, 2270 movm.l EXC_DREGS(%a6),&0x030 2271 2272 mov.w &0x30c4,EXC_VOFF(%a6) 2273 mov.w &0xe001,2+FP_SRC(%a6) 2274 2275 frestore FP_SRC(%a6) 2276 2277 mov.l (%a6),%a6 2278 2279 mov.l LOCAL_SIZE+EXC_SR(%sp 2280 mov.l LOCAL_SIZE+2+EXC_PC(% 2281 mov.l LOCAL_SIZE+EXC_EA(%sp 2282 2283 # now, we copy the default result to its prop 2284 mov.l LOCAL_SIZE+FP_DST_EX( 2285 mov.l LOCAL_SIZE+FP_DST_HI( 2286 mov.l LOCAL_SIZE+FP_DST_LO( 2287 2288 add.l &LOCAL_SIZE-0x8,%sp 2289 2290 2291 bra.l _real_inex 2292 2293 ############################################# 2294 2295 # 2296 # if we're stuffing a source operand back int 2297 # have to make sure that for single or double 2298 # format stuffed is as weird as the hardware 2299 # 2300 global funimp_skew 2301 funimp_skew: 2302 bfextu EXC_EXTWORD(%a6){&3:& 2303 cmpi.b %d0,&0x1 2304 beq.b funimp_skew_sgl 2305 cmpi.b %d0,&0x5 2306 beq.b funimp_skew_dbl 2307 rts 2308 2309 funimp_skew_sgl: 2310 mov.w FP_SRC_EX(%a6),%d0 2311 andi.w &0x7fff,%d0 2312 beq.b funimp_skew_sgl_not 2313 cmpi.w %d0,&0x3f80 2314 bgt.b funimp_skew_sgl_not 2315 neg.w %d0 2316 addi.w &0x3f81,%d0 2317 mov.l FP_SRC_HI(%a6),%d1 2318 lsr.l %d0,%d1 2319 bset &31,%d1 2320 mov.l %d1,FP_SRC_HI(%a6) 2321 andi.w &0x8000,FP_SRC_EX(%a6 2322 ori.w &0x3f80,FP_SRC_EX(%a6 2323 funimp_skew_sgl_not: 2324 rts 2325 2326 funimp_skew_dbl: 2327 mov.w FP_SRC_EX(%a6),%d0 2328 andi.w &0x7fff,%d0 2329 beq.b funimp_skew_dbl_not 2330 cmpi.w %d0,&0x3c00 2331 bgt.b funimp_skew_dbl_not 2332 2333 tst.b FP_SRC_EX(%a6) 2334 smi.b 0x2+FP_SRC(%a6) 2335 mov.w %d0,FP_SRC_EX(%a6) 2336 clr.l %d0 2337 lea FP_SRC(%a6),%a0 2338 mov.w &0x3c01,%d1 2339 bsr.l dnrm_lp 2340 mov.w &0x3c00,%d0 2341 tst.b 0x2+FP_SRC(%a6) 2342 beq.b fss_dbl_denorm_done 2343 bset &15,%d0 2344 fss_dbl_denorm_done: 2345 bset &0x7,FP_SRC_HI(%a6) 2346 mov.w %d0,FP_SRC_EX(%a6) 2347 funimp_skew_dbl_not: 2348 rts 2349 2350 ############################################# 2351 global _mem_write2 2352 _mem_write2: 2353 btst &0x5,EXC_SR(%a6) 2354 beq.l _dmem_write 2355 mov.l 0x0(%a0),FP_DST_EX(%a 2356 mov.l 0x4(%a0),FP_DST_HI(%a 2357 mov.l 0x8(%a0),FP_DST_LO(%a 2358 clr.l %d1 2359 rts 2360 2361 ############################################# 2362 # XDEF ************************************** 2363 # _fpsp_effadd(): 060FPSP entry point f 2364 # effective address" ex 2365 # 2366 # This handler should be the first code 2367 # FP Unimplemented Effective Address ex 2368 # system. 2369 # 2370 # XREF ************************************** 2371 # _imem_read_long() - read instruction 2372 # fix_skewed_ops() - adjust src operand 2373 # set_tag_x() - determine optype of src 2374 # store_fpreg() - store opclass 0 or 2 2375 # unnorm_fix() - change UNNORM operands 2376 # load_fpn2() - load dst operand from F 2377 # tbl_unsupp - add of table of emulatio 2378 # decbin() - convert packed data to FP 2379 # _real_fpu_disabled() - "callout" for 2380 # _real_access() - "callout" for access 2381 # _mem_read() - read extended immediate 2382 # _fpsp_done() - "callout" for exit; wo 2383 # _real_trace() - "callout" for Trace e 2384 # fmovm_dynamic() - emulate dynamic fmo 2385 # fmovm_ctrl() - emulate fmovm control 2386 # 2387 # INPUT ************************************* 2388 # - The system stack contains the "Unim 2389 # 2390 # OUTPUT ************************************ 2391 # If access error: 2392 # - The system stack is changed to an a 2393 # If FPU disabled: 2394 # - The system stack is changed to an F 2395 # If Trace exception enabled: 2396 # - The system stack is changed to a Tr 2397 # Else: (normal case) 2398 # - None (correct result has been store 2399 # 2400 # ALGORITHM ********************************* 2401 # This exception handles 3 types of ope 2402 # (1) FP Instructions using extended precisio 2403 # addressing mode. 2404 # (2) The "fmovm.x" instruction w/ dynamic re 2405 # (3) The "fmovm.l" instruction w/ 2 or 3 con 2406 # 2407 # For immediate data operations, the da 2408 # _mem_read() "callout", converted to FP bina 2409 # as the source operand to the instruction sp 2410 # word. If no FP exception should be reported 2411 # emulation, then the result is stored to the 2412 # the handler exits through _fpsp_done(). If 2413 # signalled as a result of emulation, then an 2414 # corresponding to the FP exception type must 2415 # FPU before exiting. In either the enabled o 2416 # must also check if a Trace exception is pen 2417 # must create a Trace exception stack frame f 2418 # stack frame. If no Trace is pending, we sim 2419 # _fpsp_done(). 2420 # For "fmovm.x", call the routine fmovm 2421 # decode and emulate the instruction. No FP e 2422 # as a result of this operation emulation. A 2423 # pending, though, which means the current st 2424 # to a Trace stack frame and an exit made thr 2425 # For the case of "fmovm.x Dn,-(a7)", where t 2426 # was executed from supervisor mode, this han 2427 # register file values to the system stack by 2428 # fmovm_dynamic() can't handle this. A normal 2429 # fpsp_done(). 2430 # For "fmovm.l", fmovm_ctrl() is used t 2431 # Again, a Trace exception may be pending and 2432 # _real_trace(). Else, a normal exit is made 2433 # 2434 # Before any of the above is attempted, 2435 # see if the FPU is disabled. Since the "Unim 2436 # before the "FPU disabled" exception, but th 2437 # has higher priority, we check the disabled 2438 # then we must create an 8 word "FPU disabled 2439 # from the current 4 word exception stack fra 2440 # reproducing the effective address of the in 2441 # new stack frame. 2442 # 2443 # In the process of all emulation work, 2444 # "callout" returns a failing result indicati 2445 # we must create an access error stack frame 2446 # frame. This information includes a faulting 2447 # status-longword. These are created within t 2448 # 2449 ############################################# 2450 2451 global _fpsp_effadd 2452 _fpsp_effadd: 2453 2454 # This exception type takes priority over the 2455 # exception. Therefore, the FPU could be disa 2456 # So, we must check to see if it's disabled a 2457 mov.l %d0,-(%sp) 2458 movc %pcr,%d0 2459 btst &0x1,%d0 2460 bne.w iea_disabled 2461 mov.l (%sp)+,%d0 2462 2463 link %a6,&-LOCAL_SIZE 2464 2465 movm.l &0x0303,EXC_DREGS(%a6 2466 fmovm.l %fpcr,%fpsr,%fpiar,US 2467 fmovm.x &0xc0,EXC_FPREGS(%a6) 2468 2469 # PC of instruction that took the exception i 2470 mov.l EXC_PC(%a6),EXC_EXTWP 2471 2472 mov.l EXC_EXTWPTR(%a6),%a0 2473 addq.l &0x4,EXC_EXTWPTR(%a6) 2474 bsr.l _imem_read_long 2475 mov.l %d0,EXC_OPWORD(%a6) 2476 2477 ############################################# 2478 2479 tst.w %d0 2480 bmi.w iea_fmovm 2481 2482 # 2483 # here, we will have: 2484 # fabs fdabs fsabs facos 2485 # fadd fdadd fsadd fasin 2486 # fcmp fatan 2487 # fdiv fddiv fsdiv fatan 2488 # fint fcos 2489 # fintrz fcosh 2490 # fmove fdmove fsmove fetox 2491 # fmul fdmul fsmul fetox 2492 # fneg fdneg fsneg fgete 2493 # fsgldiv fgetm 2494 # fsglmul flog1 2495 # fsqrt flog2 2496 # fsub fdsub fssub flogn 2497 # ftst flogn 2498 # which can all use f<op>.{x,p} 2499 # so, now it's immediate data extended precis 2500 # 2501 iea_op: 2502 andi.l &0x00ff00ff,USER_FPSR 2503 2504 btst &0xa,%d0 2505 bne.b iea_op_pack 2506 2507 2508 mov.l EXC_EXTWPTR(%a6),%a0 2509 lea FP_SRC(%a6),%a1 2510 mov.l &0xc,%d0 2511 bsr.l _imem_read 2512 2513 tst.l %d1 2514 bne.w iea_iacc 2515 2516 bra.b iea_op_setsrc 2517 2518 iea_op_pack: 2519 2520 mov.l EXC_EXTWPTR(%a6),%a0 2521 lea FP_SRC(%a6),%a1 2522 mov.l &0xc,%d0 2523 bsr.l _imem_read 2524 2525 tst.l %d1 2526 bne.w iea_iacc 2527 2528 # The packed operand is an INF or a NAN if th 2529 bfextu FP_SRC(%a6){&1:&15},% 2530 cmpi.w %d0,&0x7fff 2531 beq.b iea_op_setsrc 2532 2533 # The packed operand is a zero if the mantiss 2534 # a normal packed op. 2535 mov.b 3+FP_SRC(%a6),%d0 2536 andi.b &0x0f,%d0 2537 bne.b iea_op_gp_not_spec 2538 tst.l FP_SRC_HI(%a6) 2539 bne.b iea_op_gp_not_spec 2540 tst.l FP_SRC_LO(%a6) 2541 beq.b iea_op_setsrc 2542 iea_op_gp_not_spec: 2543 lea FP_SRC(%a6),%a0 2544 bsr.l decbin 2545 fmovm.x &0x80,FP_SRC(%a6) 2546 2547 iea_op_setsrc: 2548 addi.l &0xc,EXC_EXTWPTR(%a6) 2549 2550 # FP_SRC now holds the src operand. 2551 lea FP_SRC(%a6),%a0 2552 bsr.l set_tag_x 2553 mov.b %d0,STAG(%a6) 2554 cmpi.b %d0,&UNNORM 2555 bne.b iea_op_getdst 2556 bsr.l unnorm_fix 2557 mov.b %d0,STAG(%a6) 2558 iea_op_getdst: 2559 clr.b STORE_FLG(%a6) 2560 2561 btst &0x5,1+EXC_CMDREG(%a6 2562 beq.b iea_op_extract 2563 btst &0x4,1+EXC_CMDREG(%a6 2564 bne.b iea_op_spec 2565 2566 iea_op_loaddst: 2567 bfextu EXC_CMDREG(%a6){&6:&3 2568 bsr.l load_fpn2 2569 2570 lea FP_DST(%a6),%a0 2571 bsr.l set_tag_x 2572 mov.b %d0,DTAG(%a6) 2573 cmpi.b %d0,&UNNORM 2574 bne.b iea_op_extract 2575 bsr.l unnorm_fix 2576 mov.b %d0,DTAG(%a6) 2577 bra.b iea_op_extract 2578 2579 # the operation is fsincos, ftst, or fcmp. on 2580 iea_op_spec: 2581 btst &0x3,1+EXC_CMDREG(%a6 2582 beq.b iea_op_extract 2583 # now, we're left with ftst and fcmp. so, fir 2584 # store a result. then, only fcmp will branch 2585 st STORE_FLG(%a6) 2586 btst &0x1,1+EXC_CMDREG(%a6 2587 beq.b iea_op_loaddst 2588 2589 iea_op_extract: 2590 clr.l %d0 2591 mov.b FPCR_MODE(%a6),%d0 2592 2593 mov.b 1+EXC_CMDREG(%a6),%d1 2594 andi.w &0x007f,%d1 2595 2596 fmov.l &0x0,%fpcr 2597 fmov.l &0x0,%fpsr 2598 2599 lea FP_SRC(%a6),%a0 2600 lea FP_DST(%a6),%a1 2601 2602 mov.l (tbl_unsupp.l,%pc,%d1 2603 jsr (tbl_unsupp.l,%pc,%d1 2604 2605 # 2606 # Exceptions in order of precedence: 2607 # BSUN : none 2608 # SNAN : all operations 2609 # OPERR : all reg-reg or mem-reg oper 2610 # OVFL : same as OPERR 2611 # UNFL : same as OPERR 2612 # DZ : same as OPERR 2613 # INEX2 : same as OPERR 2614 # INEX1 : all packed immediate operat 2615 # 2616 2617 # we determine the highest priority exception 2618 # emulation routine that has also been enable 2619 mov.b FPCR_ENABLE(%a6),%d0 2620 bne.b iea_op_ena 2621 2622 # now, we save the result, unless, of course, 2623 # these don't save results. 2624 iea_op_save: 2625 tst.b STORE_FLG(%a6) 2626 bne.b iea_op_exit1 2627 2628 iea_op_store: 2629 bfextu EXC_CMDREG(%a6){&6:&3 2630 bsr.l store_fpreg 2631 2632 iea_op_exit1: 2633 mov.l EXC_PC(%a6),USER_FPIA 2634 mov.l EXC_EXTWPTR(%a6),EXC_ 2635 2636 fmovm.x EXC_FPREGS(%a6),&0xc0 2637 fmovm.l USER_FPCR(%a6),%fpcr, 2638 movm.l EXC_DREGS(%a6),&0x030 2639 2640 unlk %a6 2641 2642 btst &0x7,(%sp) 2643 bne.w iea_op_trace 2644 2645 bra.l _fpsp_done 2646 2647 iea_op_ena: 2648 and.b FPSR_EXCEPT(%a6),%d0 2649 bfffo %d0{&24:&8},%d0 2650 bne.b iea_op_exc 2651 2652 # no exception occurred. now, did a disabled, 2653 # enabled? if so, then we have to stuff an ov 2654 btst &ovfl_bit,FPSR_EXCEPT 2655 beq.b iea_op_save 2656 2657 iea_op_ovfl: 2658 btst &inex2_bit,FPCR_ENABL 2659 beq.b iea_op_store 2660 bra.b iea_op_exc_ovfl 2661 2662 # an enabled exception occurred. we have to i 2663 # the machine. 2664 iea_op_exc: 2665 subi.l &24,%d0 2666 cmpi.b %d0,&0x6 2667 bne.b iea_op_exc_force 2668 2669 # the enabled exception was inexact. so, if i 2670 # or underflow that was disabled, then we hav 2671 # underflow frame. 2672 btst &ovfl_bit,FPSR_EXCEPT 2673 bne.b iea_op_exc_ovfl 2674 btst &unfl_bit,FPSR_EXCEPT 2675 bne.b iea_op_exc_unfl 2676 2677 iea_op_exc_force: 2678 mov.w (tbl_iea_except.b,%pc 2679 bra.b iea_op_exit2 2680 2681 tbl_iea_except: 2682 short 0xe002, 0xe006, 0xe00 2683 short 0xe003, 0xe002, 0xe00 2684 2685 iea_op_exc_ovfl: 2686 mov.w &0xe005,2+FP_SRC(%a6) 2687 bra.b iea_op_exit2 2688 2689 iea_op_exc_unfl: 2690 mov.w &0xe003,2+FP_SRC(%a6) 2691 2692 iea_op_exit2: 2693 mov.l EXC_PC(%a6),USER_FPIA 2694 mov.l EXC_EXTWPTR(%a6),EXC_ 2695 2696 fmovm.x EXC_FPREGS(%a6),&0xc0 2697 fmovm.l USER_FPCR(%a6),%fpcr, 2698 movm.l EXC_DREGS(%a6),&0x030 2699 2700 frestore FP_SRC(%a6) 2701 2702 unlk %a6 2703 2704 btst &0x7,(%sp) 2705 bne.b iea_op_trace 2706 2707 bra.l _fpsp_done 2708 2709 # 2710 # The opclass two instruction that took an "U 2711 # exception was being traced. Make the "curre 2712 # the trace stack frame then jump to _real_tr 2713 # 2714 # UNIMP EA FRAME TR 2715 # ***************** ***** 2716 # * 0x0 * 0x0f0 * * 2717 # ***************** * 2718 # * Current * ***** 2719 # * PC * * 0x2 2720 # ***************** ***** 2721 # * SR * * 2722 # ***************** * 2723 # ***** 2724 # * 2725 # ***** 2726 iea_op_trace: 2727 mov.l (%sp),-(%sp) 2728 mov.w 0x8(%sp),0x4(%sp) 2729 mov.w &0x2024,0x6(%sp) 2730 fmov.l %fpiar,0x8(%sp) 2731 2732 bra.l _real_trace 2733 2734 ############################################# 2735 iea_fmovm: 2736 btst &14,%d0 2737 beq.w iea_fmovm_ctrl 2738 2739 iea_fmovm_data: 2740 2741 btst &0x5,EXC_SR(%a6) 2742 bne.b iea_fmovm_data_s 2743 2744 iea_fmovm_data_u: 2745 mov.l %usp,%a0 2746 mov.l %a0,EXC_A7(%a6) 2747 bsr.l fmovm_dynamic 2748 mov.l EXC_A7(%a6),%a0 2749 mov.l %a0,%usp 2750 bra.w iea_fmovm_exit 2751 2752 iea_fmovm_data_s: 2753 clr.b SPCOND_FLG(%a6) 2754 lea 0x2+EXC_VOFF(%a6),%a0 2755 mov.l %a0,EXC_A7(%a6) 2756 bsr.l fmovm_dynamic 2757 2758 cmpi.b SPCOND_FLG(%a6),&mda7 2759 beq.w iea_fmovm_data_predec 2760 cmpi.b SPCOND_FLG(%a6),&mia7 2761 bne.w iea_fmovm_exit 2762 2763 # right now, d0 = the size. 2764 # the data has been fetched from the supervis 2765 # incremented the stack pointer by the approp 2766 # do it here. 2767 iea_fmovm_data_postinc: 2768 btst &0x7,EXC_SR(%a6) 2769 bne.b iea_fmovm_data_pi_tra 2770 2771 mov.w EXC_SR(%a6),(EXC_SR,% 2772 mov.l EXC_EXTWPTR(%a6),(EXC 2773 mov.w &0x00f0,(EXC_VOFF,%a6 2774 2775 lea (EXC_SR,%a6,%d0),%a0 2776 mov.l %a0,EXC_SR(%a6) 2777 2778 fmovm.x EXC_FP0(%a6),&0xc0 2779 fmovm.l USER_FPCR(%a6),%fpcr, 2780 movm.l EXC_DREGS(%a6),&0x030 2781 2782 unlk %a6 2783 mov.l (%sp)+,%sp 2784 bra.l _fpsp_done 2785 2786 iea_fmovm_data_pi_trace: 2787 mov.w EXC_SR(%a6),(EXC_SR-0 2788 mov.l EXC_EXTWPTR(%a6),(EXC 2789 mov.w &0x2024,(EXC_VOFF-0x4 2790 mov.l EXC_PC(%a6),(EXC_VOFF 2791 2792 lea (EXC_SR-0x4,%a6,%d0), 2793 mov.l %a0,EXC_SR(%a6) 2794 2795 fmovm.x EXC_FP0(%a6),&0xc0 2796 fmovm.l USER_FPCR(%a6),%fpcr, 2797 movm.l EXC_DREGS(%a6),&0x030 2798 2799 unlk %a6 2800 mov.l (%sp)+,%sp 2801 bra.l _real_trace 2802 2803 # right now, d1 = size and d0 = the strg. 2804 iea_fmovm_data_predec: 2805 mov.b %d1,EXC_VOFF(%a6) 2806 mov.b %d0,0x1+EXC_VOFF(%a6) 2807 2808 fmovm.x EXC_FP0(%a6),&0xc0 2809 fmovm.l USER_FPCR(%a6),%fpcr, 2810 movm.l EXC_DREGS(%a6),&0x030 2811 2812 mov.l (%a6),-(%sp) 2813 mov.l %d0,-(%sp) 2814 mov.l %d1,-(%sp) 2815 mov.l EXC_EXTWPTR(%a6),-(%s 2816 2817 clr.l %d0 2818 mov.b 0x1+EXC_VOFF(%a6),%d0 2819 neg.l %d0 2820 2821 btst &0x7,EXC_SR(%a6) 2822 beq.b iea_fmovm_data_p2 2823 2824 mov.w EXC_SR(%a6),(EXC_SR-0 2825 mov.l EXC_PC(%a6),(EXC_VOFF 2826 mov.l (%sp)+,(EXC_PC-0x4,%a 2827 mov.w &0x2024,(EXC_VOFF-0x4 2828 2829 pea (%a6,%d0) 2830 bra.b iea_fmovm_data_p3 2831 2832 iea_fmovm_data_p2: 2833 mov.w EXC_SR(%a6),(EXC_SR,% 2834 mov.l (%sp)+,(EXC_PC,%a6,%d 2835 mov.w &0x00f0,(EXC_VOFF,%a6 2836 2837 pea (0x4,%a6,%d0) 2838 2839 iea_fmovm_data_p3: 2840 clr.l %d1 2841 mov.b EXC_VOFF(%a6),%d1 2842 2843 tst.b %d1 2844 bpl.b fm_1 2845 fmovm.x &0x80,(0x4+0x8,%a6,%d 2846 addi.l &0xc,%d0 2847 fm_1: 2848 lsl.b &0x1,%d1 2849 bpl.b fm_2 2850 fmovm.x &0x40,(0x4+0x8,%a6,%d 2851 addi.l &0xc,%d0 2852 fm_2: 2853 lsl.b &0x1,%d1 2854 bpl.b fm_3 2855 fmovm.x &0x20,(0x4+0x8,%a6,%d 2856 addi.l &0xc,%d0 2857 fm_3: 2858 lsl.b &0x1,%d1 2859 bpl.b fm_4 2860 fmovm.x &0x10,(0x4+0x8,%a6,%d 2861 addi.l &0xc,%d0 2862 fm_4: 2863 lsl.b &0x1,%d1 2864 bpl.b fm_5 2865 fmovm.x &0x08,(0x4+0x8,%a6,%d 2866 addi.l &0xc,%d0 2867 fm_5: 2868 lsl.b &0x1,%d1 2869 bpl.b fm_6 2870 fmovm.x &0x04,(0x4+0x8,%a6,%d 2871 addi.l &0xc,%d0 2872 fm_6: 2873 lsl.b &0x1,%d1 2874 bpl.b fm_7 2875 fmovm.x &0x02,(0x4+0x8,%a6,%d 2876 addi.l &0xc,%d0 2877 fm_7: 2878 lsl.b &0x1,%d1 2879 bpl.b fm_end 2880 fmovm.x &0x01,(0x4+0x8,%a6,%d 2881 fm_end: 2882 mov.l 0x4(%sp),%d1 2883 mov.l 0x8(%sp),%d0 2884 mov.l 0xc(%sp),%a6 2885 mov.l (%sp)+,%sp 2886 2887 btst &0x7,(%sp) 2888 beq.l _fpsp_done 2889 bra.l _real_trace 2890 2891 ############################################# 2892 iea_fmovm_ctrl: 2893 2894 bsr.l fmovm_ctrl 2895 2896 iea_fmovm_exit: 2897 fmovm.x EXC_FPREGS(%a6),&0xc0 2898 fmovm.l USER_FPCR(%a6),%fpcr, 2899 movm.l EXC_DREGS(%a6),&0x030 2900 2901 btst &0x7,EXC_SR(%a6) 2902 bne.b iea_fmovm_trace 2903 2904 mov.l EXC_EXTWPTR(%a6),EXC_ 2905 2906 unlk %a6 2907 2908 bra.l _fpsp_done 2909 2910 # 2911 # The control reg instruction that took an "U 2912 # exception was being traced. The "Current PC 2913 # PC stacked for Unimp EA. The "Next PC" is i 2914 # After fixing the stack frame, jump to _real 2915 # 2916 # UNIMP EA FRAME TR 2917 # ***************** ***** 2918 # * 0x0 * 0x0f0 * * 2919 # ***************** * 2920 # * Current * ***** 2921 # * PC * * 0x2 2922 # ***************** ***** 2923 # * SR * * 2924 # ***************** * 2925 # ***** 2926 # * 2927 # ***** 2928 # this ain't a pretty solution, but it works: 2929 # -restore a6 (not with unlk) 2930 # -shift stack frame down over where old a6 u 2931 # -add LOCAL_SIZE to stack pointer 2932 iea_fmovm_trace: 2933 mov.l (%a6),%a6 2934 mov.w EXC_SR+LOCAL_SIZE(%sp 2935 mov.l EXC_PC+LOCAL_SIZE(%sp 2936 mov.l EXC_EXTWPTR+LOCAL_SIZ 2937 mov.w &0x2024,0x6+LOCAL_SIZ 2938 add.l &LOCAL_SIZE,%sp 2939 2940 bra.l _real_trace 2941 2942 ############################################# 2943 # The FPU is disabled and so we should really 2944 # F Emulator" exception. So, here we create a 2945 # from our 4-word stack frame. This means we 2946 # the faulting instruction to get the "next P 2947 # immediate operands but requires some extra 2948 # which can use most addressing modes. 2949 iea_disabled: 2950 mov.l (%sp)+,%d0 2951 2952 link %a6,&-LOCAL_SIZE 2953 2954 movm.l &0x0303,EXC_DREGS(%a6 2955 2956 # PC of instruction that took the exception i 2957 mov.l EXC_PC(%a6),EXC_EXTWP 2958 mov.l EXC_EXTWPTR(%a6),%a0 2959 addq.l &0x4,EXC_EXTWPTR(%a6) 2960 bsr.l _imem_read_long 2961 mov.l %d0,EXC_OPWORD(%a6) 2962 2963 tst.w %d0 2964 bmi.b iea_dis_fmovm 2965 # instruction is using an extended precision 2966 # the total instruction length is 16 bytes. 2967 iea_dis_immed: 2968 mov.l &0x10,%d0 2969 bra.b iea_dis_cont 2970 iea_dis_fmovm: 2971 btst &0xe,%d0 2972 bne.b iea_dis_fmovm_data 2973 # the instruction is a fmovm.l with 2 or 3 re 2974 bfextu %d0{&19:&3},%d1 2975 mov.l &0xc,%d0 2976 cmpi.b %d1,&0x7 2977 bne.b iea_dis_cont 2978 addq.l &0x4,%d0 2979 bra.b iea_dis_cont 2980 # the instruction is an fmovm.x dynamic which 2981 # modes and thus can have several different t 2982 # call fmovm_calc_ea which will go through th 2983 # as a by-product, will tell us how long the 2984 iea_dis_fmovm_data: 2985 clr.l %d0 2986 bsr.l fmovm_calc_ea 2987 mov.l EXC_EXTWPTR(%a6),%d0 2988 sub.l EXC_PC(%a6),%d0 2989 iea_dis_cont: 2990 mov.w %d0,EXC_VOFF(%a6) 2991 2992 movm.l EXC_DREGS(%a6),&0x030 2993 2994 unlk %a6 2995 2996 # here, we actually create the 8-word frame f 2997 # with the "next PC" as additional info. 2998 # the <ea> field is let as undefined. 2999 subq.l &0x8,%sp 3000 mov.l %d0,-(%sp) 3001 mov.w 0xc(%sp),0x4(%sp) 3002 mov.l 0xe(%sp),0x6(%sp) 3003 clr.l %d0 3004 mov.w 0x12(%sp),%d0 3005 mov.l 0x6(%sp),0x10(%sp) 3006 add.l %d0,0x6(%sp) 3007 mov.w &0x402c,0xa(%sp) 3008 mov.l (%sp)+,%d0 3009 3010 bra.l _real_fpu_disabled 3011 3012 ########## 3013 3014 iea_iacc: 3015 movc %pcr,%d0 3016 btst &0x1,%d0 3017 bne.b iea_iacc_cont 3018 fmovm.l USER_FPCR(%a6),%fpcr, 3019 fmovm.x EXC_FPREGS(%a6),&0xc0 3020 iea_iacc_cont: 3021 movm.l EXC_DREGS(%a6),&0x030 3022 3023 unlk %a6 3024 3025 subq.w &0x8,%sp 3026 mov.l 0x8(%sp),(%sp) 3027 mov.w 0xc(%sp),0x4(%sp) 3028 mov.w &0x4008,0x6(%sp) 3029 mov.l 0x2(%sp),0x8(%sp) 3030 mov.l &0x09428001,0xc(%sp) 3031 3032 iea_acc_done: 3033 btst &0x5,(%sp) 3034 beq.b iea_acc_done2 3035 bset &0x2,0xd(%sp) 3036 3037 iea_acc_done2: 3038 bra.l _real_access 3039 3040 iea_dacc: 3041 lea -LOCAL_SIZE(%a6),%sp 3042 3043 movc %pcr,%d1 3044 btst &0x1,%d1 3045 bne.b iea_dacc_cont 3046 fmovm.x EXC_FPREGS(%a6),&0xc0 3047 fmovm.l LOCAL_SIZE+USER_FPCR( 3048 iea_dacc_cont: 3049 mov.l (%a6),%a6 3050 3051 mov.l 0x4+LOCAL_SIZE(%sp),- 3052 mov.w 0x8+LOCAL_SIZE(%sp),- 3053 mov.w &0x4008,-0x8+0xa+LOCA 3054 mov.l %a0,-0x8+0xc+LOCAL_SI 3055 mov.w %d0,-0x8+0x10+LOCAL_S 3056 mov.w &0x0001,-0x8+0x12+LOC 3057 3058 movm.l LOCAL_SIZE+EXC_DREGS( 3059 add.w &LOCAL_SIZE-0x4,%sp 3060 3061 bra.b iea_acc_done 3062 3063 ############################################# 3064 # XDEF ************************************** 3065 # _fpsp_operr(): 060FPSP entry point fo 3066 # 3067 # This handler should be the first code 3068 # FP Operand Error exception in an oper 3069 # 3070 # XREF ************************************** 3071 # _imem_read_long() - read instruction 3072 # fix_skewed_ops() - adjust src operand 3073 # _real_operr() - "callout" to operatin 3074 # _dmem_write_{byte,word,long}() - stor 3075 # store_dreg_{b,w,l}() - store data to 3076 # facc_out_{b,w,l}() - store to memory 3077 # 3078 # INPUT ************************************* 3079 # - The system stack contains the FP Op 3080 # - The fsave frame contains the source 3081 # 3082 # OUTPUT ************************************ 3083 # No access error: 3084 # - The system stack is unchanged 3085 # - The fsave frame contains the adjust 3086 # 3087 # ALGORITHM ********************************* 3088 # In a system where the FP Operr except 3089 # is to get to the handler specified at _real 3090 # for opclass zero and two instruction taking 3091 # input operand in the fsave frame may be inc 3092 # and needs to be corrected. This handler cal 3093 # do just this and then exits through _real_o 3094 # For opclass 3 instructions, the 060 d 3095 # operr result out to memory or data register 3096 # This code must emulate the move out before 3097 # _real_inex(). The move out, if to memory, i 3098 # _mem_write() "callout" routines that may re 3099 # In this special case, the handler must exit 3100 # which creates an access error stack frame f 3101 # stack frame. 3102 # 3103 ############################################# 3104 3105 global _fpsp_operr 3106 _fpsp_operr: 3107 3108 link.w %a6,&-LOCAL_SIZE 3109 3110 fsave FP_SRC(%a6) 3111 3112 movm.l &0x0303,EXC_DREGS(%a6 3113 fmovm.l %fpcr,%fpsr,%fpiar,US 3114 fmovm.x &0xc0,EXC_FPREGS(%a6) 3115 3116 # the FPIAR holds the "current PC" of the fau 3117 mov.l USER_FPIAR(%a6),EXC_E 3118 3119 mov.l EXC_EXTWPTR(%a6),%a0 3120 addq.l &0x4,EXC_EXTWPTR(%a6) 3121 bsr.l _imem_read_long 3122 mov.l %d0,EXC_OPWORD(%a6) 3123 3124 ############################################# 3125 3126 btst &13,%d0 3127 bne.b foperr_out 3128 3129 3130 # here, we simply see if the operand in the f 3131 # this would be the case for opclass two oper 3132 # denorm operand in the sgl or dbl format. NA 3133 # cause an operr so we don't need to check fo 3134 lea FP_SRC(%a6),%a0 3135 bsr.l fix_skewed_ops 3136 3137 foperr_exit: 3138 fmovm.x EXC_FPREGS(%a6),&0xc0 3139 fmovm.l USER_FPCR(%a6),%fpcr, 3140 movm.l EXC_DREGS(%a6),&0x030 3141 3142 frestore FP_SRC(%a6) 3143 3144 unlk %a6 3145 bra.l _real_operr 3146 3147 ############################################# 3148 3149 # 3150 # the hardware does not save the default resu 3151 # operand error exceptions. we do this here b 3152 # the user operand error handler. 3153 # 3154 # byte, word, and long destination format ope 3155 # through here. we simply need to test the si 3156 # operand and save the appropriate minimum or 3157 # to the effective address as pointed to by t 3158 # 3159 # although packed opclass three operations ca 3160 # exceptions, they won't pass through here si 3161 # first by the unsupported data format except 3162 # sends them directly to _real_operr() if nec 3163 # 3164 foperr_out: 3165 3166 mov.w FP_SRC_EX(%a6),%d1 3167 andi.w &0x7fff,%d1 3168 cmpi.w %d1,&0x7fff 3169 bne.b foperr_out_not_qnan 3170 # the operand is either an infinity or a QNAN 3171 tst.l FP_SRC_LO(%a6) 3172 bne.b foperr_out_qnan 3173 mov.l FP_SRC_HI(%a6),%d1 3174 andi.l &0x7fffffff,%d1 3175 beq.b foperr_out_not_qnan 3176 foperr_out_qnan: 3177 mov.l FP_SRC_HI(%a6),L_SCR1 3178 bra.b foperr_out_jmp 3179 3180 foperr_out_not_qnan: 3181 mov.l &0x7fffffff,%d1 3182 tst.b FP_SRC_EX(%a6) 3183 bpl.b foperr_out_not_qnan2 3184 addq.l &0x1,%d1 3185 foperr_out_not_qnan2: 3186 mov.l %d1,L_SCR1(%a6) 3187 3188 foperr_out_jmp: 3189 bfextu %d0{&19:&3},%d0 3190 mov.b 1+EXC_OPWORD(%a6),%d1 3191 mov.w (tbl_operr.b,%pc,%d0. 3192 jmp (tbl_operr.b,%pc,%a0) 3193 3194 tbl_operr: 3195 short foperr_out_l - tbl_op 3196 short tbl_operr - tbl_op 3197 short tbl_operr - tbl_op 3198 short foperr_exit - tbl_op 3199 short foperr_out_w - tbl_op 3200 short tbl_operr - tbl_op 3201 short foperr_out_b - tbl_op 3202 short tbl_operr - tbl_op 3203 3204 foperr_out_b: 3205 mov.b L_SCR1(%a6),%d0 3206 cmpi.b %d1,&0x7 3207 ble.b foperr_out_b_save_dn 3208 mov.l EXC_EA(%a6),%a0 3209 bsr.l _dmem_write_byte 3210 3211 tst.l %d1 3212 bne.l facc_out_b 3213 3214 bra.w foperr_exit 3215 foperr_out_b_save_dn: 3216 andi.w &0x0007,%d1 3217 bsr.l store_dreg_b 3218 bra.w foperr_exit 3219 3220 foperr_out_w: 3221 mov.w L_SCR1(%a6),%d0 3222 cmpi.b %d1,&0x7 3223 ble.b foperr_out_w_save_dn 3224 mov.l EXC_EA(%a6),%a0 3225 bsr.l _dmem_write_word 3226 3227 tst.l %d1 3228 bne.l facc_out_w 3229 3230 bra.w foperr_exit 3231 foperr_out_w_save_dn: 3232 andi.w &0x0007,%d1 3233 bsr.l store_dreg_w 3234 bra.w foperr_exit 3235 3236 foperr_out_l: 3237 mov.l L_SCR1(%a6),%d0 3238 cmpi.b %d1,&0x7 3239 ble.b foperr_out_l_save_dn 3240 mov.l EXC_EA(%a6),%a0 3241 bsr.l _dmem_write_long 3242 3243 tst.l %d1 3244 bne.l facc_out_l 3245 3246 bra.w foperr_exit 3247 foperr_out_l_save_dn: 3248 andi.w &0x0007,%d1 3249 bsr.l store_dreg_l 3250 bra.w foperr_exit 3251 3252 ############################################# 3253 # XDEF ************************************** 3254 # _fpsp_snan(): 060FPSP entry point for 3255 # 3256 # This handler should be the first code 3257 # FP Signalling NAN exception in an ope 3258 # 3259 # XREF ************************************** 3260 # _imem_read_long() - read instruction 3261 # fix_skewed_ops() - adjust src operand 3262 # _real_snan() - "callout" to operating 3263 # _dmem_write_{byte,word,long}() - stor 3264 # store_dreg_{b,w,l}() - store data to 3265 # facc_out_{b,w,l,d,x}() - store to mem 3266 # _calc_ea_fout() - fix An if <ea> is - 3267 # 3268 # INPUT ************************************* 3269 # - The system stack contains the FP SN 3270 # - The fsave frame contains the source 3271 # 3272 # OUTPUT ************************************ 3273 # No access error: 3274 # - The system stack is unchanged 3275 # - The fsave frame contains the adjust 3276 # 3277 # ALGORITHM ********************************* 3278 # In a system where the FP SNAN excepti 3279 # is to get to the handler specified at _real 3280 # for opclass zero and two instructions takin 3281 # input operand in the fsave frame may be inc 3282 # and needs to be corrected. This handler cal 3283 # do just this and then exits through _real_s 3284 # For opclass 3 instructions, the 060 d 3285 # SNAN result out to memory or data register 3286 # This code must emulate the move out before 3287 # _real_snan(). The move out, if to memory, i 3288 # _mem_write() "callout" routines that may re 3289 # In this special case, the handler must exit 3290 # which creates an access error stack frame f 3291 # stack frame. 3292 # For the case of an extended precision 3293 # if the effective addressing mode was -() or 3294 # register must get updated by calling _calc_ 3295 # was -(a7) from supervisor mode, then the ex 3296 # on the system stack must be carefully moved 3297 # for the operand being moved. 3298 # 3299 ############################################# 3300 3301 global _fpsp_snan 3302 _fpsp_snan: 3303 3304 link.w %a6,&-LOCAL_SIZE 3305 3306 fsave FP_SRC(%a6) 3307 3308 movm.l &0x0303,EXC_DREGS(%a6 3309 fmovm.l %fpcr,%fpsr,%fpiar,US 3310 fmovm.x &0xc0,EXC_FPREGS(%a6) 3311 3312 # the FPIAR holds the "current PC" of the fau 3313 mov.l USER_FPIAR(%a6),EXC_E 3314 3315 mov.l EXC_EXTWPTR(%a6),%a0 3316 addq.l &0x4,EXC_EXTWPTR(%a6) 3317 bsr.l _imem_read_long 3318 mov.l %d0,EXC_OPWORD(%a6) 3319 3320 ############################################# 3321 3322 btst &13,%d0 3323 bne.w fsnan_out 3324 3325 3326 # here, we simply see if the operand in the f 3327 # this would be the case for opclass two oper 3328 # denorm operand in the sgl or dbl format. NA 3329 # fixed here. 3330 lea FP_SRC(%a6),%a0 3331 bsr.l fix_skewed_ops 3332 3333 fsnan_exit: 3334 fmovm.x EXC_FPREGS(%a6),&0xc0 3335 fmovm.l USER_FPCR(%a6),%fpcr, 3336 movm.l EXC_DREGS(%a6),&0x030 3337 3338 frestore FP_SRC(%a6) 3339 3340 unlk %a6 3341 bra.l _real_snan 3342 3343 ############################################# 3344 3345 # 3346 # the hardware does not save the default resu 3347 # snan exceptions. we do this here before pas 3348 # the user snan handler. 3349 # 3350 # byte, word, long, and packed destination fo 3351 # through here. since packed format operation 3352 # fpsp_unsupp(), then we need to do nothing e 3353 # for byte, word, and long, we simply need to 3354 # operand and save the appropriate minimum or 3355 # to the effective address as pointed to by t 3356 # 3357 fsnan_out: 3358 3359 bfextu %d0{&19:&3},%d0 3360 mov.b 1+EXC_OPWORD(%a6),%d1 3361 mov.w (tbl_snan.b,%pc,%d0.w 3362 jmp (tbl_snan.b,%pc,%a0) 3363 3364 tbl_snan: 3365 short fsnan_out_l - tbl_sna 3366 short fsnan_out_s - tbl_sna 3367 short fsnan_out_x - tbl_sna 3368 short tbl_snan - tbl_sna 3369 short fsnan_out_w - tbl_sna 3370 short fsnan_out_d - tbl_sna 3371 short fsnan_out_b - tbl_sna 3372 short tbl_snan - tbl_sna 3373 3374 fsnan_out_b: 3375 mov.b FP_SRC_HI(%a6),%d0 3376 bset &6,%d0 3377 cmpi.b %d1,&0x7 3378 ble.b fsnan_out_b_dn 3379 mov.l EXC_EA(%a6),%a0 3380 bsr.l _dmem_write_byte 3381 3382 tst.l %d1 3383 bne.l facc_out_b 3384 3385 bra.w fsnan_exit 3386 fsnan_out_b_dn: 3387 andi.w &0x0007,%d1 3388 bsr.l store_dreg_b 3389 bra.w fsnan_exit 3390 3391 fsnan_out_w: 3392 mov.w FP_SRC_HI(%a6),%d0 3393 bset &14,%d0 3394 cmpi.b %d1,&0x7 3395 ble.b fsnan_out_w_dn 3396 mov.l EXC_EA(%a6),%a0 3397 bsr.l _dmem_write_word 3398 3399 tst.l %d1 3400 bne.l facc_out_w 3401 3402 bra.w fsnan_exit 3403 fsnan_out_w_dn: 3404 andi.w &0x0007,%d1 3405 bsr.l store_dreg_w 3406 bra.w fsnan_exit 3407 3408 fsnan_out_l: 3409 mov.l FP_SRC_HI(%a6),%d0 3410 bset &30,%d0 3411 cmpi.b %d1,&0x7 3412 ble.b fsnan_out_l_dn 3413 mov.l EXC_EA(%a6),%a0 3414 bsr.l _dmem_write_long 3415 3416 tst.l %d1 3417 bne.l facc_out_l 3418 3419 bra.w fsnan_exit 3420 fsnan_out_l_dn: 3421 andi.w &0x0007,%d1 3422 bsr.l store_dreg_l 3423 bra.w fsnan_exit 3424 3425 fsnan_out_s: 3426 cmpi.b %d1,&0x7 3427 ble.b fsnan_out_d_dn 3428 mov.l FP_SRC_EX(%a6),%d0 3429 andi.l &0x80000000,%d0 3430 ori.l &0x7fc00000,%d0 3431 mov.l FP_SRC_HI(%a6),%d1 3432 lsr.l &0x8,%d1 3433 or.l %d1,%d0 3434 mov.l EXC_EA(%a6),%a0 3435 bsr.l _dmem_write_long 3436 3437 tst.l %d1 3438 bne.l facc_out_l 3439 3440 bra.w fsnan_exit 3441 fsnan_out_d_dn: 3442 mov.l FP_SRC_EX(%a6),%d0 3443 andi.l &0x80000000,%d0 3444 ori.l &0x7fc00000,%d0 3445 mov.l %d1,-(%sp) 3446 mov.l FP_SRC_HI(%a6),%d1 3447 lsr.l &0x8,%d1 3448 or.l %d1,%d0 3449 mov.l (%sp)+,%d1 3450 andi.w &0x0007,%d1 3451 bsr.l store_dreg_l 3452 bra.w fsnan_exit 3453 3454 fsnan_out_d: 3455 mov.l FP_SRC_EX(%a6),%d0 3456 andi.l &0x80000000,%d0 3457 ori.l &0x7ff80000,%d0 3458 mov.l FP_SRC_HI(%a6),%d1 3459 mov.l %d0,FP_SCR0_EX(%a6) 3460 mov.l &11,%d0 3461 lsr.l %d0,%d1 3462 or.l %d1,FP_SCR0_EX(%a6) 3463 mov.l FP_SRC_HI(%a6),%d1 3464 andi.l &0x000007ff,%d1 3465 ror.l %d0,%d1 3466 mov.l %d1,FP_SCR0_HI(%a6) 3467 mov.l FP_SRC_LO(%a6),%d1 3468 lsr.l %d0,%d1 3469 or.l %d1,FP_SCR0_HI(%a6) 3470 lea FP_SCR0(%a6),%a0 3471 mov.l EXC_EA(%a6),%a1 3472 movq.l &0x8,%d0 3473 bsr.l _dmem_write 3474 3475 tst.l %d1 3476 bne.l facc_out_d 3477 3478 bra.w fsnan_exit 3479 3480 # for extended precision, if the addressing m 3481 # post-increment, then the address register d 3482 # in addition, for pre-decrement, the stacked 3483 fsnan_out_x: 3484 clr.b SPCOND_FLG(%a6) 3485 3486 mov.w FP_SRC_EX(%a6),FP_SCR 3487 clr.w 2+FP_SCR0(%a6) 3488 mov.l FP_SRC_HI(%a6),%d0 3489 bset &30,%d0 3490 mov.l %d0,FP_SCR0_HI(%a6) 3491 mov.l FP_SRC_LO(%a6),FP_SCR 3492 3493 btst &0x5,EXC_SR(%a6) 3494 bne.b fsnan_out_x_s 3495 3496 mov.l %usp,%a0 3497 mov.l %a0,EXC_A7(%a6) 3498 mov.l (%a6),EXC_A6(%a6) 3499 3500 bsr.l _calc_ea_fout 3501 mov.l %a0,%a1 3502 mov.l %a0,EXC_EA(%a6) 3503 3504 mov.l EXC_A7(%a6),%a0 3505 mov.l %a0,%usp 3506 mov.l EXC_A6(%a6),(%a6) 3507 3508 fsnan_out_x_save: 3509 lea FP_SCR0(%a6),%a0 3510 movq.l &0xc,%d0 3511 bsr.l _dmem_write 3512 3513 tst.l %d1 3514 bne.l facc_out_x 3515 3516 bra.w fsnan_exit 3517 3518 fsnan_out_x_s: 3519 mov.l (%a6),EXC_A6(%a6) 3520 3521 bsr.l _calc_ea_fout 3522 mov.l %a0,%a1 3523 mov.l %a0,EXC_EA(%a6) 3524 3525 mov.l EXC_A6(%a6),(%a6) 3526 3527 cmpi.b SPCOND_FLG(%a6),&mda7 3528 bne.b fsnan_out_x_save 3529 3530 # the operation was "fmove.x SNAN,-(a7)" from 3531 fmovm.x EXC_FPREGS(%a6),&0xc0 3532 fmovm.l USER_FPCR(%a6),%fpcr, 3533 movm.l EXC_DREGS(%a6),&0x030 3534 3535 frestore FP_SRC(%a6) 3536 3537 mov.l EXC_A6(%a6),%a6 3538 3539 mov.l LOCAL_SIZE+EXC_SR(%sp 3540 mov.l LOCAL_SIZE+EXC_PC+0x2 3541 mov.l LOCAL_SIZE+EXC_EA(%sp 3542 3543 mov.l LOCAL_SIZE+FP_SCR0_EX 3544 mov.l LOCAL_SIZE+FP_SCR0_HI 3545 mov.l LOCAL_SIZE+FP_SCR0_LO 3546 3547 add.l &LOCAL_SIZE-0x8,%sp 3548 3549 bra.l _real_snan 3550 3551 ############################################# 3552 # XDEF ************************************** 3553 # _fpsp_inex(): 060FPSP entry point for 3554 # 3555 # This handler should be the first code 3556 # FP Inexact exception in an operating 3557 # 3558 # XREF ************************************** 3559 # _imem_read_long() - read instruction 3560 # fix_skewed_ops() - adjust src operand 3561 # set_tag_x() - determine optype of src 3562 # store_fpreg() - store opclass 0 or 2 3563 # unnorm_fix() - change UNNORM operands 3564 # load_fpn2() - load dst operand from F 3565 # smovcr() - emulate an "fmovcr" instru 3566 # fout() - emulate an opclass 3 instruc 3567 # tbl_unsupp - add of table of emulatio 3568 # _real_inex() - "callout" to operating 3569 # 3570 # INPUT ************************************* 3571 # - The system stack contains the FP In 3572 # - The fsave frame contains the source 3573 # 3574 # OUTPUT ************************************ 3575 # - The system stack is unchanged 3576 # - The fsave frame contains the adjust 3577 # 3578 # ALGORITHM ********************************* 3579 # In a system where the FP Inexact exce 3580 # is to get to the handler specified at _real 3581 # for opclass zero and two instruction taking 3582 # hardware doesn't store the correct result t 3583 # register as did the '040 and '881/2. This h 3584 # instruction in order to get this value and 3585 # correct register before calling _real_inex( 3586 # For opclass 3 instructions, the 060 d 3587 # inexact result out to memory or data regist 3588 # This code must emulate the move out by call 3589 # exiting through _real_inex(). 3590 # 3591 ############################################# 3592 3593 global _fpsp_inex 3594 _fpsp_inex: 3595 3596 link.w %a6,&-LOCAL_SIZE 3597 3598 fsave FP_SRC(%a6) 3599 3600 movm.l &0x0303,EXC_DREGS(%a6 3601 fmovm.l %fpcr,%fpsr,%fpiar,US 3602 fmovm.x &0xc0,EXC_FPREGS(%a6) 3603 3604 # the FPIAR holds the "current PC" of the fau 3605 mov.l USER_FPIAR(%a6),EXC_E 3606 3607 mov.l EXC_EXTWPTR(%a6),%a0 3608 addq.l &0x4,EXC_EXTWPTR(%a6) 3609 bsr.l _imem_read_long 3610 mov.l %d0,EXC_OPWORD(%a6) 3611 3612 ############################################# 3613 3614 btst &13,%d0 3615 bne.w finex_out 3616 3617 3618 # the hardware, for "fabs" and "fneg" w/ a lo 3619 # longword integer directly into the upper lo 3620 # w/ an exponent value of 0x401e. we convert 3621 bfextu %d0{&19:&3},%d0 3622 bne.b finex_cont 3623 cmpi.w FP_SRC_EX(%a6),&0x401 3624 bne.b finex_cont 3625 fmov.l &0x0,%fpcr 3626 fmov.l FP_SRC_HI(%a6),%fp0 3627 fmov.x %fp0,FP_SRC(%a6) 3628 mov.w &0xe001,0x2+FP_SRC(%a 3629 3630 finex_cont: 3631 lea FP_SRC(%a6),%a0 3632 bsr.l fix_skewed_ops 3633 3634 # Here, we zero the ccode and exception byte 3635 # emulate the whole instruction. Notice, thou 3636 # INEX1 bit. This is because a packed op has 3637 # to extended before arriving here. Therefore 3638 # INEX1 bit from when the operand was first c 3639 andi.l &0x00ff01ff,USER_FPSR 3640 3641 fmov.l &0x0,%fpcr 3642 fmov.l &0x0,%fpsr 3643 3644 bfextu EXC_EXTWORD(%a6){&0:& 3645 cmpi.b %d1,&0x17 3646 beq.w finex_fmovcr 3647 3648 lea FP_SRC(%a6),%a0 3649 bsr.l set_tag_x 3650 mov.b %d0,STAG(%a6) 3651 3652 # bits four and five of the fp extension word 3653 # operations that can pass through fpsp_inex( 3654 # will never take this exception, but fsincos 3655 btst &0x5,1+EXC_CMDREG(%a6 3656 beq.b finex_extract 3657 3658 btst &0x4,1+EXC_CMDREG(%a6 3659 bne.b finex_extract 3660 3661 bfextu EXC_CMDREG(%a6){&6:&3 3662 bsr.l load_fpn2 3663 3664 lea FP_DST(%a6),%a0 3665 bsr.l set_tag_x 3666 cmpi.b %d0,&UNNORM 3667 bne.b finex_op2_done 3668 bsr.l unnorm_fix 3669 finex_op2_done: 3670 mov.b %d0,DTAG(%a6) 3671 3672 finex_extract: 3673 clr.l %d0 3674 mov.b FPCR_MODE(%a6),%d0 3675 3676 mov.b 1+EXC_CMDREG(%a6),%d1 3677 andi.w &0x007f,%d1 3678 3679 lea FP_SRC(%a6),%a0 3680 lea FP_DST(%a6),%a1 3681 3682 mov.l (tbl_unsupp.l,%pc,%d1 3683 jsr (tbl_unsupp.l,%pc,%d1 3684 3685 # the operation has been emulated. the result 3686 finex_save: 3687 bfextu EXC_CMDREG(%a6){&6:&3 3688 bsr.l store_fpreg 3689 3690 finex_exit: 3691 fmovm.x EXC_FPREGS(%a6),&0xc0 3692 fmovm.l USER_FPCR(%a6),%fpcr, 3693 movm.l EXC_DREGS(%a6),&0x030 3694 3695 frestore FP_SRC(%a6) 3696 3697 unlk %a6 3698 bra.l _real_inex 3699 3700 finex_fmovcr: 3701 clr.l %d0 3702 mov.b FPCR_MODE(%a6),%d0 3703 mov.b 1+EXC_CMDREG(%a6),%d1 3704 andi.l &0x0000007f,%d1 3705 bsr.l smovcr 3706 bra.b finex_save 3707 3708 ############################################# 3709 3710 # 3711 # the hardware does not save the default resu 3712 # inexact exceptions. we do this here before 3713 # the user inexact handler. 3714 # 3715 # byte, word, and long destination format ope 3716 # through here. so can double and single prec 3717 # although packed opclass three operations ca 3718 # exceptions, they won't pass through here si 3719 # first by the unsupported data format except 3720 # sends them directly to _real_inex() if nece 3721 # 3722 finex_out: 3723 3724 mov.b &NORM,STAG(%a6) 3725 3726 clr.l %d0 3727 mov.b FPCR_MODE(%a6),%d0 3728 3729 andi.l &0xffff00ff,USER_FPSR 3730 3731 lea FP_SRC(%a6),%a0 3732 3733 bsr.l fout 3734 3735 bra.b finex_exit 3736 3737 ############################################# 3738 # XDEF ************************************** 3739 # _fpsp_dz(): 060FPSP entry point for F 3740 # 3741 # This handler should be the first code 3742 # the FP DZ exception in an operating s 3743 # 3744 # XREF ************************************** 3745 # _imem_read_long() - read instruction 3746 # fix_skewed_ops() - adjust fsave opera 3747 # _real_dz() - "callout" exit point fro 3748 # 3749 # INPUT ************************************* 3750 # - The system stack contains the FP DZ 3751 # - The fsave frame contains the source 3752 # 3753 # OUTPUT ************************************ 3754 # - The system stack contains the FP DZ 3755 # - The fsave frame contains the adjust 3756 # 3757 # ALGORITHM ********************************* 3758 # In a system where the DZ exception is 3759 # get to the handler specified at _real_dz(). 3760 # exception is taken, the input operand in th 3761 # be incorrect for some cases and need to be 3762 # adjusts the operand using fix_skewed_ops() 3763 # _real_dz(). 3764 # 3765 ############################################# 3766 3767 global _fpsp_dz 3768 _fpsp_dz: 3769 3770 link.w %a6,&-LOCAL_SIZE 3771 3772 fsave FP_SRC(%a6) 3773 3774 movm.l &0x0303,EXC_DREGS(%a6 3775 fmovm.l %fpcr,%fpsr,%fpiar,US 3776 fmovm.x &0xc0,EXC_FPREGS(%a6) 3777 3778 # the FPIAR holds the "current PC" of the fau 3779 mov.l USER_FPIAR(%a6),EXC_E 3780 3781 mov.l EXC_EXTWPTR(%a6),%a0 3782 addq.l &0x4,EXC_EXTWPTR(%a6) 3783 bsr.l _imem_read_long 3784 mov.l %d0,EXC_OPWORD(%a6) 3785 3786 ############################################# 3787 3788 3789 # here, we simply see if the operand in the f 3790 # this would be the case for opclass two oper 3791 # in the sgl or dbl format. 3792 lea FP_SRC(%a6),%a0 3793 bsr.l fix_skewed_ops 3794 3795 fdz_exit: 3796 fmovm.x EXC_FPREGS(%a6),&0xc0 3797 fmovm.l USER_FPCR(%a6),%fpcr, 3798 movm.l EXC_DREGS(%a6),&0x030 3799 3800 frestore FP_SRC(%a6) 3801 3802 unlk %a6 3803 bra.l _real_dz 3804 3805 ############################################# 3806 # XDEF ************************************** 3807 # _fpsp_fline(): 060FPSP entry point fo 3808 # exception when the "re 3809 # FPSP is implemented th 3810 # FP unimplemented instr 3811 # 3812 # This handler should be the first code 3813 # "Line F Emulator" exception in an ope 3814 # the reduced version of 060FPSP. 3815 # 3816 # XREF ************************************** 3817 # _real_fpu_disabled() - Handle "FPU di 3818 # _real_fline() - Handle all other case 3819 # 3820 # INPUT ************************************* 3821 # - The system stack contains a "Line F 3822 # stack frame. 3823 # 3824 # OUTPUT ************************************ 3825 # - The system stack is unchanged. 3826 # 3827 # ALGORITHM ********************************* 3828 # When a "Line F Emulator" exception oc 3829 # "FPU Unimplemented" instructions will not b 3830 # can occur because then FPU is disabled or t 3831 # classifed as "Line F". This module determin 3832 # calls the appropriate "callout". 3833 # 3834 ############################################# 3835 3836 global _fpsp_fline 3837 _fpsp_fline: 3838 3839 # check to see if the FPU is disabled. if so, 3840 # point for that condition. 3841 cmpi.w 0x6(%sp),&0x402c 3842 beq.l _real_fpu_disabled 3843 3844 bra.l _real_fline 3845 3846 ############################################# 3847 # XDEF ************************************** 3848 # _dcalc_ea(): calc correct <ea> from < 3849 # 3850 # XREF ************************************** 3851 # inc_areg() - increment an address reg 3852 # dec_areg() - decrement an address reg 3853 # 3854 # INPUT ************************************* 3855 # d0 = number of bytes to adjust <ea> b 3856 # 3857 # OUTPUT ************************************ 3858 # None 3859 # 3860 # ALGORITHM ********************************* 3861 # "Dummy" CALCulate Effective Address: 3862 # The stacked <ea> for FP unimplemented 3863 # two packed instructions is correct wi 3864 # 3865 # 1) -(An) : The register is not upda 3866 # Also, for extended preci 3867 # stacked <ea> value is 8 3868 # 2) (An)+ : The register is not upda 3869 # 3) #<data> : The upper longword of th 3870 # stacked b,w,l and s size 3871 # d,x, and p are not. 3872 # 3873 ############################################# 3874 3875 global _dcalc_ea 3876 _dcalc_ea: 3877 mov.l %d0, %a0 3878 3879 mov.b 1+EXC_OPWORD(%a6), %d 3880 mov.l %d0, %d1 3881 3882 andi.w &0x38, %d0 3883 andi.l &0x7, %d1 3884 3885 cmpi.b %d0,&0x18 3886 beq.b dcea_pi 3887 3888 cmpi.b %d0,&0x20 3889 beq.b dcea_pd 3890 3891 or.w %d1,%d0 3892 cmpi.b %d0,&0x3c 3893 3894 beq.b dcea_imm 3895 3896 mov.l EXC_EA(%a6),%a0 3897 rts 3898 3899 # need to set immediate data flag here since 3900 # an imem_read to fetch this later. 3901 dcea_imm: 3902 mov.b &immed_flg,SPCOND_FLG 3903 lea ([USER_FPIAR,%a6],0x4 3904 rts 3905 3906 # here, the <ea> is stacked correctly. howeve 3907 # address register... 3908 dcea_pi: 3909 mov.l %a0,%d0 3910 bsr.l inc_areg 3911 3912 mov.l EXC_EA(%a6),%a0 3913 rts 3914 3915 # the <ea> is stacked correctly for all but e 3916 # the <ea>s are 8 bytes too large. 3917 # it would make no sense to have a pre-decrem 3918 # mode so we don't even worry about this tric 3919 dcea_pd: 3920 mov.l %a0,%d0 3921 bsr.l dec_areg 3922 3923 mov.l EXC_EA(%a6),%a0 3924 3925 cmpi.b %d0,&0xc 3926 beq.b dcea_pd2 3927 rts 3928 dcea_pd2: 3929 sub.l &0x8,%a0 3930 mov.l %a0,EXC_EA(%a6) 3931 rts 3932 3933 ############################################# 3934 # XDEF ************************************** 3935 # _calc_ea_fout(): calculate correct st 3936 # and packed data opcl 3937 # 3938 # XREF ************************************** 3939 # None 3940 # 3941 # INPUT ************************************* 3942 # None 3943 # 3944 # OUTPUT ************************************ 3945 # a0 = return correct effective address 3946 # 3947 # ALGORITHM ********************************* 3948 # For opclass 3 extended and packed dat 3949 # stacked for the exception is incorrect for 3950 # modes. Also, while we're at it, the index r 3951 # updated. 3952 # So, for -(an), we must subtract 8 off 3953 # and return that value as the correct <ea> a 3954 # For (an)+, the stacked <ea> is correct but 3955 # 3956 ############################################# 3957 3958 # This calc_ea is currently used to retrieve 3959 # for fmove outs of type extended and packed. 3960 global _calc_ea_fout 3961 _calc_ea_fout: 3962 mov.b 1+EXC_OPWORD(%a6),%d0 3963 mov.l %d0,%d1 3964 3965 andi.w &0x38,%d0 3966 andi.l &0x7,%d1 3967 3968 cmpi.b %d0,&0x18 3969 beq.b ceaf_pi 3970 3971 cmpi.b %d0,&0x20 3972 beq.w ceaf_pd 3973 3974 mov.l EXC_EA(%a6),%a0 3975 rts 3976 3977 # (An)+ : extended and packed fmove out 3978 # : stacked <ea> is correct 3979 # : "An" not updated 3980 ceaf_pi: 3981 mov.w (tbl_ceaf_pi.b,%pc,%d 3982 mov.l EXC_EA(%a6),%a0 3983 jmp (tbl_ceaf_pi.b,%pc,%d 3984 3985 swbeg &0x8 3986 tbl_ceaf_pi: 3987 short ceaf_pi0 - tbl_ceaf_p 3988 short ceaf_pi1 - tbl_ceaf_p 3989 short ceaf_pi2 - tbl_ceaf_p 3990 short ceaf_pi3 - tbl_ceaf_p 3991 short ceaf_pi4 - tbl_ceaf_p 3992 short ceaf_pi5 - tbl_ceaf_p 3993 short ceaf_pi6 - tbl_ceaf_p 3994 short ceaf_pi7 - tbl_ceaf_p 3995 3996 ceaf_pi0: 3997 addi.l &0xc,EXC_DREGS+0x8(%a 3998 rts 3999 ceaf_pi1: 4000 addi.l &0xc,EXC_DREGS+0xc(%a 4001 rts 4002 ceaf_pi2: 4003 add.l &0xc,%a2 4004 rts 4005 ceaf_pi3: 4006 add.l &0xc,%a3 4007 rts 4008 ceaf_pi4: 4009 add.l &0xc,%a4 4010 rts 4011 ceaf_pi5: 4012 add.l &0xc,%a5 4013 rts 4014 ceaf_pi6: 4015 addi.l &0xc,EXC_A6(%a6) 4016 rts 4017 ceaf_pi7: 4018 mov.b &mia7_flg,SPCOND_FLG( 4019 addi.l &0xc,EXC_A7(%a6) 4020 rts 4021 4022 # -(An) : extended and packed fmove out 4023 # : stacked <ea> = actual <ea> + 8 4024 # : "An" not updated 4025 ceaf_pd: 4026 mov.w (tbl_ceaf_pd.b,%pc,%d 4027 mov.l EXC_EA(%a6),%a0 4028 sub.l &0x8,%a0 4029 sub.l &0x8,EXC_EA(%a6) 4030 jmp (tbl_ceaf_pd.b,%pc,%d 4031 4032 swbeg &0x8 4033 tbl_ceaf_pd: 4034 short ceaf_pd0 - tbl_ceaf_p 4035 short ceaf_pd1 - tbl_ceaf_p 4036 short ceaf_pd2 - tbl_ceaf_p 4037 short ceaf_pd3 - tbl_ceaf_p 4038 short ceaf_pd4 - tbl_ceaf_p 4039 short ceaf_pd5 - tbl_ceaf_p 4040 short ceaf_pd6 - tbl_ceaf_p 4041 short ceaf_pd7 - tbl_ceaf_p 4042 4043 ceaf_pd0: 4044 mov.l %a0,EXC_DREGS+0x8(%a6 4045 rts 4046 ceaf_pd1: 4047 mov.l %a0,EXC_DREGS+0xc(%a6 4048 rts 4049 ceaf_pd2: 4050 mov.l %a0,%a2 4051 rts 4052 ceaf_pd3: 4053 mov.l %a0,%a3 4054 rts 4055 ceaf_pd4: 4056 mov.l %a0,%a4 4057 rts 4058 ceaf_pd5: 4059 mov.l %a0,%a5 4060 rts 4061 ceaf_pd6: 4062 mov.l %a0,EXC_A6(%a6) 4063 rts 4064 ceaf_pd7: 4065 mov.l %a0,EXC_A7(%a6) 4066 mov.b &mda7_flg,SPCOND_FLG( 4067 rts 4068 4069 # 4070 # This table holds the offsets of the emulati 4071 # math operation relative to the address of t 4072 # routines like fadd/fmul/fabs. The transcend 4073 # this table is for the version if the 060FPS 4074 # The location within the table is determined 4075 # operation longword. 4076 # 4077 4078 swbeg &109 4079 tbl_unsupp: 4080 long fin - tbl 4081 long fint - tbl 4082 long tbl_unsupp - tbl 4083 long fintrz - tbl 4084 long fsqrt - tbl 4085 long tbl_unsupp - tbl 4086 long tbl_unsupp - tbl 4087 long tbl_unsupp - tbl 4088 long tbl_unsupp - tbl 4089 long tbl_unsupp - tbl 4090 long tbl_unsupp - tbl 4091 long tbl_unsupp - tbl 4092 long tbl_unsupp - tbl 4093 long tbl_unsupp - tbl 4094 long tbl_unsupp - tbl 4095 long tbl_unsupp - tbl 4096 long tbl_unsupp - tbl 4097 long tbl_unsupp - tbl 4098 long tbl_unsupp - tbl 4099 long tbl_unsupp - tbl 4100 long tbl_unsupp - tbl 4101 long tbl_unsupp - tbl 4102 long tbl_unsupp - tbl 4103 long tbl_unsupp - tbl 4104 long fabs - tbl 4105 long tbl_unsupp - tbl 4106 long fneg - tbl 4107 long tbl_unsupp - tbl 4108 long tbl_unsupp - tbl 4109 long tbl_unsupp - tbl 4110 long tbl_unsupp - tbl 4111 long tbl_unsupp - tbl 4112 long fdiv - tbl 4113 long tbl_unsupp - tbl 4114 long fadd - tbl 4115 long fmul - tbl 4116 long fsgldiv - tbl 4117 long tbl_unsupp - tbl 4118 long tbl_unsupp - tbl 4119 long fsglmul - tbl 4120 long fsub - tbl 4121 long tbl_unsupp - tbl 4122 long tbl_unsupp - tbl 4123 long tbl_unsupp - tbl 4124 long tbl_unsupp - tbl 4125 long tbl_unsupp - tbl 4126 long tbl_unsupp - tbl 4127 long tbl_unsupp - tbl 4128 long tbl_unsupp - tbl 4129 long tbl_unsupp - tbl 4130 long tbl_unsupp - tbl 4131 long tbl_unsupp - tbl 4132 long tbl_unsupp - tbl 4133 long tbl_unsupp - tbl 4134 long tbl_unsupp - tbl 4135 long tbl_unsupp - tbl 4136 long fcmp - tbl 4137 long tbl_unsupp - tbl 4138 long ftst - tbl 4139 long tbl_unsupp - tbl 4140 long tbl_unsupp - tbl 4141 long tbl_unsupp - tbl 4142 long tbl_unsupp - tbl 4143 long tbl_unsupp - tbl 4144 long fsin - tbl 4145 long fssqrt - tbl 4146 long tbl_unsupp - tbl 4147 long tbl_unsupp - tbl 4148 long fdin - tbl 4149 long fdsqrt - tbl 4150 long tbl_unsupp - tbl 4151 long tbl_unsupp - tbl 4152 long tbl_unsupp - tbl 4153 long tbl_unsupp - tbl 4154 long tbl_unsupp - tbl 4155 long tbl_unsupp - tbl 4156 long tbl_unsupp - tbl 4157 long tbl_unsupp - tbl 4158 long tbl_unsupp - tbl 4159 long tbl_unsupp - tbl 4160 long tbl_unsupp - tbl 4161 long tbl_unsupp - tbl 4162 long tbl_unsupp - tbl 4163 long tbl_unsupp - tbl 4164 long tbl_unsupp - tbl 4165 long tbl_unsupp - tbl 4166 long tbl_unsupp - tbl 4167 long tbl_unsupp - tbl 4168 long fsabs - tbl 4169 long tbl_unsupp - tbl 4170 long fsneg - tbl 4171 long tbl_unsupp - tbl 4172 long fdabs - tbl 4173 long tbl_unsupp - tbl 4174 long fdneg - tbl 4175 long tbl_unsupp - tbl 4176 long fsdiv - tbl 4177 long tbl_unsupp - tbl 4178 long fsadd - tbl 4179 long fsmul - tbl 4180 long fddiv - tbl 4181 long tbl_unsupp - tbl 4182 long fdadd - tbl 4183 long fdmul - tbl 4184 long fssub - tbl 4185 long tbl_unsupp - tbl 4186 long tbl_unsupp - tbl 4187 long tbl_unsupp - tbl 4188 long fdsub - tbl 4189 4190 ############################################# 4191 # Add this here so non-fp modules can compile 4192 # (smovcr is called from fpsp_inex.) 4193 global smovcr 4194 smovcr: 4195 bra.b smovcr 4196 4197 ############################################# 4198 # XDEF ************************************** 4199 # fmovm_dynamic(): emulate "fmovm" dyna 4200 # 4201 # XREF ************************************** 4202 # fetch_dreg() - fetch data register 4203 # {i,d,}mem_read() - fetch data from me 4204 # _mem_write() - write data to memory 4205 # iea_iacc() - instruction memory acces 4206 # iea_dacc() - data memory access error 4207 # restore() - restore An index regs if 4208 # 4209 # INPUT ************************************* 4210 # None 4211 # 4212 # OUTPUT ************************************ 4213 # If instr is "fmovm Dn,-(A7)" from sup 4214 # d0 = size of dump 4215 # d1 = Dn 4216 # Else if instruction access error, 4217 # d0 = FSLW 4218 # Else if data access error, 4219 # d0 = FSLW 4220 # a0 = address of fault 4221 # Else 4222 # none. 4223 # 4224 # ALGORITHM ********************************* 4225 # The effective address must be calcula 4226 # from an "Unimplemented Effective Address" e 4227 # have our own fcalc_ea() routine here. If an 4228 # by a _{i,d,}mem_read() call, we must exit t 4229 # handler. 4230 # The data register is determined and i 4231 # string of FP registers affected. This value 4232 # a lookup table such that we can determine t 4233 # involved. 4234 # If the instruction is "fmovm.x <ea>,D 4235 # to read in all FP values. Again, _mem_read( 4236 # special exit. 4237 # If the instruction is "fmovm.x DN,<ea 4238 # to write all FP values. _mem_write() may al 4239 # If the instruction is "fmovm.x DN,-(a 4240 # then we return the size of the dump and the 4241 # so that the move can occur outside of this 4242 # case is required so that moves to the syste 4243 # correctly. 4244 # 4245 # DYNAMIC: 4246 # fmovm.x dn, <ea> 4247 # fmovm.x <ea>, dn 4248 # 4249 # <WORD 1> <WORD2> 4250 # 1111 0010 00 |<ea>| 11@& 1000 0$$ 4251 # 4252 # & = (0): predecrement addressing mode 4253 # (1): postincrement or control add 4254 # @ = (0): move listed regs from memory 4255 # (1): move listed regs from the FP 4256 # $$$ : index of data register holdi 4257 # 4258 # NOTES: 4259 # If the data register holds a zero, th 4260 # instruction is a nop. 4261 # 4262 ############################################# 4263 4264 global fmovm_dynamic 4265 fmovm_dynamic: 4266 4267 # extract the data register in which the bit 4268 mov.b 1+EXC_EXTWORD(%a6),%d 4269 andi.w &0x70,%d1 4270 lsr.b &0x4,%d1 4271 4272 # fetch the bit string into d0... 4273 bsr.l fetch_dreg 4274 4275 andi.l &0x000000ff,%d0 4276 4277 mov.l %d0,-(%sp) 4278 mov.b (tbl_fmovm_size.w,%pc 4279 mov.l %d0,-(%sp) 4280 bsr.l fmovm_calc_ea 4281 mov.l (%sp)+,%d0 4282 mov.l (%sp)+,%d1 4283 4284 # if the bit string is a zero, then the opera 4285 # but, make sure that we've calculated ea and 4286 beq.w fmovm_data_done 4287 4288 # separate move ins from move outs... 4289 btst &0x5,EXC_EXTWORD(%a6) 4290 beq.w fmovm_data_in 4291 4292 ############# 4293 # MOVE OUT: # 4294 ############# 4295 fmovm_data_out: 4296 btst &0x4,EXC_EXTWORD(%a6) 4297 bne.w fmovm_out_ctrl 4298 4299 ############################ 4300 fmovm_out_predec: 4301 # for predecrement mode, the bit string is th 4302 # operations and postincrement mode. (bit7 = 4303 # here, we convert it to be just like the oth 4304 mov.b (tbl_fmovm_convert.w, 4305 4306 btst &0x5,EXC_SR(%a6) 4307 beq.b fmovm_out_ctrl 4308 4309 fmovm_out_predec_s: 4310 cmpi.b SPCOND_FLG(%a6),&mda7 4311 bne.b fmovm_out_ctrl 4312 4313 # the operation was unfortunately an: fmovm.x 4314 # called from supervisor mode. 4315 # we're also passing "size" and "strg" back t 4316 rts 4317 4318 ############################ 4319 fmovm_out_ctrl: 4320 mov.l %a0,%a1 4321 4322 sub.l %d0,%sp 4323 lea (%sp),%a0 4324 4325 tst.b %d1 4326 bpl.b fmovm_out_ctrl_fp1 4327 4328 mov.l 0x0+EXC_FP0(%a6),(%a0 4329 mov.l 0x4+EXC_FP0(%a6),(%a0 4330 mov.l 0x8+EXC_FP0(%a6),(%a0 4331 4332 fmovm_out_ctrl_fp1: 4333 lsl.b &0x1,%d1 4334 bpl.b fmovm_out_ctrl_fp2 4335 4336 mov.l 0x0+EXC_FP1(%a6),(%a0 4337 mov.l 0x4+EXC_FP1(%a6),(%a0 4338 mov.l 0x8+EXC_FP1(%a6),(%a0 4339 4340 fmovm_out_ctrl_fp2: 4341 lsl.b &0x1,%d1 4342 bpl.b fmovm_out_ctrl_fp3 4343 4344 fmovm.x &0x20,(%a0) 4345 add.l &0xc,%a0 4346 4347 fmovm_out_ctrl_fp3: 4348 lsl.b &0x1,%d1 4349 bpl.b fmovm_out_ctrl_fp4 4350 4351 fmovm.x &0x10,(%a0) 4352 add.l &0xc,%a0 4353 4354 fmovm_out_ctrl_fp4: 4355 lsl.b &0x1,%d1 4356 bpl.b fmovm_out_ctrl_fp5 4357 4358 fmovm.x &0x08,(%a0) 4359 add.l &0xc,%a0 4360 4361 fmovm_out_ctrl_fp5: 4362 lsl.b &0x1,%d1 4363 bpl.b fmovm_out_ctrl_fp6 4364 4365 fmovm.x &0x04,(%a0) 4366 add.l &0xc,%a0 4367 4368 fmovm_out_ctrl_fp6: 4369 lsl.b &0x1,%d1 4370 bpl.b fmovm_out_ctrl_fp7 4371 4372 fmovm.x &0x02,(%a0) 4373 add.l &0xc,%a0 4374 4375 fmovm_out_ctrl_fp7: 4376 lsl.b &0x1,%d1 4377 bpl.b fmovm_out_ctrl_done 4378 4379 fmovm.x &0x01,(%a0) 4380 add.l &0xc,%a0 4381 4382 fmovm_out_ctrl_done: 4383 mov.l %a1,L_SCR1(%a6) 4384 4385 lea (%sp),%a0 4386 mov.l %d0,-(%sp) 4387 bsr.l _dmem_write 4388 4389 mov.l (%sp)+,%d0 4390 add.l %d0,%sp 4391 4392 tst.l %d1 4393 bne.w fmovm_out_err 4394 4395 rts 4396 4397 ############ 4398 # MOVE IN: # 4399 ############ 4400 fmovm_data_in: 4401 mov.l %a0,L_SCR1(%a6) 4402 4403 sub.l %d0,%sp 4404 lea (%sp),%a1 4405 4406 mov.l %d1,-(%sp) 4407 mov.l %d0,-(%sp) 4408 4409 bsr.l _dmem_read 4410 4411 mov.l (%sp)+,%d0 4412 4413 tst.l %d1 4414 bne.w fmovm_in_err 4415 4416 mov.l (%sp)+,%d1 4417 4418 lea (%sp),%a0 4419 4420 tst.b %d1 4421 bpl.b fmovm_data_in_fp1 4422 4423 mov.l (%a0)+,0x0+EXC_FP0(%a 4424 mov.l (%a0)+,0x4+EXC_FP0(%a 4425 mov.l (%a0)+,0x8+EXC_FP0(%a 4426 4427 fmovm_data_in_fp1: 4428 lsl.b &0x1,%d1 4429 bpl.b fmovm_data_in_fp2 4430 4431 mov.l (%a0)+,0x0+EXC_FP1(%a 4432 mov.l (%a0)+,0x4+EXC_FP1(%a 4433 mov.l (%a0)+,0x8+EXC_FP1(%a 4434 4435 fmovm_data_in_fp2: 4436 lsl.b &0x1,%d1 4437 bpl.b fmovm_data_in_fp3 4438 4439 fmovm.x (%a0)+,&0x20 4440 4441 fmovm_data_in_fp3: 4442 lsl.b &0x1,%d1 4443 bpl.b fmovm_data_in_fp4 4444 4445 fmovm.x (%a0)+,&0x10 4446 4447 fmovm_data_in_fp4: 4448 lsl.b &0x1,%d1 4449 bpl.b fmovm_data_in_fp5 4450 4451 fmovm.x (%a0)+,&0x08 4452 4453 fmovm_data_in_fp5: 4454 lsl.b &0x1,%d1 4455 bpl.b fmovm_data_in_fp6 4456 4457 fmovm.x (%a0)+,&0x04 4458 4459 fmovm_data_in_fp6: 4460 lsl.b &0x1,%d1 4461 bpl.b fmovm_data_in_fp7 4462 4463 fmovm.x (%a0)+,&0x02 4464 4465 fmovm_data_in_fp7: 4466 lsl.b &0x1,%d1 4467 bpl.b fmovm_data_in_done 4468 4469 fmovm.x (%a0)+,&0x01 4470 4471 fmovm_data_in_done: 4472 add.l %d0,%sp 4473 rts 4474 4475 ##################################### 4476 4477 fmovm_data_done: 4478 rts 4479 4480 ############################################# 4481 4482 # 4483 # table indexed by the operation's bit string 4484 # of bytes that will be moved. 4485 # 4486 # number of bytes = (# of 1's in bit string) 4487 # 4488 tbl_fmovm_size: 4489 byte 0x00,0x0c,0x0c,0x18,0x0c,0x18 4490 byte 0x0c,0x18,0x18,0x24,0x18,0x24 4491 byte 0x0c,0x18,0x18,0x24,0x18,0x24 4492 byte 0x18,0x24,0x24,0x30,0x24,0x30 4493 byte 0x0c,0x18,0x18,0x24,0x18,0x24 4494 byte 0x18,0x24,0x24,0x30,0x24,0x30 4495 byte 0x18,0x24,0x24,0x30,0x24,0x30 4496 byte 0x24,0x30,0x30,0x3c,0x30,0x3c 4497 byte 0x0c,0x18,0x18,0x24,0x18,0x24 4498 byte 0x18,0x24,0x24,0x30,0x24,0x30 4499 byte 0x18,0x24,0x24,0x30,0x24,0x30 4500 byte 0x24,0x30,0x30,0x3c,0x30,0x3c 4501 byte 0x18,0x24,0x24,0x30,0x24,0x30 4502 byte 0x24,0x30,0x30,0x3c,0x30,0x3c 4503 byte 0x24,0x30,0x30,0x3c,0x30,0x3c 4504 byte 0x30,0x3c,0x3c,0x48,0x3c,0x48 4505 byte 0x0c,0x18,0x18,0x24,0x18,0x24 4506 byte 0x18,0x24,0x24,0x30,0x24,0x30 4507 byte 0x18,0x24,0x24,0x30,0x24,0x30 4508 byte 0x24,0x30,0x30,0x3c,0x30,0x3c 4509 byte 0x18,0x24,0x24,0x30,0x24,0x30 4510 byte 0x24,0x30,0x30,0x3c,0x30,0x3c 4511 byte 0x24,0x30,0x30,0x3c,0x30,0x3c 4512 byte 0x30,0x3c,0x3c,0x48,0x3c,0x48 4513 byte 0x18,0x24,0x24,0x30,0x24,0x30 4514 byte 0x24,0x30,0x30,0x3c,0x30,0x3c 4515 byte 0x24,0x30,0x30,0x3c,0x30,0x3c 4516 byte 0x30,0x3c,0x3c,0x48,0x3c,0x48 4517 byte 0x24,0x30,0x30,0x3c,0x30,0x3c 4518 byte 0x30,0x3c,0x3c,0x48,0x3c,0x48 4519 byte 0x30,0x3c,0x3c,0x48,0x3c,0x48 4520 byte 0x3c,0x48,0x48,0x54,0x48,0x54 4521 4522 # 4523 # table to convert a pre-decrement bit string 4524 # or control bit string. 4525 # ex: 0x00 ==> 0x00 4526 # 0x01 ==> 0x80 4527 # 0x02 ==> 0x40 4528 # . 4529 # . 4530 # 0xfd ==> 0xbf 4531 # 0xfe ==> 0x7f 4532 # 0xff ==> 0xff 4533 # 4534 tbl_fmovm_convert: 4535 byte 0x00,0x80,0x40,0xc0,0x20,0xa0 4536 byte 0x10,0x90,0x50,0xd0,0x30,0xb0 4537 byte 0x08,0x88,0x48,0xc8,0x28,0xa8 4538 byte 0x18,0x98,0x58,0xd8,0x38,0xb8 4539 byte 0x04,0x84,0x44,0xc4,0x24,0xa4 4540 byte 0x14,0x94,0x54,0xd4,0x34,0xb4 4541 byte 0x0c,0x8c,0x4c,0xcc,0x2c,0xac 4542 byte 0x1c,0x9c,0x5c,0xdc,0x3c,0xbc 4543 byte 0x02,0x82,0x42,0xc2,0x22,0xa2 4544 byte 0x12,0x92,0x52,0xd2,0x32,0xb2 4545 byte 0x0a,0x8a,0x4a,0xca,0x2a,0xaa 4546 byte 0x1a,0x9a,0x5a,0xda,0x3a,0xba 4547 byte 0x06,0x86,0x46,0xc6,0x26,0xa6 4548 byte 0x16,0x96,0x56,0xd6,0x36,0xb6 4549 byte 0x0e,0x8e,0x4e,0xce,0x2e,0xae 4550 byte 0x1e,0x9e,0x5e,0xde,0x3e,0xbe 4551 byte 0x01,0x81,0x41,0xc1,0x21,0xa1 4552 byte 0x11,0x91,0x51,0xd1,0x31,0xb1 4553 byte 0x09,0x89,0x49,0xc9,0x29,0xa9 4554 byte 0x19,0x99,0x59,0xd9,0x39,0xb9 4555 byte 0x05,0x85,0x45,0xc5,0x25,0xa5 4556 byte 0x15,0x95,0x55,0xd5,0x35,0xb5 4557 byte 0x0d,0x8d,0x4d,0xcd,0x2d,0xad 4558 byte 0x1d,0x9d,0x5d,0xdd,0x3d,0xbd 4559 byte 0x03,0x83,0x43,0xc3,0x23,0xa3 4560 byte 0x13,0x93,0x53,0xd3,0x33,0xb3 4561 byte 0x0b,0x8b,0x4b,0xcb,0x2b,0xab 4562 byte 0x1b,0x9b,0x5b,0xdb,0x3b,0xbb 4563 byte 0x07,0x87,0x47,0xc7,0x27,0xa7 4564 byte 0x17,0x97,0x57,0xd7,0x37,0xb7 4565 byte 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf 4566 byte 0x1f,0x9f,0x5f,0xdf,0x3f,0xbf 4567 4568 global fmovm_calc_ea 4569 ############################################# 4570 # _fmovm_calc_ea: calculate effective address 4571 ############################################# 4572 fmovm_calc_ea: 4573 mov.l %d0,%a0 4574 4575 # currently, MODE and REG are taken from the 4576 # easily changed if they were inputs passed i 4577 mov.w EXC_OPWORD(%a6),%d0 4578 mov.w %d0,%d1 4579 4580 andi.w &0x3f,%d0 4581 andi.l &0x7,%d1 4582 4583 # jump to the corresponding function for each 4584 mov.w (tbl_fea_mode.b,%pc,% 4585 jmp (tbl_fea_mode.b,%pc,% 4586 4587 swbeg &64 4588 tbl_fea_mode: 4589 short tbl_fea_mode - 4590 short tbl_fea_mode - 4591 short tbl_fea_mode - 4592 short tbl_fea_mode - 4593 short tbl_fea_mode - 4594 short tbl_fea_mode - 4595 short tbl_fea_mode - 4596 short tbl_fea_mode - 4597 4598 short tbl_fea_mode - 4599 short tbl_fea_mode - 4600 short tbl_fea_mode - 4601 short tbl_fea_mode - 4602 short tbl_fea_mode - 4603 short tbl_fea_mode - 4604 short tbl_fea_mode - 4605 short tbl_fea_mode - 4606 4607 short faddr_ind_a0 - 4608 short faddr_ind_a1 - 4609 short faddr_ind_a2 - 4610 short faddr_ind_a3 - 4611 short faddr_ind_a4 - 4612 short faddr_ind_a5 - 4613 short faddr_ind_a6 - 4614 short faddr_ind_a7 - 4615 4616 short faddr_ind_p_a0 - 4617 short faddr_ind_p_a1 - 4618 short faddr_ind_p_a2 - 4619 short faddr_ind_p_a3 - 4620 short faddr_ind_p_a4 - 4621 short faddr_ind_p_a5 - 4622 short faddr_ind_p_a6 - 4623 short faddr_ind_p_a7 - 4624 4625 short faddr_ind_m_a0 - 4626 short faddr_ind_m_a1 - 4627 short faddr_ind_m_a2 - 4628 short faddr_ind_m_a3 - 4629 short faddr_ind_m_a4 - 4630 short faddr_ind_m_a5 - 4631 short faddr_ind_m_a6 - 4632 short faddr_ind_m_a7 - 4633 4634 short faddr_ind_disp_a0 4635 short faddr_ind_disp_a1 4636 short faddr_ind_disp_a2 4637 short faddr_ind_disp_a3 4638 short faddr_ind_disp_a4 4639 short faddr_ind_disp_a5 4640 short faddr_ind_disp_a6 4641 short faddr_ind_disp_a7 4642 4643 short faddr_ind_ext - 4644 short faddr_ind_ext - 4645 short faddr_ind_ext - 4646 short faddr_ind_ext - 4647 short faddr_ind_ext - 4648 short faddr_ind_ext - 4649 short faddr_ind_ext - 4650 short faddr_ind_ext - 4651 4652 short fabs_short - 4653 short fabs_long - 4654 short fpc_ind - 4655 short fpc_ind_ext - 4656 short tbl_fea_mode - 4657 short tbl_fea_mode - 4658 short tbl_fea_mode - 4659 short tbl_fea_mode - 4660 4661 ################################### 4662 # Address register indirect: (An) # 4663 ################################### 4664 faddr_ind_a0: 4665 mov.l EXC_DREGS+0x8(%a6),%a 4666 rts 4667 4668 faddr_ind_a1: 4669 mov.l EXC_DREGS+0xc(%a6),%a 4670 rts 4671 4672 faddr_ind_a2: 4673 mov.l %a2,%a0 4674 rts 4675 4676 faddr_ind_a3: 4677 mov.l %a3,%a0 4678 rts 4679 4680 faddr_ind_a4: 4681 mov.l %a4,%a0 4682 rts 4683 4684 faddr_ind_a5: 4685 mov.l %a5,%a0 4686 rts 4687 4688 faddr_ind_a6: 4689 mov.l (%a6),%a0 4690 rts 4691 4692 faddr_ind_a7: 4693 mov.l EXC_A7(%a6),%a0 4694 rts 4695 4696 ############################################# 4697 # Address register indirect w/ postincrement: 4698 ############################################# 4699 faddr_ind_p_a0: 4700 mov.l EXC_DREGS+0x8(%a6),%d 4701 mov.l %d0,%d1 4702 add.l %a0,%d1 4703 mov.l %d1,EXC_DREGS+0x8(%a6 4704 mov.l %d0,%a0 4705 rts 4706 4707 faddr_ind_p_a1: 4708 mov.l EXC_DREGS+0xc(%a6),%d 4709 mov.l %d0,%d1 4710 add.l %a0,%d1 4711 mov.l %d1,EXC_DREGS+0xc(%a6 4712 mov.l %d0,%a0 4713 rts 4714 4715 faddr_ind_p_a2: 4716 mov.l %a2,%d0 4717 mov.l %d0,%d1 4718 add.l %a0,%d1 4719 mov.l %d1,%a2 4720 mov.l %d0,%a0 4721 rts 4722 4723 faddr_ind_p_a3: 4724 mov.l %a3,%d0 4725 mov.l %d0,%d1 4726 add.l %a0,%d1 4727 mov.l %d1,%a3 4728 mov.l %d0,%a0 4729 rts 4730 4731 faddr_ind_p_a4: 4732 mov.l %a4,%d0 4733 mov.l %d0,%d1 4734 add.l %a0,%d1 4735 mov.l %d1,%a4 4736 mov.l %d0,%a0 4737 rts 4738 4739 faddr_ind_p_a5: 4740 mov.l %a5,%d0 4741 mov.l %d0,%d1 4742 add.l %a0,%d1 4743 mov.l %d1,%a5 4744 mov.l %d0,%a0 4745 rts 4746 4747 faddr_ind_p_a6: 4748 mov.l (%a6),%d0 4749 mov.l %d0,%d1 4750 add.l %a0,%d1 4751 mov.l %d1,(%a6) 4752 mov.l %d0,%a0 4753 rts 4754 4755 faddr_ind_p_a7: 4756 mov.b &mia7_flg,SPCOND_FLG( 4757 4758 mov.l EXC_A7(%a6),%d0 4759 mov.l %d0,%d1 4760 add.l %a0,%d1 4761 mov.l %d1,EXC_A7(%a6) 4762 mov.l %d0,%a0 4763 rts 4764 4765 ############################################# 4766 # Address register indirect w/ predecrement: 4767 ############################################# 4768 faddr_ind_m_a0: 4769 mov.l EXC_DREGS+0x8(%a6),%d 4770 sub.l %a0,%d0 4771 mov.l %d0,EXC_DREGS+0x8(%a6 4772 mov.l %d0,%a0 4773 rts 4774 4775 faddr_ind_m_a1: 4776 mov.l EXC_DREGS+0xc(%a6),%d 4777 sub.l %a0,%d0 4778 mov.l %d0,EXC_DREGS+0xc(%a6 4779 mov.l %d0,%a0 4780 rts 4781 4782 faddr_ind_m_a2: 4783 mov.l %a2,%d0 4784 sub.l %a0,%d0 4785 mov.l %d0,%a2 4786 mov.l %d0,%a0 4787 rts 4788 4789 faddr_ind_m_a3: 4790 mov.l %a3,%d0 4791 sub.l %a0,%d0 4792 mov.l %d0,%a3 4793 mov.l %d0,%a0 4794 rts 4795 4796 faddr_ind_m_a4: 4797 mov.l %a4,%d0 4798 sub.l %a0,%d0 4799 mov.l %d0,%a4 4800 mov.l %d0,%a0 4801 rts 4802 4803 faddr_ind_m_a5: 4804 mov.l %a5,%d0 4805 sub.l %a0,%d0 4806 mov.l %d0,%a5 4807 mov.l %d0,%a0 4808 rts 4809 4810 faddr_ind_m_a6: 4811 mov.l (%a6),%d0 4812 sub.l %a0,%d0 4813 mov.l %d0,(%a6) 4814 mov.l %d0,%a0 4815 rts 4816 4817 faddr_ind_m_a7: 4818 mov.b &mda7_flg,SPCOND_FLG( 4819 4820 mov.l EXC_A7(%a6),%d0 4821 sub.l %a0,%d0 4822 mov.l %d0,EXC_A7(%a6) 4823 mov.l %d0,%a0 4824 rts 4825 4826 ############################################# 4827 # Address register indirect w/ displacement: 4828 ############################################# 4829 faddr_ind_disp_a0: 4830 mov.l EXC_EXTWPTR(%a6),%a0 4831 addq.l &0x2,EXC_EXTWPTR(%a6) 4832 bsr.l _imem_read_word 4833 4834 tst.l %d1 4835 bne.l iea_iacc 4836 4837 mov.w %d0,%a0 4838 4839 add.l EXC_DREGS+0x8(%a6),%a 4840 rts 4841 4842 faddr_ind_disp_a1: 4843 mov.l EXC_EXTWPTR(%a6),%a0 4844 addq.l &0x2,EXC_EXTWPTR(%a6) 4845 bsr.l _imem_read_word 4846 4847 tst.l %d1 4848 bne.l iea_iacc 4849 4850 mov.w %d0,%a0 4851 4852 add.l EXC_DREGS+0xc(%a6),%a 4853 rts 4854 4855 faddr_ind_disp_a2: 4856 mov.l EXC_EXTWPTR(%a6),%a0 4857 addq.l &0x2,EXC_EXTWPTR(%a6) 4858 bsr.l _imem_read_word 4859 4860 tst.l %d1 4861 bne.l iea_iacc 4862 4863 mov.w %d0,%a0 4864 4865 add.l %a2,%a0 4866 rts 4867 4868 faddr_ind_disp_a3: 4869 mov.l EXC_EXTWPTR(%a6),%a0 4870 addq.l &0x2,EXC_EXTWPTR(%a6) 4871 bsr.l _imem_read_word 4872 4873 tst.l %d1 4874 bne.l iea_iacc 4875 4876 mov.w %d0,%a0 4877 4878 add.l %a3,%a0 4879 rts 4880 4881 faddr_ind_disp_a4: 4882 mov.l EXC_EXTWPTR(%a6),%a0 4883 addq.l &0x2,EXC_EXTWPTR(%a6) 4884 bsr.l _imem_read_word 4885 4886 tst.l %d1 4887 bne.l iea_iacc 4888 4889 mov.w %d0,%a0 4890 4891 add.l %a4,%a0 4892 rts 4893 4894 faddr_ind_disp_a5: 4895 mov.l EXC_EXTWPTR(%a6),%a0 4896 addq.l &0x2,EXC_EXTWPTR(%a6) 4897 bsr.l _imem_read_word 4898 4899 tst.l %d1 4900 bne.l iea_iacc 4901 4902 mov.w %d0,%a0 4903 4904 add.l %a5,%a0 4905 rts 4906 4907 faddr_ind_disp_a6: 4908 mov.l EXC_EXTWPTR(%a6),%a0 4909 addq.l &0x2,EXC_EXTWPTR(%a6) 4910 bsr.l _imem_read_word 4911 4912 tst.l %d1 4913 bne.l iea_iacc 4914 4915 mov.w %d0,%a0 4916 4917 add.l (%a6),%a0 4918 rts 4919 4920 faddr_ind_disp_a7: 4921 mov.l EXC_EXTWPTR(%a6),%a0 4922 addq.l &0x2,EXC_EXTWPTR(%a6) 4923 bsr.l _imem_read_word 4924 4925 tst.l %d1 4926 bne.l iea_iacc 4927 4928 mov.w %d0,%a0 4929 4930 add.l EXC_A7(%a6),%a0 4931 rts 4932 4933 ############################################# 4934 # Address register indirect w/ index(8-bit di 4935 # " " " w/ " (base dis 4936 # Memory indirect postindexed: ([bd, An], Xn, 4937 # Memory indirect preindexed: ([bd, An, Xn], 4938 ############################################# 4939 faddr_ind_ext: 4940 addq.l &0x8,%d1 4941 bsr.l fetch_dreg 4942 mov.l %d0,-(%sp) 4943 4944 mov.l EXC_EXTWPTR(%a6),%a0 4945 addq.l &0x2,EXC_EXTWPTR(%a6) 4946 bsr.l _imem_read_word 4947 4948 tst.l %d1 4949 bne.l iea_iacc 4950 4951 mov.l (%sp)+,%a0 4952 4953 btst &0x8,%d0 4954 bne.w fcalc_mem_ind 4955 4956 mov.l %d0,L_SCR1(%a6) 4957 4958 mov.l %d0,%d1 4959 rol.w &0x4,%d1 4960 andi.w &0xf,%d1 4961 4962 # count on fetch_dreg() not to alter a0... 4963 bsr.l fetch_dreg 4964 4965 mov.l %d2,-(%sp) 4966 mov.l L_SCR1(%a6),%d2 4967 4968 btst &0xb,%d2 4969 bne.b faii8_long 4970 ext.l %d0 4971 faii8_long: 4972 mov.l %d2,%d1 4973 rol.w &0x7,%d1 4974 andi.l &0x3,%d1 4975 4976 lsl.l %d1,%d0 4977 4978 extb.l %d2 4979 add.l %d2,%d0 4980 add.l %d0,%a0 4981 4982 mov.l (%sp)+,%d2 4983 rts 4984 4985 ########################### 4986 # Absolute short: (XXX).W # 4987 ########################### 4988 fabs_short: 4989 mov.l EXC_EXTWPTR(%a6),%a0 4990 addq.l &0x2,EXC_EXTWPTR(%a6) 4991 bsr.l _imem_read_word 4992 4993 tst.l %d1 4994 bne.l iea_iacc 4995 4996 mov.w %d0,%a0 4997 rts 4998 4999 ########################## 5000 # Absolute long: (XXX).L # 5001 ########################## 5002 fabs_long: 5003 mov.l EXC_EXTWPTR(%a6),%a0 5004 addq.l &0x4,EXC_EXTWPTR(%a6) 5005 bsr.l _imem_read_long 5006 5007 tst.l %d1 5008 bne.l iea_iacc 5009 5010 mov.l %d0,%a0 5011 rts 5012 5013 ############################################# 5014 # Program counter indirect w/ displacement: ( 5015 ############################################# 5016 fpc_ind: 5017 mov.l EXC_EXTWPTR(%a6),%a0 5018 addq.l &0x2,EXC_EXTWPTR(%a6) 5019 bsr.l _imem_read_word 5020 5021 tst.l %d1 5022 bne.l iea_iacc 5023 5024 mov.w %d0,%a0 5025 5026 add.l EXC_EXTWPTR(%a6),%a0 5027 5028 # _imem_read_word() increased the extwptr by 5029 subq.l &0x2,%a0 5030 rts 5031 5032 ############################################# 5033 # PC indirect w/ index(8-bit displacement): ( 5034 # " " w/ " (base displacement): (b 5035 # PC memory indirect postindexed: ([bd, PC], 5036 # PC memory indirect preindexed: ([bd, PC, Xn 5037 ############################################# 5038 fpc_ind_ext: 5039 mov.l EXC_EXTWPTR(%a6),%a0 5040 addq.l &0x2,EXC_EXTWPTR(%a6) 5041 bsr.l _imem_read_word 5042 5043 tst.l %d1 5044 bne.l iea_iacc 5045 5046 mov.l EXC_EXTWPTR(%a6),%a0 5047 subq.l &0x2,%a0 5048 5049 btst &0x8,%d0 5050 bne.w fcalc_mem_ind 5051 5052 mov.l %d0,L_SCR1(%a6) 5053 5054 mov.l %d0,%d1 5055 rol.w &0x4,%d1 5056 andi.w &0xf,%d1 5057 5058 # count on fetch_dreg() not to alter a0... 5059 bsr.l fetch_dreg 5060 5061 mov.l %d2,-(%sp) 5062 mov.l L_SCR1(%a6),%d2 5063 5064 btst &0xb,%d2 5065 bne.b fpii8_long 5066 ext.l %d0 5067 fpii8_long: 5068 mov.l %d2,%d1 5069 rol.w &0x7,%d1 5070 andi.l &0x3,%d1 5071 5072 lsl.l %d1,%d0 5073 5074 extb.l %d2 5075 add.l %d2,%d0 5076 add.l %d0,%a0 5077 5078 mov.l (%sp)+,%d2 5079 rts 5080 5081 # d2 = index 5082 # d3 = base 5083 # d4 = od 5084 # d5 = extword 5085 fcalc_mem_ind: 5086 btst &0x6,%d0 5087 beq.b fcalc_index 5088 5089 movm.l &0x3c00,-(%sp) 5090 5091 mov.l %d0,%d5 5092 mov.l %a0,%d3 5093 5094 clr.l %d2 5095 bra.b fbase_supp_ck 5096 5097 # index: 5098 fcalc_index: 5099 mov.l %d0,L_SCR1(%a6) 5100 bfextu %d0{&16:&4},%d1 5101 bsr.l fetch_dreg 5102 5103 movm.l &0x3c00,-(%sp) 5104 mov.l %d0,%d2 5105 mov.l L_SCR1(%a6),%d5 5106 mov.l %a0,%d3 5107 5108 btst &0xb,%d5 5109 bne.b fno_ext 5110 ext.l %d2 5111 5112 fno_ext: 5113 bfextu %d5{&21:&2},%d0 5114 lsl.l %d0,%d2 5115 5116 # base address (passed as parameter in d3): 5117 # we clear the value here if it should actual 5118 fbase_supp_ck: 5119 btst &0x7,%d5 5120 beq.b fno_base_sup 5121 clr.l %d3 5122 5123 # base displacement: 5124 fno_base_sup: 5125 bfextu %d5{&26:&2},%d0 5126 # beq.l fmovm_error 5127 5128 cmpi.b %d0,&0x2 5129 blt.b fno_bd 5130 beq.b fget_word_bd 5131 5132 mov.l EXC_EXTWPTR(%a6),%a0 5133 addq.l &0x4,EXC_EXTWPTR(%a6) 5134 bsr.l _imem_read_long 5135 5136 tst.l %d1 5137 bne.l fcea_iacc 5138 5139 bra.b fchk_ind 5140 5141 fget_word_bd: 5142 mov.l EXC_EXTWPTR(%a6),%a0 5143 addq.l &0x2,EXC_EXTWPTR(%a6) 5144 bsr.l _imem_read_word 5145 5146 tst.l %d1 5147 bne.l fcea_iacc 5148 5149 ext.l %d0 5150 5151 fchk_ind: 5152 add.l %d0,%d3 5153 5154 # outer displacement: 5155 fno_bd: 5156 bfextu %d5{&30:&2},%d0 5157 beq.w faii_bd 5158 5159 cmpi.b %d0,&0x2 5160 blt.b fnull_od 5161 beq.b fword_od 5162 5163 mov.l EXC_EXTWPTR(%a6),%a0 5164 addq.l &0x4,EXC_EXTWPTR(%a6) 5165 bsr.l _imem_read_long 5166 5167 tst.l %d1 5168 bne.l fcea_iacc 5169 5170 bra.b fadd_them 5171 5172 fword_od: 5173 mov.l EXC_EXTWPTR(%a6),%a0 5174 addq.l &0x2,EXC_EXTWPTR(%a6) 5175 bsr.l _imem_read_word 5176 5177 tst.l %d1 5178 bne.l fcea_iacc 5179 5180 ext.l %d0 5181 bra.b fadd_them 5182 5183 fnull_od: 5184 clr.l %d0 5185 5186 fadd_them: 5187 mov.l %d0,%d4 5188 5189 btst &0x2,%d5 5190 beq.b fpre_indexed 5191 5192 mov.l %d3,%a0 5193 bsr.l _dmem_read_long 5194 5195 tst.l %d1 5196 bne.w fcea_err 5197 5198 add.l %d2,%d0 5199 add.l %d4,%d0 5200 bra.b fdone_ea 5201 5202 fpre_indexed: 5203 add.l %d2,%d3 5204 mov.l %d3,%a0 5205 bsr.l _dmem_read_long 5206 5207 tst.l %d1 5208 bne.w fcea_err 5209 5210 add.l %d4,%d0 5211 bra.b fdone_ea 5212 5213 faii_bd: 5214 add.l %d2,%d3 5215 mov.l %d3,%d0 5216 fdone_ea: 5217 mov.l %d0,%a0 5218 5219 movm.l (%sp)+,&0x003c 5220 rts 5221 5222 ############################################# 5223 fcea_err: 5224 mov.l %d3,%a0 5225 5226 movm.l (%sp)+,&0x003c 5227 mov.w &0x0101,%d0 5228 bra.l iea_dacc 5229 5230 fcea_iacc: 5231 movm.l (%sp)+,&0x003c 5232 bra.l iea_iacc 5233 5234 fmovm_out_err: 5235 bsr.l restore 5236 mov.w &0x00e1,%d0 5237 bra.b fmovm_err 5238 5239 fmovm_in_err: 5240 bsr.l restore 5241 mov.w &0x0161,%d0 5242 5243 fmovm_err: 5244 mov.l L_SCR1(%a6),%a0 5245 bra.l iea_dacc 5246 5247 ############################################# 5248 # XDEF ************************************** 5249 # fmovm_ctrl(): emulate fmovm.l of cont 5250 # 5251 # XREF ************************************** 5252 # _imem_read_long() - read longword fro 5253 # iea_iacc() - _imem_read_long() failed 5254 # 5255 # INPUT ************************************* 5256 # None 5257 # 5258 # OUTPUT ************************************ 5259 # If _imem_read_long() doesn't fail: 5260 # USER_FPCR(a6) = new FPCR val 5261 # USER_FPSR(a6) = new FPSR val 5262 # USER_FPIAR(a6) = new FPIAR va 5263 # 5264 # ALGORITHM ********************************* 5265 # Decode the instruction type by lookin 5266 # in order to see how many control registers 5267 # Fetch them using _imem_read_long(). If this 5268 # the special access error exit handler iea_i 5269 # 5270 # Instruction word decoding: 5271 # 5272 # fmovem.l #<data>, {FPIAR&|FPCR&|FPSR} 5273 # 5274 # WORD1 WORD2 5275 # 1111 0010 00 111100 100$ $$00 000 5276 # 5277 # $$$ (100): FPCR 5278 # (010): FPSR 5279 # (001): FPIAR 5280 # (000): FPIAR 5281 # 5282 ############################################# 5283 5284 global fmovm_ctrl 5285 fmovm_ctrl: 5286 mov.b EXC_EXTWORD(%a6),%d0 5287 cmpi.b %d0,&0x9c 5288 beq.w fctrl_in_7 5289 cmpi.b %d0,&0x98 5290 beq.w fctrl_in_6 5291 cmpi.b %d0,&0x94 5292 beq.b fctrl_in_5 5293 5294 # fmovem.l #<data>, fpsr/fpiar 5295 fctrl_in_3: 5296 mov.l EXC_EXTWPTR(%a6),%a0 5297 addq.l &0x4,EXC_EXTWPTR(%a6) 5298 bsr.l _imem_read_long 5299 5300 tst.l %d1 5301 bne.l iea_iacc 5302 5303 mov.l %d0,USER_FPSR(%a6) 5304 mov.l EXC_EXTWPTR(%a6),%a0 5305 addq.l &0x4,EXC_EXTWPTR(%a6) 5306 bsr.l _imem_read_long 5307 5308 tst.l %d1 5309 bne.l iea_iacc 5310 5311 mov.l %d0,USER_FPIAR(%a6) 5312 rts 5313 5314 # fmovem.l #<data>, fpcr/fpiar 5315 fctrl_in_5: 5316 mov.l EXC_EXTWPTR(%a6),%a0 5317 addq.l &0x4,EXC_EXTWPTR(%a6) 5318 bsr.l _imem_read_long 5319 5320 tst.l %d1 5321 bne.l iea_iacc 5322 5323 mov.l %d0,USER_FPCR(%a6) 5324 mov.l EXC_EXTWPTR(%a6),%a0 5325 addq.l &0x4,EXC_EXTWPTR(%a6) 5326 bsr.l _imem_read_long 5327 5328 tst.l %d1 5329 bne.l iea_iacc 5330 5331 mov.l %d0,USER_FPIAR(%a6) 5332 rts 5333 5334 # fmovem.l #<data>, fpcr/fpsr 5335 fctrl_in_6: 5336 mov.l EXC_EXTWPTR(%a6),%a0 5337 addq.l &0x4,EXC_EXTWPTR(%a6) 5338 bsr.l _imem_read_long 5339 5340 tst.l %d1 5341 bne.l iea_iacc 5342 5343 mov.l %d0,USER_FPCR(%a6) 5344 mov.l EXC_EXTWPTR(%a6),%a0 5345 addq.l &0x4,EXC_EXTWPTR(%a6) 5346 bsr.l _imem_read_long 5347 5348 tst.l %d1 5349 bne.l iea_iacc 5350 5351 mov.l %d0,USER_FPSR(%a6) 5352 rts 5353 5354 # fmovem.l #<data>, fpcr/fpsr/fpiar 5355 fctrl_in_7: 5356 mov.l EXC_EXTWPTR(%a6),%a0 5357 addq.l &0x4,EXC_EXTWPTR(%a6) 5358 bsr.l _imem_read_long 5359 5360 tst.l %d1 5361 bne.l iea_iacc 5362 5363 mov.l %d0,USER_FPCR(%a6) 5364 mov.l EXC_EXTWPTR(%a6),%a0 5365 addq.l &0x4,EXC_EXTWPTR(%a6) 5366 bsr.l _imem_read_long 5367 5368 tst.l %d1 5369 bne.l iea_iacc 5370 5371 mov.l %d0,USER_FPSR(%a6) 5372 mov.l EXC_EXTWPTR(%a6),%a0 5373 addq.l &0x4,EXC_EXTWPTR(%a6) 5374 bsr.l _imem_read_long 5375 5376 tst.l %d1 5377 bne.l iea_iacc 5378 5379 mov.l %d0,USER_FPIAR(%a6) 5380 rts 5381 5382 ############################################# 5383 5384 ############################################# 5385 # XDEF ************************************** 5386 # addsub_scaler2(): scale inputs to fad 5387 # OVFL/UNFL exception 5388 # 5389 # XREF ************************************** 5390 # norm() - normalize mantissa after adj 5391 # 5392 # INPUT ************************************* 5393 # FP_SRC(a6) = fp op1(src) 5394 # FP_DST(a6) = fp op2(dst) 5395 # 5396 # OUTPUT ************************************ 5397 # FP_SRC(a6) = fp op1 scaled(src) 5398 # FP_DST(a6) = fp op2 scaled(dst) 5399 # d0 = scale amount 5400 # 5401 # ALGORITHM ********************************* 5402 # If the DST exponent is > the SRC expo 5403 # equal to 0x3fff and scale the SRC exponent 5404 # DST exponent was scaled by. If the SRC expo 5405 # do the opposite. Return this scale factor i 5406 # If the two exponents differ by > the 5407 # plus two, then set the smallest exponent to 5408 # quick shortcut. 5409 # 5410 ############################################# 5411 5412 global addsub_scaler2 5413 addsub_scaler2: 5414 mov.l SRC_HI(%a0),FP_SCR0_H 5415 mov.l DST_HI(%a1),FP_SCR1_H 5416 mov.l SRC_LO(%a0),FP_SCR0_L 5417 mov.l DST_LO(%a1),FP_SCR1_L 5418 mov.w SRC_EX(%a0),%d0 5419 mov.w DST_EX(%a1),%d1 5420 mov.w %d0,FP_SCR0_EX(%a6) 5421 mov.w %d1,FP_SCR1_EX(%a6) 5422 5423 andi.w &0x7fff,%d0 5424 andi.w &0x7fff,%d1 5425 mov.w %d0,L_SCR1(%a6) 5426 mov.w %d1,2+L_SCR1(%a6) 5427 5428 cmp.w %d0, %d1 5429 bge.l src_exp_ge2 5430 5431 # dst exp is > src exp; scale dst to exp = 0 5432 dst_exp_gt2: 5433 bsr.l scale_to_zero_dst 5434 mov.l %d0,-(%sp) 5435 5436 cmpi.b STAG(%a6),&DENORM 5437 bne.b cmpexp12 5438 5439 lea FP_SCR0(%a6),%a0 5440 bsr.l norm 5441 neg.w %d0 5442 mov.w %d0,L_SCR1(%a6) 5443 5444 cmpexp12: 5445 mov.w 2+L_SCR1(%a6),%d0 5446 subi.w &mantissalen+2,%d0 5447 5448 cmp.w %d0,L_SCR1(%a6) 5449 bge.b quick_scale12 5450 5451 mov.w L_SCR1(%a6),%d0 5452 add.w 0x2(%sp),%d0 5453 mov.w FP_SCR0_EX(%a6),%d1 5454 and.w &0x8000,%d1 5455 or.w %d1,%d0 5456 mov.w %d0,FP_SCR0_EX(%a6) 5457 5458 mov.l (%sp)+,%d0 5459 rts 5460 5461 quick_scale12: 5462 andi.w &0x8000,FP_SCR0_EX(%a 5463 bset &0x0,1+FP_SCR0_EX(%a6 5464 5465 mov.l (%sp)+,%d0 5466 rts 5467 5468 # src exp is >= dst exp; scale src to exp = 0 5469 src_exp_ge2: 5470 bsr.l scale_to_zero_src 5471 mov.l %d0,-(%sp) 5472 5473 cmpi.b DTAG(%a6),&DENORM 5474 bne.b cmpexp22 5475 lea FP_SCR1(%a6),%a0 5476 bsr.l norm 5477 neg.w %d0 5478 mov.w %d0,2+L_SCR1(%a6) 5479 5480 cmpexp22: 5481 mov.w L_SCR1(%a6),%d0 5482 subi.w &mantissalen+2,%d0 5483 5484 cmp.w %d0,2+L_SCR1(%a6) 5485 bge.b quick_scale22 5486 5487 mov.w 2+L_SCR1(%a6),%d0 5488 add.w 0x2(%sp),%d0 5489 mov.w FP_SCR1_EX(%a6),%d1 5490 andi.w &0x8000,%d1 5491 or.w %d1,%d0 5492 mov.w %d0,FP_SCR1_EX(%a6) 5493 5494 mov.l (%sp)+,%d0 5495 rts 5496 5497 quick_scale22: 5498 andi.w &0x8000,FP_SCR1_EX(%a 5499 bset &0x0,1+FP_SCR1_EX(%a6 5500 5501 mov.l (%sp)+,%d0 5502 rts 5503 5504 ############################################# 5505 5506 ############################################# 5507 # XDEF ************************************** 5508 # scale_to_zero_src(): scale the expone 5509 # value at FP_SCR0 5510 # 5511 # XREF ************************************** 5512 # norm() - normalize the mantissa if th 5513 # 5514 # INPUT ************************************* 5515 # FP_SCR0(a6) = extended precision oper 5516 # 5517 # OUTPUT ************************************ 5518 # FP_SCR0(a6) = scaled extended precisi 5519 # d0 = scale value 5520 # 5521 # ALGORITHM ********************************* 5522 # Set the exponent of the input operand 5523 # of the difference between the original and 5524 # normalize the operand if it was a DENORM. A 5525 # value to the previous value. Return the res 5526 # 5527 ############################################# 5528 5529 global scale_to_zero_src 5530 scale_to_zero_src: 5531 mov.w FP_SCR0_EX(%a6),%d1 5532 mov.w %d1,%d0 5533 5534 andi.l &0x7fff,%d1 5535 5536 andi.w &0x8000,%d0 5537 or.w &0x3fff,%d0 5538 5539 mov.w %d0,FP_SCR0_EX(%a6) 5540 5541 cmpi.b STAG(%a6),&DENORM 5542 beq.b stzs_denorm 5543 5544 stzs_norm: 5545 mov.l &0x3fff,%d0 5546 sub.l %d1,%d0 5547 5548 rts 5549 5550 stzs_denorm: 5551 lea FP_SCR0(%a6),%a0 5552 bsr.l norm 5553 neg.l %d0 5554 mov.l %d0,%d1 5555 bra.b stzs_norm 5556 5557 ### 5558 5559 ############################################# 5560 # XDEF ************************************** 5561 # scale_sqrt(): scale the input operand 5562 # fsqrt operation won't t 5563 # 5564 # XREF ************************************** 5565 # norm() - normalize the mantissa if th 5566 # 5567 # INPUT ************************************* 5568 # FP_SCR0(a6) = extended precision oper 5569 # 5570 # OUTPUT ************************************ 5571 # FP_SCR0(a6) = scaled extended precisi 5572 # d0 = scale value 5573 # 5574 # ALGORITHM ********************************* 5575 # If the input operand is a DENORM, nor 5576 # If the exponent of the input operand 5577 # to 0x3ffe and return a scale factor of "(ex 5578 # exponent of the input operand is off, set t 5579 # return a scale factor of "(exp-0x3fff)/2". 5580 # 5581 ############################################# 5582 5583 global scale_sqrt 5584 scale_sqrt: 5585 cmpi.b STAG(%a6),&DENORM 5586 beq.b ss_denorm 5587 5588 mov.w FP_SCR0_EX(%a6),%d1 5589 andi.l &0x7fff,%d1 5590 5591 andi.w &0x8000,FP_SCR0_EX(%a 5592 5593 btst &0x0,%d1 5594 beq.b ss_norm_even 5595 5596 ori.w &0x3fff,FP_SCR0_EX(%a 5597 5598 mov.l &0x3fff,%d0 5599 sub.l %d1,%d0 5600 asr.l &0x1,%d0 5601 rts 5602 5603 ss_norm_even: 5604 ori.w &0x3ffe,FP_SCR0_EX(%a 5605 5606 mov.l &0x3ffe,%d0 5607 sub.l %d1,%d0 5608 asr.l &0x1,%d0 5609 rts 5610 5611 ss_denorm: 5612 lea FP_SCR0(%a6),%a0 5613 bsr.l norm 5614 5615 btst &0x0,%d0 5616 beq.b ss_denorm_even 5617 5618 ori.w &0x3fff,FP_SCR0_EX(%a 5619 5620 add.l &0x3fff,%d0 5621 asr.l &0x1,%d0 5622 rts 5623 5624 ss_denorm_even: 5625 ori.w &0x3ffe,FP_SCR0_EX(%a 5626 5627 add.l &0x3ffe,%d0 5628 asr.l &0x1,%d0 5629 rts 5630 5631 ### 5632 5633 ############################################# 5634 # XDEF ************************************** 5635 # scale_to_zero_dst(): scale the expone 5636 # value at FP_SCR1 5637 # 5638 # XREF ************************************** 5639 # norm() - normalize the mantissa if th 5640 # 5641 # INPUT ************************************* 5642 # FP_SCR1(a6) = extended precision oper 5643 # 5644 # OUTPUT ************************************ 5645 # FP_SCR1(a6) = scaled extended precisi 5646 # d0 = scale value 5647 # 5648 # ALGORITHM ********************************* 5649 # Set the exponent of the input operand 5650 # of the difference between the original and 5651 # normalize the operand if it was a DENORM. A 5652 # value to the previous value. Return the res 5653 # 5654 ############################################# 5655 5656 global scale_to_zero_dst 5657 scale_to_zero_dst: 5658 mov.w FP_SCR1_EX(%a6),%d1 5659 mov.w %d1,%d0 5660 5661 andi.l &0x7fff,%d1 5662 5663 andi.w &0x8000,%d0 5664 or.w &0x3fff,%d0 5665 5666 mov.w %d0,FP_SCR1_EX(%a6) 5667 5668 cmpi.b DTAG(%a6),&DENORM 5669 beq.b stzd_denorm 5670 5671 stzd_norm: 5672 mov.l &0x3fff,%d0 5673 sub.l %d1,%d0 5674 rts 5675 5676 stzd_denorm: 5677 lea FP_SCR1(%a6),%a0 5678 bsr.l norm 5679 neg.l %d0 5680 mov.l %d0,%d1 5681 bra.b stzd_norm 5682 5683 ############################################# 5684 5685 ############################################# 5686 # XDEF ************************************** 5687 # res_qnan(): return default result w/ 5688 # res_snan(): return default result w/ 5689 # res_qnan_1op(): return dflt result w/ 5690 # res_snan_1op(): return dflt result w/ 5691 # 5692 # XREF ************************************** 5693 # None 5694 # 5695 # INPUT ************************************* 5696 # FP_SRC(a6) = pointer to extended prec 5697 # FP_DST(a6) = pointer to extended prec 5698 # 5699 # OUTPUT ************************************ 5700 # fp0 = default result 5701 # 5702 # ALGORITHM ********************************* 5703 # If either operand (but not both opera 5704 # nonsignalling NAN, then that NAN is returne 5705 # operands are nonsignalling NANs, then the d 5706 # nonsignalling NAN is returned as the result 5707 # If either operand to an operation is 5708 # then, the SNAN bit is set in the FPSR EXC b 5709 # enable bit is set in the FPCR, then the tra 5710 # destination is not modified. If the SNAN tr 5711 # then the SNAN is converted to a nonsignalli 5712 # SNAN bit in the operand to one), and the op 5713 # described in the preceding paragraph, for n 5714 # Make sure the appropriate FPSR bits a 5715 # 5716 ############################################# 5717 5718 global res_qnan 5719 global res_snan 5720 res_qnan: 5721 res_snan: 5722 cmp.b DTAG(%a6), &SNAN 5723 beq.b dst_snan2 5724 cmp.b DTAG(%a6), &QNAN 5725 beq.b dst_qnan2 5726 src_nan: 5727 cmp.b STAG(%a6), &QNAN 5728 beq.b src_qnan2 5729 global res_snan_1op 5730 res_snan_1op: 5731 src_snan2: 5732 bset &0x6, FP_SRC_HI(%a6) 5733 or.l &nan_mask+aiop_mask+s 5734 lea FP_SRC(%a6), %a0 5735 bra.b nan_comp 5736 global res_qnan_1op 5737 res_qnan_1op: 5738 src_qnan2: 5739 or.l &nan_mask, USER_FPSR( 5740 lea FP_SRC(%a6), %a0 5741 bra.b nan_comp 5742 dst_snan2: 5743 or.l &nan_mask+aiop_mask+s 5744 bset &0x6, FP_DST_HI(%a6) 5745 lea FP_DST(%a6), %a0 5746 bra.b nan_comp 5747 dst_qnan2: 5748 lea FP_DST(%a6), %a0 5749 cmp.b STAG(%a6), &SNAN 5750 bne nan_done 5751 or.l &aiop_mask+snan_mask, 5752 nan_done: 5753 or.l &nan_mask, USER_FPSR( 5754 nan_comp: 5755 btst &0x7, FTEMP_EX(%a0) 5756 beq.b nan_not_neg 5757 or.l &neg_mask, USER_FPSR( 5758 nan_not_neg: 5759 fmovm.x (%a0), &0x80 5760 rts 5761 5762 ############################################# 5763 # XDEF ************************************** 5764 # res_operr(): return default result du 5765 # 5766 # XREF ************************************** 5767 # None 5768 # 5769 # INPUT ************************************* 5770 # None 5771 # 5772 # OUTPUT ************************************ 5773 # fp0 = default operand error result 5774 # 5775 # ALGORITHM ********************************* 5776 # An nonsignalling NAN is returned as t 5777 # an operand error occurs for the following c 5778 # 5779 # Multiply: (Infinity x Zero) 5780 # Divide : (Zero / Zero) || (Infinity 5781 # 5782 ############################################# 5783 5784 global res_operr 5785 res_operr: 5786 or.l &nan_mask+operr_mask+ 5787 fmovm.x nan_return(%pc), &0x8 5788 rts 5789 5790 nan_return: 5791 long 0x7fff0000, 0xfffffff 5792 5793 ############################################# 5794 # XDEF ************************************** 5795 # _denorm(): denormalize an intermediat 5796 # 5797 # XREF ************************************** 5798 # None 5799 # 5800 # INPUT ************************************* 5801 # a0 = points to the operand to be deno 5802 # (in the internal extended for 5803 # 5804 # d0 = rounding precision 5805 # 5806 # OUTPUT ************************************ 5807 # a0 = pointer to the denormalized resu 5808 # (in the internal extended for 5809 # 5810 # d0 = guard,round,sticky 5811 # 5812 # ALGORITHM ********************************* 5813 # According to the exponent underflow t 5814 # precision, shift the mantissa bits to the r 5815 # exponent of the operand to the threshold va 5816 # mantissa bits right, maintain the value of 5817 # sticky bits. 5818 # other notes: 5819 # (1) _denorm() is called by the underf 5820 # (2) _denorm() does NOT affect the sta 5821 # 5822 ############################################# 5823 5824 # 5825 # table of exponent threshold values for each 5826 # 5827 tbl_thresh: 5828 short 0x0 5829 short sgl_thresh 5830 short dbl_thresh 5831 5832 global _denorm 5833 _denorm: 5834 # 5835 # Load the exponent threshold for the precisi 5836 # to see if (threshold - exponent) is > 65 in 5837 # simply calculate the sticky bit and zero th 5838 # we have to call the denormalization routine 5839 # 5840 lsr.b &0x2, %d0 5841 mov.w (tbl_thresh.b,%pc,%d0 5842 mov.w %d1, %d0 5843 sub.w FTEMP_EX(%a0), %d0 5844 cmpi.w %d0, &66 5845 bpl.b denorm_set_stky 5846 5847 clr.l %d0 5848 btst &inex2_bit, FPSR_EXCE 5849 beq.b denorm_call 5850 bset &29, %d0 5851 5852 denorm_call: 5853 bsr.l dnrm_lp 5854 rts 5855 5856 # 5857 # all bit would have been shifted off during 5858 # calculate if the sticky should be set and c 5859 # 5860 denorm_set_stky: 5861 mov.l &0x20000000, %d0 5862 mov.w %d1, FTEMP_EX(%a0) 5863 clr.l FTEMP_HI(%a0) 5864 clr.l FTEMP_LO(%a0) 5865 rts 5866 5867 # 5868 # dnrm_lp(): normalize exponent/mantissa to s 5869 # 5870 # INPUT: 5871 # %a0 : points to the operand to 5872 # %d0{31:29} : initial guard,round,stic 5873 # %d1{15:0} : denormalization threshol 5874 # OUTPUT: 5875 # %a0 : points to the denormaliz 5876 # %d0{31:29} : final guard,round,sticky 5877 # 5878 5879 # *** Local Equates *** # 5880 set GRS, L_SCR2 5881 set FTEMP_LO2, L_SCR1 5882 5883 global dnrm_lp 5884 dnrm_lp: 5885 5886 # 5887 # make a copy of FTEMP_LO and place the g,r,s 5888 # in memory so as to make the bitfield extrac 5889 # 5890 mov.l FTEMP_LO(%a0), FTEMP_ 5891 mov.l %d0, GRS(%a6) 5892 5893 # 5894 # check to see how much less than the underfl 5895 # exponent is. 5896 # 5897 mov.l %d1, %d0 5898 sub.w FTEMP_EX(%a0), %d1 5899 ble.b dnrm_no_lp 5900 cmpi.w %d1, &0x20 5901 blt.b case_1 5902 cmpi.w %d1, &0x40 5903 blt.b case_2 5904 bra.w case_3 5905 5906 # 5907 # No normalization necessary 5908 # 5909 dnrm_no_lp: 5910 mov.l GRS(%a6), %d0 5911 rts 5912 5913 # 5914 # case (0<d1<32) 5915 # 5916 # %d0 = denorm threshold 5917 # %d1 = "n" = amt to shift 5918 # 5919 # ------------------------------------- 5920 # | FTEMP_HI | FTEMP_LO 5921 # ------------------------------------- 5922 # <-(32 - n)-><-(n)-><-(32 - n)-><-(n)- 5923 # \ \ \ 5924 # \ \ \ 5925 # \ \ \ 5926 # \ \ \ 5927 # \ \ \ 5928 # \ \ \ 5929 # \ \ \ 5930 # \ \ 5931 # <-(n)-><-(32 - n)-><------(32)------- 5932 # ------------------------------------- 5933 # |0.....0| NEW_HI | NEW_FTEMP_LO 5934 # ------------------------------------- 5935 # 5936 case_1: 5937 mov.l %d2, -(%sp) 5938 5939 mov.w %d0, FTEMP_EX(%a0) 5940 mov.l &32, %d0 5941 sub.w %d1, %d0 5942 5943 cmpi.w %d1, &29 5944 blt.b case1_extract 5945 mov.b GRS(%a6), %d2 5946 or.b %d2, 3+FTEMP_LO2(%a6) 5947 5948 case1_extract: 5949 bfextu FTEMP_HI(%a0){&0:%d0} 5950 bfextu FTEMP_HI(%a0){%d0:&32 5951 bfextu FTEMP_LO2(%a6){%d0:&3 5952 5953 mov.l %d2, FTEMP_HI(%a0) 5954 mov.l %d1, FTEMP_LO(%a0) 5955 5956 bftst %d0{&2:&30} 5957 beq.b case1_sticky_clear 5958 bset &rnd_stky_bit, %d0 5959 5960 case1_sticky_clear: 5961 and.l &0xe0000000, %d0 5962 mov.l (%sp)+, %d2 5963 rts 5964 5965 # 5966 # case (32<=d1<64) 5967 # 5968 # %d0 = denorm threshold 5969 # %d1 = "n" = amt to shift 5970 # 5971 # ------------------------------------- 5972 # | FTEMP_HI | FTEMP_LO 5973 # ------------------------------------- 5974 # <-(32 - n)-><-(n)-><-(32 - n)-><-(n)- 5975 # \ \ \ 5976 # \ \ \ 5977 # \ \ ----- 5978 # \ -------------------- 5979 # ------------------- \ 5980 # \ \ 5981 # \ \ 5982 # \ 5983 # <-------(32)------><-(n)-><-(32 - n)- 5984 # ------------------------------------- 5985 # |0...............0|0....0| NEW_LO 5986 # ------------------------------------- 5987 # 5988 case_2: 5989 mov.l %d2, -(%sp) 5990 5991 mov.w %d0, FTEMP_EX(%a0) 5992 subi.w &0x20, %d1 5993 mov.l &0x20, %d0 5994 sub.w %d1, %d0 5995 5996 # subtle step here; or in the g,r,s at the bo 5997 # the number of bits to check for the sticky 5998 # it only plays a role in shift amounts of 61 5999 mov.b GRS(%a6), %d2 6000 or.b %d2, 3+FTEMP_LO2(%a6) 6001 6002 bfextu FTEMP_HI(%a0){&0:%d0} 6003 bfextu FTEMP_HI(%a0){%d0:&32 6004 6005 bftst %d1{&2:&30} 6006 bne.b case2_set_sticky 6007 bftst FTEMP_LO2(%a6){%d0:&3 6008 bne.b case2_set_sticky 6009 6010 mov.l %d1, %d0 6011 bra.b case2_end 6012 6013 case2_set_sticky: 6014 mov.l %d1, %d0 6015 bset &rnd_stky_bit, %d0 6016 6017 case2_end: 6018 clr.l FTEMP_HI(%a0) 6019 mov.l %d2, FTEMP_LO(%a0) 6020 and.l &0xe0000000, %d0 6021 6022 mov.l (%sp)+,%d2 6023 rts 6024 6025 # 6026 # case (d1>=64) 6027 # 6028 # %d0 = denorm threshold 6029 # %d1 = amt to shift 6030 # 6031 case_3: 6032 mov.w %d0, FTEMP_EX(%a0) 6033 6034 cmpi.w %d1, &65 6035 blt.b case3_64 6036 beq.b case3_65 6037 6038 # 6039 # case (d1>65) 6040 # 6041 # Shift value is > 65 and out of range. All b 6042 # Return a zero mantissa with the sticky bit 6043 # 6044 clr.l FTEMP_HI(%a0) 6045 clr.l FTEMP_LO(%a0) 6046 mov.l &0x20000000, %d0 6047 rts 6048 6049 # 6050 # case (d1 == 64) 6051 # 6052 # ------------------------------------- 6053 # | FTEMP_HI | FTEMP_LO 6054 # ------------------------------------- 6055 # <-------(32)------> 6056 # \ \ 6057 # \ \ 6058 # \ \ 6059 # \ --------------- 6060 # ------------------------------- 6061 # \ 6062 # \ 6063 # 6064 # 6065 # ------------------------------------- 6066 # |0...............0|0................0 6067 # ------------------------------------- 6068 # 6069 case3_64: 6070 mov.l FTEMP_HI(%a0), %d0 6071 mov.l %d0, %d1 6072 and.l &0xc0000000, %d0 6073 and.l &0x3fffffff, %d1 6074 6075 bra.b case3_complete 6076 6077 # 6078 # case (d1 == 65) 6079 # 6080 # ------------------------------------- 6081 # | FTEMP_HI | FTEMP_LO 6082 # ------------------------------------- 6083 # <-------(32)------> 6084 # \ \ 6085 # \ \ 6086 # \ \ 6087 # \ --------------- 6088 # -------------------------------- 6089 # \ 6090 # 6091 # 6092 # 6093 # ------------------------------------- 6094 # |0...............0|0................0 6095 # ------------------------------------- 6096 # 6097 case3_65: 6098 mov.l FTEMP_HI(%a0), %d0 6099 and.l &0x80000000, %d0 6100 lsr.l &0x1, %d0 6101 and.l &0x7fffffff, %d1 6102 6103 case3_complete: 6104 # last operation done was an "and" of the bit 6105 # codes are already set so branch accordingly 6106 bne.b case3_set_sticky 6107 tst.l FTEMP_LO(%a0) 6108 bne.b case3_set_sticky 6109 tst.b GRS(%a6) 6110 bne.b case3_set_sticky 6111 6112 # 6113 # no bits were shifted off so don't set the s 6114 # the guard and 6115 # the entire mantissa is zero. 6116 # 6117 clr.l FTEMP_HI(%a0) 6118 clr.l FTEMP_LO(%a0) 6119 rts 6120 6121 # 6122 # some bits were shifted off so set the stick 6123 # the entire mantissa is zero. 6124 # 6125 case3_set_sticky: 6126 bset &rnd_stky_bit,%d0 6127 clr.l FTEMP_HI(%a0) 6128 clr.l FTEMP_LO(%a0) 6129 rts 6130 6131 ############################################# 6132 # XDEF ************************************** 6133 # _round(): round result according to p 6134 # 6135 # XREF ************************************** 6136 # None 6137 # 6138 # INPUT ************************************* 6139 # a0 = ptr to input operand in i 6140 # d1(hi) = contains rounding precisi 6141 # ext = $0000xxxx 6142 # sgl = $0004xxxx 6143 # dbl = $0008xxxx 6144 # d1(lo) = contains rounding mode: 6145 # RN = $xxxx0000 6146 # RZ = $xxxx0001 6147 # RM = $xxxx0002 6148 # RP = $xxxx0003 6149 # d0{31:29} = contains the g,r,s bits ( 6150 # 6151 # OUTPUT ************************************ 6152 # a0 = pointer to rounded result 6153 # 6154 # ALGORITHM ********************************* 6155 # On return the value pointed to by a0 6156 # a0 is preserved and the g-r-s bits in 6157 # The result is not typed - the tag fie 6158 # result is still in the internal exten 6159 # 6160 # The INEX bit of USER_FPSR will be set 6161 # inexact (i.e. if any of the g-r-s bit 6162 # 6163 ############################################# 6164 6165 global _round 6166 _round: 6167 # 6168 # ext_grs() looks at the rounding precision a 6169 # G,R,S bits. 6170 # If (G,R,S == 0) then result is exact and ro 6171 # the inex flag in status reg and continue. 6172 # 6173 bsr.l ext_grs 6174 6175 tst.l %d0 6176 beq.w truncate 6177 6178 or.w &inx2a_mask, 2+USER_F 6179 6180 # 6181 # Use rounding mode as an index into a jump t 6182 # All of the following assumes grs != 0. 6183 # 6184 mov.w (tbl_mode.b,%pc,%d1.w 6185 jmp (tbl_mode.b,%pc,%a1) 6186 6187 tbl_mode: 6188 short rnd_near - tbl_mode 6189 short truncate - tbl_mode 6190 short rnd_mnus - tbl_mode 6191 short rnd_plus - tbl_mode 6192 6193 ############################################# 6194 # ROUND PLUS INFINITY 6195 # 6196 # If sign of fp number = 0 (positive), 6197 ############################################# 6198 rnd_plus: 6199 tst.b FTEMP_SGN(%a0) 6200 bmi.w truncate 6201 6202 mov.l &0xffffffff, %d0 6203 swap %d1 6204 6205 cmpi.b %d1, &s_mode 6206 beq.w add_sgl 6207 bgt.w add_dbl 6208 bra.w add_ext 6209 6210 ############################################# 6211 # ROUND MINUS INFINITY 6212 # 6213 # If sign of fp number = 1 (negative), 6214 ############################################# 6215 rnd_mnus: 6216 tst.b FTEMP_SGN(%a0) 6217 bpl.w truncate 6218 6219 mov.l &0xffffffff, %d0 6220 swap %d1 6221 6222 cmpi.b %d1, &s_mode 6223 beq.w add_sgl 6224 bgt.w add_dbl 6225 bra.w add_ext 6226 6227 ############################################# 6228 # ROUND NEAREST 6229 # 6230 # If (g=1), then add 1 to l and if (r=s 6231 # Note that this will round to even in 6232 ############################################# 6233 rnd_near: 6234 asl.l &0x1, %d0 6235 bcc.w truncate 6236 6237 swap %d1 6238 6239 cmpi.b %d1, &s_mode 6240 beq.w add_sgl 6241 bgt.w add_dbl 6242 bra.w add_ext 6243 6244 # *** LOCAL EQUATES *** 6245 set ad_1_sgl, 0x00000100 # con 6246 set ad_1_dbl, 0x00000800 # con 6247 6248 ######################### 6249 # ADD SINGLE # 6250 ######################### 6251 add_sgl: 6252 add.l &ad_1_sgl, FTEMP_HI(% 6253 bcc.b scc_clr 6254 roxr.w FTEMP_HI(%a0) 6255 roxr.w FTEMP_HI+2(%a0) 6256 add.w &0x1, FTEMP_EX(%a0) 6257 scc_clr: 6258 tst.l %d0 6259 bne.b sgl_done 6260 and.w &0xfe00, FTEMP_HI+2(% 6261 sgl_done: 6262 and.l &0xffffff00, FTEMP_HI 6263 clr.l FTEMP_LO(%a0) 6264 rts 6265 6266 ######################### 6267 # ADD EXTENDED # 6268 ######################### 6269 add_ext: 6270 addq.l &1,FTEMP_LO(%a0) 6271 bcc.b xcc_clr 6272 addq.l &1,FTEMP_HI(%a0) 6273 bcc.b xcc_clr 6274 roxr.w FTEMP_HI(%a0) 6275 roxr.w FTEMP_HI+2(%a0) 6276 roxr.w FTEMP_LO(%a0) 6277 roxr.w FTEMP_LO+2(%a0) 6278 add.w &0x1,FTEMP_EX(%a0) 6279 xcc_clr: 6280 tst.l %d0 6281 bne.b add_ext_done 6282 and.b &0xfe,FTEMP_LO+3(%a0) 6283 add_ext_done: 6284 rts 6285 6286 ######################### 6287 # ADD DOUBLE # 6288 ######################### 6289 add_dbl: 6290 add.l &ad_1_dbl, FTEMP_LO(% 6291 bcc.b dcc_clr 6292 addq.l &0x1, FTEMP_HI(%a0) 6293 bcc.b dcc_clr 6294 6295 roxr.w FTEMP_HI(%a0) 6296 roxr.w FTEMP_HI+2(%a0) 6297 roxr.w FTEMP_LO(%a0) 6298 roxr.w FTEMP_LO+2(%a0) 6299 addq.w &0x1, FTEMP_EX(%a0) 6300 dcc_clr: 6301 tst.l %d0 6302 bne.b dbl_done 6303 and.w &0xf000, FTEMP_LO+2(% 6304 6305 dbl_done: 6306 and.l &0xfffff800,FTEMP_LO( 6307 rts 6308 6309 ########################### 6310 # Truncate all other bits # 6311 ########################### 6312 truncate: 6313 swap %d1 6314 6315 cmpi.b %d1, &s_mode 6316 beq.w sgl_done 6317 bgt.b dbl_done 6318 rts 6319 6320 6321 # 6322 # ext_grs(): extract guard, round and sticky 6323 # rounding precision. 6324 # 6325 # INPUT 6326 # d0 = extended precision g,r,s 6327 # d1 = {PREC,ROUND} 6328 # OUTPUT 6329 # d0{31:29} = guard, round, sticky 6330 # 6331 # The ext_grs extract the guard/round/sticky 6332 # selected rounding precision. It is called b 6333 # only. All registers except d0 are kept int 6334 # updated guard,round,sticky in d0{31:29} 6335 # 6336 # Notes: the ext_grs uses the round PREC, and 6337 # prior to usage, and needs to restore 6338 # routine is tightly tied to the round 6339 # uphold standard subroutine calling p 6340 # 6341 6342 ext_grs: 6343 swap %d1 6344 tst.b %d1 6345 bne.b ext_grs_not_ext 6346 6347 # 6348 # %d0 actually already hold g,r,s since _roun 6349 # this function. so, as long as we don't dist 6350 # 6351 ext_grs_ext: 6352 swap %d1 6353 rts 6354 6355 ext_grs_not_ext: 6356 movm.l &0x3000, -(%sp) 6357 6358 cmpi.b %d1, &s_mode 6359 bne.b ext_grs_dbl 6360 6361 # 6362 # sgl: 6363 # 96 64 40 32 6364 # ------------------------------------- 6365 # | EXP |XXXXXXX| |xx | 6366 # ------------------------------------- 6367 # <--(24)--->nn\ 6368 # ee ------- 6369 # ww 6370 # 6371 # gr ne 6372 # 6373 ext_grs_sgl: 6374 bfextu FTEMP_HI(%a0){&24:&2} 6375 mov.l &30, %d2 6376 lsl.l %d2, %d3 6377 mov.l FTEMP_HI(%a0), %d2 6378 and.l &0x0000003f, %d2 6379 bne.b ext_grs_st_stky 6380 tst.l FTEMP_LO(%a0) 6381 bne.b ext_grs_st_stky 6382 tst.l %d0 6383 bne.b ext_grs_st_stky 6384 bra.b ext_grs_end_sd 6385 6386 # 6387 # dbl: 6388 # 96 64 32 6389 # ------------------------------------- 6390 # | EXP |XXXXXXX| | 6391 # ------------------------------------- 6392 # 6393 # 6394 # 6395 # 6396 # 6397 # 6398 ext_grs_dbl: 6399 bfextu FTEMP_LO(%a0){&21:&2} 6400 mov.l &30, %d2 6401 lsl.l %d2, %d3 6402 mov.l FTEMP_LO(%a0), %d2 6403 and.l &0x000001ff, %d2 6404 bne.b ext_grs_st_stky 6405 tst.l %d0 6406 bne.b ext_grs_st_stky 6407 bra.b ext_grs_end_sd 6408 6409 ext_grs_st_stky: 6410 bset &rnd_stky_bit, %d3 6411 ext_grs_end_sd: 6412 mov.l %d3, %d0 6413 6414 movm.l (%sp)+, &0xc 6415 6416 swap %d1 6417 rts 6418 6419 ############################################# 6420 # norm(): normalize the mantissa of an extend 6421 # input operand should not be normali 6422 # 6423 # XDEF ************************************** 6424 # norm() 6425 # 6426 # XREF ************************************** 6427 # none 6428 # 6429 # INPUT ************************************* 6430 # a0 = pointer fp extended precision op 6431 # 6432 # OUTPUT ************************************ 6433 # d0 = number of bit positions the mant 6434 # a0 = the input operand's mantissa is 6435 # is unchanged. 6436 # 6437 ############################################# 6438 global norm 6439 norm: 6440 mov.l %d2, -(%sp) 6441 mov.l %d3, -(%sp) 6442 6443 mov.l FTEMP_HI(%a0), %d0 6444 mov.l FTEMP_LO(%a0), %d1 6445 6446 bfffo %d0{&0:&32}, %d2 6447 beq.b norm_lo 6448 6449 norm_hi: 6450 lsl.l %d2, %d0 6451 bfextu %d1{&0:%d2}, %d3 6452 6453 or.l %d3, %d0 6454 lsl.l %d2, %d1 6455 6456 mov.l %d0, FTEMP_HI(%a0) 6457 mov.l %d1, FTEMP_LO(%a0) 6458 6459 mov.l %d2, %d0 6460 6461 mov.l (%sp)+, %d3 6462 mov.l (%sp)+, %d2 6463 6464 rts 6465 6466 norm_lo: 6467 bfffo %d1{&0:&32}, %d2 6468 lsl.l %d2, %d1 6469 add.l &32, %d2 6470 6471 mov.l %d1, FTEMP_HI(%a0) 6472 clr.l FTEMP_LO(%a0) 6473 6474 mov.l %d2, %d0 6475 6476 mov.l (%sp)+, %d3 6477 mov.l (%sp)+, %d2 6478 6479 rts 6480 6481 ############################################# 6482 # unnorm_fix(): - changes an UNNORM to one of 6483 # - returns corresponding optyp 6484 # 6485 # XDEF ************************************** 6486 # unnorm_fix() 6487 # 6488 # XREF ************************************** 6489 # norm() - normalize the mantissa 6490 # 6491 # INPUT ************************************* 6492 # a0 = pointer to unnormalized extended 6493 # 6494 # OUTPUT ************************************ 6495 # d0 = optype tag - is corrected to one 6496 # a0 = input operand has been converted 6497 # zero; both the exponent and mant 6498 # 6499 ############################################# 6500 6501 global unnorm_fix 6502 unnorm_fix: 6503 bfffo FTEMP_HI(%a0){&0:&32} 6504 bne.b unnorm_shift 6505 6506 # 6507 # hi(man) is all zeroes so see if any bits in 6508 # 6509 unnorm_chk_lo: 6510 bfffo FTEMP_LO(%a0){&0:&32} 6511 beq.w unnorm_zero 6512 6513 add.w &32, %d0 6514 6515 # 6516 # d0 = # shifts needed for complete normaliza 6517 # 6518 unnorm_shift: 6519 clr.l %d1 6520 mov.w FTEMP_EX(%a0), %d1 6521 and.w &0x7fff, %d1 6522 6523 cmp.w %d0, %d1 6524 bgt.b unnorm_nrm_zero 6525 6526 # 6527 # exponent would not go < 0. Therefore, numbe 6528 # 6529 sub.w %d0, %d1 6530 mov.w FTEMP_EX(%a0), %d0 6531 and.w &0x8000, %d0 6532 or.w %d0, %d1 6533 mov.w %d1, FTEMP_EX(%a0) 6534 6535 bsr.l norm 6536 6537 mov.b &NORM, %d0 6538 rts 6539 6540 # 6541 # exponent would go < 0, so only denormalize 6542 # 6543 unnorm_nrm_zero: 6544 cmp.b %d1, &32 6545 bgt.b unnorm_nrm_zero_lrg 6546 6547 bfextu FTEMP_HI(%a0){%d1:&32 6548 mov.l %d0, FTEMP_HI(%a0) 6549 6550 mov.l FTEMP_LO(%a0), %d0 6551 lsl.l %d1, %d0 6552 mov.l %d0, FTEMP_LO(%a0) 6553 6554 and.w &0x8000, FTEMP_EX(%a0 6555 6556 mov.b &DENORM, %d0 6557 rts 6558 6559 # 6560 # only mantissa bits set are in lo(man) 6561 # 6562 unnorm_nrm_zero_lrg: 6563 sub.w &32, %d1 6564 6565 mov.l FTEMP_LO(%a0), %d0 6566 lsl.l %d1, %d0 6567 6568 mov.l %d0, FTEMP_HI(%a0) 6569 clr.l FTEMP_LO(%a0) 6570 6571 and.w &0x8000, FTEMP_EX(%a0 6572 6573 mov.b &DENORM, %d0 6574 rts 6575 6576 # 6577 # whole mantissa is zero so this UNNORM is ac 6578 # 6579 unnorm_zero: 6580 and.w &0x8000, FTEMP_EX(%a0 6581 6582 mov.b &ZERO, %d0 6583 rts 6584 6585 ############################################# 6586 # XDEF ************************************** 6587 # set_tag_x(): return the optype of the 6588 # 6589 # XREF ************************************** 6590 # None 6591 # 6592 # INPUT ************************************* 6593 # a0 = pointer to extended precision op 6594 # 6595 # OUTPUT ************************************ 6596 # d0 = value of type tag 6597 # one of: NORM, INF, QNAN, SNAN 6598 # 6599 # ALGORITHM ********************************* 6600 # Simply test the exponent, j-bit, and 6601 # determine the type of operand. 6602 # If it's an unnormalized zero, alter t 6603 # to be a normal zero. 6604 # 6605 ############################################# 6606 6607 global set_tag_x 6608 set_tag_x: 6609 mov.w FTEMP_EX(%a0), %d0 6610 andi.w &0x7fff, %d0 6611 cmpi.w %d0, &0x7fff 6612 beq.b inf_or_nan_x 6613 not_inf_or_nan_x: 6614 btst &0x7,FTEMP_HI(%a0) 6615 beq.b not_norm_x 6616 is_norm_x: 6617 mov.b &NORM, %d0 6618 rts 6619 not_norm_x: 6620 tst.w %d0 6621 bne.b is_unnorm_x 6622 not_unnorm_x: 6623 tst.l FTEMP_HI(%a0) 6624 bne.b is_denorm_x 6625 tst.l FTEMP_LO(%a0) 6626 bne.b is_denorm_x 6627 is_zero_x: 6628 mov.b &ZERO, %d0 6629 rts 6630 is_denorm_x: 6631 mov.b &DENORM, %d0 6632 rts 6633 # must distinguish now "Unnormalized zeroes" 6634 # must convert to zero. 6635 is_unnorm_x: 6636 tst.l FTEMP_HI(%a0) 6637 bne.b is_unnorm_reg_x 6638 tst.l FTEMP_LO(%a0) 6639 bne.b is_unnorm_reg_x 6640 # it's an "unnormalized zero". let's convert 6641 andi.w &0x8000,FTEMP_EX(%a0) 6642 mov.b &ZERO, %d0 6643 rts 6644 is_unnorm_reg_x: 6645 mov.b &UNNORM, %d0 6646 rts 6647 inf_or_nan_x: 6648 tst.l FTEMP_LO(%a0) 6649 bne.b is_nan_x 6650 mov.l FTEMP_HI(%a0), %d0 6651 and.l &0x7fffffff, %d0 6652 bne.b is_nan_x 6653 is_inf_x: 6654 mov.b &INF, %d0 6655 rts 6656 is_nan_x: 6657 btst &0x6, FTEMP_HI(%a0) 6658 beq.b is_snan_x 6659 mov.b &QNAN, %d0 6660 rts 6661 is_snan_x: 6662 mov.b &SNAN, %d0 6663 rts 6664 6665 ############################################# 6666 # XDEF ************************************** 6667 # set_tag_d(): return the optype of the 6668 # 6669 # XREF ************************************** 6670 # None 6671 # 6672 # INPUT ************************************* 6673 # a0 = points to double precision opera 6674 # 6675 # OUTPUT ************************************ 6676 # d0 = value of type tag 6677 # one of: NORM, INF, QNAN, SNAN 6678 # 6679 # ALGORITHM ********************************* 6680 # Simply test the exponent, j-bit, and 6681 # determine the type of operand. 6682 # 6683 ############################################# 6684 6685 global set_tag_d 6686 set_tag_d: 6687 mov.l FTEMP(%a0), %d0 6688 mov.l %d0, %d1 6689 6690 andi.l &0x7ff00000, %d0 6691 beq.b zero_or_denorm_d 6692 6693 cmpi.l %d0, &0x7ff00000 6694 beq.b inf_or_nan_d 6695 6696 is_norm_d: 6697 mov.b &NORM, %d0 6698 rts 6699 zero_or_denorm_d: 6700 and.l &0x000fffff, %d1 6701 bne is_denorm_d 6702 tst.l 4+FTEMP(%a0) 6703 bne is_denorm_d 6704 is_zero_d: 6705 mov.b &ZERO, %d0 6706 rts 6707 is_denorm_d: 6708 mov.b &DENORM, %d0 6709 rts 6710 inf_or_nan_d: 6711 and.l &0x000fffff, %d1 6712 bne is_nan_d 6713 tst.l 4+FTEMP(%a0) 6714 bne is_nan_d 6715 is_inf_d: 6716 mov.b &INF, %d0 6717 rts 6718 is_nan_d: 6719 btst &19, %d1 6720 bne is_qnan_d 6721 is_snan_d: 6722 mov.b &SNAN, %d0 6723 rts 6724 is_qnan_d: 6725 mov.b &QNAN, %d0 6726 rts 6727 6728 ############################################# 6729 # XDEF ************************************** 6730 # set_tag_s(): return the optype of the 6731 # 6732 # XREF ************************************** 6733 # None 6734 # 6735 # INPUT ************************************* 6736 # a0 = pointer to single precision oper 6737 # 6738 # OUTPUT ************************************ 6739 # d0 = value of type tag 6740 # one of: NORM, INF, QNAN, SNAN 6741 # 6742 # ALGORITHM ********************************* 6743 # Simply test the exponent, j-bit, and 6744 # determine the type of operand. 6745 # 6746 ############################################# 6747 6748 global set_tag_s 6749 set_tag_s: 6750 mov.l FTEMP(%a0), %d0 6751 mov.l %d0, %d1 6752 6753 andi.l &0x7f800000, %d0 6754 beq.b zero_or_denorm_s 6755 6756 cmpi.l %d0, &0x7f800000 6757 beq.b inf_or_nan_s 6758 6759 is_norm_s: 6760 mov.b &NORM, %d0 6761 rts 6762 zero_or_denorm_s: 6763 and.l &0x007fffff, %d1 6764 bne is_denorm_s 6765 is_zero_s: 6766 mov.b &ZERO, %d0 6767 rts 6768 is_denorm_s: 6769 mov.b &DENORM, %d0 6770 rts 6771 inf_or_nan_s: 6772 and.l &0x007fffff, %d1 6773 bne is_nan_s 6774 is_inf_s: 6775 mov.b &INF, %d0 6776 rts 6777 is_nan_s: 6778 btst &22, %d1 6779 bne is_qnan_s 6780 is_snan_s: 6781 mov.b &SNAN, %d0 6782 rts 6783 is_qnan_s: 6784 mov.b &QNAN, %d0 6785 rts 6786 6787 ############################################# 6788 # XDEF ************************************** 6789 # unf_res(): routine to produce default 6790 # scaled extended precision 6791 # fadd/fdiv/fmul/etc. emulat 6792 # unf_res4(): same as above but for fsg 6793 # single round prec and ext 6794 # 6795 # XREF ************************************** 6796 # _denorm() - denormalize according to 6797 # _round() - round denormalized number 6798 # 6799 # INPUT ************************************* 6800 # a0 = pointer to extended precison ope 6801 # d0 = scale factor 6802 # d1 = rounding precision/mode 6803 # 6804 # OUTPUT ************************************ 6805 # a0 = pointer to default underflow res 6806 # d0.b = result FPSR_cc which caller ma 6807 # 6808 # ALGORITHM ********************************* 6809 # Convert the input operand to "interna 6810 # exponent is extended to 16 bits and the sig 6811 # portion of the extended precison operand. D 6812 # according to the scale factor passed in d0. 6813 # denormalized result. 6814 # Set the FPSR_exc bits as appropriate 6815 # d0 in case the caller doesn't want to save 6816 # fmove out). 6817 # unf_res4() for fsglmul/fsgldiv forces 6818 # precision and the rounding mode to single. 6819 # 6820 ############################################# 6821 global unf_res 6822 unf_res: 6823 mov.l %d1, -(%sp) 6824 6825 btst &0x7, FTEMP_EX(%a0) 6826 sne FTEMP_SGN(%a0) 6827 6828 mov.w FTEMP_EX(%a0), %d1 6829 and.w &0x7fff, %d1 6830 sub.w %d0, %d1 6831 mov.w %d1, FTEMP_EX(%a0) 6832 6833 mov.l %a0, -(%sp) 6834 6835 mov.l 0x4(%sp),%d0 6836 andi.w &0x00c0,%d0 6837 lsr.w &0x4,%d0 6838 bsr.l _denorm 6839 6840 mov.l (%sp),%a0 6841 mov.w 0x6(%sp),%d1 6842 andi.w &0xc0,%d1 6843 lsr.w &0x4,%d1 6844 swap %d1 6845 mov.w 0x6(%sp),%d1 6846 andi.w &0x30,%d1 6847 lsr.w &0x4,%d1 6848 bsr.l _round 6849 6850 mov.l (%sp)+, %a0 6851 6852 # result is now rounded properly. convert bac 6853 bclr &0x7, FTEMP_EX(%a0) 6854 tst.b FTEMP_SGN(%a0) 6855 beq.b unf_res_chkifzero 6856 bset &0x7, FTEMP_EX(%a0) 6857 clr.b FTEMP_SGN(%a0) 6858 6859 # the number may have become zero after round 6860 unf_res_chkifzero: 6861 clr.l %d0 6862 tst.l FTEMP_HI(%a0) 6863 bne.b unf_res_cont 6864 tst.l FTEMP_LO(%a0) 6865 bne.b unf_res_cont 6866 # bset &z_bit, FPSR_CC(%a6) 6867 bset &z_bit, %d0 6868 6869 unf_res_cont: 6870 6871 # 6872 # can inex1 also be set along with unfl and i 6873 # 6874 # we know that underflow has occurred. aunfl 6875 # 6876 btst &inex2_bit, FPSR_EXCE 6877 beq.b unf_res_end 6878 bset &aunfl_bit, FPSR_AEXC 6879 6880 unf_res_end: 6881 add.l &0x4, %sp 6882 rts 6883 6884 # unf_res() for fsglmul() and fsgldiv(). 6885 global unf_res4 6886 unf_res4: 6887 mov.l %d1,-(%sp) 6888 6889 btst &0x7,FTEMP_EX(%a0) 6890 sne FTEMP_SGN(%a0) 6891 6892 mov.w FTEMP_EX(%a0),%d1 6893 and.w &0x7fff,%d1 6894 sub.w %d0,%d1 6895 mov.w %d1,FTEMP_EX(%a0) 6896 6897 mov.l %a0,-(%sp) 6898 6899 clr.l %d0 6900 bsr.l _denorm 6901 6902 mov.l (%sp),%a0 6903 mov.w &s_mode,%d1 6904 swap %d1 6905 mov.w 0x6(%sp),%d1 6906 andi.w &0x30,%d1 6907 lsr.w &0x4,%d1 6908 bsr.l _round 6909 6910 mov.l (%sp)+,%a0 6911 6912 # result is now rounded properly. convert bac 6913 bclr &0x7,FTEMP_EX(%a0) 6914 tst.b FTEMP_SGN(%a0) 6915 beq.b unf_res4_chkifzero 6916 bset &0x7,FTEMP_EX(%a0) 6917 clr.b FTEMP_SGN(%a0) 6918 6919 # the number may have become zero after round 6920 unf_res4_chkifzero: 6921 clr.l %d0 6922 tst.l FTEMP_HI(%a0) 6923 bne.b unf_res4_cont 6924 tst.l FTEMP_LO(%a0) 6925 bne.b unf_res4_cont 6926 # bset &z_bit,FPSR_CC(%a6) 6927 bset &z_bit,%d0 6928 6929 unf_res4_cont: 6930 6931 # 6932 # can inex1 also be set along with unfl and i 6933 # 6934 # we know that underflow has occurred. aunfl 6935 # 6936 btst &inex2_bit,FPSR_EXCEP 6937 beq.b unf_res4_end 6938 bset &aunfl_bit,FPSR_AEXCE 6939 6940 unf_res4_end: 6941 add.l &0x4,%sp 6942 rts 6943 6944 ############################################# 6945 # XDEF ************************************** 6946 # ovf_res(): routine to produce the def 6947 # an overflowing number. 6948 # ovf_res2(): same as above but the rnd 6949 # differently. 6950 # 6951 # XREF ************************************** 6952 # none 6953 # 6954 # INPUT ************************************* 6955 # d1.b = '-1' => (-); '0' => (+) 6956 # ovf_res(): 6957 # d0 = rnd mode/prec 6958 # ovf_res2(): 6959 # hi(d0) = rnd prec 6960 # lo(d0) = rnd mode 6961 # 6962 # OUTPUT ************************************ 6963 # a0 = points to extended precisio 6964 # d0.b = condition code bits 6965 # 6966 # ALGORITHM ********************************* 6967 # The default overflow result can be de 6968 # the result and the rounding mode/prec in ef 6969 # concatenated together to create an index in 6970 # table. A pointer to the correct result is r 6971 # resulting condition codes are returned in d 6972 # doesn't want FPSR_cc altered (as is the cas 6973 # 6974 ############################################# 6975 6976 global ovf_res 6977 ovf_res: 6978 andi.w &0x10,%d1 6979 lsr.b &0x4,%d0 6980 or.b %d0,%d1 6981 mov.w %d1,%d0 6982 lsl.b &0x1,%d1 6983 bra.b ovf_res_load 6984 6985 global ovf_res2 6986 ovf_res2: 6987 and.w &0x10, %d1 6988 or.b %d0, %d1 6989 swap %d0 6990 or.b %d0, %d1 6991 mov.w %d1, %d0 6992 lsl.b &0x1, %d1 6993 6994 # 6995 # use the rounding mode, precision, and resul 6996 # two tables below to fetch the default resul 6997 # 6998 ovf_res_load: 6999 mov.b (tbl_ovfl_cc.b,%pc,%d 7000 lea (tbl_ovfl_result.b,%p 7001 7002 rts 7003 7004 tbl_ovfl_cc: 7005 byte 0x2, 0x0, 0x0, 0x2 7006 byte 0x2, 0x0, 0x0, 0x2 7007 byte 0x2, 0x0, 0x0, 0x2 7008 byte 0x0, 0x0, 0x0, 0x0 7009 byte 0x2+0x8, 0x8, 0x2+0x8 7010 byte 0x2+0x8, 0x8, 0x2+0x8 7011 byte 0x2+0x8, 0x8, 0x2+0x8 7012 7013 tbl_ovfl_result: 7014 long 0x7fff0000,0x00000000 7015 long 0x7ffe0000,0xffffffff 7016 long 0x7ffe0000,0xffffffff 7017 long 0x7fff0000,0x00000000 7018 7019 long 0x7fff0000,0x00000000 7020 long 0x407e0000,0xffffff00 7021 long 0x407e0000,0xffffff00 7022 long 0x7fff0000,0x00000000 7023 7024 long 0x7fff0000,0x00000000 7025 long 0x43fe0000,0xffffffff 7026 long 0x43fe0000,0xffffffff 7027 long 0x7fff0000,0x00000000 7028 7029 long 0x00000000,0x00000000 7030 long 0x00000000,0x00000000 7031 long 0x00000000,0x00000000 7032 long 0x00000000,0x00000000 7033 7034 long 0xffff0000,0x00000000 7035 long 0xfffe0000,0xffffffff 7036 long 0xffff0000,0x00000000 7037 long 0xfffe0000,0xffffffff 7038 7039 long 0xffff0000,0x00000000 7040 long 0xc07e0000,0xffffff00 7041 long 0xffff0000,0x00000000 7042 long 0xc07e0000,0xffffff00 7043 7044 long 0xffff0000,0x00000000 7045 long 0xc3fe0000,0xffffffff 7046 long 0xffff0000,0x00000000 7047 long 0xc3fe0000,0xffffffff 7048 7049 ############################################# 7050 # XDEF ************************************** 7051 # fout(): move from fp register to memo 7052 # 7053 # XREF ************************************** 7054 # _round() - needed to create EXOP for 7055 # norm() - needed to create EXOP for ex 7056 # ovf_res() - create default overflow r 7057 # unf_res() - create default underflow 7058 # dst_dbl() - create rounded dbl precis 7059 # dst_sgl() - create rounded sgl precis 7060 # fetch_dreg() - fetch dynamic k-factor 7061 # bindec() - convert FP binary number t 7062 # _mem_write() - write data to memory. 7063 # _mem_write2() - write data to memory 7064 # _dmem_write_{byte,word,long}() - writ 7065 # store_dreg_{b,w,l}() - store data to 7066 # facc_out_{b,w,l,d,x}() - data access 7067 # 7068 # INPUT ************************************* 7069 # a0 = pointer to extended precision so 7070 # d0 = round prec,mode 7071 # 7072 # OUTPUT ************************************ 7073 # fp0 : intermediate underflow or overf 7074 # OVFL/UNFL occurred for a sgl or 7075 # 7076 # ALGORITHM ********************************* 7077 # This routine is accessed by many hand 7078 # opclass three move of an operand out to mem 7079 # Decode an fmove out (opclass 3) instr 7080 # it's b,w,l,s,d,x, or p in size. b,w,l can b 7081 # register or memory. The algorithm uses a st 7082 # the rounded result. Also, since exceptions 7083 # create the correct OPERR default result if 7084 # For sgl or dbl precision, overflow or 7085 # either occurs and is enabled, the EXOP. 7086 # For extended precision, the stacked < 7087 # w/ the address index register as appropriat 7088 # the source is a denorm and if underflow is 7089 # created. 7090 # For packed, the k-factor must be fetc 7091 # word or a data register. The <ea> must be f 7092 # precision. Then, bindec() is called to crea 7093 # packed result. 7094 # If at any time an access error is fla 7095 # to-memory routines, then a special exit mus 7096 # access error can be handled properly. 7097 # 7098 ############################################# 7099 7100 global fout 7101 fout: 7102 bfextu EXC_CMDREG(%a6){&3:&3 7103 mov.w (tbl_fout.b,%pc,%d1.w 7104 jmp (tbl_fout.b,%pc,%a1) 7105 7106 swbeg &0x8 7107 tbl_fout: 7108 short fout_long - 7109 short fout_sgl - 7110 short fout_ext - 7111 short fout_pack - 7112 short fout_word - 7113 short fout_dbl - 7114 short fout_byte - 7115 short fout_pack - 7116 7117 ############################################# 7118 # fmove.b out ############################### 7119 ############################################# 7120 7121 # Only "Unimplemented Data Type" exceptions e 7122 # is either a DENORM or a NORM. 7123 fout_byte: 7124 tst.b STAG(%a6) 7125 bne.b fout_byte_denorm 7126 7127 fmovm.x SRC(%a0),&0x80 7128 7129 fout_byte_norm: 7130 fmov.l %d0,%fpcr 7131 7132 fmov.b %fp0,%d0 7133 7134 fmov.l &0x0,%fpcr 7135 fmov.l %fpsr,%d1 7136 or.w %d1,2+USER_FPSR(%a6) 7137 7138 mov.b 1+EXC_OPWORD(%a6),%d1 7139 andi.b &0x38,%d1 7140 beq.b fout_byte_dn 7141 7142 mov.l EXC_EA(%a6),%a0 7143 bsr.l _dmem_write_byte 7144 7145 tst.l %d1 7146 bne.l facc_out_b 7147 7148 rts 7149 7150 fout_byte_dn: 7151 mov.b 1+EXC_OPWORD(%a6),%d1 7152 andi.w &0x7,%d1 7153 bsr.l store_dreg_b 7154 rts 7155 7156 fout_byte_denorm: 7157 mov.l SRC_EX(%a0),%d1 7158 andi.l &0x80000000,%d1 7159 ori.l &0x00800000,%d1 7160 fmov.s %d1,%fp0 7161 bra.b fout_byte_norm 7162 7163 ############################################# 7164 # fmove.w out ############################### 7165 ############################################# 7166 7167 # Only "Unimplemented Data Type" exceptions e 7168 # is either a DENORM or a NORM. 7169 fout_word: 7170 tst.b STAG(%a6) 7171 bne.b fout_word_denorm 7172 7173 fmovm.x SRC(%a0),&0x80 7174 7175 fout_word_norm: 7176 fmov.l %d0,%fpcr 7177 7178 fmov.w %fp0,%d0 7179 7180 fmov.l &0x0,%fpcr 7181 fmov.l %fpsr,%d1 7182 or.w %d1,2+USER_FPSR(%a6) 7183 7184 mov.b 1+EXC_OPWORD(%a6),%d1 7185 andi.b &0x38,%d1 7186 beq.b fout_word_dn 7187 7188 mov.l EXC_EA(%a6),%a0 7189 bsr.l _dmem_write_word 7190 7191 tst.l %d1 7192 bne.l facc_out_w 7193 7194 rts 7195 7196 fout_word_dn: 7197 mov.b 1+EXC_OPWORD(%a6),%d1 7198 andi.w &0x7,%d1 7199 bsr.l store_dreg_w 7200 rts 7201 7202 fout_word_denorm: 7203 mov.l SRC_EX(%a0),%d1 7204 andi.l &0x80000000,%d1 7205 ori.l &0x00800000,%d1 7206 fmov.s %d1,%fp0 7207 bra.b fout_word_norm 7208 7209 ############################################# 7210 # fmove.l out ############################### 7211 ############################################# 7212 7213 # Only "Unimplemented Data Type" exceptions e 7214 # is either a DENORM or a NORM. 7215 fout_long: 7216 tst.b STAG(%a6) 7217 bne.b fout_long_denorm 7218 7219 fmovm.x SRC(%a0),&0x80 7220 7221 fout_long_norm: 7222 fmov.l %d0,%fpcr 7223 7224 fmov.l %fp0,%d0 7225 7226 fmov.l &0x0,%fpcr 7227 fmov.l %fpsr,%d1 7228 or.w %d1,2+USER_FPSR(%a6) 7229 7230 fout_long_write: 7231 mov.b 1+EXC_OPWORD(%a6),%d1 7232 andi.b &0x38,%d1 7233 beq.b fout_long_dn 7234 7235 mov.l EXC_EA(%a6),%a0 7236 bsr.l _dmem_write_long 7237 7238 tst.l %d1 7239 bne.l facc_out_l 7240 7241 rts 7242 7243 fout_long_dn: 7244 mov.b 1+EXC_OPWORD(%a6),%d1 7245 andi.w &0x7,%d1 7246 bsr.l store_dreg_l 7247 rts 7248 7249 fout_long_denorm: 7250 mov.l SRC_EX(%a0),%d1 7251 andi.l &0x80000000,%d1 7252 ori.l &0x00800000,%d1 7253 fmov.s %d1,%fp0 7254 bra.b fout_long_norm 7255 7256 ############################################# 7257 # fmove.x out ############################### 7258 ############################################# 7259 7260 # Only "Unimplemented Data Type" exceptions e 7261 # is either a DENORM or a NORM. 7262 # The DENORM causes an Underflow exception. 7263 fout_ext: 7264 7265 # we copy the extended precision result to FP 7266 # 16-bit field gets zeroed. we do this since 7267 # what's at SRC(a0). 7268 mov.w SRC_EX(%a0),FP_SCR0_E 7269 clr.w 2+FP_SCR0_EX(%a6) 7270 mov.l SRC_HI(%a0),FP_SCR0_H 7271 mov.l SRC_LO(%a0),FP_SCR0_L 7272 7273 fmovm.x SRC(%a0),&0x80 7274 7275 bsr.l _calc_ea_fout 7276 7277 mov.l %a0,%a1 7278 lea FP_SCR0(%a6),%a0 7279 mov.l &0xc,%d0 7280 7281 # we must not yet write the extended precisio 7282 # in the pre-decrement case from supervisor m 7283 # the stack frame. so, leave it in FP_SRC for 7284 cmpi.b SPCOND_FLG(%a6),&mda7 7285 beq.b fout_ext_a7 7286 7287 bsr.l _dmem_write 7288 7289 tst.l %d1 7290 bne.w fout_ext_err 7291 7292 tst.b STAG(%a6) 7293 bne.b fout_ext_denorm 7294 rts 7295 7296 # the number is a DENORM. must set the underf 7297 fout_ext_denorm: 7298 bset &unfl_bit,FPSR_EXCEPT 7299 7300 mov.b FPCR_ENABLE(%a6),%d0 7301 andi.b &0x0a,%d0 7302 bne.b fout_ext_exc 7303 rts 7304 7305 # we don't want to do the write if the except 7306 # so _mem_write2() handles this for us. 7307 fout_ext_a7: 7308 bsr.l _mem_write2 7309 7310 tst.l %d1 7311 bne.w fout_ext_err 7312 7313 tst.b STAG(%a6) 7314 bne.b fout_ext_denorm 7315 rts 7316 7317 fout_ext_exc: 7318 lea FP_SCR0(%a6),%a0 7319 bsr.l norm 7320 neg.w %d0 7321 andi.w &0x7fff,%d0 7322 andi.w &0x8000,FP_SCR0_EX(%a 7323 or.w %d0,FP_SCR0_EX(%a6) 7324 fmovm.x FP_SCR0(%a6),&0x40 7325 rts 7326 7327 fout_ext_err: 7328 mov.l EXC_A6(%a6),(%a6) 7329 bra.l facc_out_x 7330 7331 ############################################# 7332 # fmove.s out ############################### 7333 ############################################# 7334 fout_sgl: 7335 andi.b &0x30,%d0 7336 ori.b &s_mode*0x10,%d0 7337 mov.l %d0,L_SCR3(%a6) 7338 7339 # 7340 # operand is a normalized number. first, we c 7341 # would cause either an underflow or overflow 7342 # separately. otherwise, set the FPCR to the 7343 # execute the move. 7344 # 7345 mov.w SRC_EX(%a0),%d0 7346 andi.w &0x7fff,%d0 7347 7348 cmpi.w %d0,&SGL_HI 7349 bgt.w fout_sgl_ovfl 7350 beq.w fout_sgl_may_ovfl 7351 cmpi.w %d0,&SGL_LO 7352 blt.w fout_sgl_unfl 7353 7354 # 7355 # NORMs(in range) can be stored out by a simp 7356 # Unnormalized inputs can come through this p 7357 # 7358 fout_sgl_exg: 7359 fmovm.x SRC(%a0),&0x80 7360 7361 fmov.l L_SCR3(%a6),%fpcr 7362 fmov.l &0x0,%fpsr 7363 7364 fmov.s %fp0,%d0 7365 7366 fmov.l &0x0,%fpcr 7367 fmov.l %fpsr,%d1 7368 7369 or.w %d1,2+USER_FPSR(%a6) 7370 7371 fout_sgl_exg_write: 7372 mov.b 1+EXC_OPWORD(%a6),%d1 7373 andi.b &0x38,%d1 7374 beq.b fout_sgl_exg_write_dn 7375 7376 mov.l EXC_EA(%a6),%a0 7377 bsr.l _dmem_write_long 7378 7379 tst.l %d1 7380 bne.l facc_out_l 7381 7382 rts 7383 7384 fout_sgl_exg_write_dn: 7385 mov.b 1+EXC_OPWORD(%a6),%d1 7386 andi.w &0x7,%d1 7387 bsr.l store_dreg_l 7388 rts 7389 7390 # 7391 # here, we know that the operand would UNFL i 7392 # so, denorm and round and then use generic s 7393 # write the value to memory. 7394 # 7395 fout_sgl_unfl: 7396 bset &unfl_bit,FPSR_EXCEPT 7397 7398 mov.w SRC_EX(%a0),FP_SCR0_E 7399 mov.l SRC_HI(%a0),FP_SCR0_H 7400 mov.l SRC_LO(%a0),FP_SCR0_L 7401 mov.l %a0,-(%sp) 7402 7403 clr.l %d0 7404 7405 cmpi.b STAG(%a6),&DENORM 7406 bne.b fout_sgl_unfl_cont 7407 7408 lea FP_SCR0(%a6),%a0 7409 bsr.l norm 7410 7411 fout_sgl_unfl_cont: 7412 lea FP_SCR0(%a6),%a0 7413 mov.l L_SCR3(%a6),%d1 7414 bsr.l unf_res 7415 7416 lea FP_SCR0(%a6),%a0 7417 bsr.l dst_sgl 7418 7419 mov.b 1+EXC_OPWORD(%a6),%d1 7420 andi.b &0x38,%d1 7421 beq.b fout_sgl_unfl_dn 7422 7423 mov.l EXC_EA(%a6),%a0 7424 bsr.l _dmem_write_long 7425 7426 tst.l %d1 7427 bne.l facc_out_l 7428 7429 bra.b fout_sgl_unfl_chkexc 7430 7431 fout_sgl_unfl_dn: 7432 mov.b 1+EXC_OPWORD(%a6),%d1 7433 andi.w &0x7,%d1 7434 bsr.l store_dreg_l 7435 7436 fout_sgl_unfl_chkexc: 7437 mov.b FPCR_ENABLE(%a6),%d1 7438 andi.b &0x0a,%d1 7439 bne.w fout_sd_exc_unfl 7440 addq.l &0x4,%sp 7441 rts 7442 7443 # 7444 # it's definitely an overflow so call ovf_res 7445 # 7446 fout_sgl_ovfl: 7447 tst.b 3+SRC_HI(%a0) 7448 bne.b fout_sgl_ovfl_inex2 7449 tst.l SRC_LO(%a0) 7450 bne.b fout_sgl_ovfl_inex2 7451 ori.w &ovfl_inx_mask,2+USER 7452 bra.b fout_sgl_ovfl_cont 7453 fout_sgl_ovfl_inex2: 7454 ori.w &ovfinx_mask,2+USER_F 7455 7456 fout_sgl_ovfl_cont: 7457 mov.l %a0,-(%sp) 7458 7459 # call ovf_res() w/ sgl prec and the correct 7460 # overflow result. DON'T save the returned cc 7461 # fmove out doesn't alter them. 7462 tst.b SRC_EX(%a0) 7463 smi %d1 7464 mov.l L_SCR3(%a6),%d0 7465 bsr.l ovf_res 7466 fmovm.x (%a0),&0x80 7467 fmov.s %fp0,%d0 7468 7469 mov.b 1+EXC_OPWORD(%a6),%d1 7470 andi.b &0x38,%d1 7471 beq.b fout_sgl_ovfl_dn 7472 7473 mov.l EXC_EA(%a6),%a0 7474 bsr.l _dmem_write_long 7475 7476 tst.l %d1 7477 bne.l facc_out_l 7478 7479 bra.b fout_sgl_ovfl_chkexc 7480 7481 fout_sgl_ovfl_dn: 7482 mov.b 1+EXC_OPWORD(%a6),%d1 7483 andi.w &0x7,%d1 7484 bsr.l store_dreg_l 7485 7486 fout_sgl_ovfl_chkexc: 7487 mov.b FPCR_ENABLE(%a6),%d1 7488 andi.b &0x0a,%d1 7489 bne.w fout_sd_exc_ovfl 7490 addq.l &0x4,%sp 7491 rts 7492 7493 # 7494 # move out MAY overflow: 7495 # (1) force the exp to 0x3fff 7496 # (2) do a move w/ appropriate rnd mode 7497 # (3) if exp still equals zero, then insert o 7498 # for the correct result. 7499 # if exp now equals one, then it overflow 7500 # 7501 fout_sgl_may_ovfl: 7502 mov.w SRC_EX(%a0),%d1 7503 andi.w &0x8000,%d1 7504 ori.w &0x3fff,%d1 7505 mov.w %d1,FP_SCR0_EX(%a6) 7506 mov.l SRC_HI(%a0),FP_SCR0_H 7507 mov.l SRC_LO(%a0),FP_SCR0_L 7508 7509 fmov.l L_SCR3(%a6),%fpcr 7510 7511 fmov.x FP_SCR0(%a6),%fp0 7512 fmov.l &0x0,%fpcr 7513 7514 fabs.x %fp0 7515 fcmp.b %fp0,&0x2 7516 fblt.w fout_sgl_exg 7517 bra.w fout_sgl_ovfl 7518 7519 ################ 7520 7521 fout_sd_exc_unfl: 7522 mov.l (%sp)+,%a0 7523 7524 mov.w SRC_EX(%a0),FP_SCR0_E 7525 mov.l SRC_HI(%a0),FP_SCR0_H 7526 mov.l SRC_LO(%a0),FP_SCR0_L 7527 7528 cmpi.b STAG(%a6),&DENORM 7529 bne.b fout_sd_exc_cont 7530 7531 lea FP_SCR0(%a6),%a0 7532 bsr.l norm 7533 neg.l %d0 7534 andi.w &0x7fff,%d0 7535 bfins %d0,FP_SCR0_EX(%a6){& 7536 bra.b fout_sd_exc_cont 7537 7538 fout_sd_exc: 7539 fout_sd_exc_ovfl: 7540 mov.l (%sp)+,%a0 7541 7542 mov.w SRC_EX(%a0),FP_SCR0_E 7543 mov.l SRC_HI(%a0),FP_SCR0_H 7544 mov.l SRC_LO(%a0),FP_SCR0_L 7545 7546 fout_sd_exc_cont: 7547 bclr &0x7,FP_SCR0_EX(%a6) 7548 sne.b 2+FP_SCR0_EX(%a6) 7549 lea FP_SCR0(%a6),%a0 7550 7551 mov.b 3+L_SCR3(%a6),%d1 7552 lsr.b &0x4,%d1 7553 andi.w &0x0c,%d1 7554 swap %d1 7555 mov.b 3+L_SCR3(%a6),%d1 7556 lsr.b &0x4,%d1 7557 andi.w &0x03,%d1 7558 clr.l %d0 7559 bsr.l _round 7560 7561 tst.b 2+FP_SCR0_EX(%a6) 7562 beq.b fout_sd_exc_done 7563 bset &0x7,FP_SCR0_EX(%a6) 7564 7565 fout_sd_exc_done: 7566 fmovm.x FP_SCR0(%a6),&0x40 7567 rts 7568 7569 ############################################# 7570 # fmove.d out ############################### 7571 ############################################# 7572 fout_dbl: 7573 andi.b &0x30,%d0 7574 ori.b &d_mode*0x10,%d0 7575 mov.l %d0,L_SCR3(%a6) 7576 7577 # 7578 # operand is a normalized number. first, we c 7579 # would cause either an underflow or overflow 7580 # separately. otherwise, set the FPCR to the 7581 # execute the move. 7582 # 7583 mov.w SRC_EX(%a0),%d0 7584 andi.w &0x7fff,%d0 7585 7586 cmpi.w %d0,&DBL_HI 7587 bgt.w fout_dbl_ovfl 7588 beq.w fout_dbl_may_ovfl 7589 cmpi.w %d0,&DBL_LO 7590 blt.w fout_dbl_unfl 7591 7592 # 7593 # NORMs(in range) can be stored out by a simp 7594 # Unnormalized inputs can come through this p 7595 # 7596 fout_dbl_exg: 7597 fmovm.x SRC(%a0),&0x80 7598 7599 fmov.l L_SCR3(%a6),%fpcr 7600 fmov.l &0x0,%fpsr 7601 7602 fmov.d %fp0,L_SCR1(%a6) 7603 7604 fmov.l &0x0,%fpcr 7605 fmov.l %fpsr,%d0 7606 7607 or.w %d0,2+USER_FPSR(%a6) 7608 7609 mov.l EXC_EA(%a6),%a1 7610 lea L_SCR1(%a6),%a0 7611 movq.l &0x8,%d0 7612 bsr.l _dmem_write 7613 7614 tst.l %d1 7615 bne.l facc_out_d 7616 7617 rts 7618 7619 # 7620 # here, we know that the operand would UNFL i 7621 # so, denorm and round and then use generic s 7622 # write the value to memory. 7623 # 7624 fout_dbl_unfl: 7625 bset &unfl_bit,FPSR_EXCEPT 7626 7627 mov.w SRC_EX(%a0),FP_SCR0_E 7628 mov.l SRC_HI(%a0),FP_SCR0_H 7629 mov.l SRC_LO(%a0),FP_SCR0_L 7630 mov.l %a0,-(%sp) 7631 7632 clr.l %d0 7633 7634 cmpi.b STAG(%a6),&DENORM 7635 bne.b fout_dbl_unfl_cont 7636 7637 lea FP_SCR0(%a6),%a0 7638 bsr.l norm 7639 7640 fout_dbl_unfl_cont: 7641 lea FP_SCR0(%a6),%a0 7642 mov.l L_SCR3(%a6),%d1 7643 bsr.l unf_res 7644 7645 lea FP_SCR0(%a6),%a0 7646 bsr.l dst_dbl 7647 mov.l %d0,L_SCR1(%a6) 7648 mov.l %d1,L_SCR2(%a6) 7649 7650 mov.l EXC_EA(%a6),%a1 7651 lea L_SCR1(%a6),%a0 7652 movq.l &0x8,%d0 7653 bsr.l _dmem_write 7654 7655 tst.l %d1 7656 bne.l facc_out_d 7657 7658 mov.b FPCR_ENABLE(%a6),%d1 7659 andi.b &0x0a,%d1 7660 bne.w fout_sd_exc_unfl 7661 addq.l &0x4,%sp 7662 rts 7663 7664 # 7665 # it's definitely an overflow so call ovf_res 7666 # 7667 fout_dbl_ovfl: 7668 mov.w 2+SRC_LO(%a0),%d0 7669 andi.w &0x7ff,%d0 7670 bne.b fout_dbl_ovfl_inex2 7671 7672 ori.w &ovfl_inx_mask,2+USER 7673 bra.b fout_dbl_ovfl_cont 7674 fout_dbl_ovfl_inex2: 7675 ori.w &ovfinx_mask,2+USER_F 7676 7677 fout_dbl_ovfl_cont: 7678 mov.l %a0,-(%sp) 7679 7680 # call ovf_res() w/ dbl prec and the correct 7681 # overflow result. DON'T save the returned cc 7682 # fmove out doesn't alter them. 7683 tst.b SRC_EX(%a0) 7684 smi %d1 7685 mov.l L_SCR3(%a6),%d0 7686 bsr.l ovf_res 7687 fmovm.x (%a0),&0x80 7688 fmov.d %fp0,L_SCR1(%a6) 7689 7690 mov.l EXC_EA(%a6),%a1 7691 lea L_SCR1(%a6),%a0 7692 movq.l &0x8,%d0 7693 bsr.l _dmem_write 7694 7695 tst.l %d1 7696 bne.l facc_out_d 7697 7698 mov.b FPCR_ENABLE(%a6),%d1 7699 andi.b &0x0a,%d1 7700 bne.w fout_sd_exc_ovfl 7701 addq.l &0x4,%sp 7702 rts 7703 7704 # 7705 # move out MAY overflow: 7706 # (1) force the exp to 0x3fff 7707 # (2) do a move w/ appropriate rnd mode 7708 # (3) if exp still equals zero, then insert o 7709 # for the correct result. 7710 # if exp now equals one, then it overflow 7711 # 7712 fout_dbl_may_ovfl: 7713 mov.w SRC_EX(%a0),%d1 7714 andi.w &0x8000,%d1 7715 ori.w &0x3fff,%d1 7716 mov.w %d1,FP_SCR0_EX(%a6) 7717 mov.l SRC_HI(%a0),FP_SCR0_H 7718 mov.l SRC_LO(%a0),FP_SCR0_L 7719 7720 fmov.l L_SCR3(%a6),%fpcr 7721 7722 fmov.x FP_SCR0(%a6),%fp0 7723 fmov.l &0x0,%fpcr 7724 7725 fabs.x %fp0 7726 fcmp.b %fp0,&0x2 7727 fblt.w fout_dbl_exg 7728 bra.w fout_dbl_ovfl 7729 7730 ############################################# 7731 # XDEF ************************************** 7732 # dst_dbl(): create double precision va 7733 # 7734 # XREF ************************************** 7735 # None 7736 # 7737 # INPUT ************************************* 7738 # a0 = pointer to source operand in ext 7739 # 7740 # OUTPUT ************************************ 7741 # d0 = hi(double precision result) 7742 # d1 = lo(double precision result) 7743 # 7744 # ALGORITHM ********************************* 7745 # 7746 # Changes extended precision to double preci 7747 # Note: no attempt is made to round the exte 7748 # dbl_sign = ext_sign 7749 # dbl_exp = ext_exp - $3fff(ext bias) + 7750 # get rid of ext integer bit 7751 # dbl_mant = ext_mant{62:12} 7752 # 7753 # --------------- ----------- 7754 # extended -> |s| exp | |1| ms mant 7755 # --------------- ----------- 7756 # 95 64 63 62 7757 # | 7758 # | 7759 # | 7760 # v 7761 # --------------- 7762 # double -> |s|exp| mant | 7763 # --------------- 7764 # 63 51 32 7765 # 7766 ############################################# 7767 7768 dst_dbl: 7769 clr.l %d0 7770 mov.w FTEMP_EX(%a0),%d0 7771 subi.w &EXT_BIAS,%d0 7772 addi.w &DBL_BIAS,%d0 7773 tst.b FTEMP_HI(%a0) 7774 bmi.b dst_get_dupper 7775 subq.w &0x1,%d0 7776 dst_get_dupper: 7777 swap %d0 7778 lsl.l &0x4,%d0 7779 tst.b FTEMP_EX(%a0) 7780 bpl.b dst_get_dman 7781 bset &0x1f,%d0 7782 dst_get_dman: 7783 mov.l FTEMP_HI(%a0),%d1 7784 bfextu %d1{&1:&20},%d1 7785 or.l %d1,%d0 7786 mov.l %d0,L_SCR1(%a6) 7787 mov.l FTEMP_HI(%a0),%d1 7788 mov.l &21,%d0 7789 lsl.l %d0,%d1 7790 mov.l %d1,L_SCR2(%a6) 7791 mov.l FTEMP_LO(%a0),%d1 7792 bfextu %d1{&0:&21},%d0 7793 mov.l L_SCR2(%a6),%d1 7794 or.l %d0,%d1 7795 mov.l L_SCR1(%a6),%d0 7796 rts 7797 7798 ############################################# 7799 # XDEF ************************************** 7800 # dst_sgl(): create single precision va 7801 # 7802 # XREF ************************************** 7803 # 7804 # INPUT ************************************* 7805 # a0 = pointer to source operand in ext 7806 # 7807 # OUTPUT ************************************ 7808 # d0 = single precision result 7809 # 7810 # ALGORITHM ********************************* 7811 # 7812 # Changes extended precision to single precis 7813 # sgl_sign = ext_sign 7814 # sgl_exp = ext_exp - $3fff(ext bias) + 7815 # get rid of ext integer bit 7816 # sgl_mant = ext_mant{62:12} 7817 # 7818 # --------------- ----------- 7819 # extended -> |s| exp | |1| ms mant 7820 # --------------- ----------- 7821 # 95 64 63 62 40 7822 # | | 7823 # | | 7824 # | | 7825 # v v 7826 # --------------- 7827 # single -> |s|exp| mant | 7828 # --------------- 7829 # 31 22 0 7830 # 7831 ############################################# 7832 7833 dst_sgl: 7834 clr.l %d0 7835 mov.w FTEMP_EX(%a0),%d0 7836 subi.w &EXT_BIAS,%d0 7837 addi.w &SGL_BIAS,%d0 7838 tst.b FTEMP_HI(%a0) 7839 bmi.b dst_get_supper 7840 subq.w &0x1,%d0 7841 dst_get_supper: 7842 swap %d0 7843 lsl.l &0x7,%d0 7844 tst.b FTEMP_EX(%a0) 7845 bpl.b dst_get_sman 7846 bset &0x1f,%d0 7847 dst_get_sman: 7848 mov.l FTEMP_HI(%a0),%d1 7849 andi.l &0x7fffff00,%d1 7850 lsr.l &0x8,%d1 7851 or.l %d1,%d0 7852 rts 7853 7854 ############################################# 7855 fout_pack: 7856 bsr.l _calc_ea_fout 7857 mov.l %a0,-(%sp) 7858 7859 mov.b STAG(%a6),%d0 7860 bne.w fout_pack_not_norm 7861 7862 fout_pack_norm: 7863 btst &0x4,EXC_CMDREG(%a6) 7864 beq.b fout_pack_s 7865 7866 fout_pack_d: 7867 mov.b 1+EXC_CMDREG(%a6),%d1 7868 lsr.b &0x4,%d1 7869 andi.w &0x7,%d1 7870 7871 bsr.l fetch_dreg 7872 7873 bra.b fout_pack_type 7874 fout_pack_s: 7875 mov.b 1+EXC_CMDREG(%a6),%d0 7876 7877 fout_pack_type: 7878 bfexts %d0{&25:&7},%d0 7879 mov.l %d0,-(%sp) 7880 7881 lea FP_SRC(%a6),%a0 7882 7883 # bindec is currently scrambling FP_SRC for d 7884 # we'll have to change this, but for now, tou 7885 bsr.l bindec 7886 7887 # andi.l &0xcfff000f,FP_SCR0(% 7888 andi.l &0xcffff00f,FP_SCR0(% 7889 7890 mov.l (%sp)+,%d0 7891 7892 tst.b 3+FP_SCR0_EX(%a6) 7893 bne.b fout_pack_set 7894 tst.l FP_SCR0_HI(%a6) 7895 bne.b fout_pack_set 7896 tst.l FP_SCR0_LO(%a6) 7897 bne.b fout_pack_set 7898 7899 # add the extra condition that only if the k- 7900 # we zero the exponent 7901 tst.l %d0 7902 bne.b fout_pack_set 7903 # "mantissa" is all zero which means that the 7904 # algorithm allows the exponent to be non-zer 7905 # if the mantissa is zero, I will zero the ex 7906 # the question now is whether the exponents s 7907 # for a zero, also... 7908 andi.w &0xf000,FP_SCR0(%a6) 7909 7910 fout_pack_set: 7911 7912 lea FP_SCR0(%a6),%a0 7913 7914 fout_pack_write: 7915 mov.l (%sp)+,%a1 7916 mov.l &0xc,%d0 7917 7918 cmpi.b SPCOND_FLG(%a6),&mda7 7919 beq.b fout_pack_a7 7920 7921 bsr.l _dmem_write 7922 7923 tst.l %d1 7924 bne.w fout_ext_err 7925 7926 rts 7927 7928 # we don't want to do the write if the except 7929 # so _mem_write2() handles this for us. 7930 fout_pack_a7: 7931 bsr.l _mem_write2 7932 7933 tst.l %d1 7934 bne.w fout_ext_err 7935 7936 rts 7937 7938 fout_pack_not_norm: 7939 cmpi.b %d0,&DENORM 7940 beq.w fout_pack_norm 7941 lea FP_SRC(%a6),%a0 7942 clr.w 2+FP_SRC_EX(%a6) 7943 cmpi.b %d0,&SNAN 7944 beq.b fout_pack_snan 7945 bra.b fout_pack_write 7946 7947 fout_pack_snan: 7948 ori.w &snaniop2_mask,FPSR_E 7949 bset &0x6,FP_SRC_HI(%a6) 7950 bra.b fout_pack_write 7951 7952 ############################################# 7953 # XDEF ************************************** 7954 # fmul(): emulates the fmul instruction 7955 # fsmul(): emulates the fsmul instructi 7956 # fdmul(): emulates the fdmul instructi 7957 # 7958 # XREF ************************************** 7959 # scale_to_zero_src() - scale src expon 7960 # scale_to_zero_dst() - scale dst expon 7961 # unf_res() - return default underflow 7962 # ovf_res() - return default overflow r 7963 # res_qnan() - return QNAN result 7964 # res_snan() - return SNAN result 7965 # 7966 # INPUT ************************************* 7967 # a0 = pointer to extended precision so 7968 # a1 = pointer to extended precision de 7969 # d0 rnd prec,mode 7970 # 7971 # OUTPUT ************************************ 7972 # fp0 = result 7973 # fp1 = EXOP (if exception occurred) 7974 # 7975 # ALGORITHM ********************************* 7976 # Handle NANs, infinities, and zeroes a 7977 # norms/denorms into ext/sgl/dbl precision. 7978 # For norms/denorms, scale the exponent 7979 # instruction won't cause an exception. Use t 7980 # compute a result. Check if the regular oper 7981 # an exception. If so, return the default ove 7982 # and return the EXOP if exceptions are enabl 7983 # result operand to the proper exponent. 7984 # 7985 ############################################# 7986 7987 align 0x10 7988 tbl_fmul_ovfl: 7989 long 0x3fff - 0x7ffe 7990 long 0x3fff - 0x407e 7991 long 0x3fff - 0x43fe 7992 tbl_fmul_unfl: 7993 long 0x3fff + 0x0001 7994 long 0x3fff - 0x3f80 7995 long 0x3fff - 0x3c00 7996 7997 global fsmul 7998 fsmul: 7999 andi.b &0x30,%d0 8000 ori.b &s_mode*0x10,%d0 8001 bra.b fmul 8002 8003 global fdmul 8004 fdmul: 8005 andi.b &0x30,%d0 8006 ori.b &d_mode*0x10,%d0 8007 8008 global fmul 8009 fmul: 8010 mov.l %d0,L_SCR3(%a6) 8011 8012 clr.w %d1 8013 mov.b DTAG(%a6),%d1 8014 lsl.b &0x3,%d1 8015 or.b STAG(%a6),%d1 8016 bne.w fmul_not_norm 8017 8018 fmul_norm: 8019 mov.w DST_EX(%a1),FP_SCR1_E 8020 mov.l DST_HI(%a1),FP_SCR1_H 8021 mov.l DST_LO(%a1),FP_SCR1_L 8022 8023 mov.w SRC_EX(%a0),FP_SCR0_E 8024 mov.l SRC_HI(%a0),FP_SCR0_H 8025 mov.l SRC_LO(%a0),FP_SCR0_L 8026 8027 bsr.l scale_to_zero_src 8028 mov.l %d0,-(%sp) 8029 8030 bsr.l scale_to_zero_dst 8031 8032 add.l %d0,(%sp) 8033 8034 mov.w 2+L_SCR3(%a6),%d1 8035 lsr.b &0x6,%d1 8036 mov.l (%sp)+,%d0 8037 cmp.l %d0,(tbl_fmul_ovfl.w, 8038 beq.w fmul_may_ovfl 8039 blt.w fmul_ovfl 8040 8041 cmp.l %d0,(tbl_fmul_unfl.w, 8042 beq.w fmul_may_unfl 8043 bgt.w fmul_unfl 8044 8045 # 8046 # NORMAL: 8047 # - the result of the multiply operation will 8048 # - do the multiply to the proper precision a 8049 # - scale the result exponent using the scale 8050 # normalized then we really don't need to go 8051 # this will do. 8052 # 8053 fmul_normal: 8054 fmovm.x FP_SCR1(%a6),&0x80 8055 8056 fmov.l L_SCR3(%a6),%fpcr 8057 fmov.l &0x0,%fpsr 8058 8059 fmul.x FP_SCR0(%a6),%fp0 8060 8061 fmov.l %fpsr,%d1 8062 fmov.l &0x0,%fpcr 8063 8064 or.l %d1,USER_FPSR(%a6) 8065 8066 fmul_normal_exit: 8067 fmovm.x &0x80,FP_SCR0(%a6) 8068 mov.l %d2,-(%sp) 8069 mov.w FP_SCR0_EX(%a6),%d1 8070 mov.l %d1,%d2 8071 andi.l &0x7fff,%d1 8072 andi.w &0x8000,%d2 8073 sub.l %d0,%d1 8074 or.w %d2,%d1 8075 mov.w %d1,FP_SCR0_EX(%a6) 8076 mov.l (%sp)+,%d2 8077 fmovm.x FP_SCR0(%a6),&0x80 8078 rts 8079 8080 # 8081 # OVERFLOW: 8082 # - the result of the multiply operation is a 8083 # - do the multiply to the proper precision a 8084 # set the inexact bits. 8085 # - calculate the default result and return i 8086 # - if overflow or inexact is enabled, we nee 8087 # extended precision. if the original operati 8088 # result. if the original operation was singl 8089 # multiply using extended precision and the c 8090 # of this operation then has its exponent sca 8091 # exceptional operand. 8092 # 8093 fmul_ovfl: 8094 fmovm.x FP_SCR1(%a6),&0x80 8095 8096 fmov.l L_SCR3(%a6),%fpcr 8097 fmov.l &0x0,%fpsr 8098 8099 fmul.x FP_SCR0(%a6),%fp0 8100 8101 fmov.l %fpsr,%d1 8102 fmov.l &0x0,%fpcr 8103 8104 or.l %d1,USER_FPSR(%a6) 8105 8106 # save setting this until now because this is 8107 fmul_ovfl_tst: 8108 or.l &ovfl_inx_mask,USER_F 8109 8110 mov.b FPCR_ENABLE(%a6),%d1 8111 andi.b &0x13,%d1 8112 bne.b fmul_ovfl_ena 8113 8114 # calculate the default result 8115 fmul_ovfl_dis: 8116 btst &neg_bit,FPSR_CC(%a6) 8117 sne %d1 8118 mov.l L_SCR3(%a6),%d0 8119 bsr.l ovf_res 8120 or.b %d0,FPSR_CC(%a6) 8121 fmovm.x (%a0),&0x80 8122 rts 8123 8124 # 8125 # OVFL is enabled; Create EXOP: 8126 # - if precision is extended, then we have th 8127 # with an extra -0x6000. if the precision is 8128 # calculate a result rounded to extended prec 8129 # 8130 fmul_ovfl_ena: 8131 mov.l L_SCR3(%a6),%d1 8132 andi.b &0xc0,%d1 8133 bne.b fmul_ovfl_ena_sd 8134 8135 fmul_ovfl_ena_cont: 8136 fmovm.x &0x80,FP_SCR0(%a6) 8137 8138 mov.l %d2,-(%sp) 8139 mov.w FP_SCR0_EX(%a6),%d1 8140 mov.w %d1,%d2 8141 andi.l &0x7fff,%d1 8142 sub.l %d0,%d1 8143 subi.l &0x6000,%d1 8144 andi.w &0x7fff,%d1 8145 andi.w &0x8000,%d2 8146 or.w %d2,%d1 8147 mov.w %d1,FP_SCR0_EX(%a6) 8148 mov.l (%sp)+,%d2 8149 fmovm.x FP_SCR0(%a6),&0x40 8150 bra.b fmul_ovfl_dis 8151 8152 fmul_ovfl_ena_sd: 8153 fmovm.x FP_SCR1(%a6),&0x80 8154 8155 mov.l L_SCR3(%a6),%d1 8156 andi.b &0x30,%d1 8157 fmov.l %d1,%fpcr 8158 8159 fmul.x FP_SCR0(%a6),%fp0 8160 8161 fmov.l &0x0,%fpcr 8162 bra.b fmul_ovfl_ena_cont 8163 8164 # 8165 # may OVERFLOW: 8166 # - the result of the multiply operation MAY 8167 # - do the multiply to the proper precision a 8168 # set the inexact bits. 8169 # - calculate the default result and return i 8170 # 8171 fmul_may_ovfl: 8172 fmovm.x FP_SCR1(%a6),&0x80 8173 8174 fmov.l L_SCR3(%a6),%fpcr 8175 fmov.l &0x0,%fpsr 8176 8177 fmul.x FP_SCR0(%a6),%fp0 8178 8179 fmov.l %fpsr,%d1 8180 fmov.l &0x0,%fpcr 8181 8182 or.l %d1,USER_FPSR(%a6) 8183 8184 fabs.x %fp0,%fp1 8185 fcmp.b %fp1,&0x2 8186 fbge.w fmul_ovfl_tst 8187 8188 # no, it didn't overflow; we have correct res 8189 bra.w fmul_normal_exit 8190 8191 # 8192 # UNDERFLOW: 8193 # - the result of the multiply operation is a 8194 # - do the multiply to the proper precision a 8195 # set the inexact bits. 8196 # - calculate the default result and return i 8197 # - if overflow or inexact is enabled, we nee 8198 # extended precision. if the original operati 8199 # result. if the original operation was singl 8200 # multiply using extended precision and the c 8201 # of this operation then has its exponent sca 8202 # exceptional operand. 8203 # 8204 fmul_unfl: 8205 bset &unfl_bit,FPSR_EXCEPT 8206 8207 # for fun, let's use only extended precision, 8208 # the unf_res() routine figure out all the re 8209 # will we get the correct answer. 8210 fmovm.x FP_SCR1(%a6),&0x80 8211 8212 fmov.l &rz_mode*0x10,%fpcr 8213 fmov.l &0x0,%fpsr 8214 8215 fmul.x FP_SCR0(%a6),%fp0 8216 8217 fmov.l %fpsr,%d1 8218 fmov.l &0x0,%fpcr 8219 8220 or.l %d1,USER_FPSR(%a6) 8221 8222 mov.b FPCR_ENABLE(%a6),%d1 8223 andi.b &0x0b,%d1 8224 bne.b fmul_unfl_ena 8225 8226 fmul_unfl_dis: 8227 fmovm.x &0x80,FP_SCR0(%a6) 8228 8229 lea FP_SCR0(%a6),%a0 8230 mov.l L_SCR3(%a6),%d1 8231 bsr.l unf_res 8232 or.b %d0,FPSR_CC(%a6) 8233 fmovm.x FP_SCR0(%a6),&0x80 8234 rts 8235 8236 # 8237 # UNFL is enabled. 8238 # 8239 fmul_unfl_ena: 8240 fmovm.x FP_SCR1(%a6),&0x40 8241 8242 mov.l L_SCR3(%a6),%d1 8243 andi.b &0xc0,%d1 8244 bne.b fmul_unfl_ena_sd 8245 8246 # if the rnd mode is anything but RZ, then we 8247 # multiplication because we used RZ for all. 8248 fmov.l L_SCR3(%a6),%fpcr 8249 8250 fmul_unfl_ena_cont: 8251 fmov.l &0x0,%fpsr 8252 8253 fmul.x FP_SCR0(%a6),%fp1 8254 8255 fmov.l &0x0,%fpcr 8256 8257 fmovm.x &0x40,FP_SCR0(%a6) 8258 mov.l %d2,-(%sp) 8259 mov.w FP_SCR0_EX(%a6),%d1 8260 mov.l %d1,%d2 8261 andi.l &0x7fff,%d1 8262 andi.w &0x8000,%d2 8263 sub.l %d0,%d1 8264 addi.l &0x6000,%d1 8265 andi.w &0x7fff,%d1 8266 or.w %d2,%d1 8267 mov.w %d1,FP_SCR0_EX(%a6) 8268 mov.l (%sp)+,%d2 8269 fmovm.x FP_SCR0(%a6),&0x40 8270 bra.w fmul_unfl_dis 8271 8272 fmul_unfl_ena_sd: 8273 mov.l L_SCR3(%a6),%d1 8274 andi.b &0x30,%d1 8275 fmov.l %d1,%fpcr 8276 8277 bra.b fmul_unfl_ena_cont 8278 8279 # MAY UNDERFLOW: 8280 # -use the correct rounding mode and precisio 8281 # that do not underflow. 8282 fmul_may_unfl: 8283 fmovm.x FP_SCR1(%a6),&0x80 8284 8285 fmov.l L_SCR3(%a6),%fpcr 8286 fmov.l &0x0,%fpsr 8287 8288 fmul.x FP_SCR0(%a6),%fp0 8289 8290 fmov.l %fpsr,%d1 8291 fmov.l &0x0,%fpcr 8292 8293 or.l %d1,USER_FPSR(%a6) 8294 8295 fabs.x %fp0,%fp1 8296 fcmp.b %fp1,&0x2 8297 fbgt.w fmul_normal_exit 8298 fblt.w fmul_unfl 8299 8300 # 8301 # we still don't know if underflow occurred. 8302 # we don't know if the result was an underflo 8303 # a normalized number that rounded down to a 8304 # using RZ as the rounding mode to see what t 8305 # this case should be relatively rare. 8306 # 8307 fmovm.x FP_SCR1(%a6),&0x40 8308 8309 mov.l L_SCR3(%a6),%d1 8310 andi.b &0xc0,%d1 8311 ori.b &rz_mode*0x10,%d1 8312 8313 fmov.l %d1,%fpcr 8314 fmov.l &0x0,%fpsr 8315 8316 fmul.x FP_SCR0(%a6),%fp1 8317 8318 fmov.l &0x0,%fpcr 8319 fabs.x %fp1 8320 fcmp.b %fp1,&0x2 8321 fbge.w fmul_normal_exit 8322 bra.w fmul_unfl 8323 8324 ############################################# 8325 8326 # 8327 # Multiply: inputs are not both normalized; w 8328 # 8329 fmul_not_norm: 8330 mov.w (tbl_fmul_op.b,%pc,%d 8331 jmp (tbl_fmul_op.b,%pc,%d 8332 8333 swbeg &48 8334 tbl_fmul_op: 8335 short fmul_norm - tbl 8336 short fmul_zero - tbl 8337 short fmul_inf_src - tbl 8338 short fmul_res_qnan - tbl 8339 short fmul_norm - tbl 8340 short fmul_res_snan - tbl 8341 short tbl_fmul_op - tbl 8342 short tbl_fmul_op - tbl 8343 8344 short fmul_zero - tbl 8345 short fmul_zero - tbl 8346 short fmul_res_operr - tbl 8347 short fmul_res_qnan - tbl 8348 short fmul_zero - tbl 8349 short fmul_res_snan - tbl 8350 short tbl_fmul_op - tbl 8351 short tbl_fmul_op - tbl 8352 8353 short fmul_inf_dst - tbl 8354 short fmul_res_operr - tbl 8355 short fmul_inf_dst - tbl 8356 short fmul_res_qnan - tbl 8357 short fmul_inf_dst - tbl 8358 short fmul_res_snan - tbl 8359 short tbl_fmul_op - tbl 8360 short tbl_fmul_op - tbl 8361 8362 short fmul_res_qnan - tbl 8363 short fmul_res_qnan - tbl 8364 short fmul_res_qnan - tbl 8365 short fmul_res_qnan - tbl 8366 short fmul_res_qnan - tbl 8367 short fmul_res_snan - tbl 8368 short tbl_fmul_op - tbl 8369 short tbl_fmul_op - tbl 8370 8371 short fmul_norm - tbl 8372 short fmul_zero - tbl 8373 short fmul_inf_src - tbl 8374 short fmul_res_qnan - tbl 8375 short fmul_norm - tbl 8376 short fmul_res_snan - tbl 8377 short tbl_fmul_op - tbl 8378 short tbl_fmul_op - tbl 8379 8380 short fmul_res_snan - tbl 8381 short fmul_res_snan - tbl 8382 short fmul_res_snan - tbl 8383 short fmul_res_snan - tbl 8384 short fmul_res_snan - tbl 8385 short fmul_res_snan - tbl 8386 short tbl_fmul_op - tbl 8387 short tbl_fmul_op - tbl 8388 8389 fmul_res_operr: 8390 bra.l res_operr 8391 fmul_res_snan: 8392 bra.l res_snan 8393 fmul_res_qnan: 8394 bra.l res_qnan 8395 8396 # 8397 # Multiply: (Zero x Zero) || (Zero x norm) || 8398 # 8399 global fmul_zero 8400 fmul_zero: 8401 mov.b SRC_EX(%a0),%d0 8402 mov.b DST_EX(%a1),%d1 8403 eor.b %d0,%d1 8404 bpl.b fmul_zero_p 8405 fmul_zero_n: 8406 fmov.s &0x80000000,%fp0 8407 mov.b &z_bmask+neg_bmask,FP 8408 rts 8409 fmul_zero_p: 8410 fmov.s &0x00000000,%fp0 8411 mov.b &z_bmask,FPSR_CC(%a6) 8412 rts 8413 8414 # 8415 # Multiply: (inf x inf) || (inf x norm) || (i 8416 # 8417 # Note: The j-bit for an infinity is a don't- 8418 # strictly compatible w/ the 68881/882, we ma 8419 # INF w/ the j-bit set if the input INF j-bit 8420 # INFs take priority. 8421 # 8422 global fmul_inf_dst 8423 fmul_inf_dst: 8424 fmovm.x DST(%a1),&0x80 8425 mov.b SRC_EX(%a0),%d0 8426 mov.b DST_EX(%a1),%d1 8427 eor.b %d0,%d1 8428 bpl.b fmul_inf_dst_p 8429 fmul_inf_dst_n: 8430 fabs.x %fp0 8431 fneg.x %fp0 8432 mov.b &inf_bmask+neg_bmask, 8433 rts 8434 fmul_inf_dst_p: 8435 fabs.x %fp0 8436 mov.b &inf_bmask,FPSR_CC(%a 8437 rts 8438 8439 global fmul_inf_src 8440 fmul_inf_src: 8441 fmovm.x SRC(%a0),&0x80 8442 mov.b SRC_EX(%a0),%d0 8443 mov.b DST_EX(%a1),%d1 8444 eor.b %d0,%d1 8445 bpl.b fmul_inf_dst_p 8446 bra.b fmul_inf_dst_n 8447 8448 ############################################# 8449 # XDEF ************************************** 8450 # fin(): emulates the fmove instruction 8451 # fsin(): emulates the fsmove instructi 8452 # fdin(): emulates the fdmove instructi 8453 # 8454 # XREF ************************************** 8455 # norm() - normalize mantissa for EXOP 8456 # scale_to_zero_src() - scale src expon 8457 # ovf_res() - return default overflow r 8458 # unf_res() - return default underflow 8459 # res_qnan_1op() - return QNAN result 8460 # res_snan_1op() - return SNAN result 8461 # 8462 # INPUT ************************************* 8463 # a0 = pointer to extended precision so 8464 # d0 = round prec/mode 8465 # 8466 # OUTPUT ************************************ 8467 # fp0 = result 8468 # fp1 = EXOP (if exception occurred) 8469 # 8470 # ALGORITHM ********************************* 8471 # Handle NANs, infinities, and zeroes a 8472 # norms into extended, single, and double pre 8473 # Norms can be emulated w/ a regular fm 8474 # sgl/dbl, must scale exponent and perform an 8475 # if the result would have overflowed/underfl 8476 # or ovf_res() to return the default result. 8477 # exception is enabled. If no exception, retu 8478 # Unnorms don't pass through here. 8479 # 8480 ############################################# 8481 8482 global fsin 8483 fsin: 8484 andi.b &0x30,%d0 8485 ori.b &s_mode*0x10,%d0 8486 bra.b fin 8487 8488 global fdin 8489 fdin: 8490 andi.b &0x30,%d0 8491 ori.b &d_mode*0x10,%d0 8492 8493 global fin 8494 fin: 8495 mov.l %d0,L_SCR3(%a6) 8496 8497 mov.b STAG(%a6),%d1 8498 bne.w fin_not_norm 8499 8500 # 8501 # FP MOVE IN: NORMs and DENORMs ONLY! 8502 # 8503 fin_norm: 8504 andi.b &0xc0,%d0 8505 bne.w fin_not_ext 8506 8507 # 8508 # precision selected is extended. so...we can 8509 # or overflow because of rounding to the corr 8510 # skip the scaling and unscaling... 8511 # 8512 tst.b SRC_EX(%a0) 8513 bpl.b fin_norm_done 8514 bset &neg_bit,FPSR_CC(%a6) 8515 fin_norm_done: 8516 fmovm.x SRC(%a0),&0x80 8517 rts 8518 8519 # 8520 # for an extended precision DENORM, the UNFL 8521 # the accrued bit is NOT set in this instance 8522 # 8523 fin_denorm: 8524 andi.b &0xc0,%d0 8525 bne.w fin_not_ext 8526 8527 bset &unfl_bit,FPSR_EXCEPT 8528 tst.b SRC_EX(%a0) 8529 bpl.b fin_denorm_done 8530 bset &neg_bit,FPSR_CC(%a6) 8531 fin_denorm_done: 8532 fmovm.x SRC(%a0),&0x80 8533 btst &unfl_bit,FPCR_ENABLE 8534 bne.b fin_denorm_unfl_ena 8535 rts 8536 8537 # 8538 # the input is an extended DENORM and underfl 8539 # normalize the mantissa and add the bias of 8540 # exponent and insert back into the operand. 8541 # 8542 fin_denorm_unfl_ena: 8543 mov.w SRC_EX(%a0),FP_SCR0_E 8544 mov.l SRC_HI(%a0),FP_SCR0_H 8545 mov.l SRC_LO(%a0),FP_SCR0_L 8546 lea FP_SCR0(%a6),%a0 8547 bsr.l norm 8548 neg.w %d0 8549 addi.w &0x6000,%d0 8550 mov.w FP_SCR0_EX(%a6),%d1 8551 andi.w &0x8000,%d1 8552 andi.w &0x7fff,%d0 8553 or.w %d1,%d0 8554 mov.w %d0,FP_SCR0_EX(%a6) 8555 fmovm.x FP_SCR0(%a6),&0x40 8556 rts 8557 8558 # 8559 # operand is to be rounded to single or doubl 8560 # 8561 fin_not_ext: 8562 cmpi.b %d0,&s_mode*0x10 8563 bne.b fin_dbl 8564 8565 # 8566 # operand is to be rounded to single precisio 8567 # 8568 fin_sgl: 8569 mov.w SRC_EX(%a0),FP_SCR0_E 8570 mov.l SRC_HI(%a0),FP_SCR0_H 8571 mov.l SRC_LO(%a0),FP_SCR0_L 8572 bsr.l scale_to_zero_src 8573 8574 cmpi.l %d0,&0x3fff-0x3f80 8575 bge.w fin_sd_unfl 8576 cmpi.l %d0,&0x3fff-0x407e 8577 beq.w fin_sd_may_ovfl 8578 blt.w fin_sd_ovfl 8579 8580 # 8581 # operand will NOT overflow or underflow when 8582 # 8583 fin_sd_normal: 8584 fmov.l &0x0,%fpsr 8585 fmov.l L_SCR3(%a6),%fpcr 8586 8587 fmov.x FP_SCR0(%a6),%fp0 8588 8589 fmov.l %fpsr,%d1 8590 fmov.l &0x0,%fpcr 8591 8592 or.l %d1,USER_FPSR(%a6) 8593 8594 fin_sd_normal_exit: 8595 mov.l %d2,-(%sp) 8596 fmovm.x &0x80,FP_SCR0(%a6) 8597 mov.w FP_SCR0_EX(%a6),%d1 8598 mov.w %d1,%d2 8599 andi.l &0x7fff,%d1 8600 sub.l %d0,%d1 8601 andi.w &0x8000,%d2 8602 or.w %d1,%d2 8603 mov.w %d2,FP_SCR0_EX(%a6) 8604 mov.l (%sp)+,%d2 8605 fmovm.x FP_SCR0(%a6),&0x80 8606 rts 8607 8608 # 8609 # operand is to be rounded to double precisio 8610 # 8611 fin_dbl: 8612 mov.w SRC_EX(%a0),FP_SCR0_E 8613 mov.l SRC_HI(%a0),FP_SCR0_H 8614 mov.l SRC_LO(%a0),FP_SCR0_L 8615 bsr.l scale_to_zero_src 8616 8617 cmpi.l %d0,&0x3fff-0x3c00 8618 bge.w fin_sd_unfl 8619 cmpi.l %d0,&0x3fff-0x43fe 8620 beq.w fin_sd_may_ovfl 8621 blt.w fin_sd_ovfl 8622 bra.w fin_sd_normal 8623 8624 # 8625 # operand WILL underflow when moved in to the 8626 # 8627 fin_sd_unfl: 8628 bset &unfl_bit,FPSR_EXCEPT 8629 8630 tst.b FP_SCR0_EX(%a6) 8631 bpl.b fin_sd_unfl_tst 8632 bset &neg_bit,FPSR_CC(%a6) 8633 8634 # if underflow or inexact is enabled, then go 8635 fin_sd_unfl_tst: 8636 mov.b FPCR_ENABLE(%a6),%d1 8637 andi.b &0x0b,%d1 8638 bne.b fin_sd_unfl_ena 8639 8640 fin_sd_unfl_dis: 8641 lea FP_SCR0(%a6),%a0 8642 mov.l L_SCR3(%a6),%d1 8643 bsr.l unf_res 8644 or.b %d0,FPSR_CC(%a6) 8645 fmovm.x FP_SCR0(%a6),&0x80 8646 rts 8647 8648 # 8649 # operand will underflow AND underflow or ine 8650 # Therefore, we must return the result rounde 8651 # 8652 fin_sd_unfl_ena: 8653 mov.l FP_SCR0_HI(%a6),FP_SC 8654 mov.l FP_SCR0_LO(%a6),FP_SC 8655 mov.w FP_SCR0_EX(%a6),%d1 8656 8657 mov.l %d2,-(%sp) 8658 mov.w %d1,%d2 8659 andi.l &0x7fff,%d1 8660 sub.l %d0,%d1 8661 andi.w &0x8000,%d2 8662 addi.l &0x6000,%d1 8663 andi.w &0x7fff,%d1 8664 or.w %d1,%d2 8665 mov.w %d2,FP_SCR1_EX(%a6) 8666 fmovm.x FP_SCR1(%a6),&0x40 8667 mov.l (%sp)+,%d2 8668 bra.b fin_sd_unfl_dis 8669 8670 # 8671 # operand WILL overflow. 8672 # 8673 fin_sd_ovfl: 8674 fmov.l &0x0,%fpsr 8675 fmov.l L_SCR3(%a6),%fpcr 8676 8677 fmov.x FP_SCR0(%a6),%fp0 8678 8679 fmov.l &0x0,%fpcr 8680 fmov.l %fpsr,%d1 8681 8682 or.l %d1,USER_FPSR(%a6) 8683 8684 fin_sd_ovfl_tst: 8685 or.l &ovfl_inx_mask,USER_F 8686 8687 mov.b FPCR_ENABLE(%a6),%d1 8688 andi.b &0x13,%d1 8689 bne.b fin_sd_ovfl_ena 8690 8691 # 8692 # OVFL is not enabled; therefore, we must cre 8693 # calling ovf_res(). 8694 # 8695 fin_sd_ovfl_dis: 8696 btst &neg_bit,FPSR_CC(%a6) 8697 sne %d1 8698 mov.l L_SCR3(%a6),%d0 8699 bsr.l ovf_res 8700 or.b %d0,FPSR_CC(%a6) 8701 fmovm.x (%a0),&0x80 8702 rts 8703 8704 # 8705 # OVFL is enabled. 8706 # the INEX2 bit has already been updated by t 8707 # now, round to extended(and don't alter the 8708 # 8709 fin_sd_ovfl_ena: 8710 mov.l %d2,-(%sp) 8711 mov.w FP_SCR0_EX(%a6),%d1 8712 mov.l %d1,%d2 8713 andi.l &0x7fff,%d1 8714 andi.w &0x8000,%d2 8715 sub.l %d0,%d1 8716 sub.l &0x6000,%d1 8717 andi.w &0x7fff,%d1 8718 or.w %d2,%d1 8719 mov.w %d1,FP_SCR0_EX(%a6) 8720 mov.l (%sp)+,%d2 8721 fmovm.x FP_SCR0(%a6),&0x40 8722 bra.b fin_sd_ovfl_dis 8723 8724 # 8725 # the move in MAY overflow. so... 8726 # 8727 fin_sd_may_ovfl: 8728 fmov.l &0x0,%fpsr 8729 fmov.l L_SCR3(%a6),%fpcr 8730 8731 fmov.x FP_SCR0(%a6),%fp0 8732 8733 fmov.l %fpsr,%d1 8734 fmov.l &0x0,%fpcr 8735 8736 or.l %d1,USER_FPSR(%a6) 8737 8738 fabs.x %fp0,%fp1 8739 fcmp.b %fp1,&0x2 8740 fbge.w fin_sd_ovfl_tst 8741 8742 # no, it didn't overflow; we have correct res 8743 bra.w fin_sd_normal_exit 8744 8745 ############################################# 8746 8747 # 8748 # operand is not a NORM: check its optype and 8749 # 8750 fin_not_norm: 8751 cmpi.b %d1,&DENORM 8752 beq.w fin_denorm 8753 cmpi.b %d1,&SNAN 8754 beq.l res_snan_1op 8755 cmpi.b %d1,&QNAN 8756 beq.l res_qnan_1op 8757 8758 # 8759 # do the fmove in; at this point, only possib 8760 # use fmov to determine ccodes. 8761 # prec:mode should be zero at this point but 8762 # 8763 fmov.x SRC(%a0),%fp0 8764 fmov.l %fpsr,%d0 8765 rol.l &0x8,%d0 8766 mov.b %d0,FPSR_CC(%a6) 8767 rts 8768 8769 ############################################# 8770 # XDEF ************************************** 8771 # fdiv(): emulates the fdiv instruction 8772 # fsdiv(): emulates the fsdiv instructi 8773 # fddiv(): emulates the fddiv instructi 8774 # 8775 # XREF ************************************** 8776 # scale_to_zero_src() - scale src expon 8777 # scale_to_zero_dst() - scale dst expon 8778 # unf_res() - return default underflow 8779 # ovf_res() - return default overflow r 8780 # res_qnan() - return QNAN result 8781 # res_snan() - return SNAN result 8782 # 8783 # INPUT ************************************* 8784 # a0 = pointer to extended precision so 8785 # a1 = pointer to extended precision de 8786 # d0 rnd prec,mode 8787 # 8788 # OUTPUT ************************************ 8789 # fp0 = result 8790 # fp1 = EXOP (if exception occurred) 8791 # 8792 # ALGORITHM ********************************* 8793 # Handle NANs, infinities, and zeroes a 8794 # norms/denorms into ext/sgl/dbl precision. 8795 # For norms/denorms, scale the exponent 8796 # instruction won't cause an exception. Use t 8797 # compute a result. Check if the regular oper 8798 # an exception. If so, return the default ove 8799 # and return the EXOP if exceptions are enabl 8800 # result operand to the proper exponent. 8801 # 8802 ############################################# 8803 8804 align 0x10 8805 tbl_fdiv_unfl: 8806 long 0x3fff - 0x0000 8807 long 0x3fff - 0x3f81 8808 long 0x3fff - 0x3c01 8809 8810 tbl_fdiv_ovfl: 8811 long 0x3fff - 0x7ffe 8812 long 0x3fff - 0x407e 8813 long 0x3fff - 0x43fe 8814 8815 global fsdiv 8816 fsdiv: 8817 andi.b &0x30,%d0 8818 ori.b &s_mode*0x10,%d0 8819 bra.b fdiv 8820 8821 global fddiv 8822 fddiv: 8823 andi.b &0x30,%d0 8824 ori.b &d_mode*0x10,%d0 8825 8826 global fdiv 8827 fdiv: 8828 mov.l %d0,L_SCR3(%a6) 8829 8830 clr.w %d1 8831 mov.b DTAG(%a6),%d1 8832 lsl.b &0x3,%d1 8833 or.b STAG(%a6),%d1 8834 8835 bne.w fdiv_not_norm 8836 8837 # 8838 # DIVIDE: NORMs and DENORMs ONLY! 8839 # 8840 fdiv_norm: 8841 mov.w DST_EX(%a1),FP_SCR1_E 8842 mov.l DST_HI(%a1),FP_SCR1_H 8843 mov.l DST_LO(%a1),FP_SCR1_L 8844 8845 mov.w SRC_EX(%a0),FP_SCR0_E 8846 mov.l SRC_HI(%a0),FP_SCR0_H 8847 mov.l SRC_LO(%a0),FP_SCR0_L 8848 8849 bsr.l scale_to_zero_src 8850 mov.l %d0,-(%sp) 8851 8852 bsr.l scale_to_zero_dst 8853 8854 neg.l (%sp) 8855 add.l %d0,(%sp) 8856 8857 mov.w 2+L_SCR3(%a6),%d1 8858 lsr.b &0x6,%d1 8859 mov.l (%sp)+,%d0 8860 cmp.l %d0,(tbl_fdiv_ovfl.b, 8861 ble.w fdiv_may_ovfl 8862 8863 cmp.l %d0,(tbl_fdiv_unfl.w, 8864 beq.w fdiv_may_unfl 8865 bgt.w fdiv_unfl 8866 8867 fdiv_normal: 8868 fmovm.x FP_SCR1(%a6),&0x80 8869 8870 fmov.l L_SCR3(%a6),%fpcr 8871 fmov.l &0x0,%fpsr 8872 8873 fdiv.x FP_SCR0(%a6),%fp0 8874 8875 fmov.l %fpsr,%d1 8876 fmov.l &0x0,%fpcr 8877 8878 or.l %d1,USER_FPSR(%a6) 8879 8880 fdiv_normal_exit: 8881 fmovm.x &0x80,FP_SCR0(%a6) 8882 mov.l %d2,-(%sp) 8883 mov.w FP_SCR0_EX(%a6),%d1 8884 mov.l %d1,%d2 8885 andi.l &0x7fff,%d1 8886 andi.w &0x8000,%d2 8887 sub.l %d0,%d1 8888 or.w %d2,%d1 8889 mov.w %d1,FP_SCR0_EX(%a6) 8890 mov.l (%sp)+,%d2 8891 fmovm.x FP_SCR0(%a6),&0x80 8892 rts 8893 8894 tbl_fdiv_ovfl2: 8895 long 0x7fff 8896 long 0x407f 8897 long 0x43ff 8898 8899 fdiv_no_ovfl: 8900 mov.l (%sp)+,%d0 8901 bra.b fdiv_normal_exit 8902 8903 fdiv_may_ovfl: 8904 mov.l %d0,-(%sp) 8905 8906 fmovm.x FP_SCR1(%a6),&0x80 8907 8908 fmov.l L_SCR3(%a6),%fpcr 8909 fmov.l &0x0,%fpsr 8910 8911 fdiv.x FP_SCR0(%a6),%fp0 8912 8913 fmov.l %fpsr,%d0 8914 fmov.l &0x0,%fpcr 8915 8916 or.l %d0,USER_FPSR(%a6) 8917 8918 fmovm.x &0x01,-(%sp) 8919 mov.w (%sp),%d0 8920 add.l &0xc,%sp 8921 andi.l &0x7fff,%d0 8922 sub.l (%sp),%d0 8923 cmp.l %d0,(tbl_fdiv_ovfl2.b 8924 blt.b fdiv_no_ovfl 8925 mov.l (%sp)+,%d0 8926 8927 fdiv_ovfl_tst: 8928 or.l &ovfl_inx_mask,USER_F 8929 8930 mov.b FPCR_ENABLE(%a6),%d1 8931 andi.b &0x13,%d1 8932 bne.b fdiv_ovfl_ena 8933 8934 fdiv_ovfl_dis: 8935 btst &neg_bit,FPSR_CC(%a6) 8936 sne %d1 8937 mov.l L_SCR3(%a6),%d0 8938 bsr.l ovf_res 8939 or.b %d0,FPSR_CC(%a6) 8940 fmovm.x (%a0),&0x80 8941 rts 8942 8943 fdiv_ovfl_ena: 8944 mov.l L_SCR3(%a6),%d1 8945 andi.b &0xc0,%d1 8946 bne.b fdiv_ovfl_ena_sd 8947 8948 fdiv_ovfl_ena_cont: 8949 fmovm.x &0x80,FP_SCR0(%a6) 8950 8951 mov.l %d2,-(%sp) 8952 mov.w FP_SCR0_EX(%a6),%d1 8953 mov.w %d1,%d2 8954 andi.l &0x7fff,%d1 8955 sub.l %d0,%d1 8956 subi.l &0x6000,%d1 8957 andi.w &0x7fff,%d1 8958 andi.w &0x8000,%d2 8959 or.w %d2,%d1 8960 mov.w %d1,FP_SCR0_EX(%a6) 8961 mov.l (%sp)+,%d2 8962 fmovm.x FP_SCR0(%a6),&0x40 8963 bra.b fdiv_ovfl_dis 8964 8965 fdiv_ovfl_ena_sd: 8966 fmovm.x FP_SCR1(%a6),&0x80 8967 8968 mov.l L_SCR3(%a6),%d1 8969 andi.b &0x30,%d1 8970 fmov.l %d1,%fpcr 8971 8972 fdiv.x FP_SCR0(%a6),%fp0 8973 8974 fmov.l &0x0,%fpcr 8975 bra.b fdiv_ovfl_ena_cont 8976 8977 fdiv_unfl: 8978 bset &unfl_bit,FPSR_EXCEPT 8979 8980 fmovm.x FP_SCR1(%a6),&0x80 8981 8982 fmov.l &rz_mode*0x10,%fpcr 8983 fmov.l &0x0,%fpsr 8984 8985 fdiv.x FP_SCR0(%a6),%fp0 8986 8987 fmov.l %fpsr,%d1 8988 fmov.l &0x0,%fpcr 8989 8990 or.l %d1,USER_FPSR(%a6) 8991 8992 mov.b FPCR_ENABLE(%a6),%d1 8993 andi.b &0x0b,%d1 8994 bne.b fdiv_unfl_ena 8995 8996 fdiv_unfl_dis: 8997 fmovm.x &0x80,FP_SCR0(%a6) 8998 8999 lea FP_SCR0(%a6),%a0 9000 mov.l L_SCR3(%a6),%d1 9001 bsr.l unf_res 9002 or.b %d0,FPSR_CC(%a6) 9003 fmovm.x FP_SCR0(%a6),&0x80 9004 rts 9005 9006 # 9007 # UNFL is enabled. 9008 # 9009 fdiv_unfl_ena: 9010 fmovm.x FP_SCR1(%a6),&0x40 9011 9012 mov.l L_SCR3(%a6),%d1 9013 andi.b &0xc0,%d1 9014 bne.b fdiv_unfl_ena_sd 9015 9016 fmov.l L_SCR3(%a6),%fpcr 9017 9018 fdiv_unfl_ena_cont: 9019 fmov.l &0x0,%fpsr 9020 9021 fdiv.x FP_SCR0(%a6),%fp1 9022 9023 fmov.l &0x0,%fpcr 9024 9025 fmovm.x &0x40,FP_SCR0(%a6) 9026 mov.l %d2,-(%sp) 9027 mov.w FP_SCR0_EX(%a6),%d1 9028 mov.l %d1,%d2 9029 andi.l &0x7fff,%d1 9030 andi.w &0x8000,%d2 9031 sub.l %d0,%d1 9032 addi.l &0x6000,%d1 9033 andi.w &0x7fff,%d1 9034 or.w %d2,%d1 9035 mov.w %d1,FP_SCR0_EX(%a6) 9036 mov.l (%sp)+,%d2 9037 fmovm.x FP_SCR0(%a6),&0x40 9038 bra.w fdiv_unfl_dis 9039 9040 fdiv_unfl_ena_sd: 9041 mov.l L_SCR3(%a6),%d1 9042 andi.b &0x30,%d1 9043 fmov.l %d1,%fpcr 9044 9045 bra.b fdiv_unfl_ena_cont 9046 9047 # 9048 # the divide operation MAY underflow: 9049 # 9050 fdiv_may_unfl: 9051 fmovm.x FP_SCR1(%a6),&0x80 9052 9053 fmov.l L_SCR3(%a6),%fpcr 9054 fmov.l &0x0,%fpsr 9055 9056 fdiv.x FP_SCR0(%a6),%fp0 9057 9058 fmov.l %fpsr,%d1 9059 fmov.l &0x0,%fpcr 9060 9061 or.l %d1,USER_FPSR(%a6) 9062 9063 fabs.x %fp0,%fp1 9064 fcmp.b %fp1,&0x1 9065 fbgt.w fdiv_normal_exit 9066 fblt.w fdiv_unfl 9067 9068 # 9069 # we still don't know if underflow occurred. 9070 # we don't know if the result was an underflo 9071 # or a normalized number that rounded down to 9072 # operation using RZ as the rounding mode to 9073 # result is. this case should be relatively r 9074 # 9075 fmovm.x FP_SCR1(%a6),&0x40 9076 9077 mov.l L_SCR3(%a6),%d1 9078 andi.b &0xc0,%d1 9079 ori.b &rz_mode*0x10,%d1 9080 9081 fmov.l %d1,%fpcr 9082 fmov.l &0x0,%fpsr 9083 9084 fdiv.x FP_SCR0(%a6),%fp1 9085 9086 fmov.l &0x0,%fpcr 9087 fabs.x %fp1 9088 fcmp.b %fp1,&0x1 9089 fbge.w fdiv_normal_exit 9090 bra.w fdiv_unfl 9091 9092 ############################################# 9093 9094 # 9095 # Divide: inputs are not both normalized; wha 9096 # 9097 fdiv_not_norm: 9098 mov.w (tbl_fdiv_op.b,%pc,%d 9099 jmp (tbl_fdiv_op.b,%pc,%d 9100 9101 swbeg &48 9102 tbl_fdiv_op: 9103 short fdiv_norm - tbl 9104 short fdiv_inf_load - tbl 9105 short fdiv_zero_load - tbl 9106 short fdiv_res_qnan - tbl 9107 short fdiv_norm - tbl 9108 short fdiv_res_snan - tbl 9109 short tbl_fdiv_op - tbl 9110 short tbl_fdiv_op - tbl 9111 9112 short fdiv_zero_load - tbl 9113 short fdiv_res_operr - tbl 9114 short fdiv_zero_load - tbl 9115 short fdiv_res_qnan - tbl 9116 short fdiv_zero_load - tbl 9117 short fdiv_res_snan - tbl 9118 short tbl_fdiv_op - tbl 9119 short tbl_fdiv_op - tbl 9120 9121 short fdiv_inf_dst - tbl 9122 short fdiv_inf_dst - tbl 9123 short fdiv_res_operr - tbl 9124 short fdiv_res_qnan - tbl 9125 short fdiv_inf_dst - tbl 9126 short fdiv_res_snan - tbl 9127 short tbl_fdiv_op - tbl 9128 short tbl_fdiv_op - tbl 9129 9130 short fdiv_res_qnan - tbl 9131 short fdiv_res_qnan - tbl 9132 short fdiv_res_qnan - tbl 9133 short fdiv_res_qnan - tbl 9134 short fdiv_res_qnan - tbl 9135 short fdiv_res_snan - tbl 9136 short tbl_fdiv_op - tbl 9137 short tbl_fdiv_op - tbl 9138 9139 short fdiv_norm - tbl 9140 short fdiv_inf_load - tbl 9141 short fdiv_zero_load - tbl 9142 short fdiv_res_qnan - tbl 9143 short fdiv_norm - tbl 9144 short fdiv_res_snan - tbl 9145 short tbl_fdiv_op - tbl 9146 short tbl_fdiv_op - tbl 9147 9148 short fdiv_res_snan - tbl 9149 short fdiv_res_snan - tbl 9150 short fdiv_res_snan - tbl 9151 short fdiv_res_snan - tbl 9152 short fdiv_res_snan - tbl 9153 short fdiv_res_snan - tbl 9154 short tbl_fdiv_op - tbl 9155 short tbl_fdiv_op - tbl 9156 9157 fdiv_res_qnan: 9158 bra.l res_qnan 9159 fdiv_res_snan: 9160 bra.l res_snan 9161 fdiv_res_operr: 9162 bra.l res_operr 9163 9164 global fdiv_zero_load 9165 fdiv_zero_load: 9166 mov.b SRC_EX(%a0),%d0 9167 mov.b DST_EX(%a1),%d1 9168 eor.b %d0,%d1 9169 bpl.b fdiv_zero_load_p 9170 fmov.s &0x80000000,%fp0 9171 mov.b &z_bmask+neg_bmask,FP 9172 rts 9173 fdiv_zero_load_p: 9174 fmov.s &0x00000000,%fp0 9175 mov.b &z_bmask,FPSR_CC(%a6) 9176 rts 9177 9178 # 9179 # The destination was In Range and the source 9180 # Therefore, is an INF w/ the proper sign. 9181 # So, determine the sign and return a new INF 9182 # 9183 global fdiv_inf_load 9184 fdiv_inf_load: 9185 ori.w &dz_mask+adz_mask,2+U 9186 mov.b SRC_EX(%a0),%d0 9187 mov.b DST_EX(%a1),%d1 9188 eor.b %d0,%d1 9189 bpl.b fdiv_inf_load_p 9190 fmov.s &0xff800000,%fp0 9191 mov.b &inf_bmask+neg_bmask, 9192 rts 9193 fdiv_inf_load_p: 9194 fmov.s &0x7f800000,%fp0 9195 mov.b &inf_bmask,FPSR_CC(%a 9196 rts 9197 9198 # 9199 # The destination was an INF w/ an In Range o 9200 # an INF w/ the proper sign. 9201 # The 68881/882 returns the destination INF w 9202 # dst INF is set, then then j-bit of the resu 9203 # 9204 global fdiv_inf_dst 9205 fdiv_inf_dst: 9206 mov.b DST_EX(%a1),%d0 9207 mov.b SRC_EX(%a0),%d1 9208 eor.b %d0,%d1 9209 bpl.b fdiv_inf_dst_p 9210 9211 fmovm.x DST(%a1),&0x80 9212 fabs.x %fp0 9213 fneg.x %fp0 9214 mov.b &inf_bmask+neg_bmask, 9215 rts 9216 9217 fdiv_inf_dst_p: 9218 fmovm.x DST(%a1),&0x80 9219 fabs.x %fp0 9220 mov.b &inf_bmask,FPSR_CC(%a 9221 rts 9222 9223 ############################################# 9224 # XDEF ************************************** 9225 # fneg(): emulates the fneg instruction 9226 # fsneg(): emulates the fsneg instructi 9227 # fdneg(): emulates the fdneg instructi 9228 # 9229 # XREF ************************************** 9230 # norm() - normalize a denorm to provid 9231 # scale_to_zero_src() - scale sgl/dbl s 9232 # ovf_res() - return default overflow r 9233 # unf_res() - return default underflow 9234 # res_qnan_1op() - return QNAN result 9235 # res_snan_1op() - return SNAN result 9236 # 9237 # INPUT ************************************* 9238 # a0 = pointer to extended precision so 9239 # d0 = rnd prec,mode 9240 # 9241 # OUTPUT ************************************ 9242 # fp0 = result 9243 # fp1 = EXOP (if exception occurred) 9244 # 9245 # ALGORITHM ********************************* 9246 # Handle NANs, zeroes, and infinities a 9247 # norms/denorms into ext/sgl/dbl precisions. 9248 # emulated by simply setting sign bit. Sgl/db 9249 # and an actual fneg performed to see if over 9250 # occurred. If so, return default underflow/o 9251 # scale the result exponent and return result 9252 # the result value. 9253 # 9254 ############################################# 9255 9256 global fsneg 9257 fsneg: 9258 andi.b &0x30,%d0 9259 ori.b &s_mode*0x10,%d0 9260 bra.b fneg 9261 9262 global fdneg 9263 fdneg: 9264 andi.b &0x30,%d0 9265 ori.b &d_mode*0x10,%d0 9266 9267 global fneg 9268 fneg: 9269 mov.l %d0,L_SCR3(%a6) 9270 mov.b STAG(%a6),%d1 9271 bne.w fneg_not_norm 9272 9273 # 9274 # NEGATE SIGN : norms and denorms ONLY! 9275 # 9276 fneg_norm: 9277 andi.b &0xc0,%d0 9278 bne.w fneg_not_ext 9279 9280 # 9281 # precision selected is extended. so...we can 9282 # or overflow because of rounding to the corr 9283 # skip the scaling and unscaling... 9284 # 9285 mov.l SRC_HI(%a0),FP_SCR0_H 9286 mov.l SRC_LO(%a0),FP_SCR0_L 9287 mov.w SRC_EX(%a0),%d0 9288 eori.w &0x8000,%d0 9289 bpl.b fneg_norm_load 9290 mov.b &neg_bmask,FPSR_CC(%a 9291 fneg_norm_load: 9292 mov.w %d0,FP_SCR0_EX(%a6) 9293 fmovm.x FP_SCR0(%a6),&0x80 9294 rts 9295 9296 # 9297 # for an extended precision DENORM, the UNFL 9298 # the accrued bit is NOT set in this instance 9299 # 9300 fneg_denorm: 9301 andi.b &0xc0,%d0 9302 bne.b fneg_not_ext 9303 9304 bset &unfl_bit,FPSR_EXCEPT 9305 9306 mov.l SRC_HI(%a0),FP_SCR0_H 9307 mov.l SRC_LO(%a0),FP_SCR0_L 9308 mov.w SRC_EX(%a0),%d0 9309 eori.w &0x8000,%d0 9310 bpl.b fneg_denorm_done 9311 mov.b &neg_bmask,FPSR_CC(%a 9312 fneg_denorm_done: 9313 mov.w %d0,FP_SCR0_EX(%a6) 9314 fmovm.x FP_SCR0(%a6),&0x80 9315 9316 btst &unfl_bit,FPCR_ENABLE 9317 bne.b fneg_ext_unfl_ena 9318 rts 9319 9320 # 9321 # the input is an extended DENORM and underfl 9322 # normalize the mantissa and add the bias of 9323 # exponent and insert back into the operand. 9324 # 9325 fneg_ext_unfl_ena: 9326 lea FP_SCR0(%a6),%a0 9327 bsr.l norm 9328 neg.w %d0 9329 addi.w &0x6000,%d0 9330 mov.w FP_SCR0_EX(%a6),%d1 9331 andi.w &0x8000,%d1 9332 andi.w &0x7fff,%d0 9333 or.w %d1,%d0 9334 mov.w %d0,FP_SCR0_EX(%a6) 9335 fmovm.x FP_SCR0(%a6),&0x40 9336 rts 9337 9338 # 9339 # operand is either single or double 9340 # 9341 fneg_not_ext: 9342 cmpi.b %d0,&s_mode*0x10 9343 bne.b fneg_dbl 9344 9345 # 9346 # operand is to be rounded to single precisio 9347 # 9348 fneg_sgl: 9349 mov.w SRC_EX(%a0),FP_SCR0_E 9350 mov.l SRC_HI(%a0),FP_SCR0_H 9351 mov.l SRC_LO(%a0),FP_SCR0_L 9352 bsr.l scale_to_zero_src 9353 9354 cmpi.l %d0,&0x3fff-0x3f80 9355 bge.w fneg_sd_unfl 9356 cmpi.l %d0,&0x3fff-0x407e 9357 beq.w fneg_sd_may_ovfl 9358 blt.w fneg_sd_ovfl 9359 9360 # 9361 # operand will NOT overflow or underflow when 9362 # 9363 fneg_sd_normal: 9364 fmov.l &0x0,%fpsr 9365 fmov.l L_SCR3(%a6),%fpcr 9366 9367 fneg.x FP_SCR0(%a6),%fp0 9368 9369 fmov.l %fpsr,%d1 9370 fmov.l &0x0,%fpcr 9371 9372 or.l %d1,USER_FPSR(%a6) 9373 9374 fneg_sd_normal_exit: 9375 mov.l %d2,-(%sp) 9376 fmovm.x &0x80,FP_SCR0(%a6) 9377 mov.w FP_SCR0_EX(%a6),%d1 9378 mov.w %d1,%d2 9379 andi.l &0x7fff,%d1 9380 sub.l %d0,%d1 9381 andi.w &0x8000,%d2 9382 or.w %d1,%d2 9383 mov.w %d2,FP_SCR0_EX(%a6) 9384 mov.l (%sp)+,%d2 9385 fmovm.x FP_SCR0(%a6),&0x80 9386 rts 9387 9388 # 9389 # operand is to be rounded to double precisio 9390 # 9391 fneg_dbl: 9392 mov.w SRC_EX(%a0),FP_SCR0_E 9393 mov.l SRC_HI(%a0),FP_SCR0_H 9394 mov.l SRC_LO(%a0),FP_SCR0_L 9395 bsr.l scale_to_zero_src 9396 9397 cmpi.l %d0,&0x3fff-0x3c00 9398 bge.b fneg_sd_unfl 9399 cmpi.l %d0,&0x3fff-0x43fe 9400 beq.w fneg_sd_may_ovfl 9401 blt.w fneg_sd_ovfl 9402 bra.w fneg_sd_normal 9403 9404 # 9405 # operand WILL underflow when moved in to the 9406 # 9407 fneg_sd_unfl: 9408 bset &unfl_bit,FPSR_EXCEPT 9409 9410 eori.b &0x80,FP_SCR0_EX(%a6) 9411 bpl.b fneg_sd_unfl_tst 9412 bset &neg_bit,FPSR_CC(%a6) 9413 9414 # if underflow or inexact is enabled, go calc 9415 fneg_sd_unfl_tst: 9416 mov.b FPCR_ENABLE(%a6),%d1 9417 andi.b &0x0b,%d1 9418 bne.b fneg_sd_unfl_ena 9419 9420 fneg_sd_unfl_dis: 9421 lea FP_SCR0(%a6),%a0 9422 mov.l L_SCR3(%a6),%d1 9423 bsr.l unf_res 9424 or.b %d0,FPSR_CC(%a6) 9425 fmovm.x FP_SCR0(%a6),&0x80 9426 rts 9427 9428 # 9429 # operand will underflow AND underflow is ena 9430 # Therefore, we must return the result rounde 9431 # 9432 fneg_sd_unfl_ena: 9433 mov.l FP_SCR0_HI(%a6),FP_SC 9434 mov.l FP_SCR0_LO(%a6),FP_SC 9435 mov.w FP_SCR0_EX(%a6),%d1 9436 9437 mov.l %d2,-(%sp) 9438 mov.l %d1,%d2 9439 andi.l &0x7fff,%d1 9440 andi.w &0x8000,%d2 9441 sub.l %d0,%d1 9442 addi.l &0x6000,%d1 9443 andi.w &0x7fff,%d1 9444 or.w %d2,%d1 9445 mov.w %d1,FP_SCR1_EX(%a6) 9446 fmovm.x FP_SCR1(%a6),&0x40 9447 mov.l (%sp)+,%d2 9448 bra.b fneg_sd_unfl_dis 9449 9450 # 9451 # operand WILL overflow. 9452 # 9453 fneg_sd_ovfl: 9454 fmov.l &0x0,%fpsr 9455 fmov.l L_SCR3(%a6),%fpcr 9456 9457 fneg.x FP_SCR0(%a6),%fp0 9458 9459 fmov.l &0x0,%fpcr 9460 fmov.l %fpsr,%d1 9461 9462 or.l %d1,USER_FPSR(%a6) 9463 9464 fneg_sd_ovfl_tst: 9465 or.l &ovfl_inx_mask,USER_F 9466 9467 mov.b FPCR_ENABLE(%a6),%d1 9468 andi.b &0x13,%d1 9469 bne.b fneg_sd_ovfl_ena 9470 9471 # 9472 # OVFL is not enabled; therefore, we must cre 9473 # calling ovf_res(). 9474 # 9475 fneg_sd_ovfl_dis: 9476 btst &neg_bit,FPSR_CC(%a6) 9477 sne %d1 9478 mov.l L_SCR3(%a6),%d0 9479 bsr.l ovf_res 9480 or.b %d0,FPSR_CC(%a6) 9481 fmovm.x (%a0),&0x80 9482 rts 9483 9484 # 9485 # OVFL is enabled. 9486 # the INEX2 bit has already been updated by t 9487 # now, round to extended(and don't alter the 9488 # 9489 fneg_sd_ovfl_ena: 9490 mov.l %d2,-(%sp) 9491 mov.w FP_SCR0_EX(%a6),%d1 9492 mov.l %d1,%d2 9493 andi.l &0x7fff,%d1 9494 andi.w &0x8000,%d2 9495 sub.l %d0,%d1 9496 subi.l &0x6000,%d1 9497 andi.w &0x7fff,%d1 9498 or.w %d2,%d1 9499 mov.w %d1,FP_SCR0_EX(%a6) 9500 fmovm.x FP_SCR0(%a6),&0x40 9501 mov.l (%sp)+,%d2 9502 bra.b fneg_sd_ovfl_dis 9503 9504 # 9505 # the move in MAY underflow. so... 9506 # 9507 fneg_sd_may_ovfl: 9508 fmov.l &0x0,%fpsr 9509 fmov.l L_SCR3(%a6),%fpcr 9510 9511 fneg.x FP_SCR0(%a6),%fp0 9512 9513 fmov.l %fpsr,%d1 9514 fmov.l &0x0,%fpcr 9515 9516 or.l %d1,USER_FPSR(%a6) 9517 9518 fabs.x %fp0,%fp1 9519 fcmp.b %fp1,&0x2 9520 fbge.w fneg_sd_ovfl_tst 9521 9522 # no, it didn't overflow; we have correct res 9523 bra.w fneg_sd_normal_exit 9524 9525 ############################################# 9526 9527 # 9528 # input is not normalized; what is it? 9529 # 9530 fneg_not_norm: 9531 cmpi.b %d1,&DENORM 9532 beq.w fneg_denorm 9533 cmpi.b %d1,&SNAN 9534 beq.l res_snan_1op 9535 cmpi.b %d1,&QNAN 9536 beq.l res_qnan_1op 9537 9538 # 9539 # do the fneg; at this point, only possible o 9540 # use fneg to determine ccodes. 9541 # prec:mode should be zero at this point but 9542 # 9543 fneg.x SRC_EX(%a0),%fp0 9544 fmov.l %fpsr,%d0 9545 rol.l &0x8,%d0 9546 mov.b %d0,FPSR_CC(%a6) 9547 rts 9548 9549 ############################################# 9550 # XDEF ************************************** 9551 # ftst(): emulates the ftest instructio 9552 # 9553 # XREF ************************************** 9554 # res{s,q}nan_1op() - set NAN result fo 9555 # 9556 # INPUT ************************************* 9557 # a0 = pointer to extended precision so 9558 # 9559 # OUTPUT ************************************ 9560 # none 9561 # 9562 # ALGORITHM ********************************* 9563 # Check the source operand tag (STAG) a 9564 # to the operand type and sign. 9565 # 9566 ############################################# 9567 9568 global ftst 9569 ftst: 9570 mov.b STAG(%a6),%d1 9571 bne.b ftst_not_norm 9572 9573 # 9574 # Norm: 9575 # 9576 ftst_norm: 9577 tst.b SRC_EX(%a0) 9578 bmi.b ftst_norm_m 9579 rts 9580 ftst_norm_m: 9581 mov.b &neg_bmask,FPSR_CC(%a 9582 rts 9583 9584 # 9585 # input is not normalized; what is it? 9586 # 9587 ftst_not_norm: 9588 cmpi.b %d1,&ZERO 9589 beq.b ftst_zero 9590 cmpi.b %d1,&INF 9591 beq.b ftst_inf 9592 cmpi.b %d1,&SNAN 9593 beq.l res_snan_1op 9594 cmpi.b %d1,&QNAN 9595 beq.l res_qnan_1op 9596 9597 # 9598 # Denorm: 9599 # 9600 ftst_denorm: 9601 tst.b SRC_EX(%a0) 9602 bmi.b ftst_denorm_m 9603 rts 9604 ftst_denorm_m: 9605 mov.b &neg_bmask,FPSR_CC(%a 9606 rts 9607 9608 # 9609 # Infinity: 9610 # 9611 ftst_inf: 9612 tst.b SRC_EX(%a0) 9613 bmi.b ftst_inf_m 9614 ftst_inf_p: 9615 mov.b &inf_bmask,FPSR_CC(%a 9616 rts 9617 ftst_inf_m: 9618 mov.b &inf_bmask+neg_bmask, 9619 rts 9620 9621 # 9622 # Zero: 9623 # 9624 ftst_zero: 9625 tst.b SRC_EX(%a0) 9626 bmi.b ftst_zero_m 9627 ftst_zero_p: 9628 mov.b &z_bmask,FPSR_CC(%a6) 9629 rts 9630 ftst_zero_m: 9631 mov.b &z_bmask+neg_bmask,FP 9632 rts 9633 9634 ############################################# 9635 # XDEF ************************************** 9636 # fint(): emulates the fint instruction 9637 # 9638 # XREF ************************************** 9639 # res_{s,q}nan_1op() - set NAN result f 9640 # 9641 # INPUT ************************************* 9642 # a0 = pointer to extended precision so 9643 # d0 = round precision/mode 9644 # 9645 # OUTPUT ************************************ 9646 # fp0 = result 9647 # 9648 # ALGORITHM ********************************* 9649 # Separate according to operand type. U 9650 # here. For norms, load the rounding mode/pre 9651 # store the resulting FPSR bits. 9652 # For denorms, force the j-bit to a one 9653 # norms. Denorms are so low that the answer w 9654 # one. 9655 # For zeroes/infs/NANs, return the same 9656 # as appropriate. 9657 # 9658 ############################################# 9659 9660 global fint 9661 fint: 9662 mov.b STAG(%a6),%d1 9663 bne.b fint_not_norm 9664 9665 # 9666 # Norm: 9667 # 9668 fint_norm: 9669 andi.b &0x30,%d0 9670 9671 fmov.l %d0,%fpcr 9672 fmov.l &0x0,%fpsr 9673 9674 fint.x SRC(%a0),%fp0 9675 9676 fmov.l &0x0,%fpcr 9677 fmov.l %fpsr,%d0 9678 or.l %d0,USER_FPSR(%a6) 9679 9680 rts 9681 9682 # 9683 # input is not normalized; what is it? 9684 # 9685 fint_not_norm: 9686 cmpi.b %d1,&ZERO 9687 beq.b fint_zero 9688 cmpi.b %d1,&INF 9689 beq.b fint_inf 9690 cmpi.b %d1,&DENORM 9691 beq.b fint_denorm 9692 cmpi.b %d1,&SNAN 9693 beq.l res_snan_1op 9694 bra.l res_qnan_1op 9695 9696 # 9697 # Denorm: 9698 # 9699 # for DENORMs, the result will be either (+/- 9700 # also, the INEX2 and AINEX exception bits wi 9701 # so, we could either set these manually or f 9702 # to a very small NORM and ship it to the NOR 9703 # I do the latter. 9704 # 9705 fint_denorm: 9706 mov.w SRC_EX(%a0),FP_SCR0_E 9707 mov.b &0x80,FP_SCR0_HI(%a6) 9708 lea FP_SCR0(%a6),%a0 9709 bra.b fint_norm 9710 9711 # 9712 # Zero: 9713 # 9714 fint_zero: 9715 tst.b SRC_EX(%a0) 9716 bmi.b fint_zero_m 9717 fint_zero_p: 9718 fmov.s &0x00000000,%fp0 9719 mov.b &z_bmask,FPSR_CC(%a6) 9720 rts 9721 fint_zero_m: 9722 fmov.s &0x80000000,%fp0 9723 mov.b &z_bmask+neg_bmask,FP 9724 rts 9725 9726 # 9727 # Infinity: 9728 # 9729 fint_inf: 9730 fmovm.x SRC(%a0),&0x80 9731 tst.b SRC_EX(%a0) 9732 bmi.b fint_inf_m 9733 fint_inf_p: 9734 mov.b &inf_bmask,FPSR_CC(%a 9735 rts 9736 fint_inf_m: 9737 mov.b &inf_bmask+neg_bmask, 9738 rts 9739 9740 ############################################# 9741 # XDEF ************************************** 9742 # fintrz(): emulates the fintrz instruc 9743 # 9744 # XREF ************************************** 9745 # res_{s,q}nan_1op() - set NAN result f 9746 # 9747 # INPUT ************************************* 9748 # a0 = pointer to extended precision so 9749 # d0 = round precision/mode 9750 # 9751 # OUTPUT ************************************ 9752 # fp0 = result 9753 # 9754 # ALGORITHM ********************************* 9755 # Separate according to operand type. U 9756 # here. For norms, load the rounding mode/pre 9757 # then store the resulting FPSR bits. 9758 # For denorms, force the j-bit to a one 9759 # norms. Denorms are so low that the answer w 9760 # one. 9761 # For zeroes/infs/NANs, return the same 9762 # as appropriate. 9763 # 9764 ############################################# 9765 9766 global fintrz 9767 fintrz: 9768 mov.b STAG(%a6),%d1 9769 bne.b fintrz_not_norm 9770 9771 # 9772 # Norm: 9773 # 9774 fintrz_norm: 9775 fmov.l &0x0,%fpsr 9776 9777 fintrz.x SRC(%a0),%fp0 9778 9779 fmov.l %fpsr,%d0 9780 or.l %d0,USER_FPSR(%a6) 9781 9782 rts 9783 9784 # 9785 # input is not normalized; what is it? 9786 # 9787 fintrz_not_norm: 9788 cmpi.b %d1,&ZERO 9789 beq.b fintrz_zero 9790 cmpi.b %d1,&INF 9791 beq.b fintrz_inf 9792 cmpi.b %d1,&DENORM 9793 beq.b fintrz_denorm 9794 cmpi.b %d1,&SNAN 9795 beq.l res_snan_1op 9796 bra.l res_qnan_1op 9797 9798 # 9799 # Denorm: 9800 # 9801 # for DENORMs, the result will be (+/-)ZERO. 9802 # also, the INEX2 and AINEX exception bits wi 9803 # so, we could either set these manually or f 9804 # to a very small NORM and ship it to the NOR 9805 # I do the latter. 9806 # 9807 fintrz_denorm: 9808 mov.w SRC_EX(%a0),FP_SCR0_E 9809 mov.b &0x80,FP_SCR0_HI(%a6) 9810 lea FP_SCR0(%a6),%a0 9811 bra.b fintrz_norm 9812 9813 # 9814 # Zero: 9815 # 9816 fintrz_zero: 9817 tst.b SRC_EX(%a0) 9818 bmi.b fintrz_zero_m 9819 fintrz_zero_p: 9820 fmov.s &0x00000000,%fp0 9821 mov.b &z_bmask,FPSR_CC(%a6) 9822 rts 9823 fintrz_zero_m: 9824 fmov.s &0x80000000,%fp0 9825 mov.b &z_bmask+neg_bmask,FP 9826 rts 9827 9828 # 9829 # Infinity: 9830 # 9831 fintrz_inf: 9832 fmovm.x SRC(%a0),&0x80 9833 tst.b SRC_EX(%a0) 9834 bmi.b fintrz_inf_m 9835 fintrz_inf_p: 9836 mov.b &inf_bmask,FPSR_CC(%a 9837 rts 9838 fintrz_inf_m: 9839 mov.b &inf_bmask+neg_bmask, 9840 rts 9841 9842 ############################################# 9843 # XDEF ************************************** 9844 # fabs(): emulates the fabs instructio 9845 # fsabs(): emulates the fsabs instructi 9846 # fdabs(): emulates the fdabs instructi 9847 # 9848 # XREF ************************************** 9849 # norm() - normalize denorm mantissa to 9850 # scale_to_zero_src() - make exponent. 9851 # unf_res() - calculate underflow resul 9852 # ovf_res() - calculate overflow result 9853 # res_{s,q}nan_1op() - set NAN result f 9854 # 9855 # INPUT ************************************* 9856 # a0 = pointer to extended precision so 9857 # d0 = rnd precision/mode 9858 # 9859 # OUTPUT ************************************ 9860 # fp0 = result 9861 # fp1 = EXOP (if exception occurred) 9862 # 9863 # ALGORITHM ********************************* 9864 # Handle NANs, infinities, and zeroes a 9865 # norms into extended, single, and double pre 9866 # Simply clear sign for extended precis 9867 # gets an EXOP created for it since it's an u 9868 # Double and single precision can overf 9869 # scale the operand such that the exponent is 9870 # using the correct rnd mode/prec. Check to s 9871 # exponent would take an exception. If so, us 9872 # to calculate the default result. Also, crea 9873 # exceptional case. If no exception should oc 9874 # result exponent and return. 9875 # Unnorms don't pass through here. 9876 # 9877 ############################################# 9878 9879 global fsabs 9880 fsabs: 9881 andi.b &0x30,%d0 9882 ori.b &s_mode*0x10,%d0 9883 bra.b fabs 9884 9885 global fdabs 9886 fdabs: 9887 andi.b &0x30,%d0 9888 ori.b &d_mode*0x10,%d0 9889 9890 global fabs 9891 fabs: 9892 mov.l %d0,L_SCR3(%a6) 9893 mov.b STAG(%a6),%d1 9894 bne.w fabs_not_norm 9895 9896 # 9897 # ABSOLUTE VALUE: norms and denorms ONLY! 9898 # 9899 fabs_norm: 9900 andi.b &0xc0,%d0 9901 bne.b fabs_not_ext 9902 9903 # 9904 # precision selected is extended. so...we can 9905 # or overflow because of rounding to the corr 9906 # skip the scaling and unscaling... 9907 # 9908 mov.l SRC_HI(%a0),FP_SCR0_H 9909 mov.l SRC_LO(%a0),FP_SCR0_L 9910 mov.w SRC_EX(%a0),%d1 9911 bclr &15,%d1 9912 mov.w %d1,FP_SCR0_EX(%a6) 9913 fmovm.x FP_SCR0(%a6),&0x80 9914 rts 9915 9916 # 9917 # for an extended precision DENORM, the UNFL 9918 # the accrued bit is NOT set in this instance 9919 # 9920 fabs_denorm: 9921 andi.b &0xc0,%d0 9922 bne.b fabs_not_ext 9923 9924 bset &unfl_bit,FPSR_EXCEPT 9925 9926 mov.l SRC_HI(%a0),FP_SCR0_H 9927 mov.l SRC_LO(%a0),FP_SCR0_L 9928 mov.w SRC_EX(%a0),%d0 9929 bclr &15,%d0 9930 mov.w %d0,FP_SCR0_EX(%a6) 9931 9932 fmovm.x FP_SCR0(%a6),&0x80 9933 9934 btst &unfl_bit,FPCR_ENABLE 9935 bne.b fabs_ext_unfl_ena 9936 rts 9937 9938 # 9939 # the input is an extended DENORM and underfl 9940 # normalize the mantissa and add the bias of 9941 # exponent and insert back into the operand. 9942 # 9943 fabs_ext_unfl_ena: 9944 lea FP_SCR0(%a6),%a0 9945 bsr.l norm 9946 neg.w %d0 9947 addi.w &0x6000,%d0 9948 mov.w FP_SCR0_EX(%a6),%d1 9949 andi.w &0x8000,%d1 9950 andi.w &0x7fff,%d0 9951 or.w %d1,%d0 9952 mov.w %d0,FP_SCR0_EX(%a6) 9953 fmovm.x FP_SCR0(%a6),&0x40 9954 rts 9955 9956 # 9957 # operand is either single or double 9958 # 9959 fabs_not_ext: 9960 cmpi.b %d0,&s_mode*0x10 9961 bne.b fabs_dbl 9962 9963 # 9964 # operand is to be rounded to single precisio 9965 # 9966 fabs_sgl: 9967 mov.w SRC_EX(%a0),FP_SCR0_E 9968 mov.l SRC_HI(%a0),FP_SCR0_H 9969 mov.l SRC_LO(%a0),FP_SCR0_L 9970 bsr.l scale_to_zero_src 9971 9972 cmpi.l %d0,&0x3fff-0x3f80 9973 bge.w fabs_sd_unfl 9974 cmpi.l %d0,&0x3fff-0x407e 9975 beq.w fabs_sd_may_ovfl 9976 blt.w fabs_sd_ovfl 9977 9978 # 9979 # operand will NOT overflow or underflow when 9980 # 9981 fabs_sd_normal: 9982 fmov.l &0x0,%fpsr 9983 fmov.l L_SCR3(%a6),%fpcr 9984 9985 fabs.x FP_SCR0(%a6),%fp0 9986 9987 fmov.l %fpsr,%d1 9988 fmov.l &0x0,%fpcr 9989 9990 or.l %d1,USER_FPSR(%a6) 9991 9992 fabs_sd_normal_exit: 9993 mov.l %d2,-(%sp) 9994 fmovm.x &0x80,FP_SCR0(%a6) 9995 mov.w FP_SCR0_EX(%a6),%d1 9996 mov.l %d1,%d2 9997 andi.l &0x7fff,%d1 9998 sub.l %d0,%d1 9999 andi.w &0x8000,%d2 10000 or.w %d1,%d2 10001 mov.w %d2,FP_SCR0_EX(%a6) 10002 mov.l (%sp)+,%d2 10003 fmovm.x FP_SCR0(%a6),&0x80 10004 rts 10005 10006 # 10007 # operand is to be rounded to double precisi 10008 # 10009 fabs_dbl: 10010 mov.w SRC_EX(%a0),FP_SCR0_ 10011 mov.l SRC_HI(%a0),FP_SCR0_ 10012 mov.l SRC_LO(%a0),FP_SCR0_ 10013 bsr.l scale_to_zero_src 10014 10015 cmpi.l %d0,&0x3fff-0x3c00 10016 bge.b fabs_sd_unfl 10017 cmpi.l %d0,&0x3fff-0x43fe 10018 beq.w fabs_sd_may_ovfl 10019 blt.w fabs_sd_ovfl 10020 bra.w fabs_sd_normal 10021 10022 # 10023 # operand WILL underflow when moved in to th 10024 # 10025 fabs_sd_unfl: 10026 bset &unfl_bit,FPSR_EXCEP 10027 10028 bclr &0x7,FP_SCR0_EX(%a6) 10029 10030 # if underflow or inexact is enabled, go cal 10031 mov.b FPCR_ENABLE(%a6),%d1 10032 andi.b &0x0b,%d1 10033 bne.b fabs_sd_unfl_ena 10034 10035 fabs_sd_unfl_dis: 10036 lea FP_SCR0(%a6),%a0 10037 mov.l L_SCR3(%a6),%d1 10038 bsr.l unf_res 10039 or.b %d0,FPSR_CC(%a6) 10040 fmovm.x FP_SCR0(%a6),&0x80 10041 rts 10042 10043 # 10044 # operand will underflow AND underflow is en 10045 # Therefore, we must return the result round 10046 # 10047 fabs_sd_unfl_ena: 10048 mov.l FP_SCR0_HI(%a6),FP_S 10049 mov.l FP_SCR0_LO(%a6),FP_S 10050 mov.w FP_SCR0_EX(%a6),%d1 10051 10052 mov.l %d2,-(%sp) 10053 mov.l %d1,%d2 10054 andi.l &0x7fff,%d1 10055 andi.w &0x8000,%d2 10056 sub.l %d0,%d1 10057 addi.l &0x6000,%d1 10058 andi.w &0x7fff,%d1 10059 or.w %d2,%d1 10060 mov.w %d1,FP_SCR1_EX(%a6) 10061 fmovm.x FP_SCR1(%a6),&0x40 10062 mov.l (%sp)+,%d2 10063 bra.b fabs_sd_unfl_dis 10064 10065 # 10066 # operand WILL overflow. 10067 # 10068 fabs_sd_ovfl: 10069 fmov.l &0x0,%fpsr 10070 fmov.l L_SCR3(%a6),%fpcr 10071 10072 fabs.x FP_SCR0(%a6),%fp0 10073 10074 fmov.l &0x0,%fpcr 10075 fmov.l %fpsr,%d1 10076 10077 or.l %d1,USER_FPSR(%a6) 10078 10079 fabs_sd_ovfl_tst: 10080 or.l &ovfl_inx_mask,USER_ 10081 10082 mov.b FPCR_ENABLE(%a6),%d1 10083 andi.b &0x13,%d1 10084 bne.b fabs_sd_ovfl_ena 10085 10086 # 10087 # OVFL is not enabled; therefore, we must cr 10088 # calling ovf_res(). 10089 # 10090 fabs_sd_ovfl_dis: 10091 btst &neg_bit,FPSR_CC(%a6 10092 sne %d1 10093 mov.l L_SCR3(%a6),%d0 10094 bsr.l ovf_res 10095 or.b %d0,FPSR_CC(%a6) 10096 fmovm.x (%a0),&0x80 10097 rts 10098 10099 # 10100 # OVFL is enabled. 10101 # the INEX2 bit has already been updated by 10102 # now, round to extended(and don't alter the 10103 # 10104 fabs_sd_ovfl_ena: 10105 mov.l %d2,-(%sp) 10106 mov.w FP_SCR0_EX(%a6),%d1 10107 mov.l %d1,%d2 10108 andi.l &0x7fff,%d1 10109 andi.w &0x8000,%d2 10110 sub.l %d0,%d1 10111 subi.l &0x6000,%d1 10112 andi.w &0x7fff,%d1 10113 or.w %d2,%d1 10114 mov.w %d1,FP_SCR0_EX(%a6) 10115 fmovm.x FP_SCR0(%a6),&0x40 10116 mov.l (%sp)+,%d2 10117 bra.b fabs_sd_ovfl_dis 10118 10119 # 10120 # the move in MAY underflow. so... 10121 # 10122 fabs_sd_may_ovfl: 10123 fmov.l &0x0,%fpsr 10124 fmov.l L_SCR3(%a6),%fpcr 10125 10126 fabs.x FP_SCR0(%a6),%fp0 10127 10128 fmov.l %fpsr,%d1 10129 fmov.l &0x0,%fpcr 10130 10131 or.l %d1,USER_FPSR(%a6) 10132 10133 fabs.x %fp0,%fp1 10134 fcmp.b %fp1,&0x2 10135 fbge.w fabs_sd_ovfl_tst 10136 10137 # no, it didn't overflow; we have correct re 10138 bra.w fabs_sd_normal_exit 10139 10140 ############################################ 10141 10142 # 10143 # input is not normalized; what is it? 10144 # 10145 fabs_not_norm: 10146 cmpi.b %d1,&DENORM 10147 beq.w fabs_denorm 10148 cmpi.b %d1,&SNAN 10149 beq.l res_snan_1op 10150 cmpi.b %d1,&QNAN 10151 beq.l res_qnan_1op 10152 10153 fabs.x SRC(%a0),%fp0 10154 10155 cmpi.b %d1,&INF 10156 beq.b fabs_inf 10157 fabs_zero: 10158 mov.b &z_bmask,FPSR_CC(%a6 10159 rts 10160 fabs_inf: 10161 mov.b &inf_bmask,FPSR_CC(% 10162 rts 10163 10164 ############################################ 10165 # XDEF ************************************* 10166 # fcmp(): fp compare op routine 10167 # 10168 # XREF ************************************* 10169 # res_qnan() - return QNAN result 10170 # res_snan() - return SNAN result 10171 # 10172 # INPUT ************************************ 10173 # a0 = pointer to extended precision s 10174 # a1 = pointer to extended precision d 10175 # d0 = round prec/mode 10176 # 10177 # OUTPUT *********************************** 10178 # None 10179 # 10180 # ALGORITHM ******************************** 10181 # Handle NANs and denorms as special c 10182 # just use the actual fcmp instruction to pr 10183 # codes. 10184 # 10185 ############################################ 10186 10187 global fcmp 10188 fcmp: 10189 clr.w %d1 10190 mov.b DTAG(%a6),%d1 10191 lsl.b &0x3,%d1 10192 or.b STAG(%a6),%d1 10193 bne.b fcmp_not_norm 10194 10195 # 10196 # COMPARE FP OPs : NORMs, ZEROs, INFs, and " 10197 # 10198 fcmp_norm: 10199 fmovm.x DST(%a1),&0x80 10200 10201 fcmp.x %fp0,SRC(%a0) 10202 10203 fmov.l %fpsr,%d0 10204 rol.l &0x8,%d0 10205 mov.b %d0,FPSR_CC(%a6) 10206 10207 rts 10208 10209 # 10210 # fcmp: inputs are not both normalized; what 10211 # 10212 fcmp_not_norm: 10213 mov.w (tbl_fcmp_op.b,%pc,% 10214 jmp (tbl_fcmp_op.b,%pc,% 10215 10216 swbeg &48 10217 tbl_fcmp_op: 10218 short fcmp_norm - tb 10219 short fcmp_norm - tb 10220 short fcmp_norm - tb 10221 short fcmp_res_qnan - tb 10222 short fcmp_nrm_dnrm - tb 10223 short fcmp_res_snan - tb 10224 short tbl_fcmp_op - tb 10225 short tbl_fcmp_op - tb 10226 10227 short fcmp_norm - tb 10228 short fcmp_norm - tb 10229 short fcmp_norm - tb 10230 short fcmp_res_qnan - tb 10231 short fcmp_dnrm_s - tb 10232 short fcmp_res_snan - tb 10233 short tbl_fcmp_op - tb 10234 short tbl_fcmp_op - tb 10235 10236 short fcmp_norm - tb 10237 short fcmp_norm - tb 10238 short fcmp_norm - tb 10239 short fcmp_res_qnan - tb 10240 short fcmp_dnrm_s - tb 10241 short fcmp_res_snan - tb 10242 short tbl_fcmp_op - tb 10243 short tbl_fcmp_op - tb 10244 10245 short fcmp_res_qnan - tb 10246 short fcmp_res_qnan - tb 10247 short fcmp_res_qnan - tb 10248 short fcmp_res_qnan - tb 10249 short fcmp_res_qnan - tb 10250 short fcmp_res_snan - tb 10251 short tbl_fcmp_op - tb 10252 short tbl_fcmp_op - tb 10253 10254 short fcmp_dnrm_nrm - tb 10255 short fcmp_dnrm_d - tb 10256 short fcmp_dnrm_d - tb 10257 short fcmp_res_qnan - tb 10258 short fcmp_dnrm_sd - tb 10259 short fcmp_res_snan - tb 10260 short tbl_fcmp_op - tb 10261 short tbl_fcmp_op - tb 10262 10263 short fcmp_res_snan - tb 10264 short fcmp_res_snan - tb 10265 short fcmp_res_snan - tb 10266 short fcmp_res_snan - tb 10267 short fcmp_res_snan - tb 10268 short fcmp_res_snan - tb 10269 short tbl_fcmp_op - tb 10270 short tbl_fcmp_op - tb 10271 10272 # unlike all other functions for QNAN and SN 10273 # 'N' bit for a negative QNAN or SNAN input 10274 fcmp_res_qnan: 10275 bsr.l res_qnan 10276 andi.b &0xf7,FPSR_CC(%a6) 10277 rts 10278 fcmp_res_snan: 10279 bsr.l res_snan 10280 andi.b &0xf7,FPSR_CC(%a6) 10281 rts 10282 10283 # 10284 # DENORMs are a little more difficult. 10285 # If you have a 2 DENORMs, then you can just 10286 # and use the fcmp_norm routine. 10287 # If you have a DENORM and an INF or ZERO, j 10288 # and use the fcmp_norm routine. 10289 # If you have a DENORM and a NORM with oppos 10290 # But with a DENORM and a NORM of the same s 10291 # (1) signs are (+) and the DENORM is the ds 10292 # (2) signs are (-) and the DENORM is the sr 10293 # 10294 10295 fcmp_dnrm_s: 10296 mov.w SRC_EX(%a0),FP_SCR0_ 10297 mov.l SRC_HI(%a0),%d0 10298 bset &31,%d0 10299 mov.l %d0,FP_SCR0_HI(%a6) 10300 mov.l SRC_LO(%a0),FP_SCR0_ 10301 lea FP_SCR0(%a6),%a0 10302 bra.w fcmp_norm 10303 10304 fcmp_dnrm_d: 10305 mov.l DST_EX(%a1),FP_SCR0_ 10306 mov.l DST_HI(%a1),%d0 10307 bset &31,%d0 10308 mov.l %d0,FP_SCR0_HI(%a6) 10309 mov.l DST_LO(%a1),FP_SCR0_ 10310 lea FP_SCR0(%a6),%a1 10311 bra.w fcmp_norm 10312 10313 fcmp_dnrm_sd: 10314 mov.w DST_EX(%a1),FP_SCR1_ 10315 mov.w SRC_EX(%a0),FP_SCR0_ 10316 mov.l DST_HI(%a1),%d0 10317 bset &31,%d0 10318 mov.l %d0,FP_SCR1_HI(%a6) 10319 mov.l SRC_HI(%a0),%d0 10320 bset &31,%d0 10321 mov.l %d0,FP_SCR0_HI(%a6) 10322 mov.l DST_LO(%a1),FP_SCR1_ 10323 mov.l SRC_LO(%a0),FP_SCR0_ 10324 lea FP_SCR1(%a6),%a1 10325 lea FP_SCR0(%a6),%a0 10326 bra.w fcmp_norm 10327 10328 fcmp_nrm_dnrm: 10329 mov.b SRC_EX(%a0),%d0 10330 mov.b DST_EX(%a1),%d1 10331 eor.b %d0,%d1 10332 bmi.w fcmp_dnrm_s 10333 10334 # signs are the same, so must determine the 10335 tst.b %d0 10336 bmi.b fcmp_nrm_dnrm_m 10337 rts 10338 fcmp_nrm_dnrm_m: 10339 mov.b &neg_bmask,FPSR_CC(% 10340 rts 10341 10342 fcmp_dnrm_nrm: 10343 mov.b SRC_EX(%a0),%d0 10344 mov.b DST_EX(%a1),%d1 10345 eor.b %d0,%d1 10346 bmi.w fcmp_dnrm_d 10347 10348 # signs are the same, so must determine the 10349 tst.b %d0 10350 bpl.b fcmp_dnrm_nrm_m 10351 rts 10352 fcmp_dnrm_nrm_m: 10353 mov.b &neg_bmask,FPSR_CC(% 10354 rts 10355 10356 ############################################ 10357 # XDEF ************************************* 10358 # fsglmul(): emulates the fsglmul inst 10359 # 10360 # XREF ************************************* 10361 # scale_to_zero_src() - scale src expo 10362 # scale_to_zero_dst() - scale dst expo 10363 # unf_res4() - return default underflo 10364 # ovf_res() - return default overflow 10365 # res_qnan() - return QNAN result 10366 # res_snan() - return SNAN result 10367 # 10368 # INPUT ************************************ 10369 # a0 = pointer to extended precision s 10370 # a1 = pointer to extended precision d 10371 # d0 rnd prec,mode 10372 # 10373 # OUTPUT *********************************** 10374 # fp0 = result 10375 # fp1 = EXOP (if exception occurred) 10376 # 10377 # ALGORITHM ******************************** 10378 # Handle NANs, infinities, and zeroes 10379 # norms/denorms into ext/sgl/dbl precision. 10380 # For norms/denorms, scale the exponen 10381 # instruction won't cause an exception. Use 10382 # compute a result. Check if the regular ope 10383 # an exception. If so, return the default ov 10384 # and return the EXOP if exceptions are enab 10385 # result operand to the proper exponent. 10386 # 10387 ############################################ 10388 10389 global fsglmul 10390 fsglmul: 10391 mov.l %d0,L_SCR3(%a6) 10392 10393 clr.w %d1 10394 mov.b DTAG(%a6),%d1 10395 lsl.b &0x3,%d1 10396 or.b STAG(%a6),%d1 10397 10398 bne.w fsglmul_not_norm 10399 10400 fsglmul_norm: 10401 mov.w DST_EX(%a1),FP_SCR1_ 10402 mov.l DST_HI(%a1),FP_SCR1_ 10403 mov.l DST_LO(%a1),FP_SCR1_ 10404 10405 mov.w SRC_EX(%a0),FP_SCR0_ 10406 mov.l SRC_HI(%a0),FP_SCR0_ 10407 mov.l SRC_LO(%a0),FP_SCR0_ 10408 10409 bsr.l scale_to_zero_src 10410 mov.l %d0,-(%sp) 10411 10412 bsr.l scale_to_zero_dst 10413 10414 add.l (%sp)+,%d0 10415 10416 cmpi.l %d0,&0x3fff-0x7ffe 10417 beq.w fsglmul_may_ovfl 10418 blt.w fsglmul_ovfl 10419 10420 cmpi.l %d0,&0x3fff+0x0001 10421 beq.w fsglmul_may_unfl 10422 bgt.w fsglmul_unfl 10423 10424 fsglmul_normal: 10425 fmovm.x FP_SCR1(%a6),&0x80 10426 10427 fmov.l L_SCR3(%a6),%fpcr 10428 fmov.l &0x0,%fpsr 10429 10430 fsglmul.x FP_SCR0(%a6),%fp0 10431 10432 fmov.l %fpsr,%d1 10433 fmov.l &0x0,%fpcr 10434 10435 or.l %d1,USER_FPSR(%a6) 10436 10437 fsglmul_normal_exit: 10438 fmovm.x &0x80,FP_SCR0(%a6) 10439 mov.l %d2,-(%sp) 10440 mov.w FP_SCR0_EX(%a6),%d1 10441 mov.l %d1,%d2 10442 andi.l &0x7fff,%d1 10443 andi.w &0x8000,%d2 10444 sub.l %d0,%d1 10445 or.w %d2,%d1 10446 mov.w %d1,FP_SCR0_EX(%a6) 10447 mov.l (%sp)+,%d2 10448 fmovm.x FP_SCR0(%a6),&0x80 10449 rts 10450 10451 fsglmul_ovfl: 10452 fmovm.x FP_SCR1(%a6),&0x80 10453 10454 fmov.l L_SCR3(%a6),%fpcr 10455 fmov.l &0x0,%fpsr 10456 10457 fsglmul.x FP_SCR0(%a6),%fp0 10458 10459 fmov.l %fpsr,%d1 10460 fmov.l &0x0,%fpcr 10461 10462 or.l %d1,USER_FPSR(%a6) 10463 10464 fsglmul_ovfl_tst: 10465 10466 # save setting this until now because this i 10467 or.l &ovfl_inx_mask, USER 10468 10469 mov.b FPCR_ENABLE(%a6),%d1 10470 andi.b &0x13,%d1 10471 bne.b fsglmul_ovfl_ena 10472 10473 fsglmul_ovfl_dis: 10474 btst &neg_bit,FPSR_CC(%a6 10475 sne %d1 10476 mov.l L_SCR3(%a6),%d0 10477 andi.b &0x30,%d0 10478 bsr.l ovf_res 10479 or.b %d0,FPSR_CC(%a6) 10480 fmovm.x (%a0),&0x80 10481 rts 10482 10483 fsglmul_ovfl_ena: 10484 fmovm.x &0x80,FP_SCR0(%a6) 10485 10486 mov.l %d2,-(%sp) 10487 mov.w FP_SCR0_EX(%a6),%d1 10488 mov.l %d1,%d2 10489 andi.l &0x7fff,%d1 10490 sub.l %d0,%d1 10491 subi.l &0x6000,%d1 10492 andi.w &0x7fff,%d1 10493 andi.w &0x8000,%d2 10494 or.w %d2,%d1 10495 mov.w %d1,FP_SCR0_EX(%a6) 10496 mov.l (%sp)+,%d2 10497 fmovm.x FP_SCR0(%a6),&0x40 10498 bra.b fsglmul_ovfl_dis 10499 10500 fsglmul_may_ovfl: 10501 fmovm.x FP_SCR1(%a6),&0x80 10502 10503 fmov.l L_SCR3(%a6),%fpcr 10504 fmov.l &0x0,%fpsr 10505 10506 fsglmul.x FP_SCR0(%a6),%fp0 10507 10508 fmov.l %fpsr,%d1 10509 fmov.l &0x0,%fpcr 10510 10511 or.l %d1,USER_FPSR(%a6) 10512 10513 fabs.x %fp0,%fp1 10514 fcmp.b %fp1,&0x2 10515 fbge.w fsglmul_ovfl_tst 10516 10517 # no, it didn't overflow; we have correct re 10518 bra.w fsglmul_normal_exit 10519 10520 fsglmul_unfl: 10521 bset &unfl_bit,FPSR_EXCEP 10522 10523 fmovm.x FP_SCR1(%a6),&0x80 10524 10525 fmov.l &rz_mode*0x10,%fpcr 10526 fmov.l &0x0,%fpsr 10527 10528 fsglmul.x FP_SCR0(%a6),%fp0 10529 10530 fmov.l %fpsr,%d1 10531 fmov.l &0x0,%fpcr 10532 10533 or.l %d1,USER_FPSR(%a6) 10534 10535 mov.b FPCR_ENABLE(%a6),%d1 10536 andi.b &0x0b,%d1 10537 bne.b fsglmul_unfl_ena 10538 10539 fsglmul_unfl_dis: 10540 fmovm.x &0x80,FP_SCR0(%a6) 10541 10542 lea FP_SCR0(%a6),%a0 10543 mov.l L_SCR3(%a6),%d1 10544 bsr.l unf_res4 10545 or.b %d0,FPSR_CC(%a6) 10546 fmovm.x FP_SCR0(%a6),&0x80 10547 rts 10548 10549 # 10550 # UNFL is enabled. 10551 # 10552 fsglmul_unfl_ena: 10553 fmovm.x FP_SCR1(%a6),&0x40 10554 10555 fmov.l L_SCR3(%a6),%fpcr 10556 fmov.l &0x0,%fpsr 10557 10558 fsglmul.x FP_SCR0(%a6),%fp1 10559 10560 fmov.l &0x0,%fpcr 10561 10562 fmovm.x &0x40,FP_SCR0(%a6) 10563 mov.l %d2,-(%sp) 10564 mov.w FP_SCR0_EX(%a6),%d1 10565 mov.l %d1,%d2 10566 andi.l &0x7fff,%d1 10567 andi.w &0x8000,%d2 10568 sub.l %d0,%d1 10569 addi.l &0x6000,%d1 10570 andi.w &0x7fff,%d1 10571 or.w %d2,%d1 10572 mov.w %d1,FP_SCR0_EX(%a6) 10573 mov.l (%sp)+,%d2 10574 fmovm.x FP_SCR0(%a6),&0x40 10575 bra.w fsglmul_unfl_dis 10576 10577 fsglmul_may_unfl: 10578 fmovm.x FP_SCR1(%a6),&0x80 10579 10580 fmov.l L_SCR3(%a6),%fpcr 10581 fmov.l &0x0,%fpsr 10582 10583 fsglmul.x FP_SCR0(%a6),%fp0 10584 10585 fmov.l %fpsr,%d1 10586 fmov.l &0x0,%fpcr 10587 10588 or.l %d1,USER_FPSR(%a6) 10589 10590 fabs.x %fp0,%fp1 10591 fcmp.b %fp1,&0x2 10592 fbgt.w fsglmul_normal_exit 10593 fblt.w fsglmul_unfl 10594 10595 # 10596 # we still don't know if underflow occurred. 10597 # we don't know if the result was an underfl 10598 # a normalized number that rounded down to a 10599 # using RZ as the rounding mode to see what 10600 # this case should be relatively rare. 10601 # 10602 fmovm.x FP_SCR1(%a6),&0x40 10603 10604 mov.l L_SCR3(%a6),%d1 10605 andi.b &0xc0,%d1 10606 ori.b &rz_mode*0x10,%d1 10607 10608 fmov.l %d1,%fpcr 10609 fmov.l &0x0,%fpsr 10610 10611 fsglmul.x FP_SCR0(%a6),%fp1 10612 10613 fmov.l &0x0,%fpcr 10614 fabs.x %fp1 10615 fcmp.b %fp1,&0x2 10616 fbge.w fsglmul_normal_exit 10617 bra.w fsglmul_unfl 10618 10619 ############################################ 10620 10621 # 10622 # Single Precision Multiply: inputs are not 10623 # 10624 fsglmul_not_norm: 10625 mov.w (tbl_fsglmul_op.b,%p 10626 jmp (tbl_fsglmul_op.b,%p 10627 10628 swbeg &48 10629 tbl_fsglmul_op: 10630 short fsglmul_norm 10631 short fsglmul_zero 10632 short fsglmul_inf_src 10633 short fsglmul_res_qnan 10634 short fsglmul_norm 10635 short fsglmul_res_snan 10636 short tbl_fsglmul_op 10637 short tbl_fsglmul_op 10638 10639 short fsglmul_zero 10640 short fsglmul_zero 10641 short fsglmul_res_operr 10642 short fsglmul_res_qnan 10643 short fsglmul_zero 10644 short fsglmul_res_snan 10645 short tbl_fsglmul_op 10646 short tbl_fsglmul_op 10647 10648 short fsglmul_inf_dst 10649 short fsglmul_res_operr 10650 short fsglmul_inf_dst 10651 short fsglmul_res_qnan 10652 short fsglmul_inf_dst 10653 short fsglmul_res_snan 10654 short tbl_fsglmul_op 10655 short tbl_fsglmul_op 10656 10657 short fsglmul_res_qnan 10658 short fsglmul_res_qnan 10659 short fsglmul_res_qnan 10660 short fsglmul_res_qnan 10661 short fsglmul_res_qnan 10662 short fsglmul_res_snan 10663 short tbl_fsglmul_op 10664 short tbl_fsglmul_op 10665 10666 short fsglmul_norm 10667 short fsglmul_zero 10668 short fsglmul_inf_src 10669 short fsglmul_res_qnan 10670 short fsglmul_norm 10671 short fsglmul_res_snan 10672 short tbl_fsglmul_op 10673 short tbl_fsglmul_op 10674 10675 short fsglmul_res_snan 10676 short fsglmul_res_snan 10677 short fsglmul_res_snan 10678 short fsglmul_res_snan 10679 short fsglmul_res_snan 10680 short fsglmul_res_snan 10681 short tbl_fsglmul_op 10682 short tbl_fsglmul_op 10683 10684 fsglmul_res_operr: 10685 bra.l res_operr 10686 fsglmul_res_snan: 10687 bra.l res_snan 10688 fsglmul_res_qnan: 10689 bra.l res_qnan 10690 fsglmul_zero: 10691 bra.l fmul_zero 10692 fsglmul_inf_src: 10693 bra.l fmul_inf_src 10694 fsglmul_inf_dst: 10695 bra.l fmul_inf_dst 10696 10697 ############################################ 10698 # XDEF ************************************* 10699 # fsgldiv(): emulates the fsgldiv inst 10700 # 10701 # XREF ************************************* 10702 # scale_to_zero_src() - scale src expo 10703 # scale_to_zero_dst() - scale dst expo 10704 # unf_res4() - return default underflo 10705 # ovf_res() - return default overflow 10706 # res_qnan() - return QNAN result 10707 # res_snan() - return SNAN result 10708 # 10709 # INPUT ************************************ 10710 # a0 = pointer to extended precision s 10711 # a1 = pointer to extended precision d 10712 # d0 rnd prec,mode 10713 # 10714 # OUTPUT *********************************** 10715 # fp0 = result 10716 # fp1 = EXOP (if exception occurred) 10717 # 10718 # ALGORITHM ******************************** 10719 # Handle NANs, infinities, and zeroes 10720 # norms/denorms into ext/sgl/dbl precision. 10721 # For norms/denorms, scale the exponen 10722 # instruction won't cause an exception. Use 10723 # compute a result. Check if the regular ope 10724 # an exception. If so, return the default ov 10725 # and return the EXOP if exceptions are enab 10726 # result operand to the proper exponent. 10727 # 10728 ############################################ 10729 10730 global fsgldiv 10731 fsgldiv: 10732 mov.l %d0,L_SCR3(%a6) 10733 10734 clr.w %d1 10735 mov.b DTAG(%a6),%d1 10736 lsl.b &0x3,%d1 10737 or.b STAG(%a6),%d1 10738 10739 bne.w fsgldiv_not_norm 10740 10741 # 10742 # DIVIDE: NORMs and DENORMs ONLY! 10743 # 10744 fsgldiv_norm: 10745 mov.w DST_EX(%a1),FP_SCR1_ 10746 mov.l DST_HI(%a1),FP_SCR1_ 10747 mov.l DST_LO(%a1),FP_SCR1_ 10748 10749 mov.w SRC_EX(%a0),FP_SCR0_ 10750 mov.l SRC_HI(%a0),FP_SCR0_ 10751 mov.l SRC_LO(%a0),FP_SCR0_ 10752 10753 bsr.l scale_to_zero_src 10754 mov.l %d0,-(%sp) 10755 10756 bsr.l scale_to_zero_dst 10757 10758 neg.l (%sp) 10759 add.l %d0,(%sp) 10760 10761 mov.w 2+L_SCR3(%a6),%d1 10762 lsr.b &0x6,%d1 10763 mov.l (%sp)+,%d0 10764 cmpi.l %d0,&0x3fff-0x7ffe 10765 ble.w fsgldiv_may_ovfl 10766 10767 cmpi.l %d0,&0x3fff-0x0000 10768 beq.w fsgldiv_may_unfl 10769 bgt.w fsgldiv_unfl 10770 10771 fsgldiv_normal: 10772 fmovm.x FP_SCR1(%a6),&0x80 10773 10774 fmov.l L_SCR3(%a6),%fpcr 10775 fmov.l &0x0,%fpsr 10776 10777 fsgldiv.x FP_SCR0(%a6),%fp0 10778 10779 fmov.l %fpsr,%d1 10780 fmov.l &0x0,%fpcr 10781 10782 or.l %d1,USER_FPSR(%a6) 10783 10784 fsgldiv_normal_exit: 10785 fmovm.x &0x80,FP_SCR0(%a6) 10786 mov.l %d2,-(%sp) 10787 mov.w FP_SCR0_EX(%a6),%d1 10788 mov.l %d1,%d2 10789 andi.l &0x7fff,%d1 10790 andi.w &0x8000,%d2 10791 sub.l %d0,%d1 10792 or.w %d2,%d1 10793 mov.w %d1,FP_SCR0_EX(%a6) 10794 mov.l (%sp)+,%d2 10795 fmovm.x FP_SCR0(%a6),&0x80 10796 rts 10797 10798 fsgldiv_may_ovfl: 10799 fmovm.x FP_SCR1(%a6),&0x80 10800 10801 fmov.l L_SCR3(%a6),%fpcr 10802 fmov.l &0x0,%fpsr 10803 10804 fsgldiv.x FP_SCR0(%a6),%fp0 10805 10806 fmov.l %fpsr,%d1 10807 fmov.l &0x0,%fpcr 10808 10809 or.l %d1,USER_FPSR(%a6) 10810 10811 fmovm.x &0x01,-(%sp) 10812 mov.w (%sp),%d1 10813 add.l &0xc,%sp 10814 andi.l &0x7fff,%d1 10815 sub.l %d0,%d1 10816 cmp.l %d1,&0x7fff 10817 blt.b fsgldiv_normal_exit 10818 10819 fsgldiv_ovfl_tst: 10820 or.w &ovfl_inx_mask,2+USE 10821 10822 mov.b FPCR_ENABLE(%a6),%d1 10823 andi.b &0x13,%d1 10824 bne.b fsgldiv_ovfl_ena 10825 10826 fsgldiv_ovfl_dis: 10827 btst &neg_bit,FPSR_CC(%a6 10828 sne %d1 10829 mov.l L_SCR3(%a6),%d0 10830 andi.b &0x30,%d0 10831 bsr.l ovf_res 10832 or.b %d0,FPSR_CC(%a6) 10833 fmovm.x (%a0),&0x80 10834 rts 10835 10836 fsgldiv_ovfl_ena: 10837 fmovm.x &0x80,FP_SCR0(%a6) 10838 10839 mov.l %d2,-(%sp) 10840 mov.w FP_SCR0_EX(%a6),%d1 10841 mov.l %d1,%d2 10842 andi.l &0x7fff,%d1 10843 andi.w &0x8000,%d2 10844 sub.l %d0,%d1 10845 subi.l &0x6000,%d1 10846 andi.w &0x7fff,%d1 10847 or.w %d2,%d1 10848 mov.w %d1,FP_SCR0_EX(%a6) 10849 mov.l (%sp)+,%d2 10850 fmovm.x FP_SCR0(%a6),&0x40 10851 bra.b fsgldiv_ovfl_dis 10852 10853 fsgldiv_unfl: 10854 bset &unfl_bit,FPSR_EXCEP 10855 10856 fmovm.x FP_SCR1(%a6),&0x80 10857 10858 fmov.l &rz_mode*0x10,%fpcr 10859 fmov.l &0x0,%fpsr 10860 10861 fsgldiv.x FP_SCR0(%a6),%fp0 10862 10863 fmov.l %fpsr,%d1 10864 fmov.l &0x0,%fpcr 10865 10866 or.l %d1,USER_FPSR(%a6) 10867 10868 mov.b FPCR_ENABLE(%a6),%d1 10869 andi.b &0x0b,%d1 10870 bne.b fsgldiv_unfl_ena 10871 10872 fsgldiv_unfl_dis: 10873 fmovm.x &0x80,FP_SCR0(%a6) 10874 10875 lea FP_SCR0(%a6),%a0 10876 mov.l L_SCR3(%a6),%d1 10877 bsr.l unf_res4 10878 or.b %d0,FPSR_CC(%a6) 10879 fmovm.x FP_SCR0(%a6),&0x80 10880 rts 10881 10882 # 10883 # UNFL is enabled. 10884 # 10885 fsgldiv_unfl_ena: 10886 fmovm.x FP_SCR1(%a6),&0x40 10887 10888 fmov.l L_SCR3(%a6),%fpcr 10889 fmov.l &0x0,%fpsr 10890 10891 fsgldiv.x FP_SCR0(%a6),%fp1 10892 10893 fmov.l &0x0,%fpcr 10894 10895 fmovm.x &0x40,FP_SCR0(%a6) 10896 mov.l %d2,-(%sp) 10897 mov.w FP_SCR0_EX(%a6),%d1 10898 mov.l %d1,%d2 10899 andi.l &0x7fff,%d1 10900 andi.w &0x8000,%d2 10901 sub.l %d0,%d1 10902 addi.l &0x6000,%d1 10903 andi.w &0x7fff,%d1 10904 or.w %d2,%d1 10905 mov.w %d1,FP_SCR0_EX(%a6) 10906 mov.l (%sp)+,%d2 10907 fmovm.x FP_SCR0(%a6),&0x40 10908 bra.b fsgldiv_unfl_dis 10909 10910 # 10911 # the divide operation MAY underflow: 10912 # 10913 fsgldiv_may_unfl: 10914 fmovm.x FP_SCR1(%a6),&0x80 10915 10916 fmov.l L_SCR3(%a6),%fpcr 10917 fmov.l &0x0,%fpsr 10918 10919 fsgldiv.x FP_SCR0(%a6),%fp0 10920 10921 fmov.l %fpsr,%d1 10922 fmov.l &0x0,%fpcr 10923 10924 or.l %d1,USER_FPSR(%a6) 10925 10926 fabs.x %fp0,%fp1 10927 fcmp.b %fp1,&0x1 10928 fbgt.w fsgldiv_normal_exit 10929 fblt.w fsgldiv_unfl 10930 10931 # 10932 # we still don't know if underflow occurred. 10933 # we don't know if the result was an underfl 10934 # or a normalized number that rounded down t 10935 # operation using RZ as the rounding mode to 10936 # result is. this case should be relatively 10937 # 10938 fmovm.x FP_SCR1(%a6),&0x40 10939 10940 clr.l %d1 10941 ori.b &rz_mode*0x10,%d1 10942 10943 fmov.l %d1,%fpcr 10944 fmov.l &0x0,%fpsr 10945 10946 fsgldiv.x FP_SCR0(%a6),%fp1 10947 10948 fmov.l &0x0,%fpcr 10949 fabs.x %fp1 10950 fcmp.b %fp1,&0x1 10951 fbge.w fsgldiv_normal_exit 10952 bra.w fsgldiv_unfl 10953 10954 ############################################ 10955 10956 # 10957 # Divide: inputs are not both normalized; wh 10958 # 10959 fsgldiv_not_norm: 10960 mov.w (tbl_fsgldiv_op.b,%p 10961 jmp (tbl_fsgldiv_op.b,%p 10962 10963 swbeg &48 10964 tbl_fsgldiv_op: 10965 short fsgldiv_norm 10966 short fsgldiv_inf_load 10967 short fsgldiv_zero_load 10968 short fsgldiv_res_qnan 10969 short fsgldiv_norm 10970 short fsgldiv_res_snan 10971 short tbl_fsgldiv_op 10972 short tbl_fsgldiv_op 10973 10974 short fsgldiv_zero_load 10975 short fsgldiv_res_operr 10976 short fsgldiv_zero_load 10977 short fsgldiv_res_qnan 10978 short fsgldiv_zero_load 10979 short fsgldiv_res_snan 10980 short tbl_fsgldiv_op 10981 short tbl_fsgldiv_op 10982 10983 short fsgldiv_inf_dst 10984 short fsgldiv_inf_dst 10985 short fsgldiv_res_operr 10986 short fsgldiv_res_qnan 10987 short fsgldiv_inf_dst 10988 short fsgldiv_res_snan 10989 short tbl_fsgldiv_op 10990 short tbl_fsgldiv_op 10991 10992 short fsgldiv_res_qnan 10993 short fsgldiv_res_qnan 10994 short fsgldiv_res_qnan 10995 short fsgldiv_res_qnan 10996 short fsgldiv_res_qnan 10997 short fsgldiv_res_snan 10998 short tbl_fsgldiv_op 10999 short tbl_fsgldiv_op 11000 11001 short fsgldiv_norm 11002 short fsgldiv_inf_load 11003 short fsgldiv_zero_load 11004 short fsgldiv_res_qnan 11005 short fsgldiv_norm 11006 short fsgldiv_res_snan 11007 short tbl_fsgldiv_op 11008 short tbl_fsgldiv_op 11009 11010 short fsgldiv_res_snan 11011 short fsgldiv_res_snan 11012 short fsgldiv_res_snan 11013 short fsgldiv_res_snan 11014 short fsgldiv_res_snan 11015 short fsgldiv_res_snan 11016 short tbl_fsgldiv_op 11017 short tbl_fsgldiv_op 11018 11019 fsgldiv_res_qnan: 11020 bra.l res_qnan 11021 fsgldiv_res_snan: 11022 bra.l res_snan 11023 fsgldiv_res_operr: 11024 bra.l res_operr 11025 fsgldiv_inf_load: 11026 bra.l fdiv_inf_load 11027 fsgldiv_zero_load: 11028 bra.l fdiv_zero_load 11029 fsgldiv_inf_dst: 11030 bra.l fdiv_inf_dst 11031 11032 ############################################ 11033 # XDEF ************************************* 11034 # fadd(): emulates the fadd instructio 11035 # fsadd(): emulates the fadd instructi 11036 # fdadd(): emulates the fdadd instruct 11037 # 11038 # XREF ************************************* 11039 # addsub_scaler2() - scale the operand 11040 # ovf_res() - return default overflow 11041 # unf_res() - return default underflow 11042 # res_qnan() - set QNAN result 11043 # res_snan() - set SNAN result 11044 # res_operr() - set OPERR result 11045 # scale_to_zero_src() - set src operan 11046 # scale_to_zero_dst() - set dst operan 11047 # 11048 # INPUT ************************************ 11049 # a0 = pointer to extended precision s 11050 # a1 = pointer to extended precision d 11051 # 11052 # OUTPUT *********************************** 11053 # fp0 = result 11054 # fp1 = EXOP (if exception occurred) 11055 # 11056 # ALGORITHM ******************************** 11057 # Handle NANs, infinities, and zeroes 11058 # norms into extended, single, and double pr 11059 # Do addition after scaling exponents 11060 # occur. Then, check result exponent to see 11061 # occurred. If so, return default result and 11062 # the correct result exponent and return. Se 11063 # 11064 ############################################ 11065 11066 global fsadd 11067 fsadd: 11068 andi.b &0x30,%d0 11069 ori.b &s_mode*0x10,%d0 11070 bra.b fadd 11071 11072 global fdadd 11073 fdadd: 11074 andi.b &0x30,%d0 11075 ori.b &d_mode*0x10,%d0 11076 11077 global fadd 11078 fadd: 11079 mov.l %d0,L_SCR3(%a6) 11080 11081 clr.w %d1 11082 mov.b DTAG(%a6),%d1 11083 lsl.b &0x3,%d1 11084 or.b STAG(%a6),%d1 11085 11086 bne.w fadd_not_norm 11087 11088 # 11089 # ADD: norms and denorms 11090 # 11091 fadd_norm: 11092 bsr.l addsub_scaler2 11093 11094 fadd_zero_entry: 11095 fmovm.x FP_SCR1(%a6),&0x80 11096 11097 fmov.l &0x0,%fpsr 11098 fmov.l L_SCR3(%a6),%fpcr 11099 11100 fadd.x FP_SCR0(%a6),%fp0 11101 11102 fmov.l &0x0,%fpcr 11103 fmov.l %fpsr,%d1 11104 11105 or.l %d1,USER_FPSR(%a6) 11106 11107 fbeq.w fadd_zero_exit 11108 11109 mov.l %d2,-(%sp) 11110 11111 fmovm.x &0x01,-(%sp) 11112 11113 mov.w 2+L_SCR3(%a6),%d1 11114 lsr.b &0x6,%d1 11115 11116 mov.w (%sp),%d2 11117 andi.l &0x7fff,%d2 11118 sub.l %d0,%d2 11119 11120 cmp.l %d2,(tbl_fadd_ovfl.b 11121 bge.b fadd_ovfl 11122 11123 cmp.l %d2,(tbl_fadd_unfl.b 11124 blt.w fadd_unfl 11125 beq.w fadd_may_unfl 11126 11127 fadd_normal: 11128 mov.w (%sp),%d1 11129 andi.w &0x8000,%d1 11130 or.w %d2,%d1 11131 mov.w %d1,(%sp) 11132 11133 fmovm.x (%sp)+,&0x80 11134 11135 mov.l (%sp)+,%d2 11136 rts 11137 11138 fadd_zero_exit: 11139 # fmov.s &0x00000000,%fp0 11140 rts 11141 11142 tbl_fadd_ovfl: 11143 long 0x7fff 11144 long 0x407f 11145 long 0x43ff 11146 11147 tbl_fadd_unfl: 11148 long 0x0000 11149 long 0x3f81 11150 long 0x3c01 11151 11152 fadd_ovfl: 11153 or.l &ovfl_inx_mask,USER_ 11154 11155 mov.b FPCR_ENABLE(%a6),%d1 11156 andi.b &0x13,%d1 11157 bne.b fadd_ovfl_ena 11158 11159 add.l &0xc,%sp 11160 fadd_ovfl_dis: 11161 btst &neg_bit,FPSR_CC(%a6 11162 sne %d1 11163 mov.l L_SCR3(%a6),%d0 11164 bsr.l ovf_res 11165 or.b %d0,FPSR_CC(%a6) 11166 fmovm.x (%a0),&0x80 11167 mov.l (%sp)+,%d2 11168 rts 11169 11170 fadd_ovfl_ena: 11171 mov.b L_SCR3(%a6),%d1 11172 andi.b &0xc0,%d1 11173 bne.b fadd_ovfl_ena_sd 11174 11175 fadd_ovfl_ena_cont: 11176 mov.w (%sp),%d1 11177 andi.w &0x8000,%d1 11178 subi.l &0x6000,%d2 11179 andi.w &0x7fff,%d2 11180 or.w %d2,%d1 11181 mov.w %d1,(%sp) 11182 11183 fmovm.x (%sp)+,&0x40 11184 bra.b fadd_ovfl_dis 11185 11186 fadd_ovfl_ena_sd: 11187 fmovm.x FP_SCR1(%a6),&0x80 11188 11189 mov.l L_SCR3(%a6),%d1 11190 andi.b &0x30,%d1 11191 fmov.l %d1,%fpcr 11192 11193 fadd.x FP_SCR0(%a6),%fp0 11194 11195 fmov.l &0x0,%fpcr 11196 11197 add.l &0xc,%sp 11198 fmovm.x &0x01,-(%sp) 11199 bra.b fadd_ovfl_ena_cont 11200 11201 fadd_unfl: 11202 bset &unfl_bit,FPSR_EXCEP 11203 11204 add.l &0xc,%sp 11205 11206 fmovm.x FP_SCR1(%a6),&0x80 11207 11208 fmov.l &rz_mode*0x10,%fpcr 11209 fmov.l &0x0,%fpsr 11210 11211 fadd.x FP_SCR0(%a6),%fp0 11212 11213 fmov.l &0x0,%fpcr 11214 fmov.l %fpsr,%d1 11215 11216 or.l %d1,USER_FPSR(%a6) 11217 11218 mov.b FPCR_ENABLE(%a6),%d1 11219 andi.b &0x0b,%d1 11220 bne.b fadd_unfl_ena 11221 11222 fadd_unfl_dis: 11223 fmovm.x &0x80,FP_SCR0(%a6) 11224 11225 lea FP_SCR0(%a6),%a0 11226 mov.l L_SCR3(%a6),%d1 11227 bsr.l unf_res 11228 or.b %d0,FPSR_CC(%a6) 11229 fmovm.x FP_SCR0(%a6),&0x80 11230 mov.l (%sp)+,%d2 11231 rts 11232 11233 fadd_unfl_ena: 11234 fmovm.x FP_SCR1(%a6),&0x40 11235 11236 mov.l L_SCR3(%a6),%d1 11237 andi.b &0xc0,%d1 11238 bne.b fadd_unfl_ena_sd 11239 11240 fmov.l L_SCR3(%a6),%fpcr 11241 11242 fadd_unfl_ena_cont: 11243 fmov.l &0x0,%fpsr 11244 11245 fadd.x FP_SCR0(%a6),%fp1 11246 11247 fmov.l &0x0,%fpcr 11248 11249 fmovm.x &0x40,FP_SCR0(%a6) 11250 mov.w FP_SCR0_EX(%a6),%d1 11251 mov.l %d1,%d2 11252 andi.l &0x7fff,%d1 11253 andi.w &0x8000,%d2 11254 sub.l %d0,%d1 11255 addi.l &0x6000,%d1 11256 andi.w &0x7fff,%d1 11257 or.w %d2,%d1 11258 mov.w %d1,FP_SCR0_EX(%a6) 11259 fmovm.x FP_SCR0(%a6),&0x40 11260 bra.w fadd_unfl_dis 11261 11262 fadd_unfl_ena_sd: 11263 mov.l L_SCR3(%a6),%d1 11264 andi.b &0x30,%d1 11265 fmov.l %d1,%fpcr 11266 11267 bra.b fadd_unfl_ena_cont 11268 11269 # 11270 # result is equal to the smallest normalized 11271 # if the precision is extended, this result 11272 # underflow that rounded up. 11273 # 11274 fadd_may_unfl: 11275 mov.l L_SCR3(%a6),%d1 11276 andi.b &0xc0,%d1 11277 beq.w fadd_normal 11278 11279 mov.l 0x4(%sp),%d1 11280 cmpi.l %d1,&0x80000000 11281 bne.w fadd_normal 11282 11283 tst.l 0x8(%sp) 11284 bne.w fadd_normal 11285 11286 btst &inex2_bit,FPSR_EXCE 11287 beq.w fadd_normal 11288 11289 # 11290 # ok, so now the result has a exponent equal 11291 # exponent for the selected precision. also, 11292 # 0x8000000000000000 and this mantissa is th 11293 # g,r,s. 11294 # now, we must determine whether the pre-rou 11295 # rounded "up" or a normalized number rounde 11296 # so, we do this be re-executing the add usi 11297 # seeing if the new result is smaller or equ 11298 # 11299 fmovm.x FP_SCR1(%a6),&0x40 11300 11301 mov.l L_SCR3(%a6),%d1 11302 andi.b &0xc0,%d1 11303 ori.b &rz_mode*0x10,%d1 11304 fmov.l %d1,%fpcr 11305 fmov.l &0x0,%fpsr 11306 11307 fadd.x FP_SCR0(%a6),%fp1 11308 11309 fmov.l &0x0,%fpcr 11310 11311 fabs.x %fp0 11312 fabs.x %fp1 11313 fcmp.x %fp0,%fp1 11314 11315 fbgt.w fadd_unfl 11316 bra.w fadd_normal 11317 11318 ############################################ 11319 11320 # 11321 # Add: inputs are not both normalized; what 11322 # 11323 fadd_not_norm: 11324 mov.w (tbl_fadd_op.b,%pc,% 11325 jmp (tbl_fadd_op.b,%pc,% 11326 11327 swbeg &48 11328 tbl_fadd_op: 11329 short fadd_norm - tb 11330 short fadd_zero_src - tb 11331 short fadd_inf_src - tb 11332 short fadd_res_qnan - tb 11333 short fadd_norm - tb 11334 short fadd_res_snan - tb 11335 short tbl_fadd_op - tb 11336 short tbl_fadd_op - tb 11337 11338 short fadd_zero_dst - tb 11339 short fadd_zero_2 - tb 11340 short fadd_inf_src - tb 11341 short fadd_res_qnan - tb 11342 short fadd_zero_dst - tb 11343 short fadd_res_snan - tb 11344 short tbl_fadd_op - tb 11345 short tbl_fadd_op - tb 11346 11347 short fadd_inf_dst - tb 11348 short fadd_inf_dst - tb 11349 short fadd_inf_2 - tb 11350 short fadd_res_qnan - tb 11351 short fadd_inf_dst - tb 11352 short fadd_res_snan - tb 11353 short tbl_fadd_op - tb 11354 short tbl_fadd_op - tb 11355 11356 short fadd_res_qnan - tb 11357 short fadd_res_qnan - tb 11358 short fadd_res_qnan - tb 11359 short fadd_res_qnan - tb 11360 short fadd_res_qnan - tb 11361 short fadd_res_snan - tb 11362 short tbl_fadd_op - tb 11363 short tbl_fadd_op - tb 11364 11365 short fadd_norm - tb 11366 short fadd_zero_src - tb 11367 short fadd_inf_src - tb 11368 short fadd_res_qnan - tb 11369 short fadd_norm - tb 11370 short fadd_res_snan - tb 11371 short tbl_fadd_op - tb 11372 short tbl_fadd_op - tb 11373 11374 short fadd_res_snan - tb 11375 short fadd_res_snan - tb 11376 short fadd_res_snan - tb 11377 short fadd_res_snan - tb 11378 short fadd_res_snan - tb 11379 short fadd_res_snan - tb 11380 short tbl_fadd_op - tb 11381 short tbl_fadd_op - tb 11382 11383 fadd_res_qnan: 11384 bra.l res_qnan 11385 fadd_res_snan: 11386 bra.l res_snan 11387 11388 # 11389 # both operands are ZEROes 11390 # 11391 fadd_zero_2: 11392 mov.b SRC_EX(%a0),%d0 11393 mov.b DST_EX(%a1),%d1 11394 eor.b %d0,%d1 11395 bmi.w fadd_zero_2_chk_rm 11396 11397 # the signs are the same. so determine wheth 11398 # and return the appropriately signed zero. 11399 tst.b %d0 11400 bmi.b fadd_zero_rm 11401 fmov.s &0x00000000,%fp0 11402 mov.b &z_bmask,FPSR_CC(%a6 11403 rts 11404 11405 # 11406 # the ZEROes have opposite signs: 11407 # - Therefore, we return +ZERO if the roundi 11408 # - -ZERO is returned in the case of RM. 11409 # 11410 fadd_zero_2_chk_rm: 11411 mov.b 3+L_SCR3(%a6),%d1 11412 andi.b &0x30,%d1 11413 cmpi.b %d1,&rm_mode*0x10 11414 beq.b fadd_zero_rm 11415 fmov.s &0x00000000,%fp0 11416 mov.b &z_bmask,FPSR_CC(%a6 11417 rts 11418 11419 fadd_zero_rm: 11420 fmov.s &0x80000000,%fp0 11421 mov.b &neg_bmask+z_bmask,F 11422 rts 11423 11424 # 11425 # one operand is a ZERO and the other is a D 11426 # the DENORM or NORM and jump to the regular 11427 # 11428 fadd_zero_dst: 11429 mov.w SRC_EX(%a0),FP_SCR0_ 11430 mov.l SRC_HI(%a0),FP_SCR0_ 11431 mov.l SRC_LO(%a0),FP_SCR0_ 11432 bsr.l scale_to_zero_src 11433 clr.w FP_SCR1_EX(%a6) 11434 clr.l FP_SCR1_HI(%a6) 11435 clr.l FP_SCR1_LO(%a6) 11436 bra.w fadd_zero_entry 11437 11438 fadd_zero_src: 11439 mov.w DST_EX(%a1),FP_SCR1_ 11440 mov.l DST_HI(%a1),FP_SCR1_ 11441 mov.l DST_LO(%a1),FP_SCR1_ 11442 bsr.l scale_to_zero_dst 11443 clr.w FP_SCR0_EX(%a6) 11444 clr.l FP_SCR0_HI(%a6) 11445 clr.l FP_SCR0_LO(%a6) 11446 bra.w fadd_zero_entry 11447 11448 # 11449 # both operands are INFs. an OPERR will resu 11450 # different signs. else, an INF of the same 11451 # 11452 fadd_inf_2: 11453 mov.b SRC_EX(%a0),%d0 11454 mov.b DST_EX(%a1),%d1 11455 eor.b %d1,%d0 11456 bmi.l res_operr 11457 11458 # ok, so it's not an OPERR. but, we do have 11459 # src INF since that's where the 881/882 get 11460 11461 # 11462 # operands are INF and one of {ZERO, INF, DE 11463 # 11464 fadd_inf_src: 11465 fmovm.x SRC(%a0),&0x80 11466 tst.b SRC_EX(%a0) 11467 bpl.b fadd_inf_done 11468 mov.b &neg_bmask+inf_bmask 11469 rts 11470 11471 # 11472 # operands are INF and one of {ZERO, INF, DE 11473 # 11474 fadd_inf_dst: 11475 fmovm.x DST(%a1),&0x80 11476 tst.b DST_EX(%a1) 11477 bpl.b fadd_inf_done 11478 mov.b &neg_bmask+inf_bmask 11479 rts 11480 11481 fadd_inf_done: 11482 mov.b &inf_bmask,FPSR_CC(% 11483 rts 11484 11485 ############################################ 11486 # XDEF ************************************* 11487 # fsub(): emulates the fsub instructio 11488 # fssub(): emulates the fssub instruct 11489 # fdsub(): emulates the fdsub instruct 11490 # 11491 # XREF ************************************* 11492 # addsub_scaler2() - scale the operand 11493 # ovf_res() - return default overflow 11494 # unf_res() - return default underflow 11495 # res_qnan() - set QNAN result 11496 # res_snan() - set SNAN result 11497 # res_operr() - set OPERR result 11498 # scale_to_zero_src() - set src operan 11499 # scale_to_zero_dst() - set dst operan 11500 # 11501 # INPUT ************************************ 11502 # a0 = pointer to extended precision s 11503 # a1 = pointer to extended precision d 11504 # 11505 # OUTPUT *********************************** 11506 # fp0 = result 11507 # fp1 = EXOP (if exception occurred) 11508 # 11509 # ALGORITHM ******************************** 11510 # Handle NANs, infinities, and zeroes 11511 # norms into extended, single, and double pr 11512 # Do subtraction after scaling exponen 11513 # occur. Then, check result exponent to see 11514 # occurred. If so, return default result and 11515 # the correct result exponent and return. Se 11516 # 11517 ############################################ 11518 11519 global fssub 11520 fssub: 11521 andi.b &0x30,%d0 11522 ori.b &s_mode*0x10,%d0 11523 bra.b fsub 11524 11525 global fdsub 11526 fdsub: 11527 andi.b &0x30,%d0 11528 ori.b &d_mode*0x10,%d0 11529 11530 global fsub 11531 fsub: 11532 mov.l %d0,L_SCR3(%a6) 11533 11534 clr.w %d1 11535 mov.b DTAG(%a6),%d1 11536 lsl.b &0x3,%d1 11537 or.b STAG(%a6),%d1 11538 11539 bne.w fsub_not_norm 11540 11541 # 11542 # SUB: norms and denorms 11543 # 11544 fsub_norm: 11545 bsr.l addsub_scaler2 11546 11547 fsub_zero_entry: 11548 fmovm.x FP_SCR1(%a6),&0x80 11549 11550 fmov.l &0x0,%fpsr 11551 fmov.l L_SCR3(%a6),%fpcr 11552 11553 fsub.x FP_SCR0(%a6),%fp0 11554 11555 fmov.l &0x0,%fpcr 11556 fmov.l %fpsr,%d1 11557 11558 or.l %d1,USER_FPSR(%a6) 11559 11560 fbeq.w fsub_zero_exit 11561 11562 mov.l %d2,-(%sp) 11563 11564 fmovm.x &0x01,-(%sp) 11565 11566 mov.w 2+L_SCR3(%a6),%d1 11567 lsr.b &0x6,%d1 11568 11569 mov.w (%sp),%d2 11570 andi.l &0x7fff,%d2 11571 sub.l %d0,%d2 11572 11573 cmp.l %d2,(tbl_fsub_ovfl.b 11574 bge.b fsub_ovfl 11575 11576 cmp.l %d2,(tbl_fsub_unfl.b 11577 blt.w fsub_unfl 11578 beq.w fsub_may_unfl 11579 11580 fsub_normal: 11581 mov.w (%sp),%d1 11582 andi.w &0x8000,%d1 11583 or.w %d2,%d1 11584 mov.w %d1,(%sp) 11585 11586 fmovm.x (%sp)+,&0x80 11587 11588 mov.l (%sp)+,%d2 11589 rts 11590 11591 fsub_zero_exit: 11592 # fmov.s &0x00000000,%fp0 11593 rts 11594 11595 tbl_fsub_ovfl: 11596 long 0x7fff 11597 long 0x407f 11598 long 0x43ff 11599 11600 tbl_fsub_unfl: 11601 long 0x0000 11602 long 0x3f81 11603 long 0x3c01 11604 11605 fsub_ovfl: 11606 or.l &ovfl_inx_mask,USER_ 11607 11608 mov.b FPCR_ENABLE(%a6),%d1 11609 andi.b &0x13,%d1 11610 bne.b fsub_ovfl_ena 11611 11612 add.l &0xc,%sp 11613 fsub_ovfl_dis: 11614 btst &neg_bit,FPSR_CC(%a6 11615 sne %d1 11616 mov.l L_SCR3(%a6),%d0 11617 bsr.l ovf_res 11618 or.b %d0,FPSR_CC(%a6) 11619 fmovm.x (%a0),&0x80 11620 mov.l (%sp)+,%d2 11621 rts 11622 11623 fsub_ovfl_ena: 11624 mov.b L_SCR3(%a6),%d1 11625 andi.b &0xc0,%d1 11626 bne.b fsub_ovfl_ena_sd 11627 11628 fsub_ovfl_ena_cont: 11629 mov.w (%sp),%d1 11630 andi.w &0x8000,%d1 11631 subi.l &0x6000,%d2 11632 andi.w &0x7fff,%d2 11633 or.w %d2,%d1 11634 mov.w %d1,(%sp) 11635 11636 fmovm.x (%sp)+,&0x40 11637 bra.b fsub_ovfl_dis 11638 11639 fsub_ovfl_ena_sd: 11640 fmovm.x FP_SCR1(%a6),&0x80 11641 11642 mov.l L_SCR3(%a6),%d1 11643 andi.b &0x30,%d1 11644 fmov.l %d1,%fpcr 11645 11646 fsub.x FP_SCR0(%a6),%fp0 11647 11648 fmov.l &0x0,%fpcr 11649 11650 add.l &0xc,%sp 11651 fmovm.x &0x01,-(%sp) 11652 bra.b fsub_ovfl_ena_cont 11653 11654 fsub_unfl: 11655 bset &unfl_bit,FPSR_EXCEP 11656 11657 add.l &0xc,%sp 11658 11659 fmovm.x FP_SCR1(%a6),&0x80 11660 11661 fmov.l &rz_mode*0x10,%fpcr 11662 fmov.l &0x0,%fpsr 11663 11664 fsub.x FP_SCR0(%a6),%fp0 11665 11666 fmov.l &0x0,%fpcr 11667 fmov.l %fpsr,%d1 11668 11669 or.l %d1,USER_FPSR(%a6) 11670 11671 mov.b FPCR_ENABLE(%a6),%d1 11672 andi.b &0x0b,%d1 11673 bne.b fsub_unfl_ena 11674 11675 fsub_unfl_dis: 11676 fmovm.x &0x80,FP_SCR0(%a6) 11677 11678 lea FP_SCR0(%a6),%a0 11679 mov.l L_SCR3(%a6),%d1 11680 bsr.l unf_res 11681 or.b %d0,FPSR_CC(%a6) 11682 fmovm.x FP_SCR0(%a6),&0x80 11683 mov.l (%sp)+,%d2 11684 rts 11685 11686 fsub_unfl_ena: 11687 fmovm.x FP_SCR1(%a6),&0x40 11688 11689 mov.l L_SCR3(%a6),%d1 11690 andi.b &0xc0,%d1 11691 bne.b fsub_unfl_ena_sd 11692 11693 fmov.l L_SCR3(%a6),%fpcr 11694 11695 fsub_unfl_ena_cont: 11696 fmov.l &0x0,%fpsr 11697 11698 fsub.x FP_SCR0(%a6),%fp1 11699 11700 fmov.l &0x0,%fpcr 11701 11702 fmovm.x &0x40,FP_SCR0(%a6) 11703 mov.w FP_SCR0_EX(%a6),%d1 11704 mov.l %d1,%d2 11705 andi.l &0x7fff,%d1 11706 andi.w &0x8000,%d2 11707 sub.l %d0,%d1 11708 addi.l &0x6000,%d1 11709 andi.w &0x7fff,%d1 11710 or.w %d2,%d1 11711 mov.w %d1,FP_SCR0_EX(%a6) 11712 fmovm.x FP_SCR0(%a6),&0x40 11713 bra.w fsub_unfl_dis 11714 11715 fsub_unfl_ena_sd: 11716 mov.l L_SCR3(%a6),%d1 11717 andi.b &0x30,%d1 11718 fmov.l %d1,%fpcr 11719 11720 bra.b fsub_unfl_ena_cont 11721 11722 # 11723 # result is equal to the smallest normalized 11724 # if the precision is extended, this result 11725 # underflow that rounded up. 11726 # 11727 fsub_may_unfl: 11728 mov.l L_SCR3(%a6),%d1 11729 andi.b &0xc0,%d1 11730 beq.w fsub_normal 11731 11732 mov.l 0x4(%sp),%d1 11733 cmpi.l %d1,&0x80000000 11734 bne.w fsub_normal 11735 11736 tst.l 0x8(%sp) 11737 bne.w fsub_normal 11738 11739 btst &inex2_bit,FPSR_EXCE 11740 beq.w fsub_normal 11741 11742 # 11743 # ok, so now the result has a exponent equal 11744 # exponent for the selected precision. also, 11745 # 0x8000000000000000 and this mantissa is th 11746 # g,r,s. 11747 # now, we must determine whether the pre-rou 11748 # rounded "up" or a normalized number rounde 11749 # so, we do this be re-executing the add usi 11750 # seeing if the new result is smaller or equ 11751 # 11752 fmovm.x FP_SCR1(%a6),&0x40 11753 11754 mov.l L_SCR3(%a6),%d1 11755 andi.b &0xc0,%d1 11756 ori.b &rz_mode*0x10,%d1 11757 fmov.l %d1,%fpcr 11758 fmov.l &0x0,%fpsr 11759 11760 fsub.x FP_SCR0(%a6),%fp1 11761 11762 fmov.l &0x0,%fpcr 11763 11764 fabs.x %fp0 11765 fabs.x %fp1 11766 fcmp.x %fp0,%fp1 11767 11768 fbgt.w fsub_unfl 11769 bra.w fsub_normal 11770 11771 ############################################ 11772 11773 # 11774 # Sub: inputs are not both normalized; what 11775 # 11776 fsub_not_norm: 11777 mov.w (tbl_fsub_op.b,%pc,% 11778 jmp (tbl_fsub_op.b,%pc,% 11779 11780 swbeg &48 11781 tbl_fsub_op: 11782 short fsub_norm - tb 11783 short fsub_zero_src - tb 11784 short fsub_inf_src - tb 11785 short fsub_res_qnan - tb 11786 short fsub_norm - tb 11787 short fsub_res_snan - tb 11788 short tbl_fsub_op - tb 11789 short tbl_fsub_op - tb 11790 11791 short fsub_zero_dst - tb 11792 short fsub_zero_2 - tb 11793 short fsub_inf_src - tb 11794 short fsub_res_qnan - tb 11795 short fsub_zero_dst - tb 11796 short fsub_res_snan - tb 11797 short tbl_fsub_op - tb 11798 short tbl_fsub_op - tb 11799 11800 short fsub_inf_dst - tb 11801 short fsub_inf_dst - tb 11802 short fsub_inf_2 - tb 11803 short fsub_res_qnan - tb 11804 short fsub_inf_dst - tb 11805 short fsub_res_snan - tb 11806 short tbl_fsub_op - tb 11807 short tbl_fsub_op - tb 11808 11809 short fsub_res_qnan - tb 11810 short fsub_res_qnan - tb 11811 short fsub_res_qnan - tb 11812 short fsub_res_qnan - tb 11813 short fsub_res_qnan - tb 11814 short fsub_res_snan - tb 11815 short tbl_fsub_op - tb 11816 short tbl_fsub_op - tb 11817 11818 short fsub_norm - tb 11819 short fsub_zero_src - tb 11820 short fsub_inf_src - tb 11821 short fsub_res_qnan - tb 11822 short fsub_norm - tb 11823 short fsub_res_snan - tb 11824 short tbl_fsub_op - tb 11825 short tbl_fsub_op - tb 11826 11827 short fsub_res_snan - tb 11828 short fsub_res_snan - tb 11829 short fsub_res_snan - tb 11830 short fsub_res_snan - tb 11831 short fsub_res_snan - tb 11832 short fsub_res_snan - tb 11833 short tbl_fsub_op - tb 11834 short tbl_fsub_op - tb 11835 11836 fsub_res_qnan: 11837 bra.l res_qnan 11838 fsub_res_snan: 11839 bra.l res_snan 11840 11841 # 11842 # both operands are ZEROes 11843 # 11844 fsub_zero_2: 11845 mov.b SRC_EX(%a0),%d0 11846 mov.b DST_EX(%a1),%d1 11847 eor.b %d1,%d0 11848 bpl.b fsub_zero_2_chk_rm 11849 11850 # the signs are opposite, so, return a ZERO 11851 tst.b %d0 11852 bmi.b fsub_zero_2_rm 11853 fmov.s &0x00000000,%fp0 11854 mov.b &z_bmask,FPSR_CC(%a6 11855 rts 11856 11857 # 11858 # the ZEROes have the same signs: 11859 # - Therefore, we return +ZERO if the roundi 11860 # - -ZERO is returned in the case of RM. 11861 # 11862 fsub_zero_2_chk_rm: 11863 mov.b 3+L_SCR3(%a6),%d1 11864 andi.b &0x30,%d1 11865 cmpi.b %d1,&rm_mode*0x10 11866 beq.b fsub_zero_2_rm 11867 fmov.s &0x00000000,%fp0 11868 mov.b &z_bmask,FPSR_CC(%a6 11869 rts 11870 11871 fsub_zero_2_rm: 11872 fmov.s &0x80000000,%fp0 11873 mov.b &z_bmask+neg_bmask,F 11874 rts 11875 11876 # 11877 # one operand is a ZERO and the other is a D 11878 # scale the DENORM or NORM and jump to the r 11879 # 11880 fsub_zero_dst: 11881 mov.w SRC_EX(%a0),FP_SCR0_ 11882 mov.l SRC_HI(%a0),FP_SCR0_ 11883 mov.l SRC_LO(%a0),FP_SCR0_ 11884 bsr.l scale_to_zero_src 11885 clr.w FP_SCR1_EX(%a6) 11886 clr.l FP_SCR1_HI(%a6) 11887 clr.l FP_SCR1_LO(%a6) 11888 bra.w fsub_zero_entry 11889 11890 fsub_zero_src: 11891 mov.w DST_EX(%a1),FP_SCR1_ 11892 mov.l DST_HI(%a1),FP_SCR1_ 11893 mov.l DST_LO(%a1),FP_SCR1_ 11894 bsr.l scale_to_zero_dst 11895 clr.w FP_SCR0_EX(%a6) 11896 clr.l FP_SCR0_HI(%a6) 11897 clr.l FP_SCR0_LO(%a6) 11898 bra.w fsub_zero_entry 11899 11900 # 11901 # both operands are INFs. an OPERR will resu 11902 # same signs. else, 11903 # 11904 fsub_inf_2: 11905 mov.b SRC_EX(%a0),%d0 11906 mov.b DST_EX(%a1),%d1 11907 eor.b %d1,%d0 11908 bpl.l res_operr 11909 11910 # ok, so it's not an OPERR. but we do have t 11911 # the src INF since that's where the 881/882 11912 11913 fsub_inf_src: 11914 fmovm.x SRC(%a0),&0x80 11915 fneg.x %fp0 11916 fbge.w fsub_inf_done 11917 mov.b &neg_bmask+inf_bmask 11918 rts 11919 11920 fsub_inf_dst: 11921 fmovm.x DST(%a1),&0x80 11922 tst.b DST_EX(%a1) 11923 bpl.b fsub_inf_done 11924 mov.b &neg_bmask+inf_bmask 11925 rts 11926 11927 fsub_inf_done: 11928 mov.b &inf_bmask,FPSR_CC(% 11929 rts 11930 11931 ############################################ 11932 # XDEF ************************************* 11933 # fsqrt(): emulates the fsqrt instruct 11934 # fssqrt(): emulates the fssqrt instru 11935 # fdsqrt(): emulates the fdsqrt instru 11936 # 11937 # XREF ************************************* 11938 # scale_sqrt() - scale the source oper 11939 # unf_res() - return default underflow 11940 # ovf_res() - return default overflow 11941 # res_qnan_1op() - return QNAN result 11942 # res_snan_1op() - return SNAN result 11943 # 11944 # INPUT ************************************ 11945 # a0 = pointer to extended precision s 11946 # d0 rnd prec,mode 11947 # 11948 # OUTPUT *********************************** 11949 # fp0 = result 11950 # fp1 = EXOP (if exception occurred) 11951 # 11952 # ALGORITHM ******************************** 11953 # Handle NANs, infinities, and zeroes 11954 # norms/denorms into ext/sgl/dbl precision. 11955 # For norms/denorms, scale the exponen 11956 # instruction won't cause an exception. Use 11957 # compute a result. Check if the regular ope 11958 # an exception. If so, return the default ov 11959 # and return the EXOP if exceptions are enab 11960 # result operand to the proper exponent. 11961 # 11962 ############################################ 11963 11964 global fssqrt 11965 fssqrt: 11966 andi.b &0x30,%d0 11967 ori.b &s_mode*0x10,%d0 11968 bra.b fsqrt 11969 11970 global fdsqrt 11971 fdsqrt: 11972 andi.b &0x30,%d0 11973 ori.b &d_mode*0x10,%d0 11974 11975 global fsqrt 11976 fsqrt: 11977 mov.l %d0,L_SCR3(%a6) 11978 clr.w %d1 11979 mov.b STAG(%a6),%d1 11980 bne.w fsqrt_not_norm 11981 11982 # 11983 # SQUARE ROOT: norms and denorms ONLY! 11984 # 11985 fsqrt_norm: 11986 tst.b SRC_EX(%a0) 11987 bmi.l res_operr 11988 11989 andi.b &0xc0,%d0 11990 bne.b fsqrt_not_ext 11991 11992 fmov.l L_SCR3(%a6),%fpcr 11993 fmov.l &0x0,%fpsr 11994 11995 fsqrt.x (%a0),%fp0 11996 11997 fmov.l %fpsr,%d1 11998 or.l %d1,USER_FPSR(%a6) 11999 12000 rts 12001 12002 fsqrt_denorm: 12003 tst.b SRC_EX(%a0) 12004 bmi.l res_operr 12005 12006 andi.b &0xc0,%d0 12007 bne.b fsqrt_not_ext 12008 12009 mov.w SRC_EX(%a0),FP_SCR0_ 12010 mov.l SRC_HI(%a0),FP_SCR0_ 12011 mov.l SRC_LO(%a0),FP_SCR0_ 12012 12013 bsr.l scale_sqrt 12014 12015 bra.w fsqrt_sd_normal 12016 12017 # 12018 # operand is either single or double 12019 # 12020 fsqrt_not_ext: 12021 cmpi.b %d0,&s_mode*0x10 12022 bne.w fsqrt_dbl 12023 12024 # 12025 # operand is to be rounded to single precisi 12026 # 12027 fsqrt_sgl: 12028 mov.w SRC_EX(%a0),FP_SCR0_ 12029 mov.l SRC_HI(%a0),FP_SCR0_ 12030 mov.l SRC_LO(%a0),FP_SCR0_ 12031 12032 bsr.l scale_sqrt 12033 12034 cmpi.l %d0,&0x3fff-0x3f81 12035 beq.w fsqrt_sd_may_unfl 12036 bgt.w fsqrt_sd_unfl 12037 cmpi.l %d0,&0x3fff-0x407f 12038 beq.w fsqrt_sd_may_ovfl 12039 blt.w fsqrt_sd_ovfl 12040 12041 # 12042 # operand will NOT overflow or underflow whe 12043 # 12044 fsqrt_sd_normal: 12045 fmov.l &0x0,%fpsr 12046 fmov.l L_SCR3(%a6),%fpcr 12047 12048 fsqrt.x FP_SCR0(%a6),%fp0 12049 12050 fmov.l %fpsr,%d1 12051 fmov.l &0x0,%fpcr 12052 12053 or.l %d1,USER_FPSR(%a6) 12054 12055 fsqrt_sd_normal_exit: 12056 mov.l %d2,-(%sp) 12057 fmovm.x &0x80,FP_SCR0(%a6) 12058 mov.w FP_SCR0_EX(%a6),%d1 12059 mov.l %d1,%d2 12060 andi.l &0x7fff,%d1 12061 sub.l %d0,%d1 12062 andi.w &0x8000,%d2 12063 or.w %d1,%d2 12064 mov.w %d2,FP_SCR0_EX(%a6) 12065 mov.l (%sp)+,%d2 12066 fmovm.x FP_SCR0(%a6),&0x80 12067 rts 12068 12069 # 12070 # operand is to be rounded to double precisi 12071 # 12072 fsqrt_dbl: 12073 mov.w SRC_EX(%a0),FP_SCR0_ 12074 mov.l SRC_HI(%a0),FP_SCR0_ 12075 mov.l SRC_LO(%a0),FP_SCR0_ 12076 12077 bsr.l scale_sqrt 12078 12079 cmpi.l %d0,&0x3fff-0x3c01 12080 beq.w fsqrt_sd_may_unfl 12081 bgt.b fsqrt_sd_unfl 12082 cmpi.l %d0,&0x3fff-0x43ff 12083 beq.w fsqrt_sd_may_ovfl 12084 blt.w fsqrt_sd_ovfl 12085 bra.w fsqrt_sd_normal 12086 12087 # we're on the line here and the distinguisi 12088 # the exponent is 3fff or 3ffe. if it's 3ffe 12089 # elsewise fall through to underflow. 12090 fsqrt_sd_may_unfl: 12091 btst &0x0,1+FP_SCR0_EX(%a 12092 bne.w fsqrt_sd_normal 12093 12094 # 12095 # operand WILL underflow when moved in to th 12096 # 12097 fsqrt_sd_unfl: 12098 bset &unfl_bit,FPSR_EXCEP 12099 12100 fmov.l &rz_mode*0x10,%fpcr 12101 fmov.l &0x0,%fpsr 12102 12103 fsqrt.x FP_SCR0(%a6),%fp0 12104 12105 fmov.l %fpsr,%d1 12106 fmov.l &0x0,%fpcr 12107 12108 or.l %d1,USER_FPSR(%a6) 12109 12110 # if underflow or inexact is enabled, go cal 12111 mov.b FPCR_ENABLE(%a6),%d1 12112 andi.b &0x0b,%d1 12113 bne.b fsqrt_sd_unfl_ena 12114 12115 fsqrt_sd_unfl_dis: 12116 fmovm.x &0x80,FP_SCR0(%a6) 12117 12118 lea FP_SCR0(%a6),%a0 12119 mov.l L_SCR3(%a6),%d1 12120 bsr.l unf_res 12121 or.b %d0,FPSR_CC(%a6) 12122 fmovm.x FP_SCR0(%a6),&0x80 12123 rts 12124 12125 # 12126 # operand will underflow AND underflow is en 12127 # Therefore, we must return the result round 12128 # 12129 fsqrt_sd_unfl_ena: 12130 mov.l FP_SCR0_HI(%a6),FP_S 12131 mov.l FP_SCR0_LO(%a6),FP_S 12132 mov.w FP_SCR0_EX(%a6),%d1 12133 12134 mov.l %d2,-(%sp) 12135 mov.l %d1,%d2 12136 andi.l &0x7fff,%d1 12137 andi.w &0x8000,%d2 12138 sub.l %d0,%d1 12139 addi.l &0x6000,%d1 12140 andi.w &0x7fff,%d1 12141 or.w %d2,%d1 12142 mov.w %d1,FP_SCR1_EX(%a6) 12143 fmovm.x FP_SCR1(%a6),&0x40 12144 mov.l (%sp)+,%d2 12145 bra.b fsqrt_sd_unfl_dis 12146 12147 # 12148 # operand WILL overflow. 12149 # 12150 fsqrt_sd_ovfl: 12151 fmov.l &0x0,%fpsr 12152 fmov.l L_SCR3(%a6),%fpcr 12153 12154 fsqrt.x FP_SCR0(%a6),%fp0 12155 12156 fmov.l &0x0,%fpcr 12157 fmov.l %fpsr,%d1 12158 12159 or.l %d1,USER_FPSR(%a6) 12160 12161 fsqrt_sd_ovfl_tst: 12162 or.l &ovfl_inx_mask,USER_ 12163 12164 mov.b FPCR_ENABLE(%a6),%d1 12165 andi.b &0x13,%d1 12166 bne.b fsqrt_sd_ovfl_ena 12167 12168 # 12169 # OVFL is not enabled; therefore, we must cr 12170 # calling ovf_res(). 12171 # 12172 fsqrt_sd_ovfl_dis: 12173 btst &neg_bit,FPSR_CC(%a6 12174 sne %d1 12175 mov.l L_SCR3(%a6),%d0 12176 bsr.l ovf_res 12177 or.b %d0,FPSR_CC(%a6) 12178 fmovm.x (%a0),&0x80 12179 rts 12180 12181 # 12182 # OVFL is enabled. 12183 # the INEX2 bit has already been updated by 12184 # now, round to extended(and don't alter the 12185 # 12186 fsqrt_sd_ovfl_ena: 12187 mov.l %d2,-(%sp) 12188 mov.w FP_SCR0_EX(%a6),%d1 12189 mov.l %d1,%d2 12190 andi.l &0x7fff,%d1 12191 andi.w &0x8000,%d2 12192 sub.l %d0,%d1 12193 subi.l &0x6000,%d1 12194 andi.w &0x7fff,%d1 12195 or.w %d2,%d1 12196 mov.w %d1,FP_SCR0_EX(%a6) 12197 fmovm.x FP_SCR0(%a6),&0x40 12198 mov.l (%sp)+,%d2 12199 bra.b fsqrt_sd_ovfl_dis 12200 12201 # 12202 # the move in MAY underflow. so... 12203 # 12204 fsqrt_sd_may_ovfl: 12205 btst &0x0,1+FP_SCR0_EX(%a 12206 bne.w fsqrt_sd_ovfl 12207 12208 fmov.l &0x0,%fpsr 12209 fmov.l L_SCR3(%a6),%fpcr 12210 12211 fsqrt.x FP_SCR0(%a6),%fp0 12212 12213 fmov.l %fpsr,%d1 12214 fmov.l &0x0,%fpcr 12215 12216 or.l %d1,USER_FPSR(%a6) 12217 12218 fmov.x %fp0,%fp1 12219 fcmp.b %fp1,&0x1 12220 fbge.w fsqrt_sd_ovfl_tst 12221 12222 # no, it didn't overflow; we have correct re 12223 bra.w fsqrt_sd_normal_exit 12224 12225 ############################################ 12226 12227 # 12228 # input is not normalized; what is it? 12229 # 12230 fsqrt_not_norm: 12231 cmpi.b %d1,&DENORM 12232 beq.w fsqrt_denorm 12233 cmpi.b %d1,&ZERO 12234 beq.b fsqrt_zero 12235 cmpi.b %d1,&INF 12236 beq.b fsqrt_inf 12237 cmpi.b %d1,&SNAN 12238 beq.l res_snan_1op 12239 bra.l res_qnan_1op 12240 12241 # 12242 # fsqrt(+0) = +0 12243 # fsqrt(-0) = -0 12244 # fsqrt(+INF) = +INF 12245 # fsqrt(-INF) = OPERR 12246 # 12247 fsqrt_zero: 12248 tst.b SRC_EX(%a0) 12249 bmi.b fsqrt_zero_m 12250 fsqrt_zero_p: 12251 fmov.s &0x00000000,%fp0 12252 mov.b &z_bmask,FPSR_CC(%a6 12253 rts 12254 fsqrt_zero_m: 12255 fmov.s &0x80000000,%fp0 12256 mov.b &z_bmask+neg_bmask,F 12257 rts 12258 12259 fsqrt_inf: 12260 tst.b SRC_EX(%a0) 12261 bmi.l res_operr 12262 fsqrt_inf_p: 12263 fmovm.x SRC(%a0),&0x80 12264 mov.b &inf_bmask,FPSR_CC(% 12265 rts 12266 12267 ############################################ 12268 # XDEF ************************************* 12269 # fetch_dreg(): fetch register accordi 12270 # 12271 # XREF ************************************* 12272 # None 12273 # 12274 # INPUT ************************************ 12275 # d1 = index of register to fetch from 12276 # 12277 # OUTPUT *********************************** 12278 # d0 = value of register fetched 12279 # 12280 # ALGORITHM ******************************** 12281 # According to the index value in d1 w 12282 # to fifteen, load the corresponding registe 12283 # address register indexes start at 8). D0/D 12284 # stack. The rest should still be in their o 12285 # 12286 ############################################ 12287 12288 # this routine leaves d1 intact for subseque 12289 global fetch_dreg 12290 fetch_dreg: 12291 mov.w (tbl_fdreg.b,%pc,%d1 12292 jmp (tbl_fdreg.b,%pc,%d0 12293 12294 tbl_fdreg: 12295 short fdreg0 - tbl_fdreg 12296 short fdreg1 - tbl_fdreg 12297 short fdreg2 - tbl_fdreg 12298 short fdreg3 - tbl_fdreg 12299 short fdreg4 - tbl_fdreg 12300 short fdreg5 - tbl_fdreg 12301 short fdreg6 - tbl_fdreg 12302 short fdreg7 - tbl_fdreg 12303 short fdreg8 - tbl_fdreg 12304 short fdreg9 - tbl_fdreg 12305 short fdrega - tbl_fdreg 12306 short fdregb - tbl_fdreg 12307 short fdregc - tbl_fdreg 12308 short fdregd - tbl_fdreg 12309 short fdrege - tbl_fdreg 12310 short fdregf - tbl_fdreg 12311 12312 fdreg0: 12313 mov.l EXC_DREGS+0x0(%a6),% 12314 rts 12315 fdreg1: 12316 mov.l EXC_DREGS+0x4(%a6),% 12317 rts 12318 fdreg2: 12319 mov.l %d2,%d0 12320 rts 12321 fdreg3: 12322 mov.l %d3,%d0 12323 rts 12324 fdreg4: 12325 mov.l %d4,%d0 12326 rts 12327 fdreg5: 12328 mov.l %d5,%d0 12329 rts 12330 fdreg6: 12331 mov.l %d6,%d0 12332 rts 12333 fdreg7: 12334 mov.l %d7,%d0 12335 rts 12336 fdreg8: 12337 mov.l EXC_DREGS+0x8(%a6),% 12338 rts 12339 fdreg9: 12340 mov.l EXC_DREGS+0xc(%a6),% 12341 rts 12342 fdrega: 12343 mov.l %a2,%d0 12344 rts 12345 fdregb: 12346 mov.l %a3,%d0 12347 rts 12348 fdregc: 12349 mov.l %a4,%d0 12350 rts 12351 fdregd: 12352 mov.l %a5,%d0 12353 rts 12354 fdrege: 12355 mov.l (%a6),%d0 12356 rts 12357 fdregf: 12358 mov.l EXC_A7(%a6),%d0 12359 rts 12360 12361 ############################################ 12362 # XDEF ************************************* 12363 # store_dreg_l(): store longword to da 12364 # 12365 # XREF ************************************* 12366 # None 12367 # 12368 # INPUT ************************************ 12369 # d0 = longowrd value to store 12370 # d1 = index of register to fetch from 12371 # 12372 # OUTPUT *********************************** 12373 # (data register is updated) 12374 # 12375 # ALGORITHM ******************************** 12376 # According to the index value in d1, 12377 # in d0 to the corresponding data register. 12378 # while the rest are in their initial places 12379 # 12380 ############################################ 12381 12382 global store_dreg_l 12383 store_dreg_l: 12384 mov.w (tbl_sdregl.b,%pc,%d 12385 jmp (tbl_sdregl.b,%pc,%d 12386 12387 tbl_sdregl: 12388 short sdregl0 - tbl_sdregl 12389 short sdregl1 - tbl_sdregl 12390 short sdregl2 - tbl_sdregl 12391 short sdregl3 - tbl_sdregl 12392 short sdregl4 - tbl_sdregl 12393 short sdregl5 - tbl_sdregl 12394 short sdregl6 - tbl_sdregl 12395 short sdregl7 - tbl_sdregl 12396 12397 sdregl0: 12398 mov.l %d0,EXC_DREGS+0x0(%a 12399 rts 12400 sdregl1: 12401 mov.l %d0,EXC_DREGS+0x4(%a 12402 rts 12403 sdregl2: 12404 mov.l %d0,%d2 12405 rts 12406 sdregl3: 12407 mov.l %d0,%d3 12408 rts 12409 sdregl4: 12410 mov.l %d0,%d4 12411 rts 12412 sdregl5: 12413 mov.l %d0,%d5 12414 rts 12415 sdregl6: 12416 mov.l %d0,%d6 12417 rts 12418 sdregl7: 12419 mov.l %d0,%d7 12420 rts 12421 12422 ############################################ 12423 # XDEF ************************************* 12424 # store_dreg_w(): store word to data r 12425 # 12426 # XREF ************************************* 12427 # None 12428 # 12429 # INPUT ************************************ 12430 # d0 = word value to store 12431 # d1 = index of register to fetch from 12432 # 12433 # OUTPUT *********************************** 12434 # (data register is updated) 12435 # 12436 # ALGORITHM ******************************** 12437 # According to the index value in d1, 12438 # in d0 to the corresponding data register. 12439 # while the rest are in their initial places 12440 # 12441 ############################################ 12442 12443 global store_dreg_w 12444 store_dreg_w: 12445 mov.w (tbl_sdregw.b,%pc,%d 12446 jmp (tbl_sdregw.b,%pc,%d 12447 12448 tbl_sdregw: 12449 short sdregw0 - tbl_sdregw 12450 short sdregw1 - tbl_sdregw 12451 short sdregw2 - tbl_sdregw 12452 short sdregw3 - tbl_sdregw 12453 short sdregw4 - tbl_sdregw 12454 short sdregw5 - tbl_sdregw 12455 short sdregw6 - tbl_sdregw 12456 short sdregw7 - tbl_sdregw 12457 12458 sdregw0: 12459 mov.w %d0,2+EXC_DREGS+0x0( 12460 rts 12461 sdregw1: 12462 mov.w %d0,2+EXC_DREGS+0x4( 12463 rts 12464 sdregw2: 12465 mov.w %d0,%d2 12466 rts 12467 sdregw3: 12468 mov.w %d0,%d3 12469 rts 12470 sdregw4: 12471 mov.w %d0,%d4 12472 rts 12473 sdregw5: 12474 mov.w %d0,%d5 12475 rts 12476 sdregw6: 12477 mov.w %d0,%d6 12478 rts 12479 sdregw7: 12480 mov.w %d0,%d7 12481 rts 12482 12483 ############################################ 12484 # XDEF ************************************* 12485 # store_dreg_b(): store byte to data r 12486 # 12487 # XREF ************************************* 12488 # None 12489 # 12490 # INPUT ************************************ 12491 # d0 = byte value to store 12492 # d1 = index of register to fetch from 12493 # 12494 # OUTPUT *********************************** 12495 # (data register is updated) 12496 # 12497 # ALGORITHM ******************************** 12498 # According to the index value in d1, 12499 # in d0 to the corresponding data register. 12500 # while the rest are in their initial places 12501 # 12502 ############################################ 12503 12504 global store_dreg_b 12505 store_dreg_b: 12506 mov.w (tbl_sdregb.b,%pc,%d 12507 jmp (tbl_sdregb.b,%pc,%d 12508 12509 tbl_sdregb: 12510 short sdregb0 - tbl_sdregb 12511 short sdregb1 - tbl_sdregb 12512 short sdregb2 - tbl_sdregb 12513 short sdregb3 - tbl_sdregb 12514 short sdregb4 - tbl_sdregb 12515 short sdregb5 - tbl_sdregb 12516 short sdregb6 - tbl_sdregb 12517 short sdregb7 - tbl_sdregb 12518 12519 sdregb0: 12520 mov.b %d0,3+EXC_DREGS+0x0( 12521 rts 12522 sdregb1: 12523 mov.b %d0,3+EXC_DREGS+0x4( 12524 rts 12525 sdregb2: 12526 mov.b %d0,%d2 12527 rts 12528 sdregb3: 12529 mov.b %d0,%d3 12530 rts 12531 sdregb4: 12532 mov.b %d0,%d4 12533 rts 12534 sdregb5: 12535 mov.b %d0,%d5 12536 rts 12537 sdregb6: 12538 mov.b %d0,%d6 12539 rts 12540 sdregb7: 12541 mov.b %d0,%d7 12542 rts 12543 12544 ############################################ 12545 # XDEF ************************************* 12546 # inc_areg(): increment an address reg 12547 # 12548 # XREF ************************************* 12549 # None 12550 # 12551 # INPUT ************************************ 12552 # d0 = amount to increment by 12553 # d1 = index of address register to in 12554 # 12555 # OUTPUT *********************************** 12556 # (address register is updated) 12557 # 12558 # ALGORITHM ******************************** 12559 # Typically used for an instruction w/ 12560 # this routine adds the increment value in d 12561 # specified by d1. A0/A1/A6/A7 reside on the 12562 # in their original places. 12563 # For a7, if the increment amount is o 12564 # increment by two. For any a7 update, set t 12565 # an access error exception occurs later in 12566 # register update can be undone. 12567 # 12568 ############################################ 12569 12570 global inc_areg 12571 inc_areg: 12572 mov.w (tbl_iareg.b,%pc,%d1 12573 jmp (tbl_iareg.b,%pc,%d1 12574 12575 tbl_iareg: 12576 short iareg0 - tbl_iareg 12577 short iareg1 - tbl_iareg 12578 short iareg2 - tbl_iareg 12579 short iareg3 - tbl_iareg 12580 short iareg4 - tbl_iareg 12581 short iareg5 - tbl_iareg 12582 short iareg6 - tbl_iareg 12583 short iareg7 - tbl_iareg 12584 12585 iareg0: add.l %d0,EXC_DREGS+0x8(%a 12586 rts 12587 iareg1: add.l %d0,EXC_DREGS+0xc(%a 12588 rts 12589 iareg2: add.l %d0,%a2 12590 rts 12591 iareg3: add.l %d0,%a3 12592 rts 12593 iareg4: add.l %d0,%a4 12594 rts 12595 iareg5: add.l %d0,%a5 12596 rts 12597 iareg6: add.l %d0,(%a6) 12598 rts 12599 iareg7: mov.b &mia7_flg,SPCOND_FLG 12600 cmpi.b %d0,&0x1 12601 beq.b iareg7b 12602 add.l %d0,EXC_A7(%a6) 12603 rts 12604 iareg7b: 12605 addq.l &0x2,EXC_A7(%a6) 12606 rts 12607 12608 ############################################ 12609 # XDEF ************************************* 12610 # dec_areg(): decrement an address reg 12611 # 12612 # XREF ************************************* 12613 # None 12614 # 12615 # INPUT ************************************ 12616 # d0 = amount to decrement by 12617 # d1 = index of address register to de 12618 # 12619 # OUTPUT *********************************** 12620 # (address register is updated) 12621 # 12622 # ALGORITHM ******************************** 12623 # Typically used for an instruction w/ 12624 # this routine adds the decrement value in d 12625 # specified by d1. A0/A1/A6/A7 reside on the 12626 # in their original places. 12627 # For a7, if the decrement amount is o 12628 # decrement by two. For any a7 update, set t 12629 # an access error exception occurs later in 12630 # register update can be undone. 12631 # 12632 ############################################ 12633 12634 global dec_areg 12635 dec_areg: 12636 mov.w (tbl_dareg.b,%pc,%d1 12637 jmp (tbl_dareg.b,%pc,%d1 12638 12639 tbl_dareg: 12640 short dareg0 - tbl_dareg 12641 short dareg1 - tbl_dareg 12642 short dareg2 - tbl_dareg 12643 short dareg3 - tbl_dareg 12644 short dareg4 - tbl_dareg 12645 short dareg5 - tbl_dareg 12646 short dareg6 - tbl_dareg 12647 short dareg7 - tbl_dareg 12648 12649 dareg0: sub.l %d0,EXC_DREGS+0x8(%a 12650 rts 12651 dareg1: sub.l %d0,EXC_DREGS+0xc(%a 12652 rts 12653 dareg2: sub.l %d0,%a2 12654 rts 12655 dareg3: sub.l %d0,%a3 12656 rts 12657 dareg4: sub.l %d0,%a4 12658 rts 12659 dareg5: sub.l %d0,%a5 12660 rts 12661 dareg6: sub.l %d0,(%a6) 12662 rts 12663 dareg7: mov.b &mda7_flg,SPCOND_FLG 12664 cmpi.b %d0,&0x1 12665 beq.b dareg7b 12666 sub.l %d0,EXC_A7(%a6) 12667 rts 12668 dareg7b: 12669 subq.l &0x2,EXC_A7(%a6) 12670 rts 12671 12672 ############################################ 12673 12674 ############################################ 12675 # XDEF ************************************* 12676 # load_fpn1(): load FP register value 12677 # 12678 # XREF ************************************* 12679 # None 12680 # 12681 # INPUT ************************************ 12682 # d0 = index of FP register to load 12683 # 12684 # OUTPUT *********************************** 12685 # FP_SRC(a6) = value loaded from FP re 12686 # 12687 # ALGORITHM ******************************** 12688 # Using the index in d0, load FP_SRC(a 12689 # FP register file. 12690 # 12691 ############################################ 12692 12693 global load_fpn1 12694 load_fpn1: 12695 mov.w (tbl_load_fpn1.b,%pc 12696 jmp (tbl_load_fpn1.b,%pc 12697 12698 tbl_load_fpn1: 12699 short load_fpn1_0 - tbl_lo 12700 short load_fpn1_1 - tbl_lo 12701 short load_fpn1_2 - tbl_lo 12702 short load_fpn1_3 - tbl_lo 12703 short load_fpn1_4 - tbl_lo 12704 short load_fpn1_5 - tbl_lo 12705 short load_fpn1_6 - tbl_lo 12706 short load_fpn1_7 - tbl_lo 12707 12708 load_fpn1_0: 12709 mov.l 0+EXC_FP0(%a6), 0+FP 12710 mov.l 4+EXC_FP0(%a6), 4+FP 12711 mov.l 8+EXC_FP0(%a6), 8+FP 12712 lea FP_SRC(%a6), %a0 12713 rts 12714 load_fpn1_1: 12715 mov.l 0+EXC_FP1(%a6), 0+FP 12716 mov.l 4+EXC_FP1(%a6), 4+FP 12717 mov.l 8+EXC_FP1(%a6), 8+FP 12718 lea FP_SRC(%a6), %a0 12719 rts 12720 load_fpn1_2: 12721 fmovm.x &0x20, FP_SRC(%a6) 12722 lea FP_SRC(%a6), %a0 12723 rts 12724 load_fpn1_3: 12725 fmovm.x &0x10, FP_SRC(%a6) 12726 lea FP_SRC(%a6), %a0 12727 rts 12728 load_fpn1_4: 12729 fmovm.x &0x08, FP_SRC(%a6) 12730 lea FP_SRC(%a6), %a0 12731 rts 12732 load_fpn1_5: 12733 fmovm.x &0x04, FP_SRC(%a6) 12734 lea FP_SRC(%a6), %a0 12735 rts 12736 load_fpn1_6: 12737 fmovm.x &0x02, FP_SRC(%a6) 12738 lea FP_SRC(%a6), %a0 12739 rts 12740 load_fpn1_7: 12741 fmovm.x &0x01, FP_SRC(%a6) 12742 lea FP_SRC(%a6), %a0 12743 rts 12744 12745 ############################################ 12746 12747 ############################################ 12748 # XDEF ************************************* 12749 # load_fpn2(): load FP register value 12750 # 12751 # XREF ************************************* 12752 # None 12753 # 12754 # INPUT ************************************ 12755 # d0 = index of FP register to load 12756 # 12757 # OUTPUT *********************************** 12758 # FP_DST(a6) = value loaded from FP re 12759 # 12760 # ALGORITHM ******************************** 12761 # Using the index in d0, load FP_DST(a 12762 # FP register file. 12763 # 12764 ############################################ 12765 12766 global load_fpn2 12767 load_fpn2: 12768 mov.w (tbl_load_fpn2.b,%pc 12769 jmp (tbl_load_fpn2.b,%pc 12770 12771 tbl_load_fpn2: 12772 short load_fpn2_0 - tbl_lo 12773 short load_fpn2_1 - tbl_lo 12774 short load_fpn2_2 - tbl_lo 12775 short load_fpn2_3 - tbl_lo 12776 short load_fpn2_4 - tbl_lo 12777 short load_fpn2_5 - tbl_lo 12778 short load_fpn2_6 - tbl_lo 12779 short load_fpn2_7 - tbl_lo 12780 12781 load_fpn2_0: 12782 mov.l 0+EXC_FP0(%a6), 0+FP 12783 mov.l 4+EXC_FP0(%a6), 4+FP 12784 mov.l 8+EXC_FP0(%a6), 8+FP 12785 lea FP_DST(%a6), %a0 12786 rts 12787 load_fpn2_1: 12788 mov.l 0+EXC_FP1(%a6), 0+FP 12789 mov.l 4+EXC_FP1(%a6), 4+FP 12790 mov.l 8+EXC_FP1(%a6), 8+FP 12791 lea FP_DST(%a6), %a0 12792 rts 12793 load_fpn2_2: 12794 fmovm.x &0x20, FP_DST(%a6) 12795 lea FP_DST(%a6), %a0 12796 rts 12797 load_fpn2_3: 12798 fmovm.x &0x10, FP_DST(%a6) 12799 lea FP_DST(%a6), %a0 12800 rts 12801 load_fpn2_4: 12802 fmovm.x &0x08, FP_DST(%a6) 12803 lea FP_DST(%a6), %a0 12804 rts 12805 load_fpn2_5: 12806 fmovm.x &0x04, FP_DST(%a6) 12807 lea FP_DST(%a6), %a0 12808 rts 12809 load_fpn2_6: 12810 fmovm.x &0x02, FP_DST(%a6) 12811 lea FP_DST(%a6), %a0 12812 rts 12813 load_fpn2_7: 12814 fmovm.x &0x01, FP_DST(%a6) 12815 lea FP_DST(%a6), %a0 12816 rts 12817 12818 ############################################ 12819 12820 ############################################ 12821 # XDEF ************************************* 12822 # store_fpreg(): store an fp value to 12823 # 12824 # XREF ************************************* 12825 # None 12826 # 12827 # INPUT ************************************ 12828 # fp0 = extended precision value to st 12829 # d0 = index of floating-point regist 12830 # 12831 # OUTPUT *********************************** 12832 # None 12833 # 12834 # ALGORITHM ******************************** 12835 # Store the value in fp0 to the FP reg 12836 # value in d0. The FP number can be DENORM o 12837 # careful that we don't take an exception he 12838 # 12839 ############################################ 12840 12841 global store_fpreg 12842 store_fpreg: 12843 mov.w (tbl_store_fpreg.b,% 12844 jmp (tbl_store_fpreg.b,% 12845 12846 tbl_store_fpreg: 12847 short store_fpreg_0 - tbl_ 12848 short store_fpreg_1 - tbl_ 12849 short store_fpreg_2 - tbl_ 12850 short store_fpreg_3 - tbl_ 12851 short store_fpreg_4 - tbl_ 12852 short store_fpreg_5 - tbl_ 12853 short store_fpreg_6 - tbl_ 12854 short store_fpreg_7 - tbl_ 12855 12856 store_fpreg_0: 12857 fmovm.x &0x80, EXC_FP0(%a6) 12858 rts 12859 store_fpreg_1: 12860 fmovm.x &0x80, EXC_FP1(%a6) 12861 rts 12862 store_fpreg_2: 12863 fmovm.x &0x01, -(%sp) 12864 fmovm.x (%sp)+, &0x20 12865 rts 12866 store_fpreg_3: 12867 fmovm.x &0x01, -(%sp) 12868 fmovm.x (%sp)+, &0x10 12869 rts 12870 store_fpreg_4: 12871 fmovm.x &0x01, -(%sp) 12872 fmovm.x (%sp)+, &0x08 12873 rts 12874 store_fpreg_5: 12875 fmovm.x &0x01, -(%sp) 12876 fmovm.x (%sp)+, &0x04 12877 rts 12878 store_fpreg_6: 12879 fmovm.x &0x01, -(%sp) 12880 fmovm.x (%sp)+, &0x02 12881 rts 12882 store_fpreg_7: 12883 fmovm.x &0x01, -(%sp) 12884 fmovm.x (%sp)+, &0x01 12885 rts 12886 12887 ############################################ 12888 # XDEF ************************************* 12889 # get_packed(): fetch a packed operand 12890 # convert it to a floati 12891 # 12892 # XREF ************************************* 12893 # _dcalc_ea() - calculate the correct 12894 # _mem_read() - fetch the packed opera 12895 # facc_in_x() - the fetch failed so ju 12896 # decbin() - convert packed to bina 12897 # 12898 # INPUT ************************************ 12899 # None 12900 # 12901 # OUTPUT *********************************** 12902 # If no failure on _mem_read(): 12903 # FP_SRC(a6) = packed operand now as a 12904 # 12905 # ALGORITHM ******************************** 12906 # Get the correct <ea> which is the va 12907 # frame w/ maybe a correction factor if the 12908 # Then, fetch the operand from memory. If th 12909 # through facc_in_x(). 12910 # If the packed operand is a ZERO,NAN, 12911 # its binary representation here. Else, call 12912 # convert the packed value to an extended pr 12913 # 12914 ############################################ 12915 12916 # the stacked <ea> for packed is correct exc 12917 # the base reg must be updated for both -(An 12918 global get_packed 12919 get_packed: 12920 mov.l &0xc,%d0 12921 bsr.l _dcalc_ea 12922 12923 lea FP_SRC(%a6),%a1 12924 mov.l &0xc,%d0 12925 bsr.l _dmem_read 12926 12927 tst.l %d1 12928 bne.l facc_in_x 12929 12930 # The packed operand is an INF or a NAN if t 12931 bfextu FP_SRC(%a6){&1:&15}, 12932 cmpi.w %d0,&0x7fff 12933 bne.b gp_try_zero 12934 rts 12935 12936 # The packed operand is a zero if the mantis 12937 # a normal packed op. 12938 gp_try_zero: 12939 mov.b 3+FP_SRC(%a6),%d0 12940 andi.b &0x0f,%d0 12941 bne.b gp_not_spec 12942 tst.l FP_SRC_HI(%a6) 12943 bne.b gp_not_spec 12944 tst.l FP_SRC_LO(%a6) 12945 bne.b gp_not_spec 12946 rts 12947 gp_not_spec: 12948 lea FP_SRC(%a6),%a0 12949 bsr.l decbin 12950 fmovm.x &0x80,FP_SRC(%a6) 12951 rts 12952 12953 ############################################ 12954 # decbin(): Converts normalized packed bcd v 12955 # a0 to extended-precision value i 12956 # 12957 # INPUT ************************************ 12958 # a0 = pointer to normalized packed bc 12959 # 12960 # OUTPUT *********************************** 12961 # fp0 = exact fp representation of the 12962 # 12963 # ALGORITHM ******************************** 12964 # Expected is a normal bcd (i.e. non-e 12965 # and NaN operands are dispatched with 12966 # value in 68881/882 format at locatio 12967 # 12968 # A1. Convert the bcd exponent to bina 12969 # muls. Set the sign according to SE. 12970 # for the mantissa which is to be inte 12971 # digits, rather than 1 integer and 16 12972 # Note: this operation can never overf 12973 # 12974 # A2. Convert the bcd mantissa to bina 12975 # adds and muls in FP0. Set the sign a 12976 # The mantissa digits will be converte 12977 # assumed following the least-signific 12978 # Note: this operation can never overf 12979 # 12980 # A3. Count the number of leading/trai 12981 # bcd string. If SE is positive, coun 12982 # if negative, count the trailing zero 12983 # exponent equal to the exponent from 12984 # added if SM = 1 and subtracted if SM 12985 # mantissa the equivalent of forcing i 12986 # 12987 # SM = 0 a non-zero digit in the inte 12988 # SM = 1 a non-zero digit in Mant0, l 12989 # 12990 # this will insure that any value, reg 12991 # representation (ex. 0.1E2, 1E1, 10E0 12992 # consistently. 12993 # 12994 # A4. Calculate the factor 10^exp in F 12995 # 10^(2^n) values. To reduce the erro 12996 # greater than 10^27, a directed round 12997 # tables rounded to RN, RM, and RP, ac 12998 # in the comments of the pwrten sectio 12999 # 13000 # A5. Form the final binary number by 13001 # the exponent factor. This is done b 13002 # mantissa in FP0 by the factor in FP1 13003 # exponent sign is positive, and divid 13004 # it is negative. 13005 # 13006 # Clean up and return. Check if the fi 13007 # If so, set INEX1 in USER_FPSR. 13008 # 13009 ############################################ 13010 13011 # 13012 # PTENRN, PTENRM, and PTENRP are array 13013 # to nearest, minus, and plus, respect 13014 # 10**{1,2,4,8,16,32,64,128,256,512,10 13015 # is required until the power is great 13016 # tables include the first 5 for ease 13017 # 13018 RTABLE: 13019 byte 0,0,0,0 13020 byte 2,3,2,3 13021 byte 2,3,3,2 13022 byte 3,2,2,3 13023 13024 set FNIBS,7 13025 set FSTRT,0 13026 13027 set ESTRT,4 13028 set EDIGITS,2 13029 13030 global decbin 13031 decbin: 13032 mov.l 0x0(%a0),FP_SCR0_EX( 13033 mov.l 0x4(%a0),FP_SCR0_HI( 13034 mov.l 0x8(%a0),FP_SCR0_LO( 13035 13036 lea FP_SCR0(%a6),%a0 13037 13038 movm.l &0x3c00,-(%sp) 13039 fmovm.x &0x1,-(%sp) 13040 # 13041 # Calculate exponent: 13042 # 1. Copy bcd value in memory for use as a 13043 # 2. Calculate absolute value of exponent i 13044 # 3. Correct for exponent sign. 13045 # 4. Subtract 16 to compensate for interpre 13046 # (i.e., all digits assumed left of the 13047 # 13048 # Register usage: 13049 # 13050 # calc_e: 13051 # (*) d0: temp digit storage 13052 # (*) d1: accumulator for binary expo 13053 # (*) d2: digit count 13054 # (*) d3: offset pointer 13055 # ( ) d4: first word of bcd 13056 # ( ) a0: pointer to working bcd valu 13057 # ( ) a6: pointer to original bcd val 13058 # (*) FP_SCR1: working copy of origin 13059 # (*) L_SCR1: copy of original expone 13060 # 13061 calc_e: 13062 mov.l &EDIGITS,%d2 13063 mov.l &ESTRT,%d3 13064 mov.l (%a0),%d4 13065 clr.l %d1 13066 e_gd: 13067 mulu.l &0xa,%d1 13068 bfextu %d4{%d3:&4},%d0 13069 add.l %d0,%d1 13070 addq.b &4,%d3 13071 dbf.w %d2,e_gd 13072 btst &30,%d4 13073 beq.b e_pos 13074 neg.l %d1 13075 e_pos: 13076 sub.l &16,%d1 13077 bge.b e_save 13078 neg.l %d1 13079 or.l &0x40000000,%d4 13080 or.l &0x40000000,(%a0) 13081 e_save: 13082 mov.l %d1,-(%sp) 13083 # 13084 # 13085 # Calculate mantissa: 13086 # 1. Calculate absolute value of mantissa i 13087 # 2. Correct for mantissa sign. 13088 # (i.e., all digits assumed left of the 13089 # 13090 # Register usage: 13091 # 13092 # calc_m: 13093 # (*) d0: temp digit storage 13094 # (*) d1: lword counter 13095 # (*) d2: digit count 13096 # (*) d3: offset pointer 13097 # ( ) d4: words 2 and 3 of bcd 13098 # ( ) a0: pointer to working bcd valu 13099 # ( ) a6: pointer to original bcd val 13100 # (*) fp0: mantissa accumulator 13101 # ( ) FP_SCR1: working copy of origin 13102 # ( ) L_SCR1: copy of original expone 13103 # 13104 calc_m: 13105 mov.l &1,%d1 13106 fmov.s &0x00000000,%fp0 13107 # 13108 # 13109 # Since the packed number has a long word b 13110 # get the integer digit then skip down & ge 13111 # mantissa. We will unroll the loop once. 13112 # 13113 bfextu (%a0){&28:&4},%d0 13114 fadd.b %d0,%fp0 13115 # 13116 # 13117 # Get the rest of the mantissa. 13118 # 13119 loadlw: 13120 mov.l (%a0,%d1.L*4),%d4 13121 mov.l &FSTRT,%d3 13122 mov.l &FNIBS,%d2 13123 md2b: 13124 fmul.s &0x41200000,%fp0 13125 bfextu %d4{%d3:&4},%d0 13126 fadd.b %d0,%fp0 13127 # 13128 # 13129 # If all the digits (8) in that long word h 13130 # then inc d1 (=2) to point to the next lon 13131 # to initialize the digit offset, and set d 13132 # else continue with this long word. 13133 # 13134 addq.b &4,%d3 13135 dbf.w %d2,md2b 13136 nextlw: 13137 addq.l &1,%d1 13138 cmp.l %d1,&2 13139 ble.b loadlw 13140 # 13141 # Check the sign of the mant and make the v 13142 # 13143 m_sign: 13144 btst &31,(%a0) 13145 beq.b ap_st_z 13146 fneg.x %fp0 13147 # 13148 # Append/strip zeros: 13149 # 13150 # For adjusted exponents which have an abso 13151 # this routine calculates the amount needed 13152 # for the adjusted exponent. That number i 13153 # if the exp was positive, and added if it 13154 # of this is to reduce the value of the exp 13155 # of error in calculation of pwrten. 13156 # 13157 # 1. Branch on the sign of the adjusted exp 13158 # 2p.(positive exp) 13159 # 2. Check M16 and the digits in lwords 2 13160 # 3. Add one for each zero encountered unt 13161 # 4. Subtract the count from the exp. 13162 # 5. Check if the exp has crossed zero in 13163 # and set SE. 13164 # 6. Multiply the mantissa by 10**coun 13165 # 2n.(negative exp) 13166 # 2. Check the digits in lwords 3 and 2 in 13167 # 3. Add one for each zero encountered unt 13168 # 4. Add the count to the exp. 13169 # 5. Check if the exp has crossed zero in 13170 # 6. Divide the mantissa by 10**count. 13171 # 13172 # *Why 27? If the adjusted exponent is wit 13173 # any adjustment due to append/strip zeros 13174 # exponent towards zero. Since all pwrten 13175 # of 27 or less are exact, there is no nee 13176 # attempt to lessen the resultant exponent 13177 # 13178 # Register usage: 13179 # 13180 # ap_st_z: 13181 # (*) d0: temp digit storage 13182 # (*) d1: zero count 13183 # (*) d2: digit count 13184 # (*) d3: offset pointer 13185 # ( ) d4: first word of bcd 13186 # (*) d5: lword counter 13187 # ( ) a0: pointer to working bcd valu 13188 # ( ) FP_SCR1: working copy of origin 13189 # ( ) L_SCR1: copy of original expone 13190 # 13191 # 13192 # First check the absolute value of the expo 13193 # routine is necessary. If so, then check t 13194 # and do append (+) or strip (-) zeros accor 13195 # This section handles a positive adjusted e 13196 # 13197 ap_st_z: 13198 mov.l (%sp),%d1 13199 cmp.l %d1,&27 13200 ble.w pwrten 13201 btst &30,(%a0) 13202 bne.b ap_st_n 13203 clr.l %d1 13204 mov.l (%a0),%d4 13205 bfextu %d4{&28:&4},%d0 13206 bne.b ap_p_fx 13207 addq.l &1,%d1 13208 mov.l &1,%d5 13209 mov.l (%a0,%d5.L*4),%d4 13210 bne.b ap_p_cl 13211 addq.l &8,%d1 13212 addq.l &1,%d5 13213 mov.l (%a0,%d5.L*4),%d4 13214 ap_p_cl: 13215 clr.l %d3 13216 mov.l &7,%d2 13217 ap_p_gd: 13218 bfextu %d4{%d3:&4},%d0 13219 bne.b ap_p_fx 13220 addq.l &4,%d3 13221 addq.l &1,%d1 13222 dbf.w %d2,ap_p_gd 13223 ap_p_fx: 13224 mov.l %d1,%d0 13225 mov.l (%sp),%d1 13226 sub.l %d0,%d1 13227 bge.b ap_p_fm 13228 neg.l %d1 13229 mov.l (%a0),%d4 13230 or.l &0x40000000,%d4 13231 or.l &0x40000000,(%a0) 13232 # 13233 # Calculate the mantissa multiplier to compe 13234 # zeros from the mantissa. 13235 # 13236 ap_p_fm: 13237 lea.l PTENRN(%pc),%a1 13238 clr.l %d3 13239 fmov.s &0x3f800000,%fp1 13240 mov.l &3,%d2 13241 ap_p_el: 13242 asr.l &1,%d0 13243 bcc.b ap_p_en 13244 fmul.x (%a1,%d3),%fp1 13245 ap_p_en: 13246 add.l &12,%d3 13247 tst.l %d0 13248 bne.b ap_p_el 13249 fmul.x %fp1,%fp0 13250 bra.b pwrten 13251 # 13252 # This section handles a negative adjusted e 13253 # 13254 ap_st_n: 13255 clr.l %d1 13256 mov.l &2,%d5 13257 mov.l (%a0,%d5.L*4),%d4 13258 bne.b ap_n_cl 13259 sub.l &1,%d5 13260 addq.l &8,%d1 13261 mov.l (%a0,%d5.L*4),%d4 13262 ap_n_cl: 13263 mov.l &28,%d3 13264 mov.l &7,%d2 13265 ap_n_gd: 13266 bfextu %d4{%d3:&4},%d0 13267 bne.b ap_n_fx 13268 subq.l &4,%d3 13269 addq.l &1,%d1 13270 dbf.w %d2,ap_n_gd 13271 ap_n_fx: 13272 mov.l %d1,%d0 13273 mov.l (%sp),%d1 13274 sub.l %d0,%d1 13275 bgt.b ap_n_fm 13276 neg.l %d1 13277 mov.l (%a0),%d4 13278 and.l &0xbfffffff,%d4 13279 and.l &0xbfffffff,(%a0) 13280 # 13281 # Calculate the mantissa multiplier to compe 13282 # zeros to the mantissa. 13283 # 13284 ap_n_fm: 13285 lea.l PTENRN(%pc),%a1 13286 clr.l %d3 13287 fmov.s &0x3f800000,%fp1 13288 mov.l &3,%d2 13289 ap_n_el: 13290 asr.l &1,%d0 13291 bcc.b ap_n_en 13292 fmul.x (%a1,%d3),%fp1 13293 ap_n_en: 13294 add.l &12,%d3 13295 tst.l %d0 13296 bne.b ap_n_el 13297 fdiv.x %fp1,%fp0 13298 # 13299 # 13300 # Calculate power-of-ten factor from adjuste 13301 # 13302 # Register usage: 13303 # 13304 # pwrten: 13305 # (*) d0: temp 13306 # ( ) d1: exponent 13307 # (*) d2: {FPCR[6:5],SM,SE} as index 13308 # (*) d3: FPCR work copy 13309 # ( ) d4: first word of bcd 13310 # (*) a1: RTABLE pointer 13311 # calc_p: 13312 # (*) d0: temp 13313 # ( ) d1: exponent 13314 # (*) d3: PWRTxx table index 13315 # ( ) a0: pointer to working copy of 13316 # (*) a1: PWRTxx pointer 13317 # (*) fp1: power-of-ten accumulator 13318 # 13319 # Pwrten calculates the exponent factor in t 13320 # according to the following table: 13321 # 13322 # Sign of Mant Sign of Exp Rounding 13323 # 13324 # ANY ANY RN RN 13325 # 13326 # + + RP RP 13327 # - + RP RM 13328 # + - RP RM 13329 # - - RP RP 13330 # 13331 # + + RM RM 13332 # - + RM RP 13333 # + - RM RP 13334 # - - RM RM 13335 # 13336 # + + RZ RM 13337 # - + RZ RM 13338 # + - RZ RP 13339 # - - RZ RP 13340 # 13341 # 13342 pwrten: 13343 mov.l USER_FPCR(%a6),%d3 13344 bfextu %d3{&26:&2},%d2 13345 mov.l (%a0),%d4 13346 asl.l &2,%d2 13347 bfextu %d4{&0:&2},%d0 13348 add.l %d0,%d2 13349 lea.l RTABLE(%pc),%a1 13350 mov.b (%a1,%d2),%d0 13351 clr.l %d3 13352 bfins %d0,%d3{&26:&2} 13353 fmov.l %d3,%fpcr 13354 asr.l &1,%d0 13355 bcc.b not_rp 13356 lea.l PTENRP(%pc),%a1 13357 bra.b calc_p 13358 not_rp: 13359 asr.l &1,%d0 13360 bcc.b not_rm 13361 lea.l PTENRM(%pc),%a1 13362 bra.b calc_p 13363 not_rm: 13364 lea.l PTENRN(%pc),%a1 13365 calc_p: 13366 mov.l %d1,%d0 13367 bpl.b no_neg 13368 neg.l %d0 13369 or.l &0x40000000,(%a0) 13370 no_neg: 13371 clr.l %d3 13372 fmov.s &0x3f800000,%fp1 13373 e_loop: 13374 asr.l &1,%d0 13375 bcc.b e_next 13376 fmul.x (%a1,%d3),%fp1 13377 e_next: 13378 add.l &12,%d3 13379 tst.l %d0 13380 bne.b e_loop 13381 # 13382 # 13383 # Check the sign of the adjusted exp and ma 13384 # same sign. If the exp was pos then multip 13385 # else divide fp0/fp1. 13386 # 13387 # Register Usage: 13388 # norm: 13389 # ( ) a0: pointer to working bcd valu 13390 # (*) fp0: mantissa accumulator 13391 # ( ) fp1: scaling factor - 10**(abs(e 13392 # 13393 pnorm: 13394 btst &30,(%a0) 13395 beq.b mul 13396 div: 13397 fdiv.x %fp1,%fp0 13398 bra.b end_dec 13399 mul: 13400 fmul.x %fp1,%fp0 13401 # 13402 # 13403 # Clean up and return with result in fp0. 13404 # 13405 # If the final mul/div in decbin incurred an 13406 # it will be inex2, but will be reported as 13407 # 13408 end_dec: 13409 fmov.l %fpsr,%d0 13410 bclr &inex2_bit+8,%d0 13411 beq.b no_exc 13412 ori.w &inx1a_mask,2+USER_F 13413 no_exc: 13414 add.l &0x4,%sp 13415 fmovm.x (%sp)+,&0x40 13416 movm.l (%sp)+,&0x3c 13417 fmov.l &0x0,%fpcr 13418 fmov.l &0x0,%fpsr 13419 rts 13420 13421 ############################################ 13422 # bindec(): Converts an input in extended pr 13423 # 13424 # INPUT ************************************ 13425 # a0 = pointer to the input extended p 13426 # the input may be either normali 13427 # denormalized. 13428 # d0 = contains the k-factor sign-exte 13429 # 13430 # OUTPUT *********************************** 13431 # FP_SCR0(a6) = bcd format result on t 13432 # 13433 # ALGORITHM ******************************** 13434 # 13435 # A1. Set RM and size ext; Set SI 13436 # The k-factor is saved for us 13437 # BINDEC_FLG for separating no 13438 # input. If input is unnormal 13439 # normalize it. 13440 # 13441 # A2. Set X = abs(input). 13442 # 13443 # A3. Compute ILOG. 13444 # ILOG is the log base 10 of t 13445 # approximated by adding e + 0 13446 # value is viewed as 2^^e * 1. 13447 # This value is stored in d6. 13448 # 13449 # A4. Clr INEX bit. 13450 # The operation in A3 above ma 13451 # 13452 # A5. Set ICTR = 0; 13453 # ICTR is a flag used in A13. 13454 # loop entry A6. 13455 # 13456 # A6. Calculate LEN. 13457 # LEN is the number of digits 13458 # k-factor can dictate either 13459 # if it is a positive number, 13460 # after the decimal point whic 13461 # significant. See the 68882 13462 # If LEN is computed to be gre 13463 # USER_FPSR. LEN is stored in 13464 # 13465 # A7. Calculate SCALE. 13466 # SCALE is equal to 10^ISCALE, 13467 # of decimal places needed to 13468 # in the output before convers 13469 # sign of ISCALE, used in A9. 13470 # 10^^(abs(ISCALE)) using a ro 13471 # function of the original rou 13472 # of ISCALE and X. A table is 13473 # 13474 # A8. Clr INEX; Force RZ. 13475 # The operation in A3 above ma 13476 # RZ mode is forced for the sc 13477 # only one rounding error. Th 13478 # the INEX flag for use in A10 13479 # 13480 # A9. Scale X -> Y. 13481 # The mantissa is scaled to th 13482 # significant digits. The exc 13483 # in INEX2. 13484 # 13485 # A10. Or in INEX. 13486 # If INEX is set, round error 13487 # compensated for by 'or-ing' 13488 # the lsb of Y. 13489 # 13490 # A11. Restore original FPCR; set s 13491 # Perform FINT operation in th 13492 # Keep the size to extended. 13493 # 13494 # A12. Calculate YINT = FINT(Y) acc 13495 # mode. The FPSP routine sint 13496 # is in fp0. 13497 # 13498 # A13. Check for LEN digits. 13499 # If the int operation results 13500 # or less than LEN -1 digits, 13501 # A6. This test occurs only o 13502 # result is exactly 10^LEN, de 13503 # the mantissa by 10. 13504 # 13505 # A14. Convert the mantissa to bcd. 13506 # The binstr routine is used t 13507 # mantissa to bcd in memory. 13508 # to be a fraction; i.e. (mant 13509 # such that the decimal point 13510 # The bcd digits are stored in 13511 # the final string area in mem 13512 # 13513 # A15. Convert the exponent to bcd. 13514 # As in A14 above, the exp is 13515 # digits are stored in the fin 13516 # Test the length of the final 13517 # length is 4, set operr. 13518 # 13519 # A16. Write sign bits to final str 13520 # 13521 ############################################ 13522 13523 set BINDEC_FLG, EXC_TEMP # DE 13524 13525 # Constants in extended precision 13526 PLOG2: 13527 long 0x3FFD0000,0x9A209A8 13528 PLOG2UP1: 13529 long 0x3FFD0000,0x9A209A8 13530 13531 # Constants in single precision 13532 FONE: 13533 long 0x3F800000,0x0000000 13534 FTWO: 13535 long 0x40000000,0x0000000 13536 FTEN: 13537 long 0x41200000,0x0000000 13538 F4933: 13539 long 0x459A2800,0x0000000 13540 13541 RBDTBL: 13542 byte 0,0,0,0 13543 byte 3,3,2,2 13544 byte 3,2,2,3 13545 byte 2,3,3,2 13546 13547 # Implementation Notes: 13548 # 13549 # The registers are used as follows: 13550 # 13551 # d0: scratch; LEN input to bi 13552 # d1: scratch 13553 # d2: upper 32-bits of mantiss 13554 # d3: scratch;lower 32-bits of 13555 # d4: LEN 13556 # d5: LAMBDA/ICTR 13557 # d6: ILOG 13558 # d7: k-factor 13559 # a0: ptr for original operand 13560 # a1: scratch pointer 13561 # a2: pointer to FP_X; abs(ori 13562 # fp0: scratch 13563 # fp1: scratch 13564 # fp2: scratch 13565 # F_SCR1: 13566 # F_SCR2: 13567 # L_SCR1: 13568 # L_SCR2: 13569 13570 global bindec 13571 bindec: 13572 movm.l &0x3f20,-(%sp) # { 13573 fmovm.x &0x7,-(%sp) # { 13574 13575 # A1. Set RM and size ext. Set SIGMA = sign 13576 # The k-factor is saved for use in d7. 13577 # separating normalized/denormalized in 13578 # is a denormalized number, set the BIND 13579 # to signal denorm. If the input is unn 13580 # the input and test for denormalized re 13581 # 13582 fmov.l &rm_mode*0x10,%fpcr 13583 mov.l (%a0),L_SCR2(%a6) 13584 mov.l %d0,%d7 # mo 13585 13586 clr.b BINDEC_FLG(%a6) # cl 13587 cmpi.b STAG(%a6),&DENORM # 13588 bne.w A2_str # no 13589 13590 # 13591 # Normalize the denorm 13592 # 13593 un_de_norm: 13594 mov.w (%a0),%d0 13595 and.w &0x7fff,%d0 # st 13596 mov.l 4(%a0),%d1 13597 mov.l 8(%a0),%d2 13598 norm_loop: 13599 sub.w &1,%d0 13600 lsl.l &1,%d2 13601 roxl.l &1,%d1 13602 tst.l %d1 13603 bge.b norm_loop 13604 # 13605 # Test if the normalized input is denormaliz 13606 # 13607 tst.w %d0 13608 bgt.b pos_exp # if 13609 st BINDEC_FLG(%a6) # se 13610 pos_exp: 13611 and.w &0x7fff,%d0 # st 13612 mov.w %d0,(%a0) 13613 mov.l %d1,4(%a0) 13614 mov.l %d2,8(%a0) 13615 13616 # A2. Set X = abs(input). 13617 # 13618 A2_str: 13619 mov.l (%a0),FP_SCR1(%a6) 13620 mov.l 4(%a0),FP_SCR1+4(%a6 13621 mov.l 8(%a0),FP_SCR1+8(%a6 13622 and.l &0x7fffffff,FP_SCR1( 13623 13624 # A3. Compute ILOG. 13625 # ILOG is the log base 10 of the input v 13626 # imated by adding e + 0.f when the orig 13627 # as 2^^e * 1.f in extended precision. 13628 # in d6. 13629 # 13630 # Register usage: 13631 # Input/Output 13632 # d0: k-factor/exponent 13633 # d2: x/x 13634 # d3: x/x 13635 # d4: x/x 13636 # d5: x/x 13637 # d6: x/ILOG 13638 # d7: k-factor/Unchanged 13639 # a0: ptr for original operand/final r 13640 # a1: x/x 13641 # a2: x/x 13642 # fp0: x/float(ILOG) 13643 # fp1: x/x 13644 # fp2: x/x 13645 # F_SCR1:x/x 13646 # F_SCR2:Abs(X)/Abs(X) with $3fff expo 13647 # L_SCR1:x/x 13648 # L_SCR2:first word of X packed/Unchan 13649 13650 tst.b BINDEC_FLG(%a6) # ch 13651 beq.b A3_cont # if 13652 mov.l &-4933,%d6 # fo 13653 bra.b A4_str 13654 A3_cont: 13655 mov.w FP_SCR1(%a6),%d0 13656 mov.w &0x3fff,FP_SCR1(%a6) 13657 fmov.x FP_SCR1(%a6),%fp0 13658 sub.w &0x3fff,%d0 # st 13659 fadd.w %d0,%fp0 # ad 13660 fsub.s FONE(%pc),%fp0 # su 13661 fbge.w pos_res # if 13662 fmul.x PLOG2UP1(%pc),%fp0 13663 fmov.l %fp0,%d6 # pu 13664 bra.b A4_str # go 13665 pos_res: 13666 fmul.x PLOG2(%pc),%fp0 # if 13667 fmov.l %fp0,%d6 # pu 13668 13669 13670 # A4. Clr INEX bit. 13671 # The operation in A3 above may have set 13672 13673 A4_str: 13674 fmov.l &0,%fpsr # ze 13675 13676 13677 # A5. Set ICTR = 0; 13678 # ICTR is a flag used in A13. It must b 13679 # loop entry A6. The lower word of d5 is 13680 13681 clr.w %d5 # cl 13682 13683 # A6. Calculate LEN. 13684 # LEN is the number of digits to be disp 13685 # can dictate either the total number of 13686 # a positive number, or the number of di 13687 # original decimal point which are to be 13688 # significant. See the 68882 manual for 13689 # If LEN is computed to be greater than 13690 # USER_FPSR. LEN is stored in d4. 13691 # 13692 # Register usage: 13693 # Input/Output 13694 # d0: exponent/Unchanged 13695 # d2: x/x/scratch 13696 # d3: x/x 13697 # d4: exc picture/LEN 13698 # d5: ICTR/Unchanged 13699 # d6: ILOG/Unchanged 13700 # d7: k-factor/Unchanged 13701 # a0: ptr for original operand/final r 13702 # a1: x/x 13703 # a2: x/x 13704 # fp0: float(ILOG)/Unchanged 13705 # fp1: x/x 13706 # fp2: x/x 13707 # F_SCR1:x/x 13708 # F_SCR2:Abs(X) with $3fff exponent/Un 13709 # L_SCR1:x/x 13710 # L_SCR2:first word of X packed/Unchan 13711 13712 A6_str: 13713 tst.l %d7 # br 13714 ble.b k_neg # if 13715 mov.l %d7,%d4 # if 13716 bra.b len_ck # sk 13717 k_neg: 13718 mov.l %d6,%d4 # fi 13719 sub.l %d7,%d4 # su 13720 addq.l &1,%d4 # ad 13721 len_ck: 13722 tst.l %d4 # LE 13723 ble.b LEN_ng # if 13724 cmp.l %d4,&17 # te 13725 ble.b A7_str # if 13726 mov.l &17,%d4 # se 13727 tst.l %d7 # if 13728 ble.b A7_str # if 13729 or.l &opaop_mask,USER_FPS 13730 bra.b A7_str # fi 13731 LEN_ng: 13732 mov.l &1,%d4 # mi 13733 13734 13735 # A7. Calculate SCALE. 13736 # SCALE is equal to 10^ISCALE, where ISC 13737 # of decimal places needed to insure LEN 13738 # in the output before conversion to bcd 13739 # of ISCALE, used in A9. Fp1 contains 1 13740 # the rounding mode as given in the foll 13741 # Coonen, p. 7.23 as ref.; however, the 13742 # of opposite sign in bindec.sa from Coo 13743 # 13744 # Initial 13745 # FPCR[6:5] LAMBDA SIGN(X) 13746 # ------------------------------------ 13747 # RN 00 0 0 13748 # RN 00 0 1 13749 # RN 00 1 0 13750 # RN 00 1 1 13751 # RZ 01 0 0 13752 # RZ 01 0 1 13753 # RZ 01 1 0 13754 # RZ 01 1 1 13755 # RM 10 0 0 13756 # RM 10 0 1 13757 # RM 10 1 0 13758 # RM 10 1 1 13759 # RP 11 0 0 13760 # RP 11 0 1 13761 # RP 11 1 0 13762 # RP 11 1 1 13763 # 13764 # Register usage: 13765 # Input/Output 13766 # d0: exponent/scratch - final is 0 13767 # d2: x/0 or 24 for A9 13768 # d3: x/scratch - offset ptr into PTEN 13769 # d4: LEN/Unchanged 13770 # d5: 0/ICTR:LAMBDA 13771 # d6: ILOG/ILOG or k if ((k<=0)&(ILOG< 13772 # d7: k-factor/Unchanged 13773 # a0: ptr for original operand/final r 13774 # a1: x/ptr to PTENRM array 13775 # a2: x/x 13776 # fp0: float(ILOG)/Unchanged 13777 # fp1: x/10^ISCALE 13778 # fp2: x/x 13779 # F_SCR1:x/x 13780 # F_SCR2:Abs(X) with $3fff exponent/Un 13781 # L_SCR1:x/x 13782 # L_SCR2:first word of X packed/Unchan 13783 13784 A7_str: 13785 tst.l %d7 # te 13786 bgt.b k_pos # if 13787 cmp.l %d7,%d6 # te 13788 blt.b k_pos # if 13789 mov.l %d7,%d6 # if 13790 k_pos: 13791 mov.l %d6,%d0 # ca 13792 addq.l &1,%d0 # ad 13793 sub.l %d4,%d0 # su 13794 swap %d5 # us 13795 clr.w %d5 # se 13796 clr.w %d2 # se 13797 tst.l %d0 # te 13798 bge.b iscale # if 13799 addq.w &1,%d5 # if 13800 cmp.l %d0,&0xffffecd4 # te 13801 bgt.b no_inf # if 13802 add.l &24,%d0 # ad 13803 mov.l &24,%d2 # pu 13804 no_inf: 13805 neg.l %d0 # an 13806 iscale: 13807 fmov.s FONE(%pc),%fp1 # in 13808 bfextu USER_FPCR(%a6){&26:& 13809 lsl.w &1,%d1 # pu 13810 add.w %d5,%d1 # ad 13811 lsl.w &1,%d1 # pu 13812 tst.l L_SCR2(%a6) # te 13813 bge.b x_pos # if 13814 addq.l &1,%d1 # if 13815 x_pos: 13816 lea.l RBDTBL(%pc),%a2 # lo 13817 mov.b (%a2,%d1),%d3 # lo 13818 lsl.l &4,%d3 # pu 13819 fmov.l %d3,%fpcr # lo 13820 lsr.l &4,%d3 # pu 13821 tst.b %d3 # de 13822 bne.b not_rn # if 13823 lea.l PTENRN(%pc),%a1 # lo 13824 bra.b rmode # ex 13825 not_rn: 13826 lsr.b &1,%d3 # ge 13827 bcc.b not_rp2 # if 13828 lea.l PTENRP(%pc),%a1 # lo 13829 bra.b rmode # ex 13830 not_rp2: 13831 lea.l PTENRM(%pc),%a1 # lo 13832 rmode: 13833 clr.l %d3 # cl 13834 e_loop2: 13835 lsr.l &1,%d0 # sh 13836 bcc.b e_next2 # if 13837 fmul.x (%a1,%d3),%fp1 # mu 13838 e_next2: 13839 add.l &12,%d3 # in 13840 tst.l %d0 # te 13841 bne.b e_loop2 # if 13842 13843 # A8. Clr INEX; Force RZ. 13844 # The operation in A3 above may have set 13845 # RZ mode is forced for the scaling oper 13846 # only one rounding error. The grs bits 13847 # the INEX flag for use in A10. 13848 # 13849 # Register usage: 13850 # Input/Output 13851 13852 fmov.l &0,%fpsr # cl 13853 fmov.l &rz_mode*0x10,%fpcr 13854 13855 # A9. Scale X -> Y. 13856 # The mantissa is scaled to the desired 13857 # digits. The excess digits are collect 13858 # Check d2 for excess 10 exponential val 13859 # the iscale value would have caused the 13860 # to overflow. Only a negative iscale c 13861 # multiply by 10^(d2), which is now only 13862 # with a multiply by 10^8 and 10^16, whi 13863 # 10^24 is exact. If the input was deno 13864 # create a busy stack frame with the mul 13865 # two operands, and allow the fpu to com 13866 # 13867 # Register usage: 13868 # Input/Output 13869 # d0: FPCR with RZ mode/Unchanged 13870 # d2: 0 or 24/unchanged 13871 # d3: x/x 13872 # d4: LEN/Unchanged 13873 # d5: ICTR:LAMBDA 13874 # d6: ILOG/Unchanged 13875 # d7: k-factor/Unchanged 13876 # a0: ptr for original operand/final r 13877 # a1: ptr to PTENRM array/Unchanged 13878 # a2: x/x 13879 # fp0: float(ILOG)/X adjusted for SCAL 13880 # fp1: 10^ISCALE/Unchanged 13881 # fp2: x/x 13882 # F_SCR1:x/x 13883 # F_SCR2:Abs(X) with $3fff exponent/Un 13884 # L_SCR1:x/x 13885 # L_SCR2:first word of X packed/Unchan 13886 13887 A9_str: 13888 fmov.x (%a0),%fp0 # lo 13889 fabs.x %fp0 # us 13890 tst.w %d5 # LA 13891 bne.b sc_mul # if 13892 fdiv.x %fp1,%fp0 # ca 13893 bra.w A10_st # br 13894 13895 sc_mul: 13896 tst.b BINDEC_FLG(%a6) # ch 13897 beq.w A9_norm # if 13898 13899 # for DENORM, we must calculate: 13900 # fp0 = input_op * 10^ISCALE * 10^24 13901 # since the input operand is a DENORM, we ca 13902 # so, we do the multiplication of the expone 13903 # in this way, we avoid underflow on interme 13904 # multiplication and guarantee a result with 13905 fmovm.x &0x2,-(%sp) # sa 13906 13907 mov.w (%sp),%d3 # gr 13908 andi.w &0x7fff,%d3 # cl 13909 ori.w &0x8000,(%a0) # ma 13910 add.w (%a0),%d3 # ad 13911 subi.w &0x3fff,%d3 # su 13912 add.w 36(%a1),%d3 13913 subi.w &0x3fff,%d3 # su 13914 add.w 48(%a1),%d3 13915 subi.w &0x3fff,%d3 # su 13916 13917 bmi.w sc_mul_err # is 13918 13919 andi.w &0x8000,(%sp) # ke 13920 or.w %d3,(%sp) # in 13921 andi.w &0x7fff,(%a0) # cl 13922 mov.l 0x8(%a0),-(%sp) # pu 13923 mov.l 0x4(%a0),-(%sp) 13924 mov.l &0x3fff0000,-(%sp) # 13925 fmovm.x (%sp)+,&0x80 # lo 13926 fmul.x (%sp)+,%fp0 13927 13928 # fmul.x 36(%a1),%fp0 # multiply f 13929 # fmul.x 48(%a1),%fp0 # multiply f 13930 mov.l 36+8(%a1),-(%sp) # g 13931 mov.l 36+4(%a1),-(%sp) 13932 mov.l &0x3fff0000,-(%sp) # 13933 mov.l 48+8(%a1),-(%sp) # g 13934 mov.l 48+4(%a1),-(%sp) 13935 mov.l &0x3fff0000,-(%sp)# 13936 fmul.x (%sp)+,%fp0 # mu 13937 fmul.x (%sp)+,%fp0 # mu 13938 bra.b A10_st 13939 13940 sc_mul_err: 13941 bra.b sc_mul_err 13942 13943 A9_norm: 13944 tst.w %d2 # te 13945 beq.b A9_con # if 13946 fmul.x 36(%a1),%fp0 # mu 13947 fmul.x 48(%a1),%fp0 # mu 13948 A9_con: 13949 fmul.x %fp1,%fp0 # ca 13950 13951 # A10. Or in INEX. 13952 # If INEX is set, round error occurred. 13953 # for by 'or-ing' in the INEX2 flag to 13954 # 13955 # Register usage: 13956 # Input/Output 13957 # d0: FPCR with RZ mode/FPSR with INEX 13958 # d2: x/x 13959 # d3: x/x 13960 # d4: LEN/Unchanged 13961 # d5: ICTR:LAMBDA 13962 # d6: ILOG/Unchanged 13963 # d7: k-factor/Unchanged 13964 # a0: ptr for original operand/final r 13965 # a1: ptr to PTENxx array/Unchanged 13966 # a2: x/ptr to FP_SCR1(a6) 13967 # fp0: Y/Y with lsb adjusted 13968 # fp1: 10^ISCALE/Unchanged 13969 # fp2: x/x 13970 13971 A10_st: 13972 fmov.l %fpsr,%d0 # ge 13973 fmov.x %fp0,FP_SCR1(%a6) 13974 lea.l FP_SCR1(%a6),%a2 13975 btst &9,%d0 # ch 13976 beq.b A11_st # if 13977 or.l &1,8(%a2) # or 13978 fmov.x FP_SCR1(%a6),%fp0 13979 13980 13981 # A11. Restore original FPCR; set size ext. 13982 # Perform FINT operation in the user's 13983 # the size to extended. The sintdo ent 13984 # routine expects the FPCR value to be 13985 # mode and precision. The original FPC 13986 13987 A11_st: 13988 mov.l USER_FPCR(%a6),L_SCR 13989 and.l &0x00000030,USER_FPC 13990 # ;blo 13991 13992 13993 # A12. Calculate YINT = FINT(Y) according to 13994 # The FPSP routine sintd0 is used. The 13995 # 13996 # Register usage: 13997 # Input/Output 13998 # d0: FPSR with AINEX cleared/FPCR wit 13999 # d2: x/x/scratch 14000 # d3: x/x 14001 # d4: LEN/Unchanged 14002 # d5: ICTR:LAMBDA/Unchanged 14003 # d6: ILOG/Unchanged 14004 # d7: k-factor/Unchanged 14005 # a0: ptr for original operand/src ptr 14006 # a1: ptr to PTENxx array/Unchanged 14007 # a2: ptr to FP_SCR1(a6)/Unchanged 14008 # a6: temp pointer to FP_SCR1(a6) - or 14009 # fp0: Y/YINT 14010 # fp1: 10^ISCALE/Unchanged 14011 # fp2: x/x 14012 # F_SCR1:x/x 14013 # F_SCR2:Y adjusted for inex/Y with or 14014 # L_SCR1:x/original USER_FPCR 14015 # L_SCR2:first word of X packed/Unchan 14016 14017 A12_st: 14018 movm.l &0xc0c0,-(%sp) # save regs 14019 mov.l L_SCR1(%a6),-(%sp) 14020 mov.l L_SCR2(%a6),-(%sp) 14021 14022 lea.l FP_SCR1(%a6),%a0 14023 fmov.x %fp0,(%a0) # mo 14024 tst.l L_SCR2(%a6) # te 14025 bge.b do_fint12 14026 or.l &0x80000000,(%a0) 14027 do_fint12: 14028 mov.l USER_FPSR(%a6),-(%sp) 14029 # bsr sintdo # sint routi 14030 14031 fmov.l USER_FPCR(%a6),%fpcr 14032 fmov.l &0x0,%fpsr 14033 ## mov.l USER_FPCR(%a6),%d0 14034 ## andi.l &0x00000030,%d0 14035 ## fmov.l %d0,%fpcr 14036 fint.x FP_SCR1(%a6),%fp0 14037 fmov.l %fpsr,%d0 14038 or.w %d0,FPSR_EXCEPT(%a6) 14039 ## fmov.l &0x0,%fpcr 14040 ## fmov.l %fpsr,%d0 14041 ## or.w %d0,FPSR_EXCEPT(%a6) 14042 14043 mov.b (%sp),USER_FPSR(%a6) 14044 add.l &4,%sp 14045 14046 mov.l (%sp)+,L_SCR2(%a6) 14047 mov.l (%sp)+,L_SCR1(%a6) 14048 movm.l (%sp)+,&0x303 # restore re 14049 14050 mov.l L_SCR2(%a6),FP_SCR1(%a6) 14051 mov.l L_SCR1(%a6),USER_FPCR(%a6) 14052 14053 # A13. Check for LEN digits. 14054 # If the int operation results in more 14055 # or less than LEN -1 digits, adjust IL 14056 # A6. This test occurs only on the fir 14057 # result is exactly 10^LEN, decrement I 14058 # the mantissa by 10. The calculation 14059 # be inexact, since all powers of ten u 14060 # in extended precision, so the use of 14061 # table will introduce no error. 14062 # 14063 # 14064 # Register usage: 14065 # Input/Output 14066 # d0: FPCR with size set to ext/scratc 14067 # d2: x/x 14068 # d3: x/scratch final = x 14069 # d4: LEN/LEN adjusted 14070 # d5: ICTR:LAMBDA/LAMBDA:ICTR 14071 # d6: ILOG/ILOG adjusted 14072 # d7: k-factor/Unchanged 14073 # a0: pointer into memory for packed b 14074 # a1: ptr to PTENxx array/Unchanged 14075 # a2: ptr to FP_SCR1(a6)/Unchanged 14076 # fp0: int portion of Y/abs(YINT) adju 14077 # fp1: 10^ISCALE/Unchanged 14078 # fp2: x/10^LEN 14079 # F_SCR1:x/x 14080 # F_SCR2:Y with original exponent/Unch 14081 # L_SCR1:original USER_FPCR/Unchanged 14082 # L_SCR2:first word of X packed/Unchan 14083 14084 A13_st: 14085 swap %d5 # pu 14086 tst.w %d5 # ch 14087 bne not_zr # if 14088 # 14089 # Compute 10^(LEN-1) 14090 # 14091 fmov.s FONE(%pc),%fp2 # in 14092 mov.l %d4,%d0 # pu 14093 subq.l &1,%d0 # d0 14094 clr.l %d3 # cl 14095 l_loop: 14096 lsr.l &1,%d0 # sh 14097 bcc.b l_next # if 14098 fmul.x (%a1,%d3),%fp2 # mu 14099 l_next: 14100 add.l &12,%d3 # in 14101 tst.l %d0 # te 14102 bne.b l_loop # if 14103 # 14104 # 10^LEN-1 is computed for this test and A14 14105 # denormalized, check only the case in which 14106 # 14107 tst.b BINDEC_FLG(%a6) # ch 14108 beq.b A13_con # if 14109 fabs.x %fp0 # ta 14110 bra test_2 14111 # 14112 # Compare abs(YINT) to 10^(LEN-1) and 10^LEN 14113 # 14114 A13_con: 14115 fabs.x %fp0 # ta 14116 fcmp.x %fp0,%fp2 # co 14117 fbge.w test_2 # if 14118 subq.l &1,%d6 # su 14119 mov.w &1,%d5 # se 14120 fmov.l &rm_mode*0x10,%fpcr 14121 fmul.s FTEN(%pc),%fp2 # co 14122 bra.w A6_str # re 14123 test_2: 14124 fmul.s FTEN(%pc),%fp2 # co 14125 fcmp.x %fp0,%fp2 # co 14126 fblt.w A14_st # if 14127 fbgt.w fix_ex # if 14128 fdiv.s FTEN(%pc),%fp0 # if 14129 addq.l &1,%d6 # an 14130 bra.b A14_st # an 14131 fix_ex: 14132 addq.l &1,%d6 # in 14133 mov.w &1,%d5 # se 14134 fmov.l &rm_mode*0x10,%fpcr 14135 bra.w A6_str # re 14136 # 14137 # Since ICTR <> 0, we have already been thro 14138 # and shouldn't have another; this is to che 14139 # 10^LEN is again computed using whatever ta 14140 # value calculated cannot be inexact. 14141 # 14142 not_zr: 14143 fmov.s FONE(%pc),%fp2 # in 14144 mov.l %d4,%d0 # pu 14145 clr.l %d3 # cl 14146 z_loop: 14147 lsr.l &1,%d0 # sh 14148 bcc.b z_next # if 14149 fmul.x (%a1,%d3),%fp2 # mu 14150 z_next: 14151 add.l &12,%d3 # in 14152 tst.l %d0 # te 14153 bne.b z_loop # if 14154 fabs.x %fp0 # ge 14155 fcmp.x %fp0,%fp2 # ch 14156 fbneq.w A14_st # if 14157 fdiv.s FTEN(%pc),%fp0 # di 14158 addq.l &1,%d6 # an 14159 addq.l &1,%d4 # an 14160 fmul.s FTEN(%pc),%fp2 # if 14161 14162 # A14. Convert the mantissa to bcd. 14163 # The binstr routine is used to convert 14164 # mantissa to bcd in memory. The input 14165 # to be a fraction; i.e. (mantissa)/10^ 14166 # such that the decimal point is to the 14167 # The bcd digits are stored in the corr 14168 # the final string area in memory. 14169 # 14170 # 14171 # Register usage: 14172 # Input/Output 14173 # d0: x/LEN call to binstr - final is 14174 # d1: x/0 14175 # d2: x/ms 32-bits of mant of abs(YINT 14176 # d3: x/ls 32-bits of mant of abs(YINT 14177 # d4: LEN/Unchanged 14178 # d5: ICTR:LAMBDA/LAMBDA:ICTR 14179 # d6: ILOG 14180 # d7: k-factor/Unchanged 14181 # a0: pointer into memory for packed b 14182 # /ptr to first mantissa byte in r 14183 # a1: ptr to PTENxx array/Unchanged 14184 # a2: ptr to FP_SCR1(a6)/Unchanged 14185 # fp0: int portion of Y/abs(YINT) adju 14186 # fp1: 10^ISCALE/Unchanged 14187 # fp2: 10^LEN/Unchanged 14188 # F_SCR1:x/Work area for final result 14189 # F_SCR2:Y with original exponent/Unch 14190 # L_SCR1:original USER_FPCR/Unchanged 14191 # L_SCR2:first word of X packed/Unchan 14192 14193 A14_st: 14194 fmov.l &rz_mode*0x10,%fpcr 14195 fdiv.x %fp2,%fp0 # di 14196 lea.l FP_SCR0(%a6),%a0 14197 fmov.x %fp0,(%a0) # mo 14198 mov.l 4(%a0),%d2 # mo 14199 mov.l 8(%a0),%d3 # mo 14200 clr.l 4(%a0) # ze 14201 clr.l 8(%a0) # ze 14202 mov.l (%a0),%d0 # mo 14203 swap %d0 # pu 14204 beq.b no_sft # if 14205 sub.l &0x3ffd,%d0 # su 14206 tst.l %d0 # ch 14207 bgt.b no_sft # if 14208 neg.l %d0 # ma 14209 m_loop: 14210 lsr.l &1,%d2 # sh 14211 roxr.l &1,%d3 # th 14212 dbf.w %d0,m_loop # gi 14213 no_sft: 14214 tst.l %d2 # ch 14215 bne.b no_zr # if 14216 tst.l %d3 # co 14217 beq.b zer_m # if 14218 no_zr: 14219 clr.l %d1 # pu 14220 add.l &0x00000080,%d3 # in 14221 addx.l %d1,%d2 # co 14222 and.l &0xffffff80,%d3 # st 14223 zer_m: 14224 mov.l %d4,%d0 # pu 14225 addq.l &3,%a0 # a0 14226 bsr binstr # ca 14227 14228 14229 # A15. Convert the exponent to bcd. 14230 # As in A14 above, the exp is converted 14231 # digits are stored in the final string 14232 # 14233 # Digits are stored in L_SCR1(a6) on re 14234 # 14235 # 32 16 15 14236 # ------------------------------------ 14237 # | 0 | e3 | e2 | e1 | e4 | X | X | 14238 # ------------------------------------ 14239 # 14240 # And are moved into their proper places in 14241 # is non-zero, OPERR is signaled. In all ca 14242 # written as specified in the 881/882 manual 14243 # 14244 # Register usage: 14245 # Input/Output 14246 # d0: x/LEN call to binstr - final is 14247 # d1: x/scratch (0);shift count for fi 14248 # d2: x/ms 32-bits of exp fraction/scr 14249 # d3: x/ls 32-bits of exp fraction 14250 # d4: LEN/Unchanged 14251 # d5: ICTR:LAMBDA/LAMBDA:ICTR 14252 # d6: ILOG 14253 # d7: k-factor/Unchanged 14254 # a0: ptr to result string/ptr to L_SC 14255 # a1: ptr to PTENxx array/Unchanged 14256 # a2: ptr to FP_SCR1(a6)/Unchanged 14257 # fp0: abs(YINT) adjusted/float(ILOG) 14258 # fp1: 10^ISCALE/Unchanged 14259 # fp2: 10^LEN/Unchanged 14260 # F_SCR1:Work area for final result/BC 14261 # F_SCR2:Y with original exponent/ILOG 14262 # L_SCR1:original USER_FPCR/Exponent d 14263 # L_SCR2:first word of X packed/Unchan 14264 14265 A15_st: 14266 tst.b BINDEC_FLG(%a6) # ch 14267 beq.b not_denorm 14268 ftest.x %fp0 # te 14269 fbeq.w den_zero # if 14270 fmov.l %d6,%fp0 # fl 14271 fabs.x %fp0 # ge 14272 bra.b convrt 14273 den_zero: 14274 tst.l %d7 # ch 14275 blt.b use_ilog # if 14276 fmov.s F4933(%pc),%fp0 # fo 14277 bra.b convrt # do 14278 use_ilog: 14279 fmov.l %d6,%fp0 # fl 14280 fabs.x %fp0 # ge 14281 bra.b convrt 14282 not_denorm: 14283 ftest.x %fp0 # te 14284 fbneq.w not_zero # if 14285 fmov.s FONE(%pc),%fp0 # fo 14286 bra.b convrt # do 14287 not_zero: 14288 fmov.l %d6,%fp0 # fl 14289 fabs.x %fp0 # ge 14290 convrt: 14291 fdiv.x 24(%a1),%fp0 # co 14292 fmov.x %fp0,FP_SCR1(%a6) 14293 mov.l 4(%a2),%d2 # mo 14294 mov.l 8(%a2),%d3 # mo 14295 mov.w (%a2),%d0 # mo 14296 beq.b x_loop_fin # if 14297 sub.w &0x3ffd,%d0 # su 14298 neg.w %d0 # ma 14299 x_loop: 14300 lsr.l &1,%d2 # sh 14301 roxr.l &1,%d3 # th 14302 dbf.w %d0,x_loop # gi 14303 x_loop_fin: 14304 clr.l %d1 # pu 14305 add.l &0x00000080,%d3 # in 14306 addx.l %d1,%d2 # co 14307 and.l &0xffffff80,%d3 # st 14308 mov.l &4,%d0 # pu 14309 lea.l L_SCR1(%a6),%a0 # a0 14310 bsr binstr # ca 14311 mov.l L_SCR1(%a6),%d0 # lo 14312 mov.l &12,%d1 # us 14313 lsr.l %d1,%d0 # sh 14314 bfins %d0,FP_SCR0(%a6){&4: 14315 lsr.l %d1,%d0 # sh 14316 bfins %d0,FP_SCR0(%a6){&16 14317 tst.b %d0 # ch 14318 beq.b A16_st # if 14319 or.l &opaop_mask,USER_FPS 14320 14321 14322 # A16. Write sign bits to final string. 14323 # Sigma is bit 31 of initial value; 14324 # 14325 # Register usage: 14326 # Input/Output 14327 # d0: x/scratch - final is x 14328 # d2: x/x 14329 # d3: x/x 14330 # d4: LEN/Unchanged 14331 # d5: ICTR:LAMBDA/LAMBDA:ICTR 14332 # d6: ILOG/ILOG adjusted 14333 # d7: k-factor/Unchanged 14334 # a0: ptr to L_SCR1(a6)/Unchanged 14335 # a1: ptr to PTENxx array/Unchanged 14336 # a2: ptr to FP_SCR1(a6)/Unchanged 14337 # fp0: float(ILOG)/Unchanged 14338 # fp1: 10^ISCALE/Unchanged 14339 # fp2: 10^LEN/Unchanged 14340 # F_SCR1:BCD result with correct signs 14341 # F_SCR2:ILOG/10^4 14342 # L_SCR1:Exponent digits on return fro 14343 # L_SCR2:first word of X packed/Unchan 14344 14345 A16_st: 14346 clr.l %d0 # cl 14347 and.b &0x0f,FP_SCR0(%a6) 14348 tst.l L_SCR2(%a6) # ch 14349 bge.b mant_p # if 14350 mov.l &2,%d0 # mo 14351 mant_p: 14352 tst.l %d6 # ch 14353 bge.b wr_sgn # if 14354 addq.l &1,%d0 # se 14355 wr_sgn: 14356 bfins %d0,FP_SCR0(%a6){&0: 14357 14358 # Clean up and restore all registers used. 14359 14360 fmov.l &0,%fpsr # cl 14361 fmovm.x (%sp)+,&0xe0 # { 14362 movm.l (%sp)+,&0x4fc # { 14363 rts 14364 14365 global PTENRN 14366 PTENRN: 14367 long 0x40020000,0xA000000 14368 long 0x40050000,0xC800000 14369 long 0x400C0000,0x9C40000 14370 long 0x40190000,0xBEBC200 14371 long 0x40340000,0x8E1BC9B 14372 long 0x40690000,0x9DC5ADA 14373 long 0x40D30000,0xC2781F4 14374 long 0x41A80000,0x93BA47C 14375 long 0x43510000,0xAA7EEBF 14376 long 0x46A30000,0xE319A0A 14377 long 0x4D480000,0xC976758 14378 long 0x5A920000,0x9E8B3B5 14379 long 0x75250000,0xC460520 14380 14381 global PTENRP 14382 PTENRP: 14383 long 0x40020000,0xA000000 14384 long 0x40050000,0xC800000 14385 long 0x400C0000,0x9C40000 14386 long 0x40190000,0xBEBC200 14387 long 0x40340000,0x8E1BC9B 14388 long 0x40690000,0x9DC5ADA 14389 long 0x40D30000,0xC2781F4 14390 long 0x41A80000,0x93BA47C 14391 long 0x43510000,0xAA7EEBF 14392 long 0x46A30000,0xE319A0A 14393 long 0x4D480000,0xC976758 14394 long 0x5A920000,0x9E8B3B5 14395 long 0x75250000,0xC460520 14396 14397 global PTENRM 14398 PTENRM: 14399 long 0x40020000,0xA000000 14400 long 0x40050000,0xC800000 14401 long 0x400C0000,0x9C40000 14402 long 0x40190000,0xBEBC200 14403 long 0x40340000,0x8E1BC9B 14404 long 0x40690000,0x9DC5ADA 14405 long 0x40D30000,0xC2781F4 14406 long 0x41A80000,0x93BA47C 14407 long 0x43510000,0xAA7EEBF 14408 long 0x46A30000,0xE319A0A 14409 long 0x4D480000,0xC976758 14410 long 0x5A920000,0x9E8B3B5 14411 long 0x75250000,0xC460520 14412 14413 ############################################ 14414 # binstr(): Converts a 64-bit binary integer 14415 # 14416 # INPUT ************************************ 14417 # d2:d3 = 64-bit binary integer 14418 # d0 = desired length (LEN) 14419 # a0 = pointer to start in memory f 14420 # (This pointer must point to 14421 # lword of the packed decimal 14422 # 14423 # OUTPUT *********************************** 14424 # a0 = pointer to LEN bcd digits repre 14425 # 14426 # ALGORITHM ******************************** 14427 # The 64-bit binary is assumed to have 14428 # bit 63. The fraction is multiplied 14429 # shift and a mul by 8 shift. The bit 14430 # msb form a decimal digit. This proc 14431 # LEN digits are formed. 14432 # 14433 # A1. Init d7 to 1. D7 is the byte digit co 14434 # digit formed will be assumed the least 14435 # to force the first byte formed to have 14436 # 14437 # A2. Beginning of the loop: 14438 # Copy the fraction in d2:d3 to d4:d5. 14439 # 14440 # A3. Multiply the fraction in d2:d3 by 8 us 14441 # extracts and shifts. The three msbs f 14442 # 14443 # A4. Multiply the fraction in d4:d5 by 2 us 14444 # will be collected by the carry. 14445 # 14446 # A5. Add using the carry the 64-bit quantit 14447 # into d2:d3. D1 will contain the bcd d 14448 # 14449 # A6. Test d7. If zero, the digit formed is 14450 # zero, it is the ls digit. Put the dig 14451 # upper word of d0. If it is the ls dig 14452 # from d0 to memory. 14453 # 14454 # A7. Decrement d6 (LEN counter) and repeat 14455 # 14456 ############################################ 14457 14458 # Implementation Notes: 14459 # 14460 # The registers are used as follows: 14461 # 14462 # d0: LEN counter 14463 # d1: temp used to form the di 14464 # d2: upper 32-bits of fractio 14465 # d3: lower 32-bits of fractio 14466 # d4: upper 32-bits of fractio 14467 # d5: lower 32-bits of fractio 14468 # d6: temp for bit-field extra 14469 # d7: byte digit formation wor 14470 # a0: pointer into memory for 14471 # 14472 14473 global binstr 14474 binstr: 14475 movm.l &0xff00,-(%sp) # { 14476 14477 # 14478 # A1: Init d7 14479 # 14480 mov.l &1,%d7 # in 14481 subq.l &1,%d0 # fo 14482 # 14483 # A2. Copy d2:d3 to d4:d5. Start loop. 14484 # 14485 loop: 14486 mov.l %d2,%d4 # co 14487 mov.l %d3,%d5 # to 14488 # 14489 # A3. Multiply d2:d3 by 8; extract msbs into 14490 # 14491 bfextu %d2{&0:&3},%d1 # co 14492 asl.l &3,%d2 # sh 14493 bfextu %d3{&0:&3},%d6 # co 14494 asl.l &3,%d3 # sh 14495 or.l %d6,%d2 # or 14496 # 14497 # A4. Multiply d4:d5 by 2; add carry out to 14498 # 14499 asl.l &1,%d5 # mu 14500 roxl.l &1,%d4 # mu 14501 swap %d6 # pu 14502 addx.w %d6,%d1 # ad 14503 # 14504 # A5. Add mul by 8 to mul by 2. D1 contains 14505 # 14506 add.l %d5,%d3 # ad 14507 nop # ER 14508 addx.l %d4,%d2 # ad 14509 nop # ER 14510 addx.w %d6,%d1 # ad 14511 swap %d6 # wi 14512 # 14513 # A6. Test d7 and branch. 14514 # 14515 tst.w %d7 # if 14516 beq.b first_d # if 14517 sec_d: 14518 swap %d7 # br 14519 asl.w &4,%d7 # fi 14520 add.w %d1,%d7 # ad 14521 mov.b %d7,(%a0)+ # st 14522 swap %d7 # pu 14523 clr.w %d7 # se 14524 dbf.w %d0,loop # do 14525 bra.b end_bstr # fi 14526 first_d: 14527 swap %d7 # pu 14528 mov.w %d1,%d7 # pu 14529 swap %d7 # pu 14530 addq.w &1,%d7 # se 14531 dbf.w %d0,loop # do 14532 swap %d7 # pu 14533 lsl.w &4,%d7 # mo 14534 mov.b %d7,(%a0)+ # st 14535 # 14536 # Clean up and return with result in fp0. 14537 # 14538 end_bstr: 14539 movm.l (%sp)+,&0xff # { 14540 rts 14541 14542 ############################################ 14543 # XDEF ************************************* 14544 # facc_in_b(): dmem_read_byte failed 14545 # facc_in_w(): dmem_read_word failed 14546 # facc_in_l(): dmem_read_long failed 14547 # facc_in_d(): dmem_read of dbl prec f 14548 # facc_in_x(): dmem_read of ext prec f 14549 # 14550 # facc_out_b(): dmem_write_byte failed 14551 # facc_out_w(): dmem_write_word failed 14552 # facc_out_l(): dmem_write_long failed 14553 # facc_out_d(): dmem_write of dbl prec 14554 # facc_out_x(): dmem_write of ext prec 14555 # 14556 # XREF ************************************* 14557 # _real_access() - exit through access 14558 # 14559 # INPUT ************************************ 14560 # None 14561 # 14562 # OUTPUT *********************************** 14563 # None 14564 # 14565 # ALGORITHM ******************************** 14566 # Flow jumps here when an FP data fetc 14567 # result. This means the operating system wa 14568 # made out of the current exception stack fr 14569 # So, we first call restore() which ma 14570 # -(an)+ register gets returned to its pre-e 14571 # we change the stack to an access error sta 14572 # 14573 ############################################ 14574 14575 facc_in_b: 14576 movq.l &0x1,%d0 14577 bsr.w restore 14578 14579 mov.w &0x0121,EXC_VOFF(%a6 14580 bra.w facc_finish 14581 14582 facc_in_w: 14583 movq.l &0x2,%d0 14584 bsr.w restore 14585 14586 mov.w &0x0141,EXC_VOFF(%a6 14587 bra.b facc_finish 14588 14589 facc_in_l: 14590 movq.l &0x4,%d0 14591 bsr.w restore 14592 14593 mov.w &0x0101,EXC_VOFF(%a6 14594 bra.b facc_finish 14595 14596 facc_in_d: 14597 movq.l &0x8,%d0 14598 bsr.w restore 14599 14600 mov.w &0x0161,EXC_VOFF(%a6 14601 bra.b facc_finish 14602 14603 facc_in_x: 14604 movq.l &0xc,%d0 14605 bsr.w restore 14606 14607 mov.w &0x0161,EXC_VOFF(%a6 14608 bra.b facc_finish 14609 14610 ############################################ 14611 14612 facc_out_b: 14613 movq.l &0x1,%d0 14614 bsr.w restore 14615 14616 mov.w &0x00a1,EXC_VOFF(%a6 14617 bra.b facc_finish 14618 14619 facc_out_w: 14620 movq.l &0x2,%d0 14621 bsr.w restore 14622 14623 mov.w &0x00c1,EXC_VOFF(%a6 14624 bra.b facc_finish 14625 14626 facc_out_l: 14627 movq.l &0x4,%d0 14628 bsr.w restore 14629 14630 mov.w &0x0081,EXC_VOFF(%a6 14631 bra.b facc_finish 14632 14633 facc_out_d: 14634 movq.l &0x8,%d0 14635 bsr.w restore 14636 14637 mov.w &0x00e1,EXC_VOFF(%a6 14638 bra.b facc_finish 14639 14640 facc_out_x: 14641 mov.l &0xc,%d0 14642 bsr.w restore 14643 14644 mov.w &0x00e1,EXC_VOFF(%a6 14645 14646 # here's where we actually create the access 14647 # current exception stack frame. 14648 facc_finish: 14649 mov.l USER_FPIAR(%a6),EXC_ 14650 14651 fmovm.x EXC_FPREGS(%a6),&0xc 14652 fmovm.l USER_FPCR(%a6),%fpcr 14653 movm.l EXC_DREGS(%a6),&0x03 14654 14655 unlk %a6 14656 14657 mov.l (%sp),-(%sp) 14658 mov.l 0x8(%sp),0x4(%sp) 14659 mov.l 0xc(%sp),0x8(%sp) 14660 mov.l &0x00000001,0xc(%sp) 14661 mov.w 0x6(%sp),0xc(%sp) 14662 mov.w &0x4008,0x6(%sp) 14663 14664 btst &0x5,(%sp) 14665 beq.b facc_out2 14666 bset &0x2,0xd(%sp) 14667 14668 facc_out2: 14669 bra.l _real_access 14670 14671 ############################################ 14672 14673 # if the effective addressing mode was prede 14674 # the emulation has already changed its valu 14675 # instruction value. but since we're exiting 14676 # handler, then AN must be returned to its p 14677 # we do that here. 14678 restore: 14679 mov.b EXC_OPWORD+0x1(%a6), 14680 andi.b &0x38,%d1 14681 cmpi.b %d1,&0x18 14682 beq.w rest_inc 14683 cmpi.b %d1,&0x20 14684 beq.w rest_dec 14685 rts 14686 14687 rest_inc: 14688 mov.b EXC_OPWORD+0x1(%a6), 14689 andi.w &0x0007,%d1 14690 14691 mov.w (tbl_rest_inc.b,%pc, 14692 jmp (tbl_rest_inc.b,%pc, 14693 14694 tbl_rest_inc: 14695 short ri_a0 - tbl_rest_inc 14696 short ri_a1 - tbl_rest_inc 14697 short ri_a2 - tbl_rest_inc 14698 short ri_a3 - tbl_rest_inc 14699 short ri_a4 - tbl_rest_inc 14700 short ri_a5 - tbl_rest_inc 14701 short ri_a6 - tbl_rest_inc 14702 short ri_a7 - tbl_rest_inc 14703 14704 ri_a0: 14705 sub.l %d0,EXC_DREGS+0x8(%a 14706 rts 14707 ri_a1: 14708 sub.l %d0,EXC_DREGS+0xc(%a 14709 rts 14710 ri_a2: 14711 sub.l %d0,%a2 14712 rts 14713 ri_a3: 14714 sub.l %d0,%a3 14715 rts 14716 ri_a4: 14717 sub.l %d0,%a4 14718 rts 14719 ri_a5: 14720 sub.l %d0,%a5 14721 rts 14722 ri_a6: 14723 sub.l %d0,(%a6) 14724 rts 14725 # if it's a fmove out instruction, we don't 14726 # because we hadn't changed it yet. if it's 14727 # instruction (data moved in) and the except 14728 # mode, then also also wasn't updated. if it 14729 # restore the correct a7 which is in the USP 14730 ri_a7: 14731 cmpi.b EXC_VOFF(%a6),&0x30 14732 bne.b ri_a7_done 14733 14734 btst &0x5,EXC_SR(%a6) 14735 bne.b ri_a7_done 14736 movc %usp,%a0 14737 sub.l %d0,%a0 14738 movc %a0,%usp 14739 ri_a7_done: 14740 rts 14741 14742 # need to invert adjustment value if the <ea 14743 rest_dec: 14744 neg.l %d0 14745 bra.b rest_inc
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.