1| 2| get_op.sa 3.6 5/19/92 3| 4| get_op.sa 3.5 4/26/91 5| 6| Description: This routine is called by the unsupported format/data 7| type exception handler ('unsupp' - vector 55) and the unimplemented 8| instruction exception handler ('unimp' - vector 11). 'get_op' 9| determines the opclass (0, 2, or 3) and branches to the 10| opclass handler routine. See 68881/2 User's Manual table 4-11 11| for a description of the opclasses. 12| 13| For UNSUPPORTED data/format (exception vector 55) and for 14| UNIMPLEMENTED instructions (exception vector 11) the following 15| applies: 16| 17| - For unnormalized numbers (opclass 0, 2, or 3) the 18| number(s) is normalized and the operand type tag is updated. 19| 20| - For a packed number (opclass 2) the number is unpacked and the 21| operand type tag is updated. 22| 23| - For denormalized numbers (opclass 0 or 2) the number(s) is not 24| changed but passed to the next module. The next module for 25| unimp is do_func, the next module for unsupp is res_func. 26| 27| For UNSUPPORTED data/format (exception vector 55) only the 28| following applies: 29| 30| - If there is a move out with a packed number (opclass 3) the 31| number is packed and written to user memory. For the other 32| opclasses the number(s) are written back to the fsave stack 33| and the instruction is then restored back into the '040. The 34| '040 is then able to complete the instruction. 35| 36| For example: 37| fadd.x fpm,fpn where the fpm contains an unnormalized number. 38| The '040 takes an unsupported data trap and gets to this 39| routine. The number is normalized, put back on the stack and 40| then an frestore is done to restore the instruction back into 41| the '040. The '040 then re-executes the fadd.x fpm,fpn with 42| a normalized number in the source and the instruction is 43| successful. 44| 45| Next consider if in the process of normalizing the un- 46| normalized number it becomes a denormalized number. The 47| routine which converts the unnorm to a norm (called mk_norm) 48| detects this and tags the number as a denorm. The routine 49| res_func sees the denorm tag and converts the denorm to a 50| norm. The instruction is then restored back into the '040 51| which re_executes the instruction. 52| 53| 54| Copyright (C) Motorola, Inc. 1990 55| All Rights Reserved 56| 57| THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA 58| The copyright notice above does not evidence any 59| actual or intended publication of such source code. 60 61GET_OP: |idnt 2,1 | Motorola 040 Floating Point Software Package 62 63 |section 8 64 65 .include "fpsp.h" 66 67 .global PIRN,PIRZRM,PIRP 68 .global SMALRN,SMALRZRM,SMALRP 69 .global BIGRN,BIGRZRM,BIGRP 70 71PIRN: 72 .long 0x40000000,0xc90fdaa2,0x2168c235 |pi 73PIRZRM: 74 .long 0x40000000,0xc90fdaa2,0x2168c234 |pi 75PIRP: 76 .long 0x40000000,0xc90fdaa2,0x2168c235 |pi 77 78|round to nearest 79SMALRN: 80 .long 0x3ffd0000,0x9a209a84,0xfbcff798 |log10(2) 81 .long 0x40000000,0xadf85458,0xa2bb4a9a |e 82 .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc |log2(e) 83 .long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e) 84 .long 0x00000000,0x00000000,0x00000000 |0.0 85| round to zero;round to negative infinity 86SMALRZRM: 87 .long 0x3ffd0000,0x9a209a84,0xfbcff798 |log10(2) 88 .long 0x40000000,0xadf85458,0xa2bb4a9a |e 89 .long 0x3fff0000,0xb8aa3b29,0x5c17f0bb |log2(e) 90 .long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e) 91 .long 0x00000000,0x00000000,0x00000000 |0.0 92| round to positive infinity 93SMALRP: 94 .long 0x3ffd0000,0x9a209a84,0xfbcff799 |log10(2) 95 .long 0x40000000,0xadf85458,0xa2bb4a9b |e 96 .long 0x3fff0000,0xb8aa3b29,0x5c17f0bc |log2(e) 97 .long 0x3ffd0000,0xde5bd8a9,0x37287195 |log10(e) 98 .long 0x00000000,0x00000000,0x00000000 |0.0 99 100|round to nearest 101BIGRN: 102 .long 0x3ffe0000,0xb17217f7,0xd1cf79ac |ln(2) 103 .long 0x40000000,0x935d8ddd,0xaaa8ac17 |ln(10) 104 .long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0 105 106 .global PTENRN 107PTENRN: 108 .long 0x40020000,0xA0000000,0x00000000 |10 ^ 1 109 .long 0x40050000,0xC8000000,0x00000000 |10 ^ 2 110 .long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4 111 .long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8 112 .long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16 113 .long 0x40690000,0x9DC5ADA8,0x2B70B59E |10 ^ 32 114 .long 0x40D30000,0xC2781F49,0xFFCFA6D5 |10 ^ 64 115 .long 0x41A80000,0x93BA47C9,0x80E98CE0 |10 ^ 128 116 .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E |10 ^ 256 117 .long 0x46A30000,0xE319A0AE,0xA60E91C7 |10 ^ 512 118 .long 0x4D480000,0xC9767586,0x81750C17 |10 ^ 1024 119 .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 |10 ^ 2048 120 .long 0x75250000,0xC4605202,0x8A20979B |10 ^ 4096 121|round to minus infinity 122BIGRZRM: 123 .long 0x3ffe0000,0xb17217f7,0xd1cf79ab |ln(2) 124 .long 0x40000000,0x935d8ddd,0xaaa8ac16 |ln(10) 125 .long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0 126 127 .global PTENRM 128PTENRM: 129 .long 0x40020000,0xA0000000,0x00000000 |10 ^ 1 130 .long 0x40050000,0xC8000000,0x00000000 |10 ^ 2 131 .long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4 132 .long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8 133 .long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16 134 .long 0x40690000,0x9DC5ADA8,0x2B70B59D |10 ^ 32 135 .long 0x40D30000,0xC2781F49,0xFFCFA6D5 |10 ^ 64 136 .long 0x41A80000,0x93BA47C9,0x80E98CDF |10 ^ 128 137 .long 0x43510000,0xAA7EEBFB,0x9DF9DE8D |10 ^ 256 138 .long 0x46A30000,0xE319A0AE,0xA60E91C6 |10 ^ 512 139 .long 0x4D480000,0xC9767586,0x81750C17 |10 ^ 1024 140 .long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 |10 ^ 2048 141 .long 0x75250000,0xC4605202,0x8A20979A |10 ^ 4096 142|round to positive infinity 143BIGRP: 144 .long 0x3ffe0000,0xb17217f7,0xd1cf79ac |ln(2) 145 .long 0x40000000,0x935d8ddd,0xaaa8ac17 |ln(10) 146 .long 0x3fff0000,0x80000000,0x00000000 |10 ^ 0 147 148 .global PTENRP 149PTENRP: 150 .long 0x40020000,0xA0000000,0x00000000 |10 ^ 1 151 .long 0x40050000,0xC8000000,0x00000000 |10 ^ 2 152 .long 0x400C0000,0x9C400000,0x00000000 |10 ^ 4 153 .long 0x40190000,0xBEBC2000,0x00000000 |10 ^ 8 154 .long 0x40340000,0x8E1BC9BF,0x04000000 |10 ^ 16 155 .long 0x40690000,0x9DC5ADA8,0x2B70B59E |10 ^ 32 156 .long 0x40D30000,0xC2781F49,0xFFCFA6D6 |10 ^ 64 157 .long 0x41A80000,0x93BA47C9,0x80E98CE0 |10 ^ 128 158 .long 0x43510000,0xAA7EEBFB,0x9DF9DE8E |10 ^ 256 159 .long 0x46A30000,0xE319A0AE,0xA60E91C7 |10 ^ 512 160 .long 0x4D480000,0xC9767586,0x81750C18 |10 ^ 1024 161 .long 0x5A920000,0x9E8B3B5D,0xC53D5DE6 |10 ^ 2048 162 .long 0x75250000,0xC4605202,0x8A20979B |10 ^ 4096 163 164 |xref nrm_zero 165 |xref decbin 166 |xref round 167 168 .global get_op 169 .global uns_getop 170 .global uni_getop 171get_op: 172 clrb DY_MO_FLG(%a6) 173 tstb UFLG_TMP(%a6) |test flag for unsupp/unimp state 174 beq uni_getop 175 176uns_getop: 177 btstb #direction_bit,CMDREG1B(%a6) 178 bne opclass3 |branch if a fmove out (any kind) 179 btstb #6,CMDREG1B(%a6) 180 beqs uns_notpacked 181 182 bfextu CMDREG1B(%a6){#3:#3},%d0 183 cmpb #3,%d0 184 beq pack_source |check for a packed src op, branch if so 185uns_notpacked: 186 bsr chk_dy_mo |set the dyadic/monadic flag 187 tstb DY_MO_FLG(%a6) 188 beqs src_op_ck |if monadic, go check src op 189| ;else, check dst op (fall through) 190 191 btstb #7,DTAG(%a6) 192 beqs src_op_ck |if dst op is norm, check src op 193 bras dst_ex_dnrm |else, handle destination unnorm/dnrm 194 195uni_getop: 196 bfextu CMDREG1B(%a6){#0:#6},%d0 |get opclass and src fields 197 cmpil #0x17,%d0 |if op class and size fields are $17, 198| ;it is FMOVECR; if not, continue 199| 200| If the instruction is fmovecr, exit get_op. It is handled 201| in do_func and smovecr.sa. 202| 203 bne not_fmovecr |handle fmovecr as an unimplemented inst 204 rts 205 206not_fmovecr: 207 btstb #E1,E_BYTE(%a6) |if set, there is a packed operand 208 bne pack_source |check for packed src op, branch if so 209 210| The following lines of are coded to optimize on normalized operands 211 moveb STAG(%a6),%d0 212 orb DTAG(%a6),%d0 |check if either of STAG/DTAG msb set 213 bmis dest_op_ck |if so, some op needs to be fixed 214 rts 215 216dest_op_ck: 217 btstb #7,DTAG(%a6) |check for unsupported data types in 218 beqs src_op_ck |the destination, if not, check src op 219 bsr chk_dy_mo |set dyadic/monadic flag 220 tstb DY_MO_FLG(%a6) | 221 beqs src_op_ck |if monadic, check src op 222| 223| At this point, destination has an extended denorm or unnorm. 224| 225dst_ex_dnrm: 226 movew FPTEMP_EX(%a6),%d0 |get destination exponent 227 andiw #0x7fff,%d0 |mask sign, check if exp = 0000 228 beqs src_op_ck |if denorm then check source op. 229| ;denorms are taken care of in res_func 230| ;(unsupp) or do_func (unimp) 231| ;else unnorm fall through 232 leal FPTEMP(%a6),%a0 |point a0 to dop - used in mk_norm 233 bsr mk_norm |go normalize - mk_norm returns: 234| ;L_SCR1{7:5} = operand tag 235| ; (000 = norm, 100 = denorm) 236| ;L_SCR1{4} = fpte15 or ete15 237| ; 0 = exp > $3fff 238| ; 1 = exp <= $3fff 239| ;and puts the normalized num back 240| ;on the fsave stack 241| 242 moveb L_SCR1(%a6),DTAG(%a6) |write the new tag & fpte15 243| ;to the fsave stack and fall 244| ;through to check source operand 245| 246src_op_ck: 247 btstb #7,STAG(%a6) 248 beq end_getop |check for unsupported data types on the 249| ;source operand 250 btstb #5,STAG(%a6) 251 bnes src_sd_dnrm |if bit 5 set, handle sgl/dbl denorms 252| 253| At this point only unnorms or extended denorms are possible. 254| 255src_ex_dnrm: 256 movew ETEMP_EX(%a6),%d0 |get source exponent 257 andiw #0x7fff,%d0 |mask sign, check if exp = 0000 258 beq end_getop |if denorm then exit, denorms are 259| ;handled in do_func 260 leal ETEMP(%a6),%a0 |point a0 to sop - used in mk_norm 261 bsr mk_norm |go normalize - mk_norm returns: 262| ;L_SCR1{7:5} = operand tag 263| ; (000 = norm, 100 = denorm) 264| ;L_SCR1{4} = fpte15 or ete15 265| ; 0 = exp > $3fff 266| ; 1 = exp <= $3fff 267| ;and puts the normalized num back 268| ;on the fsave stack 269| 270 moveb L_SCR1(%a6),STAG(%a6) |write the new tag & ete15 271 rts |end_getop 272 273| 274| At this point, only single or double denorms are possible. 275| If the inst is not fmove, normalize the source. If it is, 276| do nothing to the input. 277| 278src_sd_dnrm: 279 btstb #4,CMDREG1B(%a6) |differentiate between sgl/dbl denorm 280 bnes is_double 281is_single: 282 movew #0x3f81,%d1 |write bias for sgl denorm 283 bras common |goto the common code 284is_double: 285 movew #0x3c01,%d1 |write the bias for a dbl denorm 286common: 287 btstb #sign_bit,ETEMP_EX(%a6) |grab sign bit of mantissa 288 beqs pos 289 bset #15,%d1 |set sign bit because it is negative 290pos: 291 movew %d1,ETEMP_EX(%a6) 292| ;put exponent on stack 293 294 movew CMDREG1B(%a6),%d1 295 andw #0xe3ff,%d1 |clear out source specifier 296 orw #0x0800,%d1 |set source specifier to extended prec 297 movew %d1,CMDREG1B(%a6) |write back to the command word in stack 298| ;this is needed to fix unsupp data stack 299 leal ETEMP(%a6),%a0 |point a0 to sop 300 301 bsr mk_norm |convert sgl/dbl denorm to norm 302 moveb L_SCR1(%a6),STAG(%a6) |put tag into source tag reg - d0 303 rts |end_getop 304| 305| At this point, the source is definitely packed, whether 306| instruction is dyadic or monadic is still unknown 307| 308pack_source: 309 movel FPTEMP_LO(%a6),ETEMP(%a6) |write ms part of packed 310| ;number to etemp slot 311 bsr chk_dy_mo |set dyadic/monadic flag 312 bsr unpack 313 314 tstb DY_MO_FLG(%a6) 315 beqs end_getop |if monadic, exit 316| ;else, fix FPTEMP 317pack_dya: 318 bfextu CMDREG1B(%a6){#6:#3},%d0 |extract dest fp reg 319 movel #7,%d1 320 subl %d0,%d1 321 clrl %d0 322 bsetl %d1,%d0 |set up d0 as a dynamic register mask 323 fmovemx %d0,FPTEMP(%a6) |write to FPTEMP 324 325 btstb #7,DTAG(%a6) |check dest tag for unnorm or denorm 326 bne dst_ex_dnrm |else, handle the unnorm or ext denorm 327| 328| Dest is not denormalized. Check for norm, and set fpte15 329| accordingly. 330| 331 moveb DTAG(%a6),%d0 332 andib #0xf0,%d0 |strip to only dtag:fpte15 333 tstb %d0 |check for normalized value 334 bnes end_getop |if inf/nan/zero leave get_op 335 movew FPTEMP_EX(%a6),%d0 336 andiw #0x7fff,%d0 337 cmpiw #0x3fff,%d0 |check if fpte15 needs setting 338 bges end_getop |if >= $3fff, leave fpte15=0 339 orb #0x10,DTAG(%a6) 340 bras end_getop 341 342| 343| At this point, it is either an fmoveout packed, unnorm or denorm 344| 345opclass3: 346 clrb DY_MO_FLG(%a6) |set dyadic/monadic flag to monadic 347 bfextu CMDREG1B(%a6){#4:#2},%d0 348 cmpib #3,%d0 349 bne src_ex_dnrm |if not equal, must be unnorm or denorm 350| ;else it is a packed move out 351| ;exit 352end_getop: 353 rts 354 355| 356| Sets the DY_MO_FLG correctly. This is used only on if it is an 357| unsupported data type exception. Set if dyadic. 358| 359chk_dy_mo: 360 movew CMDREG1B(%a6),%d0 361 btstl #5,%d0 |testing extension command word 362 beqs set_mon |if bit 5 = 0 then monadic 363 btstl #4,%d0 |know that bit 5 = 1 364 beqs set_dya |if bit 4 = 0 then dyadic 365 andiw #0x007f,%d0 |get rid of all but extension bits {6:0} 366 cmpiw #0x0038,%d0 |if extension = $38 then fcmp (dyadic) 367 bnes set_mon 368set_dya: 369 st DY_MO_FLG(%a6) |set the inst flag type to dyadic 370 rts 371set_mon: 372 clrb DY_MO_FLG(%a6) |set the inst flag type to monadic 373 rts 374| 375| MK_NORM 376| 377| Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl 378| exception if denorm. 379| 380| CASE opclass 0x0 unsupp 381| mk_norm till msb set 382| set tag = norm 383| 384| CASE opclass 0x0 unimp 385| mk_norm till msb set or exp = 0 386| if integer bit = 0 387| tag = denorm 388| else 389| tag = norm 390| 391| CASE opclass 011 unsupp 392| mk_norm till msb set or exp = 0 393| if integer bit = 0 394| tag = denorm 395| set unfl_nmcexe = 1 396| else 397| tag = norm 398| 399| if exp <= $3fff 400| set ete15 or fpte15 = 1 401| else set ete15 or fpte15 = 0 402 403| input: 404| a0 = points to operand to be normalized 405| output: 406| L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm) 407| L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff) 408| the normalized operand is placed back on the fsave stack 409mk_norm: 410 clrl L_SCR1(%a6) 411 bclrb #sign_bit,LOCAL_EX(%a0) 412 sne LOCAL_SGN(%a0) |transform into internal extended format 413 414 cmpib #0x2c,1+EXC_VEC(%a6) |check if unimp 415 bnes uns_data |branch if unsupp 416 bsr uni_inst |call if unimp (opclass 0x0) 417 bras reload 418uns_data: 419 btstb #direction_bit,CMDREG1B(%a6) |check transfer direction 420 bnes bit_set |branch if set (opclass 011) 421 bsr uns_opx |call if opclass 0x0 422 bras reload 423bit_set: 424 bsr uns_op3 |opclass 011 425reload: 426 cmpw #0x3fff,LOCAL_EX(%a0) |if exp > $3fff 427 bgts end_mk | fpte15/ete15 already set to 0 428 bsetb #4,L_SCR1(%a6) |else set fpte15/ete15 to 1 429| ;calling routine actually sets the 430| ;value on the stack (along with the 431| ;tag), since this routine doesn't 432| ;know if it should set ete15 or fpte15 433| ;ie, it doesn't know if this is the 434| ;src op or dest op. 435end_mk: 436 bfclr LOCAL_SGN(%a0){#0:#8} 437 beqs end_mk_pos 438 bsetb #sign_bit,LOCAL_EX(%a0) |convert back to IEEE format 439end_mk_pos: 440 rts 441| 442| CASE opclass 011 unsupp 443| 444uns_op3: 445 bsr nrm_zero |normalize till msb = 1 or exp = zero 446 btstb #7,LOCAL_HI(%a0) |if msb = 1 447 bnes no_unfl |then branch 448set_unfl: 449 orw #dnrm_tag,L_SCR1(%a6) |set denorm tag 450 bsetb #unfl_bit,FPSR_EXCEPT(%a6) |set unfl exception bit 451no_unfl: 452 rts 453| 454| CASE opclass 0x0 unsupp 455| 456uns_opx: 457 bsr nrm_zero |normalize the number 458 btstb #7,LOCAL_HI(%a0) |check if integer bit (j-bit) is set 459 beqs uns_den |if clear then now have a denorm 460uns_nrm: 461 orb #norm_tag,L_SCR1(%a6) |set tag to norm 462 rts 463uns_den: 464 orb #dnrm_tag,L_SCR1(%a6) |set tag to denorm 465 rts 466| 467| CASE opclass 0x0 unimp 468| 469uni_inst: 470 bsr nrm_zero 471 btstb #7,LOCAL_HI(%a0) |check if integer bit (j-bit) is set 472 beqs uni_den |if clear then now have a denorm 473uni_nrm: 474 orb #norm_tag,L_SCR1(%a6) |set tag to norm 475 rts 476uni_den: 477 orb #dnrm_tag,L_SCR1(%a6) |set tag to denorm 478 rts 479 480| 481| Decimal to binary conversion 482| 483| Special cases of inf and NaNs are completed outside of decbin. 484| If the input is an snan, the snan bit is not set. 485| 486| input: 487| ETEMP(a6) - points to packed decimal string in memory 488| output: 489| fp0 - contains packed string converted to extended precision 490| ETEMP - same as fp0 491unpack: 492 movew CMDREG1B(%a6),%d0 |examine command word, looking for fmove's 493 andw #0x3b,%d0 494 beq move_unpack |special handling for fmove: must set FPSR_CC 495 496 movew ETEMP(%a6),%d0 |get word with inf information 497 bfextu %d0{#20:#12},%d1 |get exponent into d1 498 cmpiw #0x0fff,%d1 |test for inf or NaN 499 bnes try_zero |if not equal, it is not special 500 bfextu %d0{#17:#3},%d1 |get SE and y bits into d1 501 cmpiw #7,%d1 |SE and y bits must be on for special 502 bnes try_zero |if not on, it is not special 503|input is of the special cases of inf and NaN 504 tstl ETEMP_HI(%a6) |check ms mantissa 505 bnes fix_nan |if non-zero, it is a NaN 506 tstl ETEMP_LO(%a6) |check ls mantissa 507 bnes fix_nan |if non-zero, it is a NaN 508 bra finish |special already on stack 509fix_nan: 510 btstb #signan_bit,ETEMP_HI(%a6) |test for snan 511 bne finish 512 orl #snaniop_mask,USER_FPSR(%a6) |always set snan if it is so 513 bra finish 514try_zero: 515 movew ETEMP_EX+2(%a6),%d0 |get word 4 516 andiw #0x000f,%d0 |clear all but last ni(y)bble 517 tstw %d0 |check for zero. 518 bne not_spec 519 tstl ETEMP_HI(%a6) |check words 3 and 2 520 bne not_spec 521 tstl ETEMP_LO(%a6) |check words 1 and 0 522 bne not_spec 523 tstl ETEMP(%a6) |test sign of the zero 524 bges pos_zero 525 movel #0x80000000,ETEMP(%a6) |write neg zero to etemp 526 clrl ETEMP_HI(%a6) 527 clrl ETEMP_LO(%a6) 528 bra finish 529pos_zero: 530 clrl ETEMP(%a6) 531 clrl ETEMP_HI(%a6) 532 clrl ETEMP_LO(%a6) 533 bra finish 534 535not_spec: 536 fmovemx %fp0-%fp1,-(%a7) |save fp0 - decbin returns in it 537 bsr decbin 538 fmovex %fp0,ETEMP(%a6) |put the unpacked sop in the fsave stack 539 fmovemx (%a7)+,%fp0-%fp1 540 fmovel #0,%FPSR |clr fpsr from decbin 541 bra finish 542 543| 544| Special handling for packed move in: Same results as all other 545| packed cases, but we must set the FPSR condition codes properly. 546| 547move_unpack: 548 movew ETEMP(%a6),%d0 |get word with inf information 549 bfextu %d0{#20:#12},%d1 |get exponent into d1 550 cmpiw #0x0fff,%d1 |test for inf or NaN 551 bnes mtry_zero |if not equal, it is not special 552 bfextu %d0{#17:#3},%d1 |get SE and y bits into d1 553 cmpiw #7,%d1 |SE and y bits must be on for special 554 bnes mtry_zero |if not on, it is not special 555|input is of the special cases of inf and NaN 556 tstl ETEMP_HI(%a6) |check ms mantissa 557 bnes mfix_nan |if non-zero, it is a NaN 558 tstl ETEMP_LO(%a6) |check ls mantissa 559 bnes mfix_nan |if non-zero, it is a NaN 560|input is inf 561 orl #inf_mask,USER_FPSR(%a6) |set I bit 562 tstl ETEMP(%a6) |check sign 563 bge finish 564 orl #neg_mask,USER_FPSR(%a6) |set N bit 565 bra finish |special already on stack 566mfix_nan: 567 orl #nan_mask,USER_FPSR(%a6) |set NaN bit 568 moveb #nan_tag,STAG(%a6) |set stag to NaN 569 btstb #signan_bit,ETEMP_HI(%a6) |test for snan 570 bnes mn_snan 571 orl #snaniop_mask,USER_FPSR(%a6) |set snan bit 572 btstb #snan_bit,FPCR_ENABLE(%a6) |test for snan enabled 573 bnes mn_snan 574 bsetb #signan_bit,ETEMP_HI(%a6) |force snans to qnans 575mn_snan: 576 tstl ETEMP(%a6) |check for sign 577 bge finish |if clr, go on 578 orl #neg_mask,USER_FPSR(%a6) |set N bit 579 bra finish 580 581mtry_zero: 582 movew ETEMP_EX+2(%a6),%d0 |get word 4 583 andiw #0x000f,%d0 |clear all but last ni(y)bble 584 tstw %d0 |check for zero. 585 bnes mnot_spec 586 tstl ETEMP_HI(%a6) |check words 3 and 2 587 bnes mnot_spec 588 tstl ETEMP_LO(%a6) |check words 1 and 0 589 bnes mnot_spec 590 tstl ETEMP(%a6) |test sign of the zero 591 bges mpos_zero 592 orl #neg_mask+z_mask,USER_FPSR(%a6) |set N and Z 593 movel #0x80000000,ETEMP(%a6) |write neg zero to etemp 594 clrl ETEMP_HI(%a6) 595 clrl ETEMP_LO(%a6) 596 bras finish 597mpos_zero: 598 orl #z_mask,USER_FPSR(%a6) |set Z 599 clrl ETEMP(%a6) 600 clrl ETEMP_HI(%a6) 601 clrl ETEMP_LO(%a6) 602 bras finish 603 604mnot_spec: 605 fmovemx %fp0-%fp1,-(%a7) |save fp0 ,fp1 - decbin returns in fp0 606 bsr decbin 607 fmovex %fp0,ETEMP(%a6) 608| ;put the unpacked sop in the fsave stack 609 fmovemx (%a7)+,%fp0-%fp1 610 611finish: 612 movew CMDREG1B(%a6),%d0 |get the command word 613 andw #0xfbff,%d0 |change the source specifier field to 614| ;extended (was packed). 615 movew %d0,CMDREG1B(%a6) |write command word back to fsave stack 616| ;we need to do this so the 040 will 617| ;re-execute the inst. without taking 618| ;another packed trap. 619 620fix_stag: 621|Converted result is now in etemp on fsave stack, now set the source 622|tag (stag) 623| if (ete =$7fff) then INF or NAN 624| if (etemp = $x.0----0) then 625| stag = INF 626| else 627| stag = NAN 628| else 629| if (ete = $0000) then 630| stag = ZERO 631| else 632| stag = NORM 633| 634| Note also that the etemp_15 bit (just right of the stag) must 635| be set accordingly. 636| 637 movew ETEMP_EX(%a6),%d1 638 andiw #0x7fff,%d1 |strip sign 639 cmpw #0x7fff,%d1 640 bnes z_or_nrm 641 movel ETEMP_HI(%a6),%d1 642 bnes is_nan 643 movel ETEMP_LO(%a6),%d1 644 bnes is_nan 645is_inf: 646 moveb #0x40,STAG(%a6) 647 movel #0x40,%d0 648 rts 649is_nan: 650 moveb #0x60,STAG(%a6) 651 movel #0x60,%d0 652 rts 653z_or_nrm: 654 tstw %d1 655 bnes is_nrm 656is_zro: 657| For a zero, set etemp_15 658 moveb #0x30,STAG(%a6) 659 movel #0x20,%d0 660 rts 661is_nrm: 662| For a norm, check if the exp <= $3fff; if so, set etemp_15 663 cmpiw #0x3fff,%d1 664 bles set_bit15 665 moveb #0,STAG(%a6) 666 bras end_is_nrm 667set_bit15: 668 moveb #0x10,STAG(%a6) 669end_is_nrm: 670 movel #0,%d0 671end_fix: 672 rts 673 674end_get: 675 rts 676 |end 677