[BACK]Return to get_op.sa CVS log [TXT][DIR] Up to [local] / sys / arch / m68k / fpsp

Annotation of sys/arch/m68k/fpsp/get_op.sa, Revision 1.1.1.1

1.1       nbrk        1: *      $OpenBSD: get_op.sa,v 1.2 1996/05/29 21:05:29 niklas Exp $
                      2: *      $NetBSD: get_op.sa,v 1.3 1994/10/26 07:49:09 cgd Exp $
                      3:
                      4: *      MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
                      5: *      M68000 Hi-Performance Microprocessor Division
                      6: *      M68040 Software Package
                      7: *
                      8: *      M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
                      9: *      All rights reserved.
                     10: *
                     11: *      THE SOFTWARE is provided on an "AS IS" basis and without warranty.
                     12: *      To the maximum extent permitted by applicable law,
                     13: *      MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
                     14: *      INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
                     15: *      PARTICULAR PURPOSE and any warranty against infringement with
                     16: *      regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
                     17: *      and any accompanying written materials.
                     18: *
                     19: *      To the maximum extent permitted by applicable law,
                     20: *      IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
                     21: *      (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
                     22: *      PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
                     23: *      OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
                     24: *      SOFTWARE.  Motorola assumes no responsibility for the maintenance
                     25: *      and support of the SOFTWARE.
                     26: *
                     27: *      You are hereby granted a copyright license to use, modify, and
                     28: *      distribute the SOFTWARE so long as this entire notice is retained
                     29: *      without alteration in any modified and/or redistributed versions,
                     30: *      and that such modified versions are clearly identified as such.
                     31: *      No licenses are granted by implication, estoppel or otherwise
                     32: *      under any patents or trademarks of Motorola, Inc.
                     33:
                     34: *
                     35: *      get_op.sa 3.6 5/19/92
                     36: *
                     37: *      get_op.sa 3.5 4/26/91
                     38: *
                     39: *  Description: This routine is called by the unsupported format/data
                     40: * type exception handler ('unsupp' - vector 55) and the unimplemented
                     41: * instruction exception handler ('unimp' - vector 11).  'get_op'
                     42: * determines the opclass (0, 2, or 3) and branches to the
                     43: * opclass handler routine.  See 68881/2 User's Manual table 4-11
                     44: * for a description of the opclasses.
                     45: *
                     46: * For UNSUPPORTED data/format (exception vector 55) and for
                     47: * UNIMPLEMENTED instructions (exception vector 11) the following
                     48: * applies:
                     49: *
                     50: * - For unnormormalized numbers (opclass 0, 2, or 3) the
                     51: * number(s) is normalized and the operand type tag is updated.
                     52: *
                     53: * - For a packed number (opclass 2) the number is unpacked and the
                     54: * operand type tag is updated.
                     55: *
                     56: * - For denormalized numbers (opclass 0 or 2) the number(s) is not
                     57: * changed but passed to the next module.  The next module for
                     58: * unimp is do_func, the next module for unsupp is res_func.
                     59: *
                     60: * For UNSUPPORTED data/format (exception vector 55) only the
                     61: * following applies:
                     62: *
                     63: * - If there is a move out with a packed number (opclass 3) the
                     64: * number is packed and written to user memory.  For the other
                     65: * opclasses the number(s) are written back to the fsave stack
                     66: * and the instruction is then restored back into the '040.  The
                     67: * '040 is then able to complete the instruction.
                     68: *
                     69: * For example:
                     70: * fadd.x fpm,fpn where the fpm contains an unnormalized number.
                     71: * The '040 takes an unsupported data trap and gets to this
                     72: * routine.  The number is normalized, put back on the stack and
                     73: * then an frestore is done to restore the instruction back into
                     74: * the '040.  The '040 then re-executes the fadd.x fpm,fpn with
                     75: * a normalized number in the source and the instruction is
                     76: * successful.
                     77: *
                     78: * Next consider if in the process of normalizing the un-
                     79: * normalized number it becomes a denormalized number.  The
                     80: * routine which converts the unnorm to a norm (called mk_norm)
                     81: * detects this and tags the number as a denorm.  The routine
                     82: * res_func sees the denorm tag and converts the denorm to a
                     83: * norm.  The instruction is then restored back into the '040
                     84: * which re_executess the instruction.
                     85: *
                     86:
                     87: GET_OP    IDNT    2,1 Motorola 040 Floating Point Software Package
                     88:
                     89:        section 8
                     90:
                     91:        include fpsp.h
                     92:
                     93:        xdef    PIRN,PIRZRM,PIRP
                     94:        xdef    SMALRN,SMALRZRM,SMALRP
                     95:        xdef    BIGRN,BIGRZRM,BIGRP
                     96:
                     97: PIRN:
                     98:        dc.l $40000000,$c90fdaa2,$2168c235    ;pi
                     99: PIRZRM:
                    100:        dc.l $40000000,$c90fdaa2,$2168c234    ;pi
                    101: PIRP:
                    102:        dc.l $40000000,$c90fdaa2,$2168c235    ;pi
                    103:
                    104: *round to nearest
                    105: SMALRN:
                    106:        dc.l $3ffd0000,$9a209a84,$fbcff798    ;log10(2)
                    107:        dc.l $40000000,$adf85458,$a2bb4a9a    ;e
                    108:        dc.l $3fff0000,$b8aa3b29,$5c17f0bc    ;log2(e)
                    109:        dc.l $3ffd0000,$de5bd8a9,$37287195    ;log10(e)
                    110:        dc.l $00000000,$00000000,$00000000    ;0.0
                    111: * round to zero;round to negative infinity
                    112: SMALRZRM:
                    113:        dc.l $3ffd0000,$9a209a84,$fbcff798    ;log10(2)
                    114:        dc.l $40000000,$adf85458,$a2bb4a9a    ;e
                    115:        dc.l $3fff0000,$b8aa3b29,$5c17f0bb    ;log2(e)
                    116:        dc.l $3ffd0000,$de5bd8a9,$37287195    ;log10(e)
                    117:        dc.l $00000000,$00000000,$00000000    ;0.0
                    118: * round to positive infinity
                    119: SMALRP:
                    120:        dc.l $3ffd0000,$9a209a84,$fbcff799    ;log10(2)
                    121:        dc.l $40000000,$adf85458,$a2bb4a9b    ;e
                    122:        dc.l $3fff0000,$b8aa3b29,$5c17f0bc    ;log2(e)
                    123:        dc.l $3ffd0000,$de5bd8a9,$37287195    ;log10(e)
                    124:        dc.l $00000000,$00000000,$00000000    ;0.0
                    125:
                    126: *round to nearest
                    127: BIGRN:
                    128:        dc.l $3ffe0000,$b17217f7,$d1cf79ac    ;ln(2)
                    129:        dc.l $40000000,$935d8ddd,$aaa8ac17    ;ln(10)
                    130:        dc.l $3fff0000,$80000000,$00000000    ;10 ^ 0
                    131:
                    132:        xdef    PTENRN
                    133: PTENRN:
                    134:        dc.l $40020000,$A0000000,$00000000    ;10 ^ 1
                    135:        dc.l $40050000,$C8000000,$00000000    ;10 ^ 2
                    136:        dc.l $400C0000,$9C400000,$00000000    ;10 ^ 4
                    137:        dc.l $40190000,$BEBC2000,$00000000    ;10 ^ 8
                    138:        dc.l $40340000,$8E1BC9BF,$04000000    ;10 ^ 16
                    139:        dc.l $40690000,$9DC5ADA8,$2B70B59E    ;10 ^ 32
                    140:        dc.l $40D30000,$C2781F49,$FFCFA6D5    ;10 ^ 64
                    141:        dc.l $41A80000,$93BA47C9,$80E98CE0    ;10 ^ 128
                    142:        dc.l $43510000,$AA7EEBFB,$9DF9DE8E    ;10 ^ 256
                    143:        dc.l $46A30000,$E319A0AE,$A60E91C7    ;10 ^ 512
                    144:        dc.l $4D480000,$C9767586,$81750C17    ;10 ^ 1024
                    145:        dc.l $5A920000,$9E8B3B5D,$C53D5DE5    ;10 ^ 2048
                    146:        dc.l $75250000,$C4605202,$8A20979B    ;10 ^ 4096
                    147: *round to minus infinity
                    148: BIGRZRM:
                    149:        dc.l $3ffe0000,$b17217f7,$d1cf79ab    ;ln(2)
                    150:        dc.l $40000000,$935d8ddd,$aaa8ac16    ;ln(10)
                    151:        dc.l $3fff0000,$80000000,$00000000    ;10 ^ 0
                    152:
                    153:        xdef    PTENRM
                    154: PTENRM:
                    155:        dc.l $40020000,$A0000000,$00000000    ;10 ^ 1
                    156:        dc.l $40050000,$C8000000,$00000000    ;10 ^ 2
                    157:        dc.l $400C0000,$9C400000,$00000000    ;10 ^ 4
                    158:        dc.l $40190000,$BEBC2000,$00000000    ;10 ^ 8
                    159:        dc.l $40340000,$8E1BC9BF,$04000000    ;10 ^ 16
                    160:        dc.l $40690000,$9DC5ADA8,$2B70B59D    ;10 ^ 32
                    161:        dc.l $40D30000,$C2781F49,$FFCFA6D5    ;10 ^ 64
                    162:        dc.l $41A80000,$93BA47C9,$80E98CDF    ;10 ^ 128
                    163:        dc.l $43510000,$AA7EEBFB,$9DF9DE8D    ;10 ^ 256
                    164:        dc.l $46A30000,$E319A0AE,$A60E91C6    ;10 ^ 512
                    165:        dc.l $4D480000,$C9767586,$81750C17    ;10 ^ 1024
                    166:        dc.l $5A920000,$9E8B3B5D,$C53D5DE5    ;10 ^ 2048
                    167:        dc.l $75250000,$C4605202,$8A20979A    ;10 ^ 4096
                    168: *round to positive infinity
                    169: BIGRP:
                    170:        dc.l $3ffe0000,$b17217f7,$d1cf79ac    ;ln(2)
                    171:        dc.l $40000000,$935d8ddd,$aaa8ac17    ;ln(10)
                    172:        dc.l $3fff0000,$80000000,$00000000    ;10 ^ 0
                    173:
                    174:        xdef    PTENRP
                    175: PTENRP:
                    176:        dc.l $40020000,$A0000000,$00000000    ;10 ^ 1
                    177:        dc.l $40050000,$C8000000,$00000000    ;10 ^ 2
                    178:        dc.l $400C0000,$9C400000,$00000000    ;10 ^ 4
                    179:        dc.l $40190000,$BEBC2000,$00000000    ;10 ^ 8
                    180:        dc.l $40340000,$8E1BC9BF,$04000000    ;10 ^ 16
                    181:        dc.l $40690000,$9DC5ADA8,$2B70B59E    ;10 ^ 32
                    182:        dc.l $40D30000,$C2781F49,$FFCFA6D6    ;10 ^ 64
                    183:        dc.l $41A80000,$93BA47C9,$80E98CE0    ;10 ^ 128
                    184:        dc.l $43510000,$AA7EEBFB,$9DF9DE8E    ;10 ^ 256
                    185:        dc.l $46A30000,$E319A0AE,$A60E91C7    ;10 ^ 512
                    186:        dc.l $4D480000,$C9767586,$81750C18    ;10 ^ 1024
                    187:        dc.l $5A920000,$9E8B3B5D,$C53D5DE6    ;10 ^ 2048
                    188:        dc.l $75250000,$C4605202,$8A20979B    ;10 ^ 4096
                    189:
                    190:        xref    nrm_zero
                    191:        xref    decbin
                    192:        xref    round
                    193:
                    194:        xdef    get_op
                    195:        xdef    uns_getop
                    196:        xdef    uni_getop
                    197: get_op:
                    198:        clr.b   DY_MO_FLG(a6)
                    199:        tst.b   UFLG_TMP(a6)    ;test flag for unsupp/unimp state
                    200:        beq.b   uni_getop
                    201:
                    202: uns_getop:
                    203:        btst.b  #direction_bit,CMDREG1B(a6)
                    204:        bne.w   opclass3        ;branch if a fmove out (any kind)
                    205:        btst.b  #6,CMDREG1B(a6)
                    206:        beq.b   uns_notpacked
                    207:
                    208:        bfextu  CMDREG1B(a6){3:3},d0
                    209:        cmp.b   #3,d0
                    210:        beq.w   pack_source     ;check for a packed src op, branch if so
                    211: uns_notpacked:
                    212:        bsr     chk_dy_mo       ;set the dyadic/monadic flag
                    213:        tst.b   DY_MO_FLG(a6)
                    214:        beq.b   src_op_ck       ;if monadic, go check src op
                    215: *                              ;else, check dst op (fall through)
                    216:
                    217:        btst.b  #7,DTAG(a6)
                    218:        beq.b   src_op_ck       ;if dst op is norm, check src op
                    219:        bra.b   dst_ex_dnrm     ;else, handle destination unnorm/dnrm
                    220:
                    221: 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:
                    232: not_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:
                    242: dest_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: *
                    251: dst_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: *
                    272: src_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: *
                    281: src_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: *
                    304: src_sd_dnrm:
                    305:        btst.b  #4,CMDREG1B(a6) ;differentiate between sgl/dbl denorm
                    306:        bne.b   is_double
                    307: is_single:
                    308:        move.w  #$3f81,d1       ;write bias for sgl denorm
                    309:        bra.b   common          ;goto the common code
                    310: is_double:
                    311:        move.w  #$3c01,d1       ;write the bias for a dbl denorm
                    312: common:
                    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
                    316: pos:
                    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: *
                    334: pack_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
                    343: pack_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: *
                    371: opclass3:
                    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
                    378: end_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: *
                    385: chk_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
                    394: set_dya:
                    395:        st.b    DY_MO_FLG(a6)   ;set the inst flag type to dyadic
                    396:        rts
                    397: set_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
                    435: mk_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
                    444: uns_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
                    449: bit_set:
                    450:        bsr     uns_op3         ;opclass 011
                    451: reload:
                    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.
                    461: end_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
                    465: end_mk_pos:
                    466:        rts
                    467: *
                    468: *     CASE opclass 011 unsupp
                    469: *
                    470: uns_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
                    474: set_unfl:
                    475:        or.b    #dnrm_tag,L_SCR1(a6) ;set denorm tag
                    476:        bset.b  #unfl_bit,FPSR_EXCEPT(a6) ;set unfl exception bit
                    477: no_unfl:
                    478:        rts
                    479: *
                    480: *     CASE opclass 0x0 unsupp
                    481: *
                    482: uns_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
                    486: uns_nrm:
                    487:        or.b    #norm_tag,L_SCR1(a6) ;set tag to norm
                    488:        rts
                    489: uns_den:
                    490:        or.b    #dnrm_tag,L_SCR1(a6) ;set tag to denorm
                    491:        rts
                    492: *
                    493: *     CASE opclass 0x0 unimp
                    494: *
                    495: uni_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
                    499: uni_nrm:
                    500:        or.b    #norm_tag,L_SCR1(a6) ;set tag to norm
                    501:        rts
                    502: uni_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
                    517: unpack:
                    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
                    535: fix_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
                    540: try_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
                    555: pos_zero:
                    556:        clr.l   ETEMP(a6)
                    557:        clr.l   ETEMP_HI(a6)
                    558:        clr.l   ETEMP_LO(a6)
                    559:        bra.w   finish
                    560:
                    561: not_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: *
                    573: move_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
                    592: mfix_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
                    601: mn_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:
                    607: mtry_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
                    623: mpos_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:
                    630: mnot_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:
                    637: finish:
                    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:
                    646: fix_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
                    671: is_inf:
                    672:        move.b          #$40,STAG(a6)
                    673:        move.l          #$40,d0
                    674:        rts
                    675: is_nan:
                    676:        move.b          #$60,STAG(a6)
                    677:        move.l          #$60,d0
                    678:        rts
                    679: z_or_nrm:
                    680:        tst.w           d1
                    681:        bne.b           is_nrm
                    682: is_zro:
                    683: * For a zero, set etemp_15
                    684:        move.b          #$30,STAG(a6)
                    685:        move.l          #$20,d0
                    686:        rts
                    687: is_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
                    693: set_bit15:
                    694:        move.b          #$10,STAG(a6)
                    695: end_is_nrm:
                    696:        clr.l           d0
                    697: end_fix:
                    698:        rts
                    699:
                    700: end_get:
                    701:        rts
                    702:        end

CVSweb