Annotation of sys/arch/m68k/fpsp/x_snan.sa, Revision 1.1
1.1 ! nbrk 1: * $OpenBSD: x_snan.sa,v 1.3 2001/09/20 17:02:30 mpech Exp $
! 2: * $NetBSD: x_snan.sa,v 1.3 1994/10/26 07:50:28 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_snan.sa 3.3 7/1/91
! 36: *
! 37: * fpsp_snan --- FPSP handler for signalling NAN exception
! 38: *
! 39: * SNAN for float -> integer conversions (integer conversion of
! 40: * an SNAN) is a non-maskable run-time exception.
! 41: *
! 42: * For trap disabled the 040 does the following:
! 43: * If the dest data format is s, d, or x, then the SNAN bit in the NAN
! 44: * is set to one and the resulting non-signaling NAN (truncated if
! 45: * necessary) is transferred to the dest. If the dest format is b, w,
! 46: * or l, then garbage is written to the dest (actually the upper 32 bits
! 47: * of the mantissa are sent to the integer unit).
! 48: *
! 49: * For trap enabled the 040 does the following:
! 50: * If the inst is move_out, then the results are the same as for trap
! 51: * disabled with the exception posted. If the instruction is not move_
! 52: * out, the dest. is not modified, and the exception is posted.
! 53: *
! 54:
! 55: X_SNAN IDNT 2,1 Motorola 040 Floating Point Software Package
! 56:
! 57: section 8
! 58:
! 59: include fpsp.h
! 60:
! 61: xref get_fline
! 62: xref mem_write
! 63: xref real_snan
! 64: xref real_inex
! 65: xref fpsp_done
! 66: xref reg_dest
! 67:
! 68: xdef fpsp_snan
! 69: fpsp_snan:
! 70: link a6,#-LOCAL_SIZE
! 71: fsave -(a7)
! 72: movem.l d0-d1/a0-a1,USER_DA(a6)
! 73: fmovem.x fp0-fp3,USER_FP0(a6)
! 74: fmovem.l fpcr/fpsr/fpiar,USER_FPCR(a6)
! 75:
! 76: *
! 77: * Check if trap enabled
! 78: *
! 79: btst.b #snan_bit,FPCR_ENABLE(a6)
! 80: bne.b ena ;If enabled, then branch
! 81:
! 82: bsr.l move_out ;else SNAN disabled
! 83: *
! 84: * It is possible to have an inex1 exception with the
! 85: * snan. If the inex enable bit is set in the FPCR, and either
! 86: * inex2 or inex1 occurred, we must clean up and branch to the
! 87: * real inex handler.
! 88: *
! 89: ck_inex:
! 90: move.b FPCR_ENABLE(a6),d0
! 91: and.b FPSR_EXCEPT(a6),d0
! 92: andi.b #$3,d0
! 93: beq.w end_snan
! 94: *
! 95: * Inexact enabled and reported, and we must take an inexact exception.
! 96: *
! 97: take_inex:
! 98: move.b #INEX_VEC,EXC_VEC+1(a6)
! 99: movem.l USER_DA(a6),d0-d1/a0-a1
! 100: fmovem.x USER_FP0(a6),fp0-fp3
! 101: fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
! 102: frestore (a7)+
! 103: unlk a6
! 104: bra.l real_inex
! 105: *
! 106: * SNAN is enabled. Check if inst is move_out.
! 107: * Make any corrections to the 040 output as necessary.
! 108: *
! 109: ena:
! 110: btst.b #5,CMDREG1B(a6) ;if set, inst is move out
! 111: beq.w not_out
! 112:
! 113: bsr.l move_out
! 114:
! 115: report_snan:
! 116: move.b (a7),VER_TMP(a6)
! 117: cmpi.b #VER_40,(a7) ;test for orig unimp frame
! 118: bne.b ck_rev
! 119: moveq.l #13,d0 ;need to zero 14 lwords
! 120: bra.b rep_con
! 121: ck_rev:
! 122: moveq.l #11,d0 ;need to zero 12 lwords
! 123: rep_con:
! 124: clr.l (a7)
! 125: loop1:
! 126: clr.l -(a7) ;clear and dec a7
! 127: dbra.w d0,loop1
! 128: move.b VER_TMP(a6),(a7) ;format a busy frame
! 129: move.b #BUSY_SIZE-4,1(a7)
! 130: move.l USER_FPSR(a6),FPSR_SHADOW(a6)
! 131: or.l #sx_mask,E_BYTE(a6)
! 132: movem.l USER_DA(a6),d0-d1/a0-a1
! 133: fmovem.x USER_FP0(a6),fp0-fp3
! 134: fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
! 135: frestore (a7)+
! 136: unlk a6
! 137: bra.l real_snan
! 138: *
! 139: * Exit snan handler by expanding the unimp frame into a busy frame
! 140: *
! 141: end_snan:
! 142: bclr.b #E1,E_BYTE(a6)
! 143:
! 144: move.b (a7),VER_TMP(a6)
! 145: cmpi.b #VER_40,(a7) ;test for orig unimp frame
! 146: bne.b ck_rev2
! 147: moveq.l #13,d0 ;need to zero 14 lwords
! 148: bra.b rep_con2
! 149: ck_rev2:
! 150: moveq.l #11,d0 ;need to zero 12 lwords
! 151: rep_con2:
! 152: clr.l (a7)
! 153: loop2:
! 154: clr.l -(a7) ;clear and dec a7
! 155: dbra.w d0,loop2
! 156: move.b VER_TMP(a6),(a7) ;format a busy frame
! 157: move.b #BUSY_SIZE-4,1(a7) ;write busy size
! 158: move.l USER_FPSR(a6),FPSR_SHADOW(a6)
! 159: or.l #sx_mask,E_BYTE(a6)
! 160: movem.l USER_DA(a6),d0-d1/a0-a1
! 161: fmovem.x USER_FP0(a6),fp0-fp3
! 162: fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
! 163: frestore (a7)+
! 164: unlk a6
! 165: bra.l fpsp_done
! 166:
! 167: *
! 168: * Move_out
! 169: *
! 170: move_out:
! 171: move.l EXC_EA(a6),a0 ;get <ea> from exc frame
! 172:
! 173: bfextu CMDREG1B(a6){3:3},d0 ;move rx field to d0{2:0}
! 174: tst.l d0 ;check for long
! 175: beq.b sto_long ;branch if move_out long
! 176:
! 177: cmpi.l #4,d0 ;check for word
! 178: beq.b sto_word ;branch if move_out word
! 179:
! 180: cmpi.l #6,d0 ;check for byte
! 181: beq.b sto_byte ;branch if move_out byte
! 182:
! 183: *
! 184: * Not byte, word or long
! 185: *
! 186: rts
! 187: *
! 188: * Get the 32 most significant bits of etemp mantissa
! 189: *
! 190: sto_long:
! 191: move.l ETEMP_HI(a6),d1
! 192: move.l #4,d0 ;load byte count
! 193: *
! 194: * Set signalling nan bit
! 195: *
! 196: bset.l #30,d1
! 197: *
! 198: * Store to the users destination address
! 199: *
! 200: tst.l a0 ;check if <ea> is 0
! 201: beq.b wrt_dn ;destination is a data register
! 202:
! 203: move.l d1,-(a7) ;move the snan onto the stack
! 204: move.l a0,a1 ;load dest addr into a1
! 205: move.l a7,a0 ;load src addr of snan into a0
! 206: bsr.l mem_write ;write snan to user memory
! 207: move.l (a7)+,d1 ;clear off stack
! 208: rts
! 209: *
! 210: * Get the 16 most significant bits of etemp mantissa
! 211: *
! 212: sto_word:
! 213: move.l ETEMP_HI(a6),d1
! 214: move.l #2,d0 ;load byte count
! 215: *
! 216: * Set signalling nan bit
! 217: *
! 218: bset.l #30,d1
! 219: *
! 220: * Store to the users destination address
! 221: *
! 222: tst.l a0 ;check if <ea> is 0
! 223: beq.b wrt_dn ;destination is a data register
! 224:
! 225: move.l d1,-(a7) ;move the snan onto the stack
! 226: move.l a0,a1 ;load dest addr into a1
! 227: move.l a7,a0 ;point to low word
! 228: bsr.l mem_write ;write snan to user memory
! 229: move.l (a7)+,d1 ;clear off stack
! 230: rts
! 231: *
! 232: * Get the 8 most significant bits of etemp mantissa
! 233: *
! 234: sto_byte:
! 235: move.l ETEMP_HI(a6),d1
! 236: move.l #1,d0 ;load byte count
! 237: *
! 238: * Set signalling nan bit
! 239: *
! 240: bset.l #30,d1
! 241: *
! 242: * Store to the users destination address
! 243: *
! 244: tst.l a0 ;check if <ea> is 0
! 245: beq.b wrt_dn ;destination is a data register
! 246: move.l d1,-(a7) ;move the snan onto the stack
! 247: move.l a0,a1 ;load dest addr into a1
! 248: move.l a7,a0 ;point to source byte
! 249: bsr.l mem_write ;write snan to user memory
! 250: move.l (a7)+,d1 ;clear off stack
! 251: rts
! 252:
! 253: *
! 254: * wrt_dn --- write to a data register
! 255: *
! 256: * We get here with D1 containing the data to write and D0 the
! 257: * number of bytes to write: 1=byte,2=word,4=long.
! 258: *
! 259: wrt_dn:
! 260: move.l d1,L_SCR1(a6) ;data
! 261: move.l d0,-(a7) ;size
! 262: bsr.l get_fline ;returns fline word in d0
! 263: move.l d0,d1
! 264: andi.l #$7,d1 ;d1 now holds register number
! 265: move.l (sp)+,d0 ;get original size
! 266: cmpi.l #4,d0
! 267: beq.b wrt_long
! 268: cmpi.l #2,d0
! 269: bne.b wrt_byte
! 270: wrt_word:
! 271: or.l #$8,d1
! 272: bra.l reg_dest
! 273: wrt_long:
! 274: or.l #$10,d1
! 275: bra.l reg_dest
! 276: wrt_byte:
! 277: bra.l reg_dest
! 278: *
! 279: * Check if it is a src nan or dst nan
! 280: *
! 281: not_out:
! 282: move.l DTAG(a6),d0
! 283: bfextu d0{0:3},d0 ;isolate dtag in lsbs
! 284:
! 285: cmpi.b #3,d0 ;check for nan in destination
! 286: bne.b issrc ;destination nan has priority
! 287: dst_nan:
! 288: btst.b #6,FPTEMP_HI(a6) ;check if dest nan is an snan
! 289: bne.b issrc ;no, so check source for snan
! 290: move.w FPTEMP_EX(a6),d0
! 291: bra.b cont
! 292: issrc:
! 293: move.w ETEMP_EX(a6),d0
! 294: cont:
! 295: btst.l #15,d0 ;test for sign of snan
! 296: beq.b clr_neg
! 297: bset.b #neg_bit,FPSR_CC(a6)
! 298: bra.w report_snan
! 299: clr_neg:
! 300: bclr.b #neg_bit,FPSR_CC(a6)
! 301: bra.w report_snan
! 302:
! 303: end
CVSweb