1 | 2 | round.sa 3.4 7/29/91 3 | 4 | handle rounding and normalization tasks 5 | 6 | 7 | 8 | Copyright (C) Motorola, Inc. 1990 9 | All Rights Reserved 10 | 11 | THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA 12 | The copyright notice above does not evidence any 13 | actual or intended publication of such source code. 14 15 |ROUND idnt 2,1 | Motorola 040 Floating Point Software Package 16 17 |section 8 18 19 .include "fpsp.h" 20 21 | 22 | round --- round result according to precision/mode 23 | 24 | a0 points to the input operand in the internal extended format 25 | d1(high word) contains rounding precision: 26 | ext = $0000xxxx 27 | sgl = $0001xxxx 28 | dbl = $0002xxxx 29 | d1(low word) contains rounding mode: 30 | RN = $xxxx0000 31 | RZ = $xxxx0001 32 | RM = $xxxx0010 33 | RP = $xxxx0011 34 | d0{31:29} contains the g,r,s bits (extended) 35 | 36 | On return the value pointed to by a0 is correctly rounded, 37 | a0 is preserved and the g-r-s bits in d0 are cleared. 38 | The result is not typed - the tag field is invalid. The 39 | result is still in the internal extended format. 40 | 41 | The INEX bit of USER_FPSR will be set if the rounded result was 42 | inexact (i.e. if any of the g-r-s bits were set). 43 | 44 45 .global round 46 round: 47 | If g=r=s=0 then result is exact and round is done, else set 48 | the inex flag in status reg and continue. 49 | 50 bsrs ext_grs |this subroutine looks at the 51 | :rounding precision and sets 52 | ;the appropriate g-r-s bits. 53 tstl %d0 |if grs are zero, go force 54 bne rnd_cont |lower bits to zero for size 55 56 swap %d1 |set up d1.w for round prec. 57 bra truncate 58 59 rnd_cont: 60 | 61 | Use rounding mode as an index into a jump table for these modes. 62 | 63 orl #inx2a_mask,USER_FPSR(%a6) |set inex2/ainex 64 lea mode_tab,%a1 65 movel (%a1,%d1.w*4),%a1 66 jmp (%a1) 67 | 68 | Jump table indexed by rounding mode in d1.w. All following assumes 69 | grs != 0. 70 | 71 mode_tab: 72 .long rnd_near 73 .long rnd_zero 74 .long rnd_mnus 75 .long rnd_plus 76 | 77 | ROUND PLUS INFINITY 78 | 79 | If sign of fp number = 0 (positive), then add 1 to l. 80 | 81 rnd_plus: 82 swap %d1 |set up d1 for round prec. 83 tstb LOCAL_SGN(%a0) |check for sign 84 bmi truncate |if positive then truncate 85 movel #0xffffffff,%d0 |force g,r,s to be all f's 86 lea add_to_l,%a1 87 movel (%a1,%d1.w*4),%a1 88 jmp (%a1) 89 | 90 | ROUND MINUS INFINITY 91 | 92 | If sign of fp number = 1 (negative), then add 1 to l. 93 | 94 rnd_mnus: 95 swap %d1 |set up d1 for round prec. 96 tstb LOCAL_SGN(%a0) |check for sign 97 bpl truncate |if negative then truncate 98 movel #0xffffffff,%d0 |force g,r,s to be all f's 99 lea add_to_l,%a1 100 movel (%a1,%d1.w*4),%a1 101 jmp (%a1) 102 | 103 | ROUND ZERO 104 | 105 | Always truncate. 106 rnd_zero: 107 swap %d1 |set up d1 for round prec. 108 bra truncate 109 | 110 | 111 | ROUND NEAREST 112 | 113 | If (g=1), then add 1 to l and if (r=s=0), then clear l 114 | Note that this will round to even in case of a tie. 115 | 116 rnd_near: 117 swap %d1 |set up d1 for round prec. 118 asll #1,%d0 |shift g-bit to c-bit 119 bcc truncate |if (g=1) then 120 lea add_to_l,%a1 121 movel (%a1,%d1.w*4),%a1 122 jmp (%a1) 123 124 | 125 | ext_grs --- extract guard, round and sticky bits 126 | 127 | Input: d1 = PREC:ROUND 128 | Output: d0{31:29}= guard, round, sticky 129 | 130 | The ext_grs extract the guard/round/sticky bits according to the 131 | selected rounding precision. It is called by the round subroutine 132 | only. All registers except d0 are kept intact. d0 becomes an 133 | updated guard,round,sticky in d0{31:29} 134 | 135 | Notes: the ext_grs uses the round PREC, and therefore has to swap d1 136 | prior to usage, and needs to restore d1 to original. 137 | 138 ext_grs: 139 swap %d1 |have d1.w point to round precision 140 cmpiw #0,%d1 141 bnes sgl_or_dbl 142 bras end_ext_grs 143 144 sgl_or_dbl: 145 moveml %d2/%d3,-(%a7) |make some temp registers 146 cmpiw #1,%d1 147 bnes grs_dbl 148 grs_sgl: 149 bfextu LOCAL_HI(%a0){#24:#2},%d3 |sgl prec. g-r are 2 bits right 150 movel #30,%d2 |of the sgl prec. limits 151 lsll %d2,%d3 |shift g-r bits to MSB of d3 152 movel LOCAL_HI(%a0),%d2 |get word 2 for s-bit test 153 andil #0x0000003f,%d2 |s bit is the or of all other 154 bnes st_stky |bits to the right of g-r 155 tstl LOCAL_LO(%a0) |test lower mantissa 156 bnes st_stky |if any are set, set sticky 157 tstl %d0 |test original g,r,s 158 bnes st_stky |if any are set, set sticky 159 bras end_sd |if words 3 and 4 are clr, exit 160 grs_dbl: 161 bfextu LOCAL_LO(%a0){#21:#2},%d3 |dbl-prec. g-r are 2 bits right 162 movel #30,%d2 |of the dbl prec. limits 163 lsll %d2,%d3 |shift g-r bits to the MSB of d3 164 movel LOCAL_LO(%a0),%d2 |get lower mantissa for s-bit test 165 andil #0x000001ff,%d2 |s bit is the or-ing of all 166 bnes st_stky |other bits to the right of g-r 167 tstl %d0 |test word original g,r,s 168 bnes st_stky |if any are set, set sticky 169 bras end_sd |if clear, exit 170 st_stky: 171 bset #rnd_stky_bit,%d3 172 end_sd: 173 movel %d3,%d0 |return grs to d0 174 moveml (%a7)+,%d2/%d3 |restore scratch registers 175 end_ext_grs: 176 swap %d1 |restore d1 to original 177 rts 178 179 |******************* Local Equates 180 .set ad_1_sgl,0x00000100 | constant to add 1 to l-bit in sgl prec 181 .set ad_1_dbl,0x00000800 | constant to add 1 to l-bit in dbl prec 182 183 184 |Jump table for adding 1 to the l-bit indexed by rnd prec 185 186 add_to_l: 187 .long add_ext 188 .long add_sgl 189 .long add_dbl 190 .long add_dbl 191 | 192 | ADD SINGLE 193 | 194 add_sgl: 195 addl #ad_1_sgl,LOCAL_HI(%a0) 196 bccs scc_clr |no mantissa overflow 197 roxrw LOCAL_HI(%a0) |shift v-bit back in 198 roxrw LOCAL_HI+2(%a0) |shift v-bit back in 199 addw #0x1,LOCAL_EX(%a0) |and incr exponent 200 scc_clr: 201 tstl %d0 |test for rs = 0 202 bnes sgl_done 203 andiw #0xfe00,LOCAL_HI+2(%a0) |clear the l-bit 204 sgl_done: 205 andil #0xffffff00,LOCAL_HI(%a0) |truncate bits beyond sgl limit 206 clrl LOCAL_LO(%a0) |clear d2 207 rts 208 209 | 210 | ADD EXTENDED 211 | 212 add_ext: 213 addql #1,LOCAL_LO(%a0) |add 1 to l-bit 214 bccs xcc_clr |test for carry out 215 addql #1,LOCAL_HI(%a0) |propagate carry 216 bccs xcc_clr 217 roxrw LOCAL_HI(%a0) |mant is 0 so restore v-bit 218 roxrw LOCAL_HI+2(%a0) |mant is 0 so restore v-bit 219 roxrw LOCAL_LO(%a0) 220 roxrw LOCAL_LO+2(%a0) 221 addw #0x1,LOCAL_EX(%a0) |and inc exp 222 xcc_clr: 223 tstl %d0 |test rs = 0 224 bnes add_ext_done 225 andib #0xfe,LOCAL_LO+3(%a0) |clear the l bit 226 add_ext_done: 227 rts 228 | 229 | ADD DOUBLE 230 | 231 add_dbl: 232 addl #ad_1_dbl,LOCAL_LO(%a0) 233 bccs dcc_clr 234 addql #1,LOCAL_HI(%a0) |propagate carry 235 bccs dcc_clr 236 roxrw LOCAL_HI(%a0) |mant is 0 so restore v-bit 237 roxrw LOCAL_HI+2(%a0) |mant is 0 so restore v-bit 238 roxrw LOCAL_LO(%a0) 239 roxrw LOCAL_LO+2(%a0) 240 addw #0x1,LOCAL_EX(%a0) |incr exponent 241 dcc_clr: 242 tstl %d0 |test for rs = 0 243 bnes dbl_done 244 andiw #0xf000,LOCAL_LO+2(%a0) |clear the l-bit 245 246 dbl_done: 247 andil #0xfffff800,LOCAL_LO(%a0) |truncate bits beyond dbl limit 248 rts 249 250 error: 251 rts 252 | 253 | Truncate all other bits 254 | 255 trunct: 256 .long end_rnd 257 .long sgl_done 258 .long dbl_done 259 .long dbl_done 260 261 truncate: 262 lea trunct,%a1 263 movel (%a1,%d1.w*4),%a1 264 jmp (%a1) 265 266 end_rnd: 267 rts 268 269 | 270 | NORMALIZE 271 | 272 | These routines (nrm_zero & nrm_set) normalize the unnorm. This 273 | is done by shifting the mantissa left while decrementing the 274 | exponent. 275 | 276 | NRM_SET shifts and decrements until there is a 1 set in the integer 277 | bit of the mantissa (msb in d1). 278 | 279 | NRM_ZERO shifts and decrements until there is a 1 set in the integer 280 | bit of the mantissa (msb in d1) unless this would mean the exponent 281 | would go less than 0. In that case the number becomes a denorm - the 282 | exponent (d0) is set to 0 and the mantissa (d1 & d2) is not 283 | normalized. 284 | 285 | Note that both routines have been optimized (for the worst case) and 286 | therefore do not have the easy to follow decrement/shift loop. 287 | 288 | NRM_ZERO 289 | 290 | Distance to first 1 bit in mantissa = X 291 | Distance to 0 from exponent = Y 292 | If X < Y 293 | Then 294 | nrm_set 295 | Else 296 | shift mantissa by Y 297 | set exponent = 0 298 | 299 |input: 300 | FP_SCR1 = exponent, ms mantissa part, ls mantissa part 301 |output: 302 | L_SCR1{4} = fpte15 or ete15 bit 303 | 304 .global nrm_zero 305 nrm_zero: 306 movew LOCAL_EX(%a0),%d0 307 cmpw #64,%d0 |see if exp > 64 308 bmis d0_less 309 bsr nrm_set |exp > 64 so exp won't exceed 0 310 rts 311 d0_less: 312 moveml %d2/%d3/%d5/%d6,-(%a7) 313 movel LOCAL_HI(%a0),%d1 314 movel LOCAL_LO(%a0),%d2 315 316 bfffo %d1{#0:#32},%d3 |get the distance to the first 1 317 | ;in ms mant 318 beqs ms_clr |branch if no bits were set 319 cmpw %d3,%d0 |of X>Y 320 bmis greater |then exp will go past 0 (neg) if 321 | ;it is just shifted 322 bsr nrm_set |else exp won't go past 0 323 moveml (%a7)+,%d2/%d3/%d5/%d6 324 rts 325 greater: 326 movel %d2,%d6 |save ls mant in d6 327 lsll %d0,%d2 |shift ls mant by count 328 lsll %d0,%d1 |shift ms mant by count 329 movel #32,%d5 330 subl %d0,%d5 |make op a denorm by shifting bits 331 lsrl %d5,%d6 |by the number in the exp, then 332 | ;set exp = 0. 333 orl %d6,%d1 |shift the ls mant bits into the ms mant 334 movel #0,%d0 |same as if decremented exp to 0 335 | ;while shifting 336 movew %d0,LOCAL_EX(%a0) 337 movel %d1,LOCAL_HI(%a0) 338 movel %d2,LOCAL_LO(%a0) 339 moveml (%a7)+,%d2/%d3/%d5/%d6 340 rts 341 ms_clr: 342 bfffo %d2{#0:#32},%d3 |check if any bits set in ls mant 343 beqs all_clr |branch if none set 344 addw #32,%d3 345 cmpw %d3,%d0 |if X>Y 346 bmis greater |then branch 347 bsr nrm_set |else exp won't go past 0 348 moveml (%a7)+,%d2/%d3/%d5/%d6 349 rts 350 all_clr: 351 movew #0,LOCAL_EX(%a0) |no mantissa bits set. Set exp = 0. 352 moveml (%a7)+,%d2/%d3/%d5/%d6 353 rts 354 | 355 | NRM_SET 356 | 357 .global nrm_set 358 nrm_set: 359 movel %d7,-(%a7) 360 bfffo LOCAL_HI(%a0){#0:#32},%d7 |find first 1 in ms mant to d7) 361 beqs lower |branch if ms mant is all 0's 362 363 movel %d6,-(%a7) 364 365 subw %d7,LOCAL_EX(%a0) |sub exponent by count 366 movel LOCAL_HI(%a0),%d0 |d0 has ms mant 367 movel LOCAL_LO(%a0),%d1 |d1 has ls mant 368 369 lsll %d7,%d0 |shift first 1 to j bit position 370 movel %d1,%d6 |copy ls mant into d6 371 lsll %d7,%d6 |shift ls mant by count 372 movel %d6,LOCAL_LO(%a0) |store ls mant into memory 373 moveql #32,%d6 374 subl %d7,%d6 |continue shift 375 lsrl %d6,%d1 |shift off all bits but those that will 376 | ;be shifted into ms mant 377 orl %d1,%d0 |shift the ls mant bits into the ms mant 378 movel %d0,LOCAL_HI(%a0) |store ms mant into memory 379 moveml (%a7)+,%d7/%d6 |restore registers 380 rts 381 382 | 383 | We get here if ms mant was = 0, and we assume ls mant has bits 384 | set (otherwise this would have been tagged a zero not a denorm). 385 | 386 lower: 387 movew LOCAL_EX(%a0),%d0 |d0 has exponent 388 movel LOCAL_LO(%a0),%d1 |d1 has ls mant 389 subw #32,%d0 |account for ms mant being all zeros 390 bfffo %d1{#0:#32},%d7 |find first 1 in ls mant to d7) 391 subw %d7,%d0 |subtract shift count from exp 392 lsll %d7,%d1 |shift first 1 to integer bit in ms mant 393 movew %d0,LOCAL_EX(%a0) |store ms mant 394 movel %d1,LOCAL_HI(%a0) |store exp 395 clrl LOCAL_LO(%a0) |clear ls mant 396 movel (%a7)+,%d7 397 rts 398 | 399 | denorm --- denormalize an intermediate result 400 | 401 | Used by underflow. 402 | 403 | Input: 404 | a0 points to the operand to be denormalized 405 | (in the internal extended format) 406 | 407 | d0: rounding precision 408 | Output: 409 | a0 points to the denormalized result 410 | (in the internal extended format) 411 | 412 | d0 is guard,round,sticky 413 | 414 | d0 comes into this routine with the rounding precision. It 415 | is then loaded with the denormalized exponent threshold for the 416 | rounding precision. 417 | 418 419 .global denorm 420 denorm: 421 btstb #6,LOCAL_EX(%a0) |check for exponents between $7fff-$4000 422 beqs no_sgn_ext 423 bsetb #7,LOCAL_EX(%a0) |sign extend if it is so 424 no_sgn_ext: 425 426 cmpib #0,%d0 |if 0 then extended precision 427 bnes not_ext |else branch 428 429 clrl %d1 |load d1 with ext threshold 430 clrl %d0 |clear the sticky flag 431 bsr dnrm_lp |denormalize the number 432 tstb %d1 |check for inex 433 beq no_inex |if clr, no inex 434 bras dnrm_inex |if set, set inex 435 436 not_ext: 437 cmpil #1,%d0 |if 1 then single precision 438 beqs load_sgl |else must be 2, double prec 439 440 load_dbl: 441 movew #dbl_thresh,%d1 |put copy of threshold in d1 442 movel %d1,%d0 |copy d1 into d0 443 subw LOCAL_EX(%a0),%d0 |diff = threshold - exp 444 cmpw #67,%d0 |if diff > 67 (mant + grs bits) 445 bpls chk_stky |then branch (all bits would be 446 | ; shifted off in denorm routine) 447 clrl %d0 |else clear the sticky flag 448 bsr dnrm_lp |denormalize the number 449 tstb %d1 |check flag 450 beqs no_inex |if clr, no inex 451 bras dnrm_inex |if set, set inex 452 453 load_sgl: 454 movew #sgl_thresh,%d1 |put copy of threshold in d1 455 movel %d1,%d0 |copy d1 into d0 456 subw LOCAL_EX(%a0),%d0 |diff = threshold - exp 457 cmpw #67,%d0 |if diff > 67 (mant + grs bits) 458 bpls chk_stky |then branch (all bits would be 459 | ; shifted off in denorm routine) 460 clrl %d0 |else clear the sticky flag 461 bsr dnrm_lp |denormalize the number 462 tstb %d1 |check flag 463 beqs no_inex |if clr, no inex 464 bras dnrm_inex |if set, set inex 465 466 chk_stky: 467 tstl LOCAL_HI(%a0) |check for any bits set 468 bnes set_stky 469 tstl LOCAL_LO(%a0) |check for any bits set 470 bnes set_stky 471 bras clr_mant 472 set_stky: 473 orl #inx2a_mask,USER_FPSR(%a6) |set inex2/ainex 474 movel #0x20000000,%d0 |set sticky bit in return value 475 clr_mant: 476 movew %d1,LOCAL_EX(%a0) |load exp with threshold 477 movel #0,LOCAL_HI(%a0) |set d1 = 0 (ms mantissa) 478 movel #0,LOCAL_LO(%a0) |set d2 = 0 (ms mantissa) 479 rts 480 dnrm_inex: 481 orl #inx2a_mask,USER_FPSR(%a6) |set inex2/ainex 482 no_inex: 483 rts 484 485 | 486 | dnrm_lp --- normalize exponent/mantissa to specified threshold 487 | 488 | Input: 489 | a0 points to the operand to be denormalized 490 | d0{31:29} initial guard,round,sticky 491 | d1{15:0} denormalization threshold 492 | Output: 493 | a0 points to the denormalized operand 494 | d0{31:29} final guard,round,sticky 495 | d1.b inexact flag: all ones means inexact result 496 | 497 | The LOCAL_LO and LOCAL_GRS parts of the value are copied to FP_SCR2 498 | so that bfext can be used to extract the new low part of the mantissa. 499 | Dnrm_lp can be called with a0 pointing to ETEMP or WBTEMP and there 500 | is no LOCAL_GRS scratch word following it on the fsave frame. 501 | 502 .global dnrm_lp 503 dnrm_lp: 504 movel %d2,-(%sp) |save d2 for temp use 505 btstb #E3,E_BYTE(%a6) |test for type E3 exception 506 beqs not_E3 |not type E3 exception 507 bfextu WBTEMP_GRS(%a6){#6:#3},%d2 |extract guard,round, sticky bit 508 movel #29,%d0 509 lsll %d0,%d2 |shift g,r,s to their positions 510 movel %d2,%d0 511 not_E3: 512 movel (%sp)+,%d2 |restore d2 513 movel LOCAL_LO(%a0),FP_SCR2+LOCAL_LO(%a6) 514 movel %d0,FP_SCR2+LOCAL_GRS(%a6) 515 movel %d1,%d0 |copy the denorm threshold 516 subw LOCAL_EX(%a0),%d1 |d1 = threshold - uns exponent 517 bles no_lp |d1 <= 0 518 cmpw #32,%d1 519 blts case_1 |0 = d1 < 32 520 cmpw #64,%d1 521 blts case_2 |32 <= d1 < 64 522 bra case_3 |d1 >= 64 523 | 524 | No normalization necessary 525 | 526 no_lp: 527 clrb %d1 |set no inex2 reported 528 movel FP_SCR2+LOCAL_GRS(%a6),%d0 |restore original g,r,s 529 rts 530 | 531 | case (0<d1<32) 532 | 533 case_1: 534 movel %d2,-(%sp) 535 movew %d0,LOCAL_EX(%a0) |exponent = denorm threshold 536 movel #32,%d0 537 subw %d1,%d0 |d0 = 32 - d1 538 bfextu LOCAL_EX(%a0){%d0:#32},%d2 539 bfextu %d2{%d1:%d0},%d2 |d2 = new LOCAL_HI 540 bfextu LOCAL_HI(%a0){%d0:#32},%d1 |d1 = new LOCAL_LO 541 bfextu FP_SCR2+LOCAL_LO(%a6){%d0:#32},%d0 |d0 = new G,R,S 542 movel %d2,LOCAL_HI(%a0) |store new LOCAL_HI 543 movel %d1,LOCAL_LO(%a0) |store new LOCAL_LO 544 clrb %d1 545 bftst %d0{#2:#30} 546 beqs c1nstky 547 bsetl #rnd_stky_bit,%d0 548 st %d1 549 c1nstky: 550 movel FP_SCR2+LOCAL_GRS(%a6),%d2 |restore original g,r,s 551 andil #0xe0000000,%d2 |clear all but G,R,S 552 tstl %d2 |test if original G,R,S are clear 553 beqs grs_clear 554 orl #0x20000000,%d0 |set sticky bit in d0 555 grs_clear: 556 andil #0xe0000000,%d0 |clear all but G,R,S 557 movel (%sp)+,%d2 558 rts 559 | 560 | case (32<=d1<64) 561 | 562 case_2: 563 movel %d2,-(%sp) 564 movew %d0,LOCAL_EX(%a0) |unsigned exponent = threshold 565 subw #32,%d1 |d1 now between 0 and 32 566 movel #32,%d0 567 subw %d1,%d0 |d0 = 32 - d1 568 bfextu LOCAL_EX(%a0){%d0:#32},%d2 569 bfextu %d2{%d1:%d0},%d2 |d2 = new LOCAL_LO 570 bfextu LOCAL_HI(%a0){%d0:#32},%d1 |d1 = new G,R,S 571 bftst %d1{#2:#30} 572 bnes c2_sstky |bra if sticky bit to be set 573 bftst FP_SCR2+LOCAL_LO(%a6){%d0:#32} 574 bnes c2_sstky |bra if sticky bit to be set 575 movel %d1,%d0 576 clrb %d1 577 bras end_c2 578 c2_sstky: 579 movel %d1,%d0 580 bsetl #rnd_stky_bit,%d0 581 st %d1 582 end_c2: 583 clrl LOCAL_HI(%a0) |store LOCAL_HI = 0 584 movel %d2,LOCAL_LO(%a0) |store LOCAL_LO 585 movel FP_SCR2+LOCAL_GRS(%a6),%d2 |restore original g,r,s 586 andil #0xe0000000,%d2 |clear all but G,R,S 587 tstl %d2 |test if original G,R,S are clear 588 beqs clear_grs 589 orl #0x20000000,%d0 |set sticky bit in d0 590 clear_grs: 591 andil #0xe0000000,%d0 |get rid of all but G,R,S 592 movel (%sp)+,%d2 593 rts 594 | 595 | d1 >= 64 Force the exponent to be the denorm threshold with the 596 | correct sign. 597 | 598 case_3: 599 movew %d0,LOCAL_EX(%a0) 600 tstw LOCAL_SGN(%a0) 601 bges c3con 602 c3neg: 603 orl #0x80000000,LOCAL_EX(%a0) 604 c3con: 605 cmpw #64,%d1 606 beqs sixty_four 607 cmpw #65,%d1 608 beqs sixty_five 609 | 610 | Shift value is out of range. Set d1 for inex2 flag and 611 | return a zero with the given threshold. 612 | 613 clrl LOCAL_HI(%a0) 614 clrl LOCAL_LO(%a0) 615 movel #0x20000000,%d0 616 st %d1 617 rts 618 619 sixty_four: 620 movel LOCAL_HI(%a0),%d0 621 bfextu %d0{#2:#30},%d1 622 andil #0xc0000000,%d0 623 bras c3com 624 625 sixty_five: 626 movel LOCAL_HI(%a0),%d0 627 bfextu %d0{#1:#31},%d1 628 andil #0x80000000,%d0 629 lsrl #1,%d0 |shift high bit into R bit 630 631 c3com: 632 tstl %d1 633 bnes c3ssticky 634 tstl LOCAL_LO(%a0) 635 bnes c3ssticky 636 tstb FP_SCR2+LOCAL_GRS(%a6) 637 bnes c3ssticky 638 clrb %d1 639 bras c3end 640 641 c3ssticky: 642 bsetl #rnd_stky_bit,%d0 643 st %d1 644 c3end: 645 clrl LOCAL_HI(%a0) 646 clrl LOCAL_LO(%a0) 647 rts 648 649 |end