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

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

1.1     ! nbrk        1: *      $OpenBSD: x_unfl.sa,v 1.3 2001/09/20 17:02:30 mpech Exp $
        !             2: *      $NetBSD: x_unfl.sa,v 1.3 1994/10/26 07:50:30 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: *      x_unfl.sa 3.4 7/1/91
        !            36: *
        !            37: *      fpsp_unfl --- FPSP handler for underflow exception
        !            38: *
        !            39: * Trap disabled results
        !            40: *      For 881/2 compatibility, sw must denormalize the intermediate
        !            41: * result, then store the result.  Denormalization is accomplished
        !            42: * by taking the intermediate result (which is always normalized) and
        !            43: * shifting the mantissa right while incrementing the exponent until
        !            44: * it is equal to the denormalized exponent for the destination
        !            45: * format.  After denormalizatoin, the result is rounded to the
        !            46: * destination format.
        !            47: *
        !            48: * Trap enabled results
        !            49: *      All trap disabled code applies. In addition the exceptional
        !            50: * operand needs to made available to the user with a bias of $6000
        !            51: * added to the exponent.
        !            52: *
        !            53:
        !            54: X_UNFL IDNT    2,1 Motorola 040 Floating Point Software Package
        !            55:
        !            56:        section 8
        !            57:
        !            58:        include fpsp.h
        !            59:
        !            60:        xref    denorm
        !            61:        xref    round
        !            62:        xref    store
        !            63:        xref    g_rndpr
        !            64:        xref    g_opcls
        !            65:        xref    g_dfmtou
        !            66:        xref    real_unfl
        !            67:        xref    real_inex
        !            68:        xref    fpsp_done
        !            69:        xref    b1238_fix
        !            70:
        !            71:        xdef    fpsp_unfl
        !            72: fpsp_unfl:
        !            73:        link            a6,#-LOCAL_SIZE
        !            74:        fsave           -(a7)
        !            75:        movem.l         d0-d1/a0-a1,USER_DA(a6)
        !            76:        fmovem.x        fp0-fp3,USER_FP0(a6)
        !            77:        fmovem.l        fpcr/fpsr/fpiar,USER_FPCR(a6)
        !            78:
        !            79: *
        !            80:        bsr.l           unf_res ;denormalize, round & store interm op
        !            81: *
        !            82: * If underflow exceptions are not enabled, check for inexact
        !            83: * exception
        !            84: *
        !            85:        btst.b          #unfl_bit,FPCR_ENABLE(a6)
        !            86:        beq.b           ck_inex
        !            87:
        !            88:        btst.b          #E3,E_BYTE(a6)
        !            89:        beq.b           no_e3_1
        !            90: *
        !            91: * Clear dirty bit on dest resister in the frame before branching
        !            92: * to b1238_fix.
        !            93: *
        !            94:        bfextu          CMDREG3B(a6){6:3},d0    ;get dest reg no
        !            95:        bclr.b          d0,FPR_DIRTY_BITS(a6)   ;clr dest dirty bit
        !            96:        bsr.l           b1238_fix               ;test for bug1238 case
        !            97:        move.l          USER_FPSR(a6),FPSR_SHADOW(a6)
        !            98:        or.l            #sx_mask,E_BYTE(a6)
        !            99: no_e3_1:
        !           100:        movem.l         USER_DA(a6),d0-d1/a0-a1
        !           101:        fmovem.x        USER_FP0(a6),fp0-fp3
        !           102:        fmovem.l        USER_FPCR(a6),fpcr/fpsr/fpiar
        !           103:        frestore        (a7)+
        !           104:        unlk            a6
        !           105:        bra.l           real_unfl
        !           106: *
        !           107: * It is possible to have either inex2 or inex1 exceptions with the
        !           108: * unfl.  If the inex enable bit is set in the FPCR, and either
        !           109: * inex2 or inex1 occurred, we must clean up and branch to the
        !           110: * real inex handler.
        !           111: *
        !           112: ck_inex:
        !           113:        move.b          FPCR_ENABLE(a6),d0
        !           114:        and.b           FPSR_EXCEPT(a6),d0
        !           115:        andi.b          #$3,d0
        !           116:        beq.b           unfl_done
        !           117:
        !           118: *
        !           119: * Inexact enabled and reported, and we must take an inexact exception
        !           120: *
        !           121: take_inex:
        !           122:        btst.b          #E3,E_BYTE(a6)
        !           123:        beq.b           no_e3_2
        !           124: *
        !           125: * Clear dirty bit on dest resister in the frame before branching
        !           126: * to b1238_fix.
        !           127: *
        !           128:        bfextu          CMDREG3B(a6){6:3},d0    ;get dest reg no
        !           129:        bclr.b          d0,FPR_DIRTY_BITS(a6)   ;clr dest dirty bit
        !           130:        bsr.l           b1238_fix               ;test for bug1238 case
        !           131:        move.l          USER_FPSR(a6),FPSR_SHADOW(a6)
        !           132:        or.l            #sx_mask,E_BYTE(a6)
        !           133: no_e3_2:
        !           134:        move.b          #INEX_VEC,EXC_VEC+1(a6)
        !           135:        movem.l         USER_DA(a6),d0-d1/a0-a1
        !           136:        fmovem.x        USER_FP0(a6),fp0-fp3
        !           137:        fmovem.l        USER_FPCR(a6),fpcr/fpsr/fpiar
        !           138:        frestore        (a7)+
        !           139:        unlk            a6
        !           140:        bra.l           real_inex
        !           141:
        !           142: unfl_done:
        !           143:        bclr.b          #E3,E_BYTE(a6)
        !           144:        beq.b           e1_set          ;if set then branch
        !           145: *
        !           146: * Clear dirty bit on dest resister in the frame before branching
        !           147: * to b1238_fix.
        !           148: *
        !           149:        bfextu          CMDREG3B(a6){6:3},d0            ;get dest reg no
        !           150:        bclr.b          d0,FPR_DIRTY_BITS(a6)   ;clr dest dirty bit
        !           151:        bsr.l           b1238_fix               ;test for bug1238 case
        !           152:        move.l          USER_FPSR(a6),FPSR_SHADOW(a6)
        !           153:        or.l            #sx_mask,E_BYTE(a6)
        !           154:        movem.l         USER_DA(a6),d0-d1/a0-a1
        !           155:        fmovem.x        USER_FP0(a6),fp0-fp3
        !           156:        fmovem.l        USER_FPCR(a6),fpcr/fpsr/fpiar
        !           157:        frestore        (a7)+
        !           158:        unlk            a6
        !           159:        bra.l           fpsp_done
        !           160: e1_set:
        !           161:        movem.l         USER_DA(a6),d0-d1/a0-a1
        !           162:        fmovem.x        USER_FP0(a6),fp0-fp3
        !           163:        fmovem.l        USER_FPCR(a6),fpcr/fpsr/fpiar
        !           164:        unlk            a6
        !           165:        bra.l           fpsp_done
        !           166: *
        !           167: *      unf_res --- underflow result calculation
        !           168: *
        !           169: unf_res:
        !           170:        bsr.l           g_rndpr         ;returns RND_PREC in d0 0=ext,
        !           171: *                                      ;1=sgl, 2=dbl
        !           172: *                                      ;we need the RND_PREC in the
        !           173: *                                      ;upper word for round
        !           174:        clr.w           -(a7)
        !           175:        move.w          d0,-(a7)        ;copy RND_PREC to stack
        !           176: *
        !           177: *
        !           178: * If the exception bit set is E3, the exceptional operand from the
        !           179: * fpu is in WBTEMP; else it is in FPTEMP.
        !           180: *
        !           181:        btst.b          #E3,E_BYTE(a6)
        !           182:        beq.b           unf_E1
        !           183: unf_E3:
        !           184:        lea             WBTEMP(a6),a0   ;a0 now points to operand
        !           185: *
        !           186: * Test for fsgldiv and fsglmul.  If the inst was one of these, then
        !           187: * force the precision to extended for the denorm routine.  Use
        !           188: * the user's precision for the round routine.
        !           189: *
        !           190:        move.w          CMDREG3B(a6),d1 ;check for fsgldiv or fsglmul
        !           191:        andi.w          #$7f,d1
        !           192:        cmpi.w          #$30,d1         ;check for sgldiv
        !           193:        beq.b           unf_sgl
        !           194:        cmpi.w          #$33,d1         ;check for sglmul
        !           195:        bne.b           unf_cont        ;if not, use fpcr prec in round
        !           196: unf_sgl:
        !           197:        clr.l           d0
        !           198:        move.w          #$1,(a7)        ;override g_rndpr precision
        !           199: *                                      ;force single
        !           200:        bra.b           unf_cont
        !           201: unf_E1:
        !           202:        lea             FPTEMP(a6),a0   ;a0 now points to operand
        !           203: unf_cont:
        !           204:        bclr.b          #sign_bit,LOCAL_EX(a0)  ;clear sign bit
        !           205:        sne             LOCAL_SGN(a0)           ;store sign
        !           206:
        !           207:        bsr.l           denorm          ;returns denorm, a0 points to it
        !           208: *
        !           209: * WARNING:
        !           210: *                              ;d0 has guard,round sticky bit
        !           211: *                              ;make sure that it is not corrupted
        !           212: *                              ;before it reaches the round subroutine
        !           213: *                              ;also ensure that a0 isn't corrupted
        !           214:
        !           215: *
        !           216: * Set up d1 for round subroutine d1 contains the PREC/MODE
        !           217: * information respectively on upper/lower register halves.
        !           218: *
        !           219:        bfextu          FPCR_MODE(a6){2:2},d1   ;get mode from FPCR
        !           220: *                                              ;mode in lower d1
        !           221:        add.l           (a7)+,d1                ;merge PREC/MODE
        !           222: *
        !           223: * WARNING: a0 and d0 are assumed to be intact between the denorm and
        !           224: * round subroutines. All code between these two subroutines
        !           225: * must not corrupt a0 and d0.
        !           226: *
        !           227: *
        !           228: * Perform Round
        !           229: *      Input:          a0 points to input operand
        !           230: *                      d0{31:29} has guard, round, sticky
        !           231: *                      d1{01:00} has rounding mode
        !           232: *                      d1{17:16} has rounding precision
        !           233: *      Output:         a0 points to rounded operand
        !           234: *
        !           235:
        !           236:        bsr.l           round           ;returns rounded denorm at (a0)
        !           237: *
        !           238: * Differentiate between store to memory vs. store to register
        !           239: *
        !           240: unf_store:
        !           241:        bsr.l           g_opcls         ;returns opclass in d0{2:0}
        !           242:        cmpi.b          #$3,d0
        !           243:        bne.b           not_opc011
        !           244: *
        !           245: * At this point, a store to memory is pending
        !           246: *
        !           247: opc011:
        !           248:        bsr.l           g_dfmtou
        !           249:        tst.b           d0
        !           250:        beq.b           ext_opc011      ;If extended, do not subtract
        !           251: *                              ;If destination format is sgl/dbl,
        !           252:        tst.b           LOCAL_HI(a0)    ;If rounded result is normal,don't
        !           253: *                                      ;subtract
        !           254:        bmi.b           ext_opc011
        !           255:        subq.w          #1,LOCAL_EX(a0) ;account for denorm bias vs.
        !           256: *                              ;normalized bias
        !           257: *                              ;          normalized   denormalized
        !           258: *                              ;single       $7f           $7e
        !           259: *                              ;double       $3ff          $3fe
        !           260: *
        !           261: ext_opc011:
        !           262:        bsr.l           store           ;stores to memory
        !           263:        bra.b           unf_done        ;finish up
        !           264:
        !           265: *
        !           266: * At this point, a store to a float register is pending
        !           267: *
        !           268: not_opc011:
        !           269:        bsr.l           store   ;stores to float register
        !           270: *                              ;a0 is not corrupted on a store to a
        !           271: *                              ;float register.
        !           272: *
        !           273: * Set the condition codes according to result
        !           274: *
        !           275:        tst.l           LOCAL_HI(a0)    ;check upper mantissa
        !           276:        bne.b           ck_sgn
        !           277:        tst.l           LOCAL_LO(a0)    ;check lower mantissa
        !           278:        bne.b           ck_sgn
        !           279:        bset.b          #z_bit,FPSR_CC(a6) ;set condition codes if zero
        !           280: ck_sgn:
        !           281:        btst.b          #sign_bit,LOCAL_EX(a0)  ;check the sign bit
        !           282:        beq.b           unf_done
        !           283:        bset.b          #neg_bit,FPSR_CC(a6)
        !           284:
        !           285: *
        !           286: * Finish.
        !           287: *
        !           288: unf_done:
        !           289:        btst.b          #inex2_bit,FPSR_EXCEPT(a6)
        !           290:        beq.b           no_aunfl
        !           291:        bset.b          #aunfl_bit,FPSR_AEXCEPT(a6)
        !           292: no_aunfl:
        !           293:        rts
        !           294:
        !           295:        end

CVSweb