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