Annotation of sys/arch/m68k/fpsp/x_store.sa, Revision 1.1
1.1 ! nbrk 1: * $OpenBSD: x_store.sa,v 1.2 1996/05/29 21:05:49 niklas Exp $
! 2: * $NetBSD: x_store.sa,v 1.3 1994/10/26 07:50:29 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_store.sa 3.2 1/24/91
! 36: *
! 37: * store --- store operand to memory or register
! 38: *
! 39: * Used by underflow and overflow handlers.
! 40: *
! 41: * a6 = points to fp value to be stored.
! 42: *
! 43:
! 44: X_STORE IDNT 2,1 Motorola 040 Floating Point Software Package
! 45:
! 46: section 8
! 47:
! 48: fpreg_mask:
! 49: dc.b $80,$40,$20,$10,$08,$04,$02,$01
! 50:
! 51: include fpsp.h
! 52:
! 53: xref mem_write
! 54: xref get_fline
! 55: xref g_opcls
! 56: xref g_dfmtou
! 57: xref reg_dest
! 58:
! 59: xdef dest_ext
! 60: xdef dest_dbl
! 61: xdef dest_sgl
! 62:
! 63: xdef store
! 64: store:
! 65: btst.b #E3,E_BYTE(a6)
! 66: beq.b E1_sto
! 67: E3_sto:
! 68: move.l CMDREG3B(a6),d0
! 69: bfextu d0{6:3},d0 ;isolate dest. reg from cmdreg3b
! 70: sto_fp:
! 71: lea fpreg_mask,a1
! 72: move.b (a1,d0.w),d0 ;convert reg# to dynamic register mask
! 73: tst.b LOCAL_SGN(a0)
! 74: beq.b is_pos
! 75: bset.b #sign_bit,LOCAL_EX(a0)
! 76: is_pos:
! 77: fmovem.x (a0),d0 ;move to correct register
! 78: *
! 79: * if fp0-fp3 is being modified, we must put a copy
! 80: * in the USER_FPn variable on the stack because all exception
! 81: * handlers restore fp0-fp3 from there.
! 82: *
! 83: cmp.b #$80,d0
! 84: bne.b not_fp0
! 85: fmovem.x fp0,USER_FP0(a6)
! 86: rts
! 87: not_fp0:
! 88: cmp.b #$40,d0
! 89: bne.b not_fp1
! 90: fmovem.x fp1,USER_FP1(a6)
! 91: rts
! 92: not_fp1:
! 93: cmp.b #$20,d0
! 94: bne.b not_fp2
! 95: fmovem.x fp2,USER_FP2(a6)
! 96: rts
! 97: not_fp2:
! 98: cmp.b #$10,d0
! 99: bne.b not_fp3
! 100: fmovem.x fp3,USER_FP3(a6)
! 101: rts
! 102: not_fp3:
! 103: rts
! 104:
! 105: E1_sto:
! 106: bsr.l g_opcls ;returns opclass in d0
! 107: cmpi.b #3,d0
! 108: beq opc011 ;branch if opclass 3
! 109: move.l CMDREG1B(a6),d0
! 110: bfextu d0{6:3},d0 ;extract destination register
! 111: bra.b sto_fp
! 112:
! 113: opc011:
! 114: bsr.l g_dfmtou ;returns dest format in d0
! 115: * ;ext=00, sgl=01, dbl=10
! 116: move.l a0,a1 ;save source addr in a1
! 117: move.l EXC_EA(a6),a0 ;get the address
! 118: tst.l d0 ;if dest format is extended
! 119: beq.w dest_ext ;then branch
! 120: cmpi.l #1,d0 ;if dest format is single
! 121: beq.b dest_sgl ;then branch
! 122: *
! 123: * fall through to dest_dbl
! 124: *
! 125:
! 126: *
! 127: * dest_dbl --- write double precision value to user space
! 128: *
! 129: *Input
! 130: * a0 -> destination address
! 131: * a1 -> source in extended precision
! 132: *Output
! 133: * a0 -> destroyed
! 134: * a1 -> destroyed
! 135: * d0 -> 0
! 136: *
! 137: *Changes extended precision to double precision.
! 138: * Note: no attempt is made to round the extended value to double.
! 139: * dbl_sign = ext_sign
! 140: * dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)
! 141: * get rid of ext integer bit
! 142: * dbl_mant = ext_mant{62:12}
! 143: *
! 144: * --------------- --------------- ---------------
! 145: * extended -> |s| exp | |1| ms mant | | ls mant |
! 146: * --------------- --------------- ---------------
! 147: * 95 64 63 62 32 31 11 0
! 148: * | |
! 149: * | |
! 150: * | |
! 151: * v v
! 152: * --------------- ---------------
! 153: * double -> |s|exp| mant | | mant |
! 154: * --------------- ---------------
! 155: * 63 51 32 31 0
! 156: *
! 157: dest_dbl:
! 158: clr.l d0 ;clear d0
! 159: move.w LOCAL_EX(a1),d0 ;get exponent
! 160: sub.w #$3fff,d0 ;subtract extended precision bias
! 161: cmp.w #$4000,d0 ;check if inf
! 162: beq.b inf ;if so, special case
! 163: add.w #$3ff,d0 ;add double precision bias
! 164: swap d0 ;d0 now in upper word
! 165: lsl.l #4,d0 ;d0 now in proper place for dbl prec exp
! 166: tst.b LOCAL_SGN(a1)
! 167: beq.b get_mant ;if postive, go process mantissa
! 168: bset.l #31,d0 ;if negative, put in sign information
! 169: * ; before continuing
! 170: bra.b get_mant ;go process mantissa
! 171: inf:
! 172: move.l #$7ff00000,d0 ;load dbl inf exponent
! 173: clr.l LOCAL_HI(a1) ;clear msb
! 174: tst.b LOCAL_SGN(a1)
! 175: beq.b dbl_inf ;if positive, go ahead and write it
! 176: bset.l #31,d0 ;if negative put in sign information
! 177: dbl_inf:
! 178: move.l d0,LOCAL_EX(a1) ;put the new exp back on the stack
! 179: bra.b dbl_wrt
! 180: get_mant:
! 181: move.l LOCAL_HI(a1),d1 ;get ms mantissa
! 182: bfextu d1{1:20},d1 ;get upper 20 bits of ms
! 183: or.l d1,d0 ;put these bits in ms word of double
! 184: move.l d0,LOCAL_EX(a1) ;put the new exp back on the stack
! 185: move.l LOCAL_HI(a1),d1 ;get ms mantissa
! 186: move.l #21,d0 ;load shift count
! 187: lsl.l d0,d1 ;put lower 11 bits in upper bits
! 188: move.l d1,LOCAL_HI(a1) ;build lower lword in memory
! 189: move.l LOCAL_LO(a1),d1 ;get ls mantissa
! 190: bfextu d1{0:21},d0 ;get ls 21 bits of double
! 191: or.l d0,LOCAL_HI(a1) ;put them in double result
! 192: dbl_wrt:
! 193: move.l #$8,d0 ;byte count for double precision number
! 194: exg a0,a1 ;a0=supervisor source, a1=user dest
! 195: bsr.l mem_write ;move the number to the user's memory
! 196: rts
! 197: *
! 198: * dest_sgl --- write single precision value to user space
! 199: *
! 200: *Input
! 201: * a0 -> destination address
! 202: * a1 -> source in extended precision
! 203: *
! 204: *Output
! 205: * a0 -> destroyed
! 206: * a1 -> destroyed
! 207: * d0 -> 0
! 208: *
! 209: *Changes extended precision to single precision.
! 210: * sgl_sign = ext_sign
! 211: * sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)
! 212: * get rid of ext integer bit
! 213: * sgl_mant = ext_mant{62:12}
! 214: *
! 215: * --------------- --------------- ---------------
! 216: * extended -> |s| exp | |1| ms mant | | ls mant |
! 217: * --------------- --------------- ---------------
! 218: * 95 64 63 62 40 32 31 12 0
! 219: * | |
! 220: * | |
! 221: * | |
! 222: * v v
! 223: * ---------------
! 224: * single -> |s|exp| mant |
! 225: * ---------------
! 226: * 31 22 0
! 227: *
! 228: dest_sgl:
! 229: clr.l d0
! 230: move.w LOCAL_EX(a1),d0 ;get exponent
! 231: sub.w #$3fff,d0 ;subtract extended precision bias
! 232: cmp.w #$4000,d0 ;check if inf
! 233: beq.b sinf ;if so, special case
! 234: add.w #$7f,d0 ;add single precision bias
! 235: swap d0 ;put exp in upper word of d0
! 236: lsl.l #7,d0 ;shift it into single exp bits
! 237: tst.b LOCAL_SGN(a1)
! 238: beq.b get_sman ;if positive, continue
! 239: bset.l #31,d0 ;if negative, put in sign first
! 240: bra.b get_sman ;get mantissa
! 241: sinf:
! 242: move.l #$7f800000,d0 ;load single inf exp to d0
! 243: tst.b LOCAL_SGN(a1)
! 244: beq.b sgl_wrt ;if positive, continue
! 245: bset.l #31,d0 ;if negative, put in sign info
! 246: bra.b sgl_wrt
! 247:
! 248: get_sman:
! 249: move.l LOCAL_HI(a1),d1 ;get ms mantissa
! 250: bfextu d1{1:23},d1 ;get upper 23 bits of ms
! 251: or.l d1,d0 ;put these bits in ms word of single
! 252:
! 253: sgl_wrt:
! 254: move.l d0,L_SCR1(a6) ;put the new exp back on the stack
! 255: move.l #$4,d0 ;byte count for single precision number
! 256: tst.l a0 ;users destination address
! 257: beq.b sgl_Dn ;destination is a data register
! 258: exg a0,a1 ;a0=supervisor source, a1=user dest
! 259: lea.l L_SCR1(a6),a0 ;point a0 to data
! 260: bsr.l mem_write ;move the number to the user's memory
! 261: rts
! 262: sgl_Dn:
! 263: bsr.l get_fline ;returns fline word in d0
! 264: and.w #$7,d0 ;isolate register number
! 265: move.l d0,d1 ;d1 has size:reg formatted for reg_dest
! 266: or.l #$10,d1 ;reg_dest wants size added to reg#
! 267: bra.l reg_dest ;size is X, rts in reg_dest will
! 268: * ;return to caller of dest_sgl
! 269:
! 270: dest_ext:
! 271: tst.b LOCAL_SGN(a1) ;put back sign into exponent word
! 272: beq.b dstx_cont
! 273: bset.b #sign_bit,LOCAL_EX(a1)
! 274: dstx_cont:
! 275: clr.b LOCAL_SGN(a1) ;clear out the sign byte
! 276:
! 277: move.l #$0c,d0 ;byte count for extended number
! 278: exg a0,a1 ;a0=supervisor source, a1=user dest
! 279: bsr.l mem_write ;move the number to the user's memory
! 280: rts
! 281:
! 282: end
CVSweb