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

Annotation of sys/arch/m68k/fpsp/kernel_ex.sa, Revision 1.1

1.1     ! nbrk        1: *      $OpenBSD: kernel_ex.sa,v 1.2 1996/05/29 21:05:30 niklas Exp $
        !             2: *      $NetBSD: kernel_ex.sa,v 1.2 1994/10/26 07:49:12 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: *      kernel_ex.sa 3.3 12/19/90
        !            36: *
        !            37: * This file contains routines to force exception status in the
        !            38: * fpu for exceptional cases detected or reported within the
        !            39: * transcendental functions.  Typically, the t_xx routine will
        !            40: * set the appropriate bits in the USER_FPSR word on the stack.
        !            41: * The bits are tested in gen_except.sa to determine if an exceptional
        !            42: * situation needs to be created on return from the FPSP.
        !            43: *
        !            44:
        !            45: KERNEL_EX    IDNT    2,1 Motorola 040 Floating Point Software Package
        !            46:
        !            47:        section    8
        !            48:
        !            49:        include fpsp.h
        !            50:
        !            51: mns_inf  dc.l $ffff0000,$00000000,$00000000
        !            52: pls_inf  dc.l $7fff0000,$00000000,$00000000
        !            53: nan      dc.l $7fff0000,$ffffffff,$ffffffff
        !            54: huge     dc.l $7ffe0000,$ffffffff,$ffffffff
        !            55:
        !            56:        xref      ovf_r_k
        !            57:        xref      unf_sub
        !            58:        xref      nrm_set
        !            59:
        !            60:        xdef      t_dz
        !            61:        xdef      t_dz2
        !            62:        xdef      t_operr
        !            63:        xdef      t_unfl
        !            64:        xdef      t_ovfl
        !            65:        xdef      t_ovfl2
        !            66:        xdef      t_inx2
        !            67:        xdef      t_frcinx
        !            68:        xdef      t_extdnrm
        !            69:        xdef      t_resdnrm
        !            70:        xdef      dst_nan
        !            71:        xdef      src_nan
        !            72: *
        !            73: *      DZ exception
        !            74: *
        !            75: *
        !            76: *      if dz trap disabled
        !            77: *              store properly signed inf (use sign of etemp) into fp0
        !            78: *              set FPSR exception status dz bit, condition code
        !            79: *              inf bit, and accrued dz bit
        !            80: *              return
        !            81: *              frestore the frame into the machine (done by unimp_hd)
        !            82: *
        !            83: *      else dz trap enabled
        !            84: *              set exception status bit & accrued bits in FPSR
        !            85: *              set flag to disable sto_res from corrupting fp register
        !            86: *              return
        !            87: *              frestore the frame into the machine (done by unimp_hd)
        !            88: *
        !            89: * t_dz2 is used by monadic functions such as flogn (from do_func).
        !            90: * t_dz is used by monadic functions such as satanh (from the
        !            91: * transcendental function).
        !            92: *
        !            93: t_dz2:
        !            94:        bset.b  #neg_bit,FPSR_CC(a6)    ;set neg bit in FPSR
        !            95:        fmove.l #0,FPSR                 ;clr status bits (Z set)
        !            96:        btst.b  #dz_bit,FPCR_ENABLE(a6) ;test FPCR for dz exc enabled
        !            97:        bne.b   dz_ena_end
        !            98:        bra.b   m_inf                   ;flogx always returns -inf
        !            99: t_dz:
        !           100:        fmove.l #0,FPSR                 ;clr status bits (Z set)
        !           101:        btst.b  #dz_bit,FPCR_ENABLE(a6) ;test FPCR for dz exc enabled
        !           102:        bne.b   dz_ena
        !           103: *
        !           104: *      dz disabled
        !           105: *
        !           106:        btst.b  #sign_bit,ETEMP_EX(a6)  ;check sign for neg or pos
        !           107:        beq.b   p_inf                   ;branch if pos sign
        !           108:
        !           109: m_inf:
        !           110:        fmovem.x mns_inf,fp0            ;load -inf
        !           111:        bset.b  #neg_bit,FPSR_CC(a6)    ;set neg bit in FPSR
        !           112:        bra.b   set_fpsr
        !           113: p_inf:
        !           114:        fmovem.x pls_inf,fp0            ;load +inf
        !           115: set_fpsr:
        !           116:        or.l    #dzinf_mask,USER_FPSR(a6) ;set I,DZ,ADZ
        !           117:        rts
        !           118: *
        !           119: *      dz enabled
        !           120: *
        !           121: dz_ena:
        !           122:        btst.b  #sign_bit,ETEMP_EX(a6)  ;check sign for neg or pos
        !           123:        beq.b   dz_ena_end
        !           124:        bset.b  #neg_bit,FPSR_CC(a6)    ;set neg bit in FPSR
        !           125: dz_ena_end:
        !           126:        or.l    #dzinf_mask,USER_FPSR(a6) ;set I,DZ,ADZ
        !           127:        st.b    STORE_FLG(a6)
        !           128:        rts
        !           129: *
        !           130: *      OPERR exception
        !           131: *
        !           132: *      if (operr trap disabled)
        !           133: *              set FPSR exception status operr bit, condition code
        !           134: *              nan bit; Store default NAN into fp0
        !           135: *              frestore the frame into the machine (done by unimp_hd)
        !           136: *
        !           137: *      else (operr trap enabled)
        !           138: *              set FPSR exception status operr bit, accrued operr bit
        !           139: *              set flag to disable sto_res from corrupting fp register
        !           140: *              frestore the frame into the machine (done by unimp_hd)
        !           141: *
        !           142: t_operr:
        !           143:        or.l    #opnan_mask,USER_FPSR(a6) ;set NaN, OPERR, AIOP
        !           144:
        !           145:        btst.b  #operr_bit,FPCR_ENABLE(a6) ;test FPCR for operr enabled
        !           146:        bne.b   op_ena
        !           147:
        !           148:        fmovem.x nan,fp0                ;load default nan
        !           149:        rts
        !           150: op_ena:
        !           151:        st.b    STORE_FLG(a6)           ;do not corrupt destination
        !           152:        rts
        !           153:
        !           154: *
        !           155: *      t_unfl --- UNFL exception
        !           156: *
        !           157: * This entry point is used by all routines requiring unfl, inex2,
        !           158: * aunfl, and ainex to be set on exit.
        !           159: *
        !           160: * On entry, a0 points to the exceptional operand.  The final exceptional
        !           161: * operand is built in FP_SCR1 and only the sign from the original operand
        !           162: * is used.
        !           163: *
        !           164: t_unfl:
        !           165:        clr.l   FP_SCR1(a6)             ;set exceptional operand to zero
        !           166:        clr.l   FP_SCR1+4(a6)
        !           167:        clr.l   FP_SCR1+8(a6)
        !           168:        tst.b   (a0)                    ;extract sign from caller's exop
        !           169:        bpl.b   unfl_signok
        !           170:        bset    #sign_bit,FP_SCR1(a6)
        !           171: unfl_signok:
        !           172:        lea.l   FP_SCR1(a6),a0
        !           173:        or.l    #unfinx_mask,USER_FPSR(a6)
        !           174: *                                      ;set UNFL, INEX2, AUNFL, AINEX
        !           175: unfl_con:
        !           176:        btst.b  #unfl_bit,FPCR_ENABLE(a6)
        !           177:        beq.b   unfl_dis
        !           178:
        !           179: unfl_ena:
        !           180:        bfclr   STAG(a6){5:3}           ;clear wbtm66,wbtm1,wbtm0
        !           181:        bset.b  #wbtemp15_bit,WB_BYTE(a6) ;set wbtemp15
        !           182:        bset.b  #sticky_bit,STICKY(a6)  ;set sticky bit
        !           183:
        !           184:        bclr.b  #E1,E_BYTE(a6)
        !           185:
        !           186: unfl_dis:
        !           187:        bfextu  FPCR_MODE(a6){0:2},d0   ;get round precision
        !           188:
        !           189:        bclr.b  #sign_bit,LOCAL_EX(a0)
        !           190:        sne     LOCAL_SGN(a0)           ;convert to internal ext format
        !           191:
        !           192:        bsr     unf_sub                 ;returns IEEE result at a0
        !           193: *                                      ;and sets FPSR_CC accordingly
        !           194:
        !           195:        bfclr   LOCAL_SGN(a0){0:8}      ;convert back to IEEE ext format
        !           196:        beq.b   unfl_fin
        !           197:
        !           198:        bset.b  #sign_bit,LOCAL_EX(a0)
        !           199:        bset.b  #sign_bit,FP_SCR1(a6)   ;set sign bit of exc operand
        !           200:
        !           201: unfl_fin:
        !           202:        fmovem.x (a0),fp0               ;store result in fp0
        !           203:        rts
        !           204:
        !           205:
        !           206: *
        !           207: *      t_ovfl2 --- OVFL exception (without inex2 returned)
        !           208: *
        !           209: * This entry is used by scale to force catastrophic overflow.  The
        !           210: * ovfl, aovfl, and ainex bits are set, but not the inex2 bit.
        !           211: *
        !           212: t_ovfl2:
        !           213:        or.l    #ovfl_inx_mask,USER_FPSR(a6)
        !           214:        move.l  ETEMP(a6),FP_SCR1(a6)
        !           215:        move.l  ETEMP_HI(a6),FP_SCR1+4(a6)
        !           216:        move.l  ETEMP_LO(a6),FP_SCR1+8(a6)
        !           217: *
        !           218: * Check for single or double round precision.  If single, check if
        !           219: * the lower 40 bits of ETEMP are zero; if not, set inex2.  If double,
        !           220: * check if the lower 21 bits are zero; if not, set inex2.
        !           221: *
        !           222:        move.b  FPCR_MODE(a6),d0
        !           223:        andi.b  #$c0,d0
        !           224:        beq.w   t_work          ;if extended, finish ovfl processing
        !           225:        cmpi.b  #$40,d0         ;test for single
        !           226:        bne.b   t_dbl
        !           227: t_sgl:
        !           228:        tst.b   ETEMP_LO(a6)
        !           229:        bne.b   t_setinx2
        !           230:        move.l  ETEMP_HI(a6),d0
        !           231:        andi.l  #$ff,d0         ;look at only lower 8 bits
        !           232:        bne.b   t_setinx2
        !           233:        bra.w   t_work
        !           234: t_dbl:
        !           235:        move.l  ETEMP_LO(a6),d0
        !           236:        andi.l  #$7ff,d0        ;look at only lower 11 bits
        !           237:        beq.w   t_work
        !           238: t_setinx2:
        !           239:        or.l    #inex2_mask,USER_FPSR(a6)
        !           240:        bra.b   t_work
        !           241: *
        !           242: *      t_ovfl --- OVFL exception
        !           243: *
        !           244: *** Note: the exc operand is returned in ETEMP.
        !           245: *
        !           246: t_ovfl:
        !           247:        or.l    #ovfinx_mask,USER_FPSR(a6)
        !           248: t_work:
        !           249:        btst.b  #ovfl_bit,FPCR_ENABLE(a6) ;test FPCR for ovfl enabled
        !           250:        beq.b   ovf_dis
        !           251:
        !           252: ovf_ena:
        !           253:        clr.l   FP_SCR1(a6)             ;set exceptional operand
        !           254:        clr.l   FP_SCR1+4(a6)
        !           255:        clr.l   FP_SCR1+8(a6)
        !           256:
        !           257:        bfclr   STAG(a6){5:3}           ;clear wbtm66,wbtm1,wbtm0
        !           258:        bclr.b  #wbtemp15_bit,WB_BYTE(a6) ;clear wbtemp15
        !           259:        bset.b  #sticky_bit,STICKY(a6)  ;set sticky bit
        !           260:
        !           261:        bclr.b  #E1,E_BYTE(a6)
        !           262: *                                      ;fall through to disabled case
        !           263:
        !           264: * For disabled overflow call 'ovf_r_k'.  This routine loads the
        !           265: * correct result based on the rounding precision, destination
        !           266: * format, rounding mode and sign.
        !           267: *
        !           268: ovf_dis:
        !           269:        bsr     ovf_r_k                 ;returns unsigned ETEMP_EX
        !           270: *                                      ;and sets FPSR_CC accordingly.
        !           271:        bfclr   ETEMP_SGN(a6){0:8}      ;fix sign
        !           272:        beq.b   ovf_pos
        !           273:        bset.b  #sign_bit,ETEMP_EX(a6)
        !           274:        bset.b  #sign_bit,FP_SCR1(a6)   ;set exceptional operand sign
        !           275: ovf_pos:
        !           276:        fmovem.x ETEMP(a6),fp0          ;move the result to fp0
        !           277:        rts
        !           278:
        !           279:
        !           280: *
        !           281: *      INEX2 exception
        !           282: *
        !           283: * The inex2 and ainex bits are set.
        !           284: *
        !           285: t_inx2:
        !           286:        or.l    #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
        !           287:        rts
        !           288:
        !           289: *
        !           290: *      Force Inex2
        !           291: *
        !           292: * This routine is called by the transcendental routines to force
        !           293: * the inex2 exception bits set in the FPSR.  If the underflow bit
        !           294: * is set, but the underflow trap was not taken, the aunfl bit in
        !           295: * the FPSR must be set.
        !           296: *
        !           297: t_frcinx:
        !           298:        or.l    #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
        !           299:        btst.b  #unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set
        !           300:        beq.b   no_uacc1                ;if clear, do not set aunfl
        !           301:        bset.b  #aunfl_bit,FPSR_AEXCEPT(a6)
        !           302: no_uacc1:
        !           303:        rts
        !           304:
        !           305: *
        !           306: *      DST_NAN
        !           307: *
        !           308: * Determine if the destination nan is signalling or non-signalling,
        !           309: * and set the FPSR bits accordingly.  See the MC68040 User's Manual
        !           310: * section 3.2.2.5 NOT-A-NUMBERS.
        !           311: *
        !           312: dst_nan:
        !           313:        btst.b  #sign_bit,FPTEMP_EX(a6) ;test sign of nan
        !           314:        beq.b   dst_pos                 ;if clr, it was positive
        !           315:        bset.b  #neg_bit,FPSR_CC(a6)    ;set N bit
        !           316: dst_pos:
        !           317:        btst.b  #signan_bit,FPTEMP_HI(a6) ;check if signalling
        !           318:        beq.b   dst_snan                ;branch if signalling
        !           319:
        !           320:        fmove.l d1,fpcr                 ;restore user's rmode/prec
        !           321:        fmove.x FPTEMP(a6),fp0          ;return the non-signalling nan
        !           322: *
        !           323: * Check the source nan.  If it is signalling, snan will be reported.
        !           324: *
        !           325:        move.b  STAG(a6),d0
        !           326:        andi.b  #$e0,d0
        !           327:        cmpi.b  #$60,d0
        !           328:        bne.b   no_snan
        !           329:        btst.b  #signan_bit,ETEMP_HI(a6) ;check if signalling
        !           330:        bne.b   no_snan
        !           331:        or.l    #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
        !           332: no_snan:
        !           333:        rts
        !           334:
        !           335: dst_snan:
        !           336:        btst.b  #snan_bit,FPCR_ENABLE(a6) ;check if trap enabled
        !           337:        beq.b   dst_dis                 ;branch if disabled
        !           338:
        !           339:        or.b    #nan_tag,DTAG(a6)       ;set up dtag for nan
        !           340:        st.b    STORE_FLG(a6)           ;do not store a result
        !           341:        or.l    #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
        !           342:        rts
        !           343:
        !           344: dst_dis:
        !           345:        bset.b  #signan_bit,FPTEMP_HI(a6) ;set SNAN bit in sop
        !           346:        fmove.l d1,fpcr                 ;restore user's rmode/prec
        !           347:        fmove.x FPTEMP(a6),fp0          ;load non-sign. nan
        !           348:        or.l    #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
        !           349:        rts
        !           350:
        !           351: *
        !           352: *      SRC_NAN
        !           353: *
        !           354: * Determine if the source nan is signalling or non-signalling,
        !           355: * and set the FPSR bits accordingly.  See the MC68040 User's Manual
        !           356: * section 3.2.2.5 NOT-A-NUMBERS.
        !           357: *
        !           358: src_nan:
        !           359:        btst.b  #sign_bit,ETEMP_EX(a6) ;test sign of nan
        !           360:        beq.b   src_pos                 ;if clr, it was positive
        !           361:        bset.b  #neg_bit,FPSR_CC(a6)    ;set N bit
        !           362: src_pos:
        !           363:        btst.b  #signan_bit,ETEMP_HI(a6) ;check if signalling
        !           364:        beq.b   src_snan                ;branch if signalling
        !           365:        fmove.l d1,fpcr                 ;restore user's rmode/prec
        !           366:        fmove.x ETEMP(a6),fp0           ;return the non-signalling nan
        !           367:        rts
        !           368:
        !           369: src_snan:
        !           370:        btst.b  #snan_bit,FPCR_ENABLE(a6) ;check if trap enabled
        !           371:        beq.b   src_dis                 ;branch if disabled
        !           372:        bset.b  #signan_bit,ETEMP_HI(a6) ;set SNAN bit in sop
        !           373:        or.b    #norm_tag,DTAG(a6)      ;set up dtag for norm
        !           374:        or.b    #nan_tag,STAG(a6)       ;set up stag for nan
        !           375:        st.b    STORE_FLG(a6)           ;do not store a result
        !           376:        or.l    #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
        !           377:        rts
        !           378:
        !           379: src_dis:
        !           380:        bset.b  #signan_bit,ETEMP_HI(a6) ;set SNAN bit in sop
        !           381:        fmove.l d1,fpcr                 ;restore user's rmode/prec
        !           382:        fmove.x ETEMP(a6),fp0           ;load non-sign. nan
        !           383:        or.l    #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
        !           384:        rts
        !           385:
        !           386: *
        !           387: * For all functions that have a denormalized input and that f(x)=x,
        !           388: * this is the entry point
        !           389: *
        !           390: t_extdnrm:
        !           391:        or.l    #unfinx_mask,USER_FPSR(a6)
        !           392: *                                      ;set UNFL, INEX2, AUNFL, AINEX
        !           393:        bra.b   xdnrm_con
        !           394: *
        !           395: * Entry point for scale with extended denorm.  The function does
        !           396: * not set inex2, aunfl, or ainex.
        !           397: *
        !           398: t_resdnrm:
        !           399:        or.l    #unfl_mask,USER_FPSR(a6)
        !           400:
        !           401: xdnrm_con:
        !           402:        btst.b  #unfl_bit,FPCR_ENABLE(a6)
        !           403:        beq.b   xdnrm_dis
        !           404:
        !           405: *
        !           406: * If exceptions are enabled, the additional task of setting up WBTEMP
        !           407: * is needed so that when the underflow exception handler is entered,
        !           408: * the user perceives no difference between what the 040 provides vs.
        !           409: * what the FPSP provides.
        !           410: *
        !           411: xdnrm_ena:
        !           412:        move.l  a0,-(a7)
        !           413:
        !           414:        move.l  LOCAL_EX(a0),FP_SCR1(a6)
        !           415:        move.l  LOCAL_HI(a0),FP_SCR1+4(a6)
        !           416:        move.l  LOCAL_LO(a0),FP_SCR1+8(a6)
        !           417:
        !           418:        lea     FP_SCR1(a6),a0
        !           419:
        !           420:        bclr.b  #sign_bit,LOCAL_EX(a0)
        !           421:        sne     LOCAL_SGN(a0)           ;convert to internal ext format
        !           422:        tst.w   LOCAL_EX(a0)            ;check if input is denorm
        !           423:        beq.b   xdnrm_dn                ;if so, skip nrm_set
        !           424:        bsr     nrm_set                 ;normalize the result (exponent
        !           425: *                                      ;will be negative
        !           426: xdnrm_dn:
        !           427:        bclr.b  #sign_bit,LOCAL_EX(a0)  ;take off false sign
        !           428:        bfclr   LOCAL_SGN(a0){0:8}      ;change back to IEEE ext format
        !           429:        beq.b   xdep
        !           430:        bset.b  #sign_bit,LOCAL_EX(a0)
        !           431: xdep:
        !           432:        bfclr   STAG(a6){5:3}           ;clear wbtm66,wbtm1,wbtm0
        !           433:        bset.b  #wbtemp15_bit,WB_BYTE(a6) ;set wbtemp15
        !           434:        bclr.b  #sticky_bit,STICKY(a6)  ;clear sticky bit
        !           435:        bclr.b  #E1,E_BYTE(a6)
        !           436:        move.l  (a7)+,a0
        !           437: xdnrm_dis:
        !           438:        bfextu  FPCR_MODE(a6){0:2},d0   ;get round precision
        !           439:        bne.b   not_ext                 ;if not round extended, store
        !           440: *                                      ;IEEE defaults
        !           441: is_ext:
        !           442:        btst.b  #sign_bit,LOCAL_EX(a0)
        !           443:        beq.b   xdnrm_store
        !           444:
        !           445:        bset.b  #neg_bit,FPSR_CC(a6)    ;set N bit in FPSR_CC
        !           446:
        !           447:        bra.b   xdnrm_store
        !           448:
        !           449: not_ext:
        !           450:        bclr.b  #sign_bit,LOCAL_EX(a0)
        !           451:        sne     LOCAL_SGN(a0)           ;convert to internal ext format
        !           452:        bsr     unf_sub                 ;returns IEEE result pointed by
        !           453: *                                      ;a0; sets FPSR_CC accordingly
        !           454:        bfclr   LOCAL_SGN(a0){0:8}      ;convert back to IEEE ext format
        !           455:        beq.b   xdnrm_store
        !           456:        bset.b  #sign_bit,LOCAL_EX(a0)
        !           457: xdnrm_store:
        !           458:        fmovem.x (a0),fp0               ;store result in fp0
        !           459:        rts
        !           460:
        !           461: *
        !           462: * This subroutine is used for dyadic operations that use an extended
        !           463: * denorm within the kernel. The approach used is to capture the frame,
        !           464: * fix/restore.
        !           465: *
        !           466:        xdef    t_avoid_unsupp
        !           467: t_avoid_unsupp:
        !           468:        link    a2,#-LOCAL_SIZE         ;so that a2 fpsp.h negative
        !           469: *                                      ;offsets may be used
        !           470:        fsave   -(a7)
        !           471:        tst.b   1(a7)                   ;check if idle, exit if so
        !           472:        beq.w   idle_end
        !           473:        btst.b  #E1,E_BYTE(a2)          ;check for an E1 exception if
        !           474: *                                      ;enabled, there is an unsupp
        !           475:        beq.w   end_avun                ;else, exit
        !           476:        btst.b  #7,DTAG(a2)             ;check for denorm destination
        !           477:        beq.b   src_den                 ;else, must be a source denorm
        !           478: *
        !           479: * handle destination denorm
        !           480: *
        !           481:        lea     FPTEMP(a2),a0
        !           482:        btst.b  #sign_bit,LOCAL_EX(a0)
        !           483:        sne     LOCAL_SGN(a0)           ;convert to internal ext format
        !           484:        bclr.b  #7,DTAG(a2)             ;set DTAG to norm
        !           485:        bsr     nrm_set                 ;normalize result, exponent
        !           486: *                                      ;will become negative
        !           487:        bclr.b  #sign_bit,LOCAL_EX(a0)  ;get rid of fake sign
        !           488:        bfclr   LOCAL_SGN(a0){0:8}      ;convert back to IEEE ext format
        !           489:        beq.b   ck_src_den              ;check if source is also denorm
        !           490:        bset.b  #sign_bit,LOCAL_EX(a0)
        !           491: ck_src_den:
        !           492:        btst.b  #7,STAG(a2)
        !           493:        beq.b   end_avun
        !           494: src_den:
        !           495:        lea     ETEMP(a2),a0
        !           496:        btst.b  #sign_bit,LOCAL_EX(a0)
        !           497:        sne     LOCAL_SGN(a0)           ;convert to internal ext format
        !           498:        bclr.b  #7,STAG(a2)             ;set STAG to norm
        !           499:        bsr     nrm_set                 ;normalize result, exponent
        !           500: *                                      ;will become negative
        !           501:        bclr.b  #sign_bit,LOCAL_EX(a0)  ;get rid of fake sign
        !           502:        bfclr   LOCAL_SGN(a0){0:8}      ;convert back to IEEE ext format
        !           503:        beq.b   den_com
        !           504:        bset.b  #sign_bit,LOCAL_EX(a0)
        !           505: den_com:
        !           506:        move.b  #$fe,CU_SAVEPC(a2)      ;set continue frame
        !           507:        clr.w   NMNEXC(a2)              ;clear NMNEXC
        !           508:        bclr.b  #E1,E_BYTE(a2)
        !           509: *      fmove.l FPSR,FPSR_SHADOW(a2)
        !           510: *      bset.b  #SFLAG,E_BYTE(a2)
        !           511: *      bset.b  #XFLAG,T_BYTE(a2)
        !           512: end_avun:
        !           513:        frestore (a7)+
        !           514:        unlk    a2
        !           515:        rts
        !           516: idle_end:
        !           517:        add.l   #4,a7
        !           518:        unlk    a2
        !           519:        rts
        !           520:        end

CVSweb