[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

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