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