root/arch/m68k/fpsp040/get_op.S

/* [previous][next][first][last][top][bottom][index][help] */
   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 
  61 GET_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 
  71 PIRN:
  72         .long 0x40000000,0xc90fdaa2,0x2168c235    |pi
  73 PIRZRM:
  74         .long 0x40000000,0xc90fdaa2,0x2168c234    |pi
  75 PIRP:
  76         .long 0x40000000,0xc90fdaa2,0x2168c235    |pi
  77 
  78 |round to nearest
  79 SMALRN:
  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
  86 SMALRZRM:
  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
  93 SMALRP:
  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
 101 BIGRN:
 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
 107 PTENRN:
 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
 122 BIGRZRM:
 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
 128 PTENRM:
 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
 143 BIGRP:
 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
 149 PTENRP:
 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
 171 get_op:
 172         clrb    DY_MO_FLG(%a6)
 173         tstb    UFLG_TMP(%a6)   |test flag for unsupp/unimp state
 174         beqs    uni_getop
 175 
 176 uns_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
 185 uns_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 
 195 uni_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 
 206 not_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 
 216 dest_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 |
 225 dst_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 |
 246 src_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 |
 255 src_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 |
 278 src_sd_dnrm:
 279         btstb   #4,CMDREG1B(%a6)        |differentiate between sgl/dbl denorm
 280         bnes    is_double
 281 is_single:
 282         movew   #0x3f81,%d1     |write bias for sgl denorm
 283         bras    common          |goto the common code
 284 is_double:
 285         movew   #0x3c01,%d1     |write the bias for a dbl denorm
 286 common:
 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
 290 pos:
 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 |
 308 pack_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
 317 pack_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 |
 345 opclass3:
 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
 352 end_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 |
 359 chk_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
 368 set_dya:
 369         st      DY_MO_FLG(%a6)  |set the inst flag type to dyadic
 370         rts
 371 set_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
 409 mk_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
 418 uns_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
 423 bit_set:
 424         bsr     uns_op3         |opclass 011
 425 reload:
 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.
 435 end_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
 439 end_mk_pos:
 440         rts
 441 |
 442 |     CASE opclass 011 unsupp
 443 |
 444 uns_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
 448 set_unfl:
 449         orw     #dnrm_tag,L_SCR1(%a6) |set denorm tag
 450         bsetb   #unfl_bit,FPSR_EXCEPT(%a6) |set unfl exception bit
 451 no_unfl:
 452         rts
 453 |
 454 |     CASE opclass 0x0 unsupp
 455 |
 456 uns_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
 460 uns_nrm:
 461         orb     #norm_tag,L_SCR1(%a6) |set tag to norm
 462         rts
 463 uns_den:
 464         orb     #dnrm_tag,L_SCR1(%a6) |set tag to denorm
 465         rts
 466 |
 467 |     CASE opclass 0x0 unimp
 468 |
 469 uni_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
 473 uni_nrm:
 474         orb     #norm_tag,L_SCR1(%a6) |set tag to norm
 475         rts
 476 uni_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
 491 unpack:
 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
 509 fix_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
 514 try_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
 529 pos_zero:
 530         clrl    ETEMP(%a6)
 531         clrl    ETEMP_HI(%a6)
 532         clrl    ETEMP_LO(%a6)
 533         bra     finish
 534 
 535 not_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 |
 547 move_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
 566 mfix_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
 575 mn_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 
 581 mtry_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
 597 mpos_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 
 604 mnot_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 
 611 finish:
 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 
 620 fix_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
 645 is_inf:
 646         moveb           #0x40,STAG(%a6)
 647         movel           #0x40,%d0
 648         rts
 649 is_nan:
 650         moveb           #0x60,STAG(%a6)
 651         movel           #0x60,%d0
 652         rts
 653 z_or_nrm:
 654         tstw            %d1  
 655         bnes            is_nrm
 656 is_zro:
 657 | For a zero, set etemp_15
 658         moveb           #0x30,STAG(%a6)
 659         movel           #0x20,%d0
 660         rts
 661 is_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
 667 set_bit15:
 668         moveb           #0x10,STAG(%a6)
 669 end_is_nrm:
 670         movel           #0,%d0
 671 end_fix:
 672         rts
 673  
 674 end_get:
 675         rts
 676         |end

/* [previous][next][first][last][top][bottom][index][help] */