[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

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