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