[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     ! 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