1* $NetBSD: get_op.sa,v 1.4 2001/12/09 01:43:13 briggs Exp $ 2 3* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 4* M68000 Hi-Performance Microprocessor Division 5* M68040 Software Package 6* 7* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc. 8* All rights reserved. 9* 10* THE SOFTWARE is provided on an "AS IS" basis and without warranty. 11* To the maximum extent permitted by applicable law, 12* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 13* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A 14* PARTICULAR PURPOSE and any warranty against infringement with 15* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 16* and any accompanying written materials. 17* 18* To the maximum extent permitted by applicable law, 19* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 20* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS 21* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR 22* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE 23* SOFTWARE. Motorola assumes no responsibility for the maintenance 24* and support of the SOFTWARE. 25* 26* You are hereby granted a copyright license to use, modify, and 27* distribute the SOFTWARE so long as this entire notice is retained 28* without alteration in any modified and/or redistributed versions, 29* and that such modified versions are clearly identified as such. 30* No licenses are granted by implication, estoppel or otherwise 31* under any patents or trademarks of Motorola, Inc. 32 33* 34* get_op.sa 3.6 5/19/92 35* 36* get_op.sa 3.5 4/26/91 37* 38* Description: This routine is called by the unsupported format/data 39* type exception handler ('unsupp' - vector 55) and the unimplemented 40* instruction exception handler ('unimp' - vector 11). 'get_op' 41* determines the opclass (0, 2, or 3) and branches to the 42* opclass handler routine. See 68881/2 User's Manual table 4-11 43* for a description of the opclasses. 44* 45* For UNSUPPORTED data/format (exception vector 55) and for 46* UNIMPLEMENTED instructions (exception vector 11) the following 47* applies: 48* 49* - For unnormormalized numbers (opclass 0, 2, or 3) the 50* number(s) is normalized and the operand type tag is updated. 51* 52* - For a packed number (opclass 2) the number is unpacked and the 53* operand type tag is updated. 54* 55* - For denormalized numbers (opclass 0 or 2) the number(s) is not 56* changed but passed to the next module. The next module for 57* unimp is do_func, the next module for unsupp is res_func. 58* 59* For UNSUPPORTED data/format (exception vector 55) only the 60* following applies: 61* 62* - If there is a move out with a packed number (opclass 3) the 63* number is packed and written to user memory. For the other 64* opclasses the number(s) are written back to the fsave stack 65* and the instruction is then restored back into the '040. The 66* '040 is then able to complete the instruction. 67* 68* For example: 69* fadd.x fpm,fpn where the fpm contains an unnormalized number. 70* The '040 takes an unsupported data trap and gets to this 71* routine. The number is normalized, put back on the stack and 72* then an frestore is done to restore the instruction back into 73* the '040. The '040 then re-executes the fadd.x fpm,fpn with 74* a normalized number in the source and the instruction is 75* successful. 76* 77* Next consider if in the process of normalizing the un- 78* normalized number it becomes a denormalized number. The 79* routine which converts the unnorm to a norm (called mk_norm) 80* detects this and tags the number as a denorm. The routine 81* res_func sees the denorm tag and converts the denorm to a 82* norm. The instruction is then restored back into the '040 83* which re_executess the instruction. 84* 85 86GET_OP IDNT 2,1 Motorola 040 Floating Point Software Package 87 88 section 8 89 90 include fpsp.h 91 92 xdef PIRN,PIRZRM,PIRP 93 xdef SMALRN,SMALRZRM,SMALRP 94 xdef BIGRN,BIGRZRM,BIGRP 95 96PIRN: 97 dc.l $40000000,$c90fdaa2,$2168c235 ;pi 98PIRZRM: 99 dc.l $40000000,$c90fdaa2,$2168c234 ;pi 100PIRP: 101 dc.l $40000000,$c90fdaa2,$2168c235 ;pi 102 103*round to nearest 104SMALRN: 105 dc.l $3ffd0000,$9a209a84,$fbcff798 ;log10(2) 106 dc.l $40000000,$adf85458,$a2bb4a9a ;e 107 dc.l $3fff0000,$b8aa3b29,$5c17f0bc ;log2(e) 108 dc.l $3ffd0000,$de5bd8a9,$37287195 ;log10(e) 109 dc.l $00000000,$00000000,$00000000 ;0.0 110* round to zero;round to negative infinity 111SMALRZRM: 112 dc.l $3ffd0000,$9a209a84,$fbcff798 ;log10(2) 113 dc.l $40000000,$adf85458,$a2bb4a9a ;e 114 dc.l $3fff0000,$b8aa3b29,$5c17f0bb ;log2(e) 115 dc.l $3ffd0000,$de5bd8a9,$37287195 ;log10(e) 116 dc.l $00000000,$00000000,$00000000 ;0.0 117* round to positive infinity 118SMALRP: 119 dc.l $3ffd0000,$9a209a84,$fbcff799 ;log10(2) 120 dc.l $40000000,$adf85458,$a2bb4a9b ;e 121 dc.l $3fff0000,$b8aa3b29,$5c17f0bc ;log2(e) 122 dc.l $3ffd0000,$de5bd8a9,$37287195 ;log10(e) 123 dc.l $00000000,$00000000,$00000000 ;0.0 124 125*round to nearest 126BIGRN: 127 dc.l $3ffe0000,$b17217f7,$d1cf79ac ;ln(2) 128 dc.l $40000000,$935d8ddd,$aaa8ac17 ;ln(10) 129 dc.l $3fff0000,$80000000,$00000000 ;10 ^ 0 130 131 xdef PTENRN 132PTENRN: 133 dc.l $40020000,$A0000000,$00000000 ;10 ^ 1 134 dc.l $40050000,$C8000000,$00000000 ;10 ^ 2 135 dc.l $400C0000,$9C400000,$00000000 ;10 ^ 4 136 dc.l $40190000,$BEBC2000,$00000000 ;10 ^ 8 137 dc.l $40340000,$8E1BC9BF,$04000000 ;10 ^ 16 138 dc.l $40690000,$9DC5ADA8,$2B70B59E ;10 ^ 32 139 dc.l $40D30000,$C2781F49,$FFCFA6D5 ;10 ^ 64 140 dc.l $41A80000,$93BA47C9,$80E98CE0 ;10 ^ 128 141 dc.l $43510000,$AA7EEBFB,$9DF9DE8E ;10 ^ 256 142 dc.l $46A30000,$E319A0AE,$A60E91C7 ;10 ^ 512 143 dc.l $4D480000,$C9767586,$81750C17 ;10 ^ 1024 144 dc.l $5A920000,$9E8B3B5D,$C53D5DE5 ;10 ^ 2048 145 dc.l $75250000,$C4605202,$8A20979B ;10 ^ 4096 146*round to minus infinity 147BIGRZRM: 148 dc.l $3ffe0000,$b17217f7,$d1cf79ab ;ln(2) 149 dc.l $40000000,$935d8ddd,$aaa8ac16 ;ln(10) 150 dc.l $3fff0000,$80000000,$00000000 ;10 ^ 0 151 152 xdef PTENRM 153PTENRM: 154 dc.l $40020000,$A0000000,$00000000 ;10 ^ 1 155 dc.l $40050000,$C8000000,$00000000 ;10 ^ 2 156 dc.l $400C0000,$9C400000,$00000000 ;10 ^ 4 157 dc.l $40190000,$BEBC2000,$00000000 ;10 ^ 8 158 dc.l $40340000,$8E1BC9BF,$04000000 ;10 ^ 16 159 dc.l $40690000,$9DC5ADA8,$2B70B59D ;10 ^ 32 160 dc.l $40D30000,$C2781F49,$FFCFA6D5 ;10 ^ 64 161 dc.l $41A80000,$93BA47C9,$80E98CDF ;10 ^ 128 162 dc.l $43510000,$AA7EEBFB,$9DF9DE8D ;10 ^ 256 163 dc.l $46A30000,$E319A0AE,$A60E91C6 ;10 ^ 512 164 dc.l $4D480000,$C9767586,$81750C17 ;10 ^ 1024 165 dc.l $5A920000,$9E8B3B5D,$C53D5DE5 ;10 ^ 2048 166 dc.l $75250000,$C4605202,$8A20979A ;10 ^ 4096 167*round to positive infinity 168BIGRP: 169 dc.l $3ffe0000,$b17217f7,$d1cf79ac ;ln(2) 170 dc.l $40000000,$935d8ddd,$aaa8ac17 ;ln(10) 171 dc.l $3fff0000,$80000000,$00000000 ;10 ^ 0 172 173 xdef PTENRP 174PTENRP: 175 dc.l $40020000,$A0000000,$00000000 ;10 ^ 1 176 dc.l $40050000,$C8000000,$00000000 ;10 ^ 2 177 dc.l $400C0000,$9C400000,$00000000 ;10 ^ 4 178 dc.l $40190000,$BEBC2000,$00000000 ;10 ^ 8 179 dc.l $40340000,$8E1BC9BF,$04000000 ;10 ^ 16 180 dc.l $40690000,$9DC5ADA8,$2B70B59E ;10 ^ 32 181 dc.l $40D30000,$C2781F49,$FFCFA6D6 ;10 ^ 64 182 dc.l $41A80000,$93BA47C9,$80E98CE0 ;10 ^ 128 183 dc.l $43510000,$AA7EEBFB,$9DF9DE8E ;10 ^ 256 184 dc.l $46A30000,$E319A0AE,$A60E91C7 ;10 ^ 512 185 dc.l $4D480000,$C9767586,$81750C18 ;10 ^ 1024 186 dc.l $5A920000,$9E8B3B5D,$C53D5DE6 ;10 ^ 2048 187 dc.l $75250000,$C4605202,$8A20979B ;10 ^ 4096 188 189 xref nrm_zero 190 xref decbin 191 xref round 192 193 xdef get_op 194 xdef uns_getop 195 xdef uni_getop 196get_op: 197 clr.b DY_MO_FLG(a6) 198 tst.b UFLG_TMP(a6) ;test flag for unsupp/unimp state 199 beq.b short_uni_getop 200 201uns_getop: 202 btst.b #direction_bit,CMDREG1B(a6) 203 bne.w opclass3 ;branch if a fmove out (any kind) 204 btst.b #6,CMDREG1B(a6) 205 beq.b uns_notpacked 206 207 bfextu CMDREG1B(a6){3:3},d0 208 cmp.b #3,d0 209 beq.w pack_source ;check for a packed src op, branch if so 210uns_notpacked: 211 bsr chk_dy_mo ;set the dyadic/monadic flag 212 tst.b DY_MO_FLG(a6) 213 beq.b src_op_ck ;if monadic, go check src op 214* ;else, check dst op (fall through) 215 216 btst.b #7,DTAG(a6) 217 beq.b src_op_ck ;if dst op is norm, check src op 218 bra.b dst_ex_dnrm ;else, handle destination unnorm/dnrm 219 220uni_getop: 221short_uni_getop: 222 bfextu CMDREG1B(a6){0:6},d0 ;get opclass and src fields 223 cmpi.l #$17,d0 ;if op class and size fields are $17, 224* ;it is FMOVECR; if not, continue 225* 226* If the instruction is fmovecr, exit get_op. It is handled 227* in do_func and smovecr.sa. 228* 229 bne.w not_fmovecr ;handle fmovecr as an unimplemented inst 230 rts 231 232not_fmovecr: 233 btst.b #E1,E_BYTE(a6) ;if set, there is a packed operand 234 bne.w pack_source ;check for packed src op, branch if so 235 236* The following lines of are coded to optimize on normalized operands 237 move.b STAG(a6),d0 238 or.b DTAG(a6),d0 ;check if either of STAG/DTAG msb set 239 bmi.b dest_op_ck ;if so, some op needs to be fixed 240 rts 241 242dest_op_ck: 243 btst.b #7,DTAG(a6) ;check for unsupported data types in 244 beq.b src_op_ck ;the destination, if not, check src op 245 bsr chk_dy_mo ;set dyadic/monadic flag 246 tst.b DY_MO_FLG(a6) ; 247 beq.b src_op_ck ;if monadic, check src op 248* 249* At this point, destination has an extended denorm or unnorm. 250* 251dst_ex_dnrm: 252 move.w FPTEMP_EX(a6),d0 ;get destination exponent 253 andi.w #$7fff,d0 ;mask sign, check if exp = 0000 254 beq.b src_op_ck ;if denorm then check source op. 255* ;denorms are taken care of in res_func 256* ;(unsupp) or do_func (unimp) 257* ;else unnorm fall through 258 lea.l FPTEMP(a6),a0 ;point a0 to dop - used in mk_norm 259 bsr mk_norm ;go normalize - mk_norm returns: 260* ;L_SCR1{7:5} = operand tag 261* ; (000 = norm, 100 = denorm) 262* ;L_SCR1{4} = fpte15 or ete15 263* ; 0 = exp > $3fff 264* ; 1 = exp <= $3fff 265* ;and puts the normalized num back 266* ;on the fsave stack 267* 268 move.b L_SCR1(a6),DTAG(a6) ;write the new tag & fpte15 269* ;to the fsave stack and fall 270* ;through to check source operand 271* 272src_op_ck: 273 btst.b #7,STAG(a6) 274 beq.w end_getop ;check for unsupported data types on the 275* ;source operand 276 btst.b #5,STAG(a6) 277 bne.b src_sd_dnrm ;if bit 5 set, handle sgl/dbl denorms 278* 279* At this point only unnorms or extended denorms are possible. 280* 281src_ex_dnrm: 282 move.w ETEMP_EX(a6),d0 ;get source exponent 283 andi.w #$7fff,d0 ;mask sign, check if exp = 0000 284 beq.w end_getop ;if denorm then exit, denorms are 285* ;handled in do_func 286 lea.l ETEMP(a6),a0 ;point a0 to sop - used in mk_norm 287 bsr mk_norm ;go normalize - mk_norm returns: 288* ;L_SCR1{7:5} = operand tag 289* ; (000 = norm, 100 = denorm) 290* ;L_SCR1{4} = fpte15 or ete15 291* ; 0 = exp > $3fff 292* ; 1 = exp <= $3fff 293* ;and puts the normalized num back 294* ;on the fsave stack 295* 296 move.b L_SCR1(a6),STAG(a6) ;write the new tag & ete15 297 rts ;end_getop 298 299* 300* At this point, only single or double denorms are possible. 301* If the inst is not fmove, normalize the source. If it is, 302* do nothing to the input. 303* 304src_sd_dnrm: 305 btst.b #4,CMDREG1B(a6) ;differentiate between sgl/dbl denorm 306 bne.b is_double 307is_single: 308 move.w #$3f81,d1 ;write bias for sgl denorm 309 bra.b common ;goto the common code 310is_double: 311 move.w #$3c01,d1 ;write the bias for a dbl denorm 312common: 313 btst.b #sign_bit,ETEMP_EX(a6) ;grab sign bit of mantissa 314 beq.b pos 315 bset #15,d1 ;set sign bit because it is negative 316pos: 317 move.w d1,ETEMP_EX(a6) 318* ;put exponent on stack 319 320 move.w CMDREG1B(a6),d1 321 and.w #$e3ff,d1 ;clear out source specifier 322 or.w #$0800,d1 ;set source specifier to extended prec 323 move.w d1,CMDREG1B(a6) ;write back to the command word in stack 324* ;this is needed to fix unsupp data stack 325 lea.l ETEMP(a6),a0 ;point a0 to sop 326 327 bsr mk_norm ;convert sgl/dbl denorm to norm 328 move.b L_SCR1(a6),STAG(a6) ;put tag into source tag reg - d0 329 rts ;end_getop 330* 331* At this point, the source is definitely packed, whether 332* instruction is dyadic or monadic is still unknown 333* 334pack_source: 335 move.l FPTEMP_LO(a6),ETEMP(a6) ;write ms part of packed 336* ;number to etemp slot 337 bsr chk_dy_mo ;set dyadic/monadic flag 338 bsr unpack 339 340 tst.b DY_MO_FLG(a6) 341 beq.b end_getop ;if monadic, exit 342* ;else, fix FPTEMP 343pack_dya: 344 bfextu CMDREG1B(a6){6:3},d0 ;extract dest fp reg 345 move.l #7,d1 346 sub.l d0,d1 347 clr.l d0 348 bset.l d1,d0 ;set up d0 as a dynamic register mask 349 fmovem.x d0,FPTEMP(a6) ;write to FPTEMP 350 351 btst.b #7,DTAG(a6) ;check dest tag for unnorm or denorm 352 bne.w dst_ex_dnrm ;else, handle the unnorm or ext denorm 353* 354* Dest is not denormalized. Check for norm, and set fpte15 355* accordingly. 356* 357 move.b DTAG(a6),d0 358 andi.b #$f0,d0 ;strip to only dtag:fpte15 359 tst.b d0 ;check for normalized value 360 bne.b end_getop ;if inf/nan/zero leave get_op 361 move.w FPTEMP_EX(a6),d0 362 andi.w #$7fff,d0 363 cmpi.w #$3fff,d0 ;check if fpte15 needs setting 364 bge.b end_getop ;if >= $3fff, leave fpte15=0 365 or.b #$10,DTAG(a6) 366 bra.b end_getop 367 368* 369* At this point, it is either an fmoveout packed, unnorm or denorm 370* 371opclass3: 372 clr.b DY_MO_FLG(a6) ;set dyadic/monadic flag to monadic 373 bfextu CMDREG1B(a6){4:2},d0 374 cmpi.b #3,d0 375 bne.w src_ex_dnrm ;if not equal, must be unnorm or denorm 376* ;else it is a packed move out 377* ;exit 378end_getop: 379 rts 380 381* 382* Sets the DY_MO_FLG correctly. This is used only on if it is an 383* unuspported data type exception. Set if dyadic. 384* 385chk_dy_mo: 386 move.w CMDREG1B(a6),d0 387 btst.l #5,d0 ;testing extension command word 388 beq.b set_mon ;if bit 5 = 0 then monadic 389 btst.l #4,d0 ;know that bit 5 = 1 390 beq.b set_dya ;if bit 4 = 0 then dyadic 391 andi.w #$007f,d0 ;get rid of all but extension bits {6:0} 392 cmpi.w #$0038,d0 ;if extension = $38 then fcmp (dyadic) 393 bne.b set_mon 394set_dya: 395 st.b DY_MO_FLG(a6) ;set the inst flag type to dyadic 396 rts 397set_mon: 398 clr.b DY_MO_FLG(a6) ;set the inst flag type to monadic 399 rts 400* 401* MK_NORM 402* 403* Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl 404* exception if denorm. 405* 406* CASE opclass 0x0 unsupp 407* mk_norm till msb set 408* set tag = norm 409* 410* CASE opclass 0x0 unimp 411* mk_norm till msb set or exp = 0 412* if integer bit = 0 413* tag = denorm 414* else 415* tag = norm 416* 417* CASE opclass 011 unsupp 418* mk_norm till msb set or exp = 0 419* if integer bit = 0 420* tag = denorm 421* set unfl_nmcexe = 1 422* else 423* tag = norm 424* 425* if exp <= $3fff 426* set ete15 or fpte15 = 1 427* else set ete15 or fpte15 = 0 428 429* input: 430* a0 = points to operand to be normalized 431* output: 432* L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm) 433* L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff) 434* the normalized operand is placed back on the fsave stack 435mk_norm: 436 clr.l L_SCR1(a6) 437 bclr.b #sign_bit,LOCAL_EX(a0) 438 sne LOCAL_SGN(a0) ;transform into internal extended format 439 440 cmpi.b #$2c,1+EXC_VEC(a6) ;check if unimp 441 bne.b uns_data ;branch if unsupp 442 bsr uni_inst ;call if unimp (opclass 0x0) 443 bra.b reload 444uns_data: 445 btst.b #direction_bit,CMDREG1B(a6) ;check transfer direction 446 bne.b bit_set ;branch if set (opclass 011) 447 bsr uns_opx ;call if opclass 0x0 448 bra.b reload 449bit_set: 450 bsr uns_op3 ;opclass 011 451reload: 452 cmp.w #$3fff,LOCAL_EX(a0) ;if exp > $3fff 453 bgt.b end_mk ; fpte15/ete15 already set to 0 454 bset.b #4,L_SCR1(a6) ;else set fpte15/ete15 to 1 455* ;calling routine actually sets the 456* ;value on the stack (along with the 457* ;tag), since this routine doesn't 458* ;know if it should set ete15 or fpte15 459* ;ie, it doesn't know if this is the 460* ;src op or dest op. 461end_mk: 462 bfclr LOCAL_SGN(a0){0:8} 463 beq.b end_mk_pos 464 bset.b #sign_bit,LOCAL_EX(a0) ;convert back to IEEE format 465end_mk_pos: 466 rts 467* 468* CASE opclass 011 unsupp 469* 470uns_op3: 471 bsr nrm_zero ;normalize till msb = 1 or exp = zero 472 btst.b #7,LOCAL_HI(a0) ;if msb = 1 473 bne.b no_unfl ;then branch 474set_unfl: 475 or.b #dnrm_tag,L_SCR1(a6) ;set denorm tag 476 bset.b #unfl_bit,FPSR_EXCEPT(a6) ;set unfl exception bit 477no_unfl: 478 rts 479* 480* CASE opclass 0x0 unsupp 481* 482uns_opx: 483 bsr nrm_zero ;normalize the number 484 btst.b #7,LOCAL_HI(a0) ;check if integer bit (j-bit) is set 485 beq.b uns_den ;if clear then now have a denorm 486uns_nrm: 487 or.b #norm_tag,L_SCR1(a6) ;set tag to norm 488 rts 489uns_den: 490 or.b #dnrm_tag,L_SCR1(a6) ;set tag to denorm 491 rts 492* 493* CASE opclass 0x0 unimp 494* 495uni_inst: 496 bsr nrm_zero 497 btst.b #7,LOCAL_HI(a0) ;check if integer bit (j-bit) is set 498 beq.b uni_den ;if clear then now have a denorm 499uni_nrm: 500 or.b #norm_tag,L_SCR1(a6) ;set tag to norm 501 rts 502uni_den: 503 or.b #dnrm_tag,L_SCR1(a6) ;set tag to denorm 504 rts 505 506* 507* Decimal to binary conversion 508* 509* Special cases of inf and NaNs are completed outside of decbin. 510* If the input is an snan, the snan bit is not set. 511* 512* input: 513* ETEMP(a6) - points to packed decimal string in memory 514* output: 515* fp0 - contains packed string converted to extended precision 516* ETEMP - same as fp0 517unpack: 518 move.w CMDREG1B(a6),d0 ;examine command word, looking for fmove's 519 and.w #$3b,d0 520 beq move_unpack ;special handling for fmove: must set FPSR_CC 521 522 move.w ETEMP(a6),d0 ;get word with inf information 523 bfextu d0{20:12},d1 ;get exponent into d1 524 cmpi.w #$0fff,d1 ;test for inf or NaN 525 bne.b try_zero ;if not equal, it is not special 526 bfextu d0{17:3},d1 ;get SE and y bits into d1 527 cmpi.w #7,d1 ;SE and y bits must be on for special 528 bne.b try_zero ;if not on, it is not special 529*input is of the special cases of inf and NaN 530 tst.l ETEMP_HI(a6) ;check ms mantissa 531 bne.b fix_nan ;if non-zero, it is a NaN 532 tst.l ETEMP_LO(a6) ;check ls mantissa 533 bne.b fix_nan ;if non-zero, it is a NaN 534 bra.w finish ;special already on stack 535fix_nan: 536 btst.b #signan_bit,ETEMP_HI(a6) ;test for snan 537 bne.w finish 538 or.l #snaniop_mask,USER_FPSR(a6) ;always set snan if it is so 539 bra.w finish 540try_zero: 541 move.w ETEMP_EX+2(a6),d0 ;get word 4 542 andi.w #$000f,d0 ;clear all but last ni(y)bble 543 tst.w d0 ;check for zero. 544 bne.w not_spec 545 tst.l ETEMP_HI(a6) ;check words 3 and 2 546 bne.w not_spec 547 tst.l ETEMP_LO(a6) ;check words 1 and 0 548 bne.w not_spec 549 tst.l ETEMP(a6) ;test sign of the zero 550 bge.b pos_zero 551 move.l #$80000000,ETEMP(a6) ;write neg zero to etemp 552 clr.l ETEMP_HI(a6) 553 clr.l ETEMP_LO(a6) 554 bra.w finish 555pos_zero: 556 clr.l ETEMP(a6) 557 clr.l ETEMP_HI(a6) 558 clr.l ETEMP_LO(a6) 559 bra.w finish 560 561not_spec: 562 fmovem.x fp0-fp1,-(a7) ;save fp0 - decbin returns in it 563 bsr decbin 564 fmove.x fp0,ETEMP(a6) ;put the unpacked sop in the fsave stack 565 fmovem.x (a7)+,fp0-fp1 566 fmove.l #0,FPSR ;clr fpsr from decbin 567 bra finish 568 569* 570* Special handling for packed move in: Same results as all other 571* packed cases, but we must set the FPSR condition codes properly. 572* 573move_unpack: 574 move.w ETEMP(a6),d0 ;get word with inf information 575 bfextu d0{20:12},d1 ;get exponent into d1 576 cmpi.w #$0fff,d1 ;test for inf or NaN 577 bne.b mtry_zero ;if not equal, it is not special 578 bfextu d0{17:3},d1 ;get SE and y bits into d1 579 cmpi.w #7,d1 ;SE and y bits must be on for special 580 bne.b mtry_zero ;if not on, it is not special 581*input is of the special cases of inf and NaN 582 tst.l ETEMP_HI(a6) ;check ms mantissa 583 bne.b mfix_nan ;if non-zero, it is a NaN 584 tst.l ETEMP_LO(a6) ;check ls mantissa 585 bne.b mfix_nan ;if non-zero, it is a NaN 586*input is inf 587 or.l #inf_mask,USER_FPSR(a6) ;set I bit 588 tst.l ETEMP(a6) ;check sign 589 bge.w finish 590 or.l #neg_mask,USER_FPSR(a6) ;set N bit 591 bra.w finish ;special already on stack 592mfix_nan: 593 or.l #nan_mask,USER_FPSR(a6) ;set NaN bit 594 move.b #nan_tag,STAG(a6) ;set stag to NaN 595 btst.b #signan_bit,ETEMP_HI(a6) ;test for snan 596 bne.b mn_snan 597 or.l #snaniop_mask,USER_FPSR(a6) ;set snan bit 598 btst.b #snan_bit,FPCR_ENABLE(a6) ;test for snan enabled 599 bne.b mn_snan 600 bset.b #signan_bit,ETEMP_HI(a6) ;force snans to qnans 601mn_snan: 602 tst.l ETEMP(a6) ;check for sign 603 bge.w finish ;if clr, go on 604 or.l #neg_mask,USER_FPSR(a6) ;set N bit 605 bra.w finish 606 607mtry_zero: 608 move.w ETEMP_EX+2(a6),d0 ;get word 4 609 andi.w #$000f,d0 ;clear all but last ni(y)bble 610 tst.w d0 ;check for zero. 611 bne.b mnot_spec 612 tst.l ETEMP_HI(a6) ;check words 3 and 2 613 bne.b mnot_spec 614 tst.l ETEMP_LO(a6) ;check words 1 and 0 615 bne.b mnot_spec 616 tst.l ETEMP(a6) ;test sign of the zero 617 bge.b mpos_zero 618 or.l #neg_mask+z_mask,USER_FPSR(a6) ;set N and Z 619 move.l #$80000000,ETEMP(a6) ;write neg zero to etemp 620 clr.l ETEMP_HI(a6) 621 clr.l ETEMP_LO(a6) 622 bra.b finish 623mpos_zero: 624 or.l #z_mask,USER_FPSR(a6) ;set Z 625 clr.l ETEMP(a6) 626 clr.l ETEMP_HI(a6) 627 clr.l ETEMP_LO(a6) 628 bra.b finish 629 630mnot_spec: 631 fmovem.x fp0-fp1,-(a7) ;save fp0 ,fp1 - decbin returns in fp0 632 bsr decbin 633 fmove.x fp0,ETEMP(a6) 634* ;put the unpacked sop in the fsave stack 635 fmovem.x (a7)+,fp0-fp1 636 637finish: 638 move.w CMDREG1B(a6),d0 ;get the command word 639 and.w #$fbff,d0 ;change the source specifier field to 640* ;extended (was packed). 641 move.w d0,CMDREG1B(a6) ;write command word back to fsave stack 642* ;we need to do this so the 040 will 643* ;re-execute the inst. without taking 644* ;another packed trap. 645 646fix_stag: 647*Converted result is now in etemp on fsave stack, now set the source 648*tag (stag) 649* if (ete =$7fff) then INF or NAN 650* if (etemp = $x.0----0) then 651* stag = INF 652* else 653* stag = NAN 654* else 655* if (ete = $0000) then 656* stag = ZERO 657* else 658* stag = NORM 659* 660* Note also that the etemp_15 bit (just right of the stag) must 661* be set accordingly. 662* 663 move.w ETEMP_EX(a6),d1 664 andi.w #$7fff,d1 ;strip sign 665 cmp.w #$7fff,d1 666 bne.b z_or_nrm 667 move.l ETEMP_HI(a6),d1 668 bne.b is_nan 669 move.l ETEMP_LO(a6),d1 670 bne.b is_nan 671is_inf: 672 move.b #$40,STAG(a6) 673 move.l #$40,d0 674 rts 675is_nan: 676 move.b #$60,STAG(a6) 677 move.l #$60,d0 678 rts 679z_or_nrm: 680 tst.w d1 681 bne.b is_nrm 682is_zro: 683* For a zero, set etemp_15 684 move.b #$30,STAG(a6) 685 move.l #$20,d0 686 rts 687is_nrm: 688* For a norm, check if the exp <= $3fff; if so, set etemp_15 689 cmpi.w #$3fff,d1 690 ble.b set_bit15 691 clr.b STAG(a6) 692 bra.b end_is_nrm 693set_bit15: 694 move.b #$10,STAG(a6) 695end_is_nrm: 696 clr.l d0 697end_fix: 698 rts 699 700end_get: 701 rts 702 end 703