![]() |
|
|||
File indexing completed on 2025-05-11 08:23:48
0001 #include "fpsp-namespace.h" 0002 // 0003 // 0004 // round.sa 3.4 7/29/91 0005 // 0006 // handle rounding and normalization tasks 0007 // 0008 // 0009 // 0010 // Copyright (C) Motorola, Inc. 1990 0011 // All Rights Reserved 0012 // 0013 // THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA 0014 // The copyright notice above does not evidence any 0015 // actual or intended publication of such source code. 0016 0017 //ROUND idnt 2,1 | Motorola 040 Floating Point Software Package 0018 0019 |section 8 0020 0021 #include "fpsp.defs" 0022 0023 // 0024 // round --- round result according to precision/mode 0025 // 0026 // a0 points to the input operand in the internal extended format 0027 // d1(high word) contains rounding precision: 0028 // ext = $0000xxxx 0029 // sgl = $0001xxxx 0030 // dbl = $0002xxxx 0031 // d1(low word) contains rounding mode: 0032 // RN = $xxxx0000 0033 // RZ = $xxxx0001 0034 // RM = $xxxx0010 0035 // RP = $xxxx0011 0036 // d0{31:29} contains the g,r,s bits (extended) 0037 // 0038 // On return the value pointed to by a0 is correctly rounded, 0039 // a0 is preserved and the g-r-s bits in d0 are cleared. 0040 // The result is not typed - the tag field is invalid. The 0041 // result is still in the internal extended format. 0042 // 0043 // The INEX bit of USER_FPSR will be set if the rounded result was 0044 // inexact (i.e. if any of the g-r-s bits were set). 0045 // 0046 0047 .global round 0048 round: 0049 // If g=r=s=0 then result is exact and round is done, else set 0050 // the inex flag in status reg and continue. 0051 // 0052 bsrs ext_grs //this subroutine looks at the 0053 // :rounding precision and sets 0054 // ;the appropriate g-r-s bits. 0055 tstl %d0 //if grs are zero, go force 0056 bne rnd_cont //lower bits to zero for size 0057 0058 swap %d1 //set up d1.w for round prec. 0059 bra truncate 0060 0061 rnd_cont: 0062 // 0063 // Use rounding mode as an index into a jump table for these modes. 0064 // 0065 orl #inx2a_mask,USER_FPSR(%a6) //set inex2/ainex 0066 lea mode_tab,%a1 0067 movel (%a1,%d1.w*4),%a1 0068 jmp (%a1) 0069 // 0070 // Jump table indexed by rounding mode in d1.w. All following assumes 0071 // grs != 0. 0072 // 0073 mode_tab: 0074 .long rnd_near 0075 .long rnd_zero 0076 .long rnd_mnus 0077 .long rnd_plus 0078 // 0079 // ROUND PLUS INFINITY 0080 // 0081 // If sign of fp number = 0 (positive), then add 1 to l. 0082 // 0083 rnd_plus: 0084 swap %d1 //set up d1 for round prec. 0085 tstb LOCAL_SGN(%a0) //check for sign 0086 bmi truncate //if positive then truncate 0087 movel #0xffffffff,%d0 //force g,r,s to be all f's 0088 lea add_to_l,%a1 0089 movel (%a1,%d1.w*4),%a1 0090 jmp (%a1) 0091 // 0092 // ROUND MINUS INFINITY 0093 // 0094 // If sign of fp number = 1 (negative), then add 1 to l. 0095 // 0096 rnd_mnus: 0097 swap %d1 //set up d1 for round prec. 0098 tstb LOCAL_SGN(%a0) //check for sign 0099 bpl truncate //if negative then truncate 0100 movel #0xffffffff,%d0 //force g,r,s to be all f's 0101 lea add_to_l,%a1 0102 movel (%a1,%d1.w*4),%a1 0103 jmp (%a1) 0104 // 0105 // ROUND ZERO 0106 // 0107 // Always truncate. 0108 rnd_zero: 0109 swap %d1 //set up d1 for round prec. 0110 bra truncate 0111 // 0112 // 0113 // ROUND NEAREST 0114 // 0115 // If (g=1), then add 1 to l and if (r=s=0), then clear l 0116 // Note that this will round to even in case of a tie. 0117 // 0118 rnd_near: 0119 swap %d1 //set up d1 for round prec. 0120 asll #1,%d0 //shift g-bit to c-bit 0121 bcc truncate //if (g=1) then 0122 lea add_to_l,%a1 0123 movel (%a1,%d1.w*4),%a1 0124 jmp (%a1) 0125 0126 // 0127 // ext_grs --- extract guard, round and sticky bits 0128 // 0129 // Input: d1 = PREC:ROUND 0130 // Output: d0{31:29}= guard, round, sticky 0131 // 0132 // The ext_grs extract the guard/round/sticky bits according to the 0133 // selected rounding precision. It is called by the round subroutine 0134 // only. All registers except d0 are kept intact. d0 becomes an 0135 // updated guard,round,sticky in d0{31:29} 0136 // 0137 // Notes: the ext_grs uses the round PREC, and therefore has to swap d1 0138 // prior to usage, and needs to restore d1 to original. 0139 // 0140 ext_grs: 0141 swap %d1 //have d1.w point to round precision 0142 cmpiw #0,%d1 0143 bnes sgl_or_dbl 0144 bras end_ext_grs 0145 0146 sgl_or_dbl: 0147 moveml %d2/%d3,-(%a7) //make some temp registers 0148 cmpiw #1,%d1 0149 bnes grs_dbl 0150 grs_sgl: 0151 bfextu LOCAL_HI(%a0){#24:#2},%d3 //sgl prec. g-r are 2 bits right 0152 movel #30,%d2 //of the sgl prec. limits 0153 lsll %d2,%d3 //shift g-r bits to MSB of d3 0154 movel LOCAL_HI(%a0),%d2 //get word 2 for s-bit test 0155 andil #0x0000003f,%d2 //s bit is the or of all other 0156 bnes st_stky //bits to the right of g-r 0157 tstl LOCAL_LO(%a0) //test lower mantissa 0158 bnes st_stky //if any are set, set sticky 0159 tstl %d0 //test original g,r,s 0160 bnes st_stky //if any are set, set sticky 0161 bras end_sd //if words 3 and 4 are clr, exit 0162 grs_dbl: 0163 bfextu LOCAL_LO(%a0){#21:#2},%d3 //dbl-prec. g-r are 2 bits right 0164 movel #30,%d2 //of the dbl prec. limits 0165 lsll %d2,%d3 //shift g-r bits to the MSB of d3 0166 movel LOCAL_LO(%a0),%d2 //get lower mantissa for s-bit test 0167 andil #0x000001ff,%d2 //s bit is the or-ing of all 0168 bnes st_stky //other bits to the right of g-r 0169 tstl %d0 //test word original g,r,s 0170 bnes st_stky //if any are set, set sticky 0171 bras end_sd //if clear, exit 0172 st_stky: 0173 bset #rnd_stky_bit,%d3 0174 end_sd: 0175 movel %d3,%d0 //return grs to d0 0176 moveml (%a7)+,%d2/%d3 //restore scratch registers 0177 end_ext_grs: 0178 swap %d1 //restore d1 to original 0179 rts 0180 0181 //******************* Local Equates 0182 .set ad_1_sgl,0x00000100 // constant to add 1 to l-bit in sgl prec 0183 .set ad_1_dbl,0x00000800 // constant to add 1 to l-bit in dbl prec 0184 0185 0186 //Jump table for adding 1 to the l-bit indexed by rnd prec 0187 0188 add_to_l: 0189 .long add_ext 0190 .long add_sgl 0191 .long add_dbl 0192 .long add_dbl 0193 // 0194 // ADD SINGLE 0195 // 0196 add_sgl: 0197 addl #ad_1_sgl,LOCAL_HI(%a0) 0198 bccs scc_clr //no mantissa overflow 0199 roxrw LOCAL_HI(%a0) //shift v-bit back in 0200 roxrw LOCAL_HI+2(%a0) //shift v-bit back in 0201 addw #0x1,LOCAL_EX(%a0) //and incr exponent 0202 scc_clr: 0203 tstl %d0 //test for rs = 0 0204 bnes sgl_done 0205 andiw #0xfe00,LOCAL_HI+2(%a0) //clear the l-bit 0206 sgl_done: 0207 andil #0xffffff00,LOCAL_HI(%a0) //truncate bits beyond sgl limit 0208 clrl LOCAL_LO(%a0) //clear d2 0209 rts 0210 0211 // 0212 // ADD EXTENDED 0213 // 0214 add_ext: 0215 addql #1,LOCAL_LO(%a0) //add 1 to l-bit 0216 bccs xcc_clr //test for carry out 0217 addql #1,LOCAL_HI(%a0) //propagate carry 0218 bccs xcc_clr 0219 roxrw LOCAL_HI(%a0) //mant is 0 so restore v-bit 0220 roxrw LOCAL_HI+2(%a0) //mant is 0 so restore v-bit 0221 roxrw LOCAL_LO(%a0) 0222 roxrw LOCAL_LO+2(%a0) 0223 addw #0x1,LOCAL_EX(%a0) //and inc exp 0224 xcc_clr: 0225 tstl %d0 //test rs = 0 0226 bnes add_ext_done 0227 andib #0xfe,LOCAL_LO+3(%a0) //clear the l bit 0228 add_ext_done: 0229 rts 0230 // 0231 // ADD DOUBLE 0232 // 0233 add_dbl: 0234 addl #ad_1_dbl,LOCAL_LO(%a0) 0235 bccs dcc_clr 0236 addql #1,LOCAL_HI(%a0) //propagate carry 0237 bccs dcc_clr 0238 roxrw LOCAL_HI(%a0) //mant is 0 so restore v-bit 0239 roxrw LOCAL_HI+2(%a0) //mant is 0 so restore v-bit 0240 roxrw LOCAL_LO(%a0) 0241 roxrw LOCAL_LO+2(%a0) 0242 addw #0x1,LOCAL_EX(%a0) //incr exponent 0243 dcc_clr: 0244 tstl %d0 //test for rs = 0 0245 bnes dbl_done 0246 andiw #0xf000,LOCAL_LO+2(%a0) //clear the l-bit 0247 0248 dbl_done: 0249 andil #0xfffff800,LOCAL_LO(%a0) //truncate bits beyond dbl limit 0250 rts 0251 0252 error: 0253 rts 0254 // 0255 // Truncate all other bits 0256 // 0257 trunct: 0258 .long end_rnd 0259 .long sgl_done 0260 .long dbl_done 0261 .long dbl_done 0262 0263 truncate: 0264 lea trunct,%a1 0265 movel (%a1,%d1.w*4),%a1 0266 jmp (%a1) 0267 0268 end_rnd: 0269 rts 0270 0271 // 0272 // NORMALIZE 0273 // 0274 // These routines (nrm_zero & nrm_set) normalize the unnorm. This 0275 // is done by shifting the mantissa left while decrementing the 0276 // exponent. 0277 // 0278 // NRM_SET shifts and decrements until there is a 1 set in the integer 0279 // bit of the mantissa (msb in d1). 0280 // 0281 // NRM_ZERO shifts and decrements until there is a 1 set in the integer 0282 // bit of the mantissa (msb in d1) unless this would mean the exponent 0283 // would go less than 0. In that case the number becomes a denorm - the 0284 // exponent (d0) is set to 0 and the mantissa (d1 & d2) is not 0285 // normalized. 0286 // 0287 // Note that both routines have been optimized (for the worst case) and 0288 // therefore do not have the easy to follow decrement/shift loop. 0289 // 0290 // NRM_ZERO 0291 // 0292 // Distance to first 1 bit in mantissa = X 0293 // Distance to 0 from exponent = Y 0294 // If X < Y 0295 // Then 0296 // nrm_set 0297 // Else 0298 // shift mantissa by Y 0299 // set exponent = 0 0300 // 0301 //input: 0302 // FP_SCR1 = exponent, ms mantissa part, ls mantissa part 0303 //output: 0304 // L_SCR1{4} = fpte15 or ete15 bit 0305 // 0306 .global nrm_zero 0307 nrm_zero: 0308 movew LOCAL_EX(%a0),%d0 0309 cmpw #64,%d0 //see if exp > 64 0310 bmis d0_less 0311 bsr nrm_set //exp > 64 so exp won't exceed 0 0312 rts 0313 d0_less: 0314 moveml %d2/%d3/%d5/%d6,-(%a7) 0315 movel LOCAL_HI(%a0),%d1 0316 movel LOCAL_LO(%a0),%d2 0317 0318 bfffo %d1{#0:#32},%d3 //get the distance to the first 1 0319 // ;in ms mant 0320 beqs ms_clr //branch if no bits were set 0321 cmpw %d3,%d0 //of X>Y 0322 bmis greater //then exp will go past 0 (neg) if 0323 // ;it is just shifted 0324 bsr nrm_set //else exp won't go past 0 0325 moveml (%a7)+,%d2/%d3/%d5/%d6 0326 rts 0327 greater: 0328 movel %d2,%d6 //save ls mant in d6 0329 lsll %d0,%d2 //shift ls mant by count 0330 lsll %d0,%d1 //shift ms mant by count 0331 movel #32,%d5 0332 subl %d0,%d5 //make op a denorm by shifting bits 0333 lsrl %d5,%d6 //by the number in the exp, then 0334 // ;set exp = 0. 0335 orl %d6,%d1 //shift the ls mant bits into the ms mant 0336 movel #0,%d0 //same as if decremented exp to 0 0337 // ;while shifting 0338 movew %d0,LOCAL_EX(%a0) 0339 movel %d1,LOCAL_HI(%a0) 0340 movel %d2,LOCAL_LO(%a0) 0341 moveml (%a7)+,%d2/%d3/%d5/%d6 0342 rts 0343 ms_clr: 0344 bfffo %d2{#0:#32},%d3 //check if any bits set in ls mant 0345 beqs all_clr //branch if none set 0346 addw #32,%d3 0347 cmpw %d3,%d0 //if X>Y 0348 bmis greater //then branch 0349 bsr nrm_set //else exp won't go past 0 0350 moveml (%a7)+,%d2/%d3/%d5/%d6 0351 rts 0352 all_clr: 0353 movew #0,LOCAL_EX(%a0) //no mantissa bits set. Set exp = 0. 0354 moveml (%a7)+,%d2/%d3/%d5/%d6 0355 rts 0356 // 0357 // NRM_SET 0358 // 0359 .global nrm_set 0360 nrm_set: 0361 movel %d7,-(%a7) 0362 bfffo LOCAL_HI(%a0){#0:#32},%d7 //find first 1 in ms mant to d7) 0363 beqs lower //branch if ms mant is all 0's 0364 0365 movel %d6,-(%a7) 0366 0367 subw %d7,LOCAL_EX(%a0) //sub exponent by count 0368 movel LOCAL_HI(%a0),%d0 //d0 has ms mant 0369 movel LOCAL_LO(%a0),%d1 //d1 has ls mant 0370 0371 lsll %d7,%d0 //shift first 1 to j bit position 0372 movel %d1,%d6 //copy ls mant into d6 0373 lsll %d7,%d6 //shift ls mant by count 0374 movel %d6,LOCAL_LO(%a0) //store ls mant into memory 0375 moveql #32,%d6 0376 subl %d7,%d6 //continue shift 0377 lsrl %d6,%d1 //shift off all bits but those that will 0378 // ;be shifted into ms mant 0379 orl %d1,%d0 //shift the ls mant bits into the ms mant 0380 movel %d0,LOCAL_HI(%a0) //store ms mant into memory 0381 moveml (%a7)+,%d7/%d6 //restore registers 0382 rts 0383 0384 // 0385 // We get here if ms mant was = 0, and we assume ls mant has bits 0386 // set (otherwise this would have been tagged a zero not a denorm). 0387 // 0388 lower: 0389 movew LOCAL_EX(%a0),%d0 //d0 has exponent 0390 movel LOCAL_LO(%a0),%d1 //d1 has ls mant 0391 subw #32,%d0 //account for ms mant being all zeros 0392 bfffo %d1{#0:#32},%d7 //find first 1 in ls mant to d7) 0393 subw %d7,%d0 //subtract shift count from exp 0394 lsll %d7,%d1 //shift first 1 to integer bit in ms mant 0395 movew %d0,LOCAL_EX(%a0) //store ms mant 0396 movel %d1,LOCAL_HI(%a0) //store exp 0397 clrl LOCAL_LO(%a0) //clear ls mant 0398 movel (%a7)+,%d7 0399 rts 0400 // 0401 // denorm --- denormalize an intermediate result 0402 // 0403 // Used by underflow. 0404 // 0405 // Input: 0406 // a0 points to the operand to be denormalized 0407 // (in the internal extended format) 0408 // 0409 // d0: rounding precision 0410 // Output: 0411 // a0 points to the denormalized result 0412 // (in the internal extended format) 0413 // 0414 // d0 is guard,round,sticky 0415 // 0416 // d0 comes into this routine with the rounding precision. It 0417 // is then loaded with the denormalized exponent threshold for the 0418 // rounding precision. 0419 // 0420 0421 .global denorm 0422 denorm: 0423 btstb #6,LOCAL_EX(%a0) //check for exponents between $7fff-$4000 0424 beqs no_sgn_ext 0425 bsetb #7,LOCAL_EX(%a0) //sign extend if it is so 0426 no_sgn_ext: 0427 0428 cmpib #0,%d0 //if 0 then extended precision 0429 bnes not_ext //else branch 0430 0431 clrl %d1 //load d1 with ext threshold 0432 clrl %d0 //clear the sticky flag 0433 bsr dnrm_lp //denormalize the number 0434 tstb %d1 //check for inex 0435 beq no_inex //if clr, no inex 0436 bras dnrm_inex //if set, set inex 0437 0438 not_ext: 0439 cmpil #1,%d0 //if 1 then single precision 0440 beqs load_sgl //else must be 2, double prec 0441 0442 load_dbl: 0443 movew #dbl_thresh,%d1 //put copy of threshold in d1 0444 movel %d1,%d0 //copy d1 into d0 0445 subw LOCAL_EX(%a0),%d0 //diff = threshold - exp 0446 cmpw #67,%d0 //if diff > 67 (mant + grs bits) 0447 bpls chk_stky //then branch (all bits would be 0448 // ; shifted off in denorm routine) 0449 clrl %d0 //else clear the sticky flag 0450 bsr dnrm_lp //denormalize the number 0451 tstb %d1 //check flag 0452 beqs no_inex //if clr, no inex 0453 bras dnrm_inex //if set, set inex 0454 0455 load_sgl: 0456 movew #sgl_thresh,%d1 //put copy of threshold in d1 0457 movel %d1,%d0 //copy d1 into d0 0458 subw LOCAL_EX(%a0),%d0 //diff = threshold - exp 0459 cmpw #67,%d0 //if diff > 67 (mant + grs bits) 0460 bpls chk_stky //then branch (all bits would be 0461 // ; shifted off in denorm routine) 0462 clrl %d0 //else clear the sticky flag 0463 bsr dnrm_lp //denormalize the number 0464 tstb %d1 //check flag 0465 beqs no_inex //if clr, no inex 0466 bras dnrm_inex //if set, set inex 0467 0468 chk_stky: 0469 tstl LOCAL_HI(%a0) //check for any bits set 0470 bnes set_stky 0471 tstl LOCAL_LO(%a0) //check for any bits set 0472 bnes set_stky 0473 bras clr_mant 0474 set_stky: 0475 orl #inx2a_mask,USER_FPSR(%a6) //set inex2/ainex 0476 movel #0x20000000,%d0 //set sticky bit in return value 0477 clr_mant: 0478 movew %d1,LOCAL_EX(%a0) //load exp with threshold 0479 movel #0,LOCAL_HI(%a0) //set d1 = 0 (ms mantissa) 0480 movel #0,LOCAL_LO(%a0) //set d2 = 0 (ms mantissa) 0481 rts 0482 dnrm_inex: 0483 orl #inx2a_mask,USER_FPSR(%a6) //set inex2/ainex 0484 no_inex: 0485 rts 0486 0487 // 0488 // dnrm_lp --- normalize exponent/mantissa to specified threshold 0489 // 0490 // Input: 0491 // a0 points to the operand to be denormalized 0492 // d0{31:29} initial guard,round,sticky 0493 // d1{15:0} denormalization threshold 0494 // Output: 0495 // a0 points to the denormalized operand 0496 // d0{31:29} final guard,round,sticky 0497 // d1.b inexact flag: all ones means inexact result 0498 // 0499 // The LOCAL_LO and LOCAL_GRS parts of the value are copied to FP_SCR2 0500 // so that bfext can be used to extract the new low part of the mantissa. 0501 // Dnrm_lp can be called with a0 pointing to ETEMP or WBTEMP and there 0502 // is no LOCAL_GRS scratch word following it on the fsave frame. 0503 // 0504 .global dnrm_lp 0505 dnrm_lp: 0506 movel %d2,-(%sp) //save d2 for temp use 0507 btstb #E3,E_BYTE(%a6) //test for type E3 exception 0508 beqs not_E3 //not type E3 exception 0509 bfextu WBTEMP_GRS(%a6){#6:#3},%d2 //extract guard,round, sticky bit 0510 movel #29,%d0 0511 lsll %d0,%d2 //shift g,r,s to their positions 0512 movel %d2,%d0 0513 not_E3: 0514 movel (%sp)+,%d2 //restore d2 0515 movel LOCAL_LO(%a0),FP_SCR2+LOCAL_LO(%a6) 0516 movel %d0,FP_SCR2+LOCAL_GRS(%a6) 0517 movel %d1,%d0 //copy the denorm threshold 0518 subw LOCAL_EX(%a0),%d1 //d1 = threshold - uns exponent 0519 bles no_lp //d1 <= 0 0520 cmpw #32,%d1 0521 blts case_1 //0 = d1 < 32 0522 cmpw #64,%d1 0523 blts case_2 //32 <= d1 < 64 0524 bra case_3 //d1 >= 64 0525 // 0526 // No normalization necessary 0527 // 0528 no_lp: 0529 clrb %d1 //set no inex2 reported 0530 movel FP_SCR2+LOCAL_GRS(%a6),%d0 //restore original g,r,s 0531 rts 0532 // 0533 // case (0<d1<32) 0534 // 0535 case_1: 0536 movel %d2,-(%sp) 0537 movew %d0,LOCAL_EX(%a0) //exponent = denorm threshold 0538 movel #32,%d0 0539 subw %d1,%d0 //d0 = 32 - d1 0540 bfextu LOCAL_EX(%a0){%d0:#32},%d2 0541 bfextu %d2{%d1:%d0},%d2 //d2 = new LOCAL_HI 0542 bfextu LOCAL_HI(%a0){%d0:#32},%d1 //d1 = new LOCAL_LO 0543 bfextu FP_SCR2+LOCAL_LO(%a6){%d0:#32},%d0 //d0 = new G,R,S 0544 movel %d2,LOCAL_HI(%a0) //store new LOCAL_HI 0545 movel %d1,LOCAL_LO(%a0) //store new LOCAL_LO 0546 clrb %d1 0547 bftst %d0{#2:#30} 0548 beqs c1nstky 0549 bsetl #rnd_stky_bit,%d0 0550 st %d1 0551 c1nstky: 0552 movel FP_SCR2+LOCAL_GRS(%a6),%d2 //restore original g,r,s 0553 andil #0xe0000000,%d2 //clear all but G,R,S 0554 tstl %d2 //test if original G,R,S are clear 0555 beqs grs_clear 0556 orl #0x20000000,%d0 //set sticky bit in d0 0557 grs_clear: 0558 andil #0xe0000000,%d0 //clear all but G,R,S 0559 movel (%sp)+,%d2 0560 rts 0561 // 0562 // case (32<=d1<64) 0563 // 0564 case_2: 0565 movel %d2,-(%sp) 0566 movew %d0,LOCAL_EX(%a0) //unsigned exponent = threshold 0567 subw #32,%d1 //d1 now between 0 and 32 0568 movel #32,%d0 0569 subw %d1,%d0 //d0 = 32 - d1 0570 bfextu LOCAL_EX(%a0){%d0:#32},%d2 0571 bfextu %d2{%d1:%d0},%d2 //d2 = new LOCAL_LO 0572 bfextu LOCAL_HI(%a0){%d0:#32},%d1 //d1 = new G,R,S 0573 bftst %d1{#2:#30} 0574 bnes c2_sstky //bra if sticky bit to be set 0575 bftst FP_SCR2+LOCAL_LO(%a6){%d0:#32} 0576 bnes c2_sstky //bra if sticky bit to be set 0577 movel %d1,%d0 0578 clrb %d1 0579 bras end_c2 0580 c2_sstky: 0581 movel %d1,%d0 0582 bsetl #rnd_stky_bit,%d0 0583 st %d1 0584 end_c2: 0585 clrl LOCAL_HI(%a0) //store LOCAL_HI = 0 0586 movel %d2,LOCAL_LO(%a0) //store LOCAL_LO 0587 movel FP_SCR2+LOCAL_GRS(%a6),%d2 //restore original g,r,s 0588 andil #0xe0000000,%d2 //clear all but G,R,S 0589 tstl %d2 //test if original G,R,S are clear 0590 beqs clear_grs 0591 orl #0x20000000,%d0 //set sticky bit in d0 0592 clear_grs: 0593 andil #0xe0000000,%d0 //get rid of all but G,R,S 0594 movel (%sp)+,%d2 0595 rts 0596 // 0597 // d1 >= 64 Force the exponent to be the denorm threshold with the 0598 // correct sign. 0599 // 0600 case_3: 0601 movew %d0,LOCAL_EX(%a0) 0602 tstw LOCAL_SGN(%a0) 0603 bges c3con 0604 c3neg: 0605 orl #0x80000000,LOCAL_EX(%a0) 0606 c3con: 0607 cmpw #64,%d1 0608 beqs sixty_four 0609 cmpw #65,%d1 0610 beqs sixty_five 0611 // 0612 // Shift value is out of range. Set d1 for inex2 flag and 0613 // return a zero with the given threshold. 0614 // 0615 clrl LOCAL_HI(%a0) 0616 clrl LOCAL_LO(%a0) 0617 movel #0x20000000,%d0 0618 st %d1 0619 rts 0620 0621 sixty_four: 0622 movel LOCAL_HI(%a0),%d0 0623 bfextu %d0{#2:#30},%d1 0624 andil #0xc0000000,%d0 0625 bras c3com 0626 0627 sixty_five: 0628 movel LOCAL_HI(%a0),%d0 0629 bfextu %d0{#1:#31},%d1 0630 andil #0x80000000,%d0 0631 lsrl #1,%d0 //shift high bit into R bit 0632 0633 c3com: 0634 tstl %d1 0635 bnes c3ssticky 0636 tstl LOCAL_LO(%a0) 0637 bnes c3ssticky 0638 tstb FP_SCR2+LOCAL_GRS(%a6) 0639 bnes c3ssticky 0640 clrb %d1 0641 bras c3end 0642 0643 c3ssticky: 0644 bsetl #rnd_stky_bit,%d0 0645 st %d1 0646 c3end: 0647 clrl LOCAL_HI(%a0) 0648 clrl LOCAL_LO(%a0) 0649 rts 0650 0651 |end
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |