1* $NetBSD: x_store.sa,v 1.4 2001/12/09 01:43:13 briggs Exp $ 2 3* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 4* M68000 Hi-Performance Microprocessor Division 5* M68040 Software Package 6* 7* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc. 8* All rights reserved. 9* 10* THE SOFTWARE is provided on an "AS IS" basis and without warranty. 11* To the maximum extent permitted by applicable law, 12* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 13* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A 14* PARTICULAR PURPOSE and any warranty against infringement with 15* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 16* and any accompanying written materials. 17* 18* To the maximum extent permitted by applicable law, 19* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 20* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS 21* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR 22* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE 23* SOFTWARE. Motorola assumes no responsibility for the maintenance 24* and support of the SOFTWARE. 25* 26* You are hereby granted a copyright license to use, modify, and 27* distribute the SOFTWARE so long as this entire notice is retained 28* without alteration in any modified and/or redistributed versions, 29* and that such modified versions are clearly identified as such. 30* No licenses are granted by implication, estoppel or otherwise 31* under any patents or trademarks of Motorola, Inc. 32 33* 34* x_store.sa 3.2 1/24/91 35* 36* store --- store operand to memory or register 37* 38* Used by underflow and overflow handlers. 39* 40* a6 = points to fp value to be stored. 41* 42 43X_STORE IDNT 2,1 Motorola 040 Floating Point Software Package 44 45 section 8 46 47fpreg_mask: 48 dc.b $80,$40,$20,$10,$08,$04,$02,$01 49 50 include fpsp.h 51 52 xref mem_write 53 xref get_fline 54 xref g_opcls 55 xref g_dfmtou 56 xref reg_dest 57 58 xdef dest_ext 59 xdef dest_dbl 60 xdef dest_sgl 61 62 xdef store 63store: 64 btst.b #E3,E_BYTE(a6) 65 beq.b E1_sto 66E3_sto: 67 move.l CMDREG3B(a6),d0 68 bfextu d0{6:3},d0 ;isolate dest. reg from cmdreg3b 69sto_fp: 70 lea fpreg_mask,a1 71 move.b (a1,d0.w),d0 ;convert reg# to dynamic register mask 72 tst.b LOCAL_SGN(a0) 73 beq.b is_pos 74 bset.b #sign_bit,LOCAL_EX(a0) 75is_pos: 76 fmovem.x (a0),d0 ;move to correct register 77* 78* if fp0-fp3 is being modified, we must put a copy 79* in the USER_FPn variable on the stack because all exception 80* handlers restore fp0-fp3 from there. 81* 82 cmp.b #$80,d0 83 bne.b not_fp0 84 fmovem.x fp0,USER_FP0(a6) 85 rts 86not_fp0: 87 cmp.b #$40,d0 88 bne.b not_fp1 89 fmovem.x fp1,USER_FP1(a6) 90 rts 91not_fp1: 92 cmp.b #$20,d0 93 bne.b not_fp2 94 fmovem.x fp2,USER_FP2(a6) 95 rts 96not_fp2: 97 cmp.b #$10,d0 98 bne.b not_fp3 99 fmovem.x fp3,USER_FP3(a6) 100 rts 101not_fp3: 102 rts 103 104E1_sto: 105 bsr.l g_opcls ;returns opclass in d0 106 cmpi.b #3,d0 107 beq opc011 ;branch if opclass 3 108 move.l CMDREG1B(a6),d0 109 bfextu d0{6:3},d0 ;extract destination register 110 bra.b sto_fp 111 112opc011: 113 bsr.l g_dfmtou ;returns dest format in d0 114* ;ext=00, sgl=01, dbl=10 115 move.l a0,a1 ;save source addr in a1 116 move.l EXC_EA(a6),a0 ;get the address 117 tst.l d0 ;if dest format is extended 118 beq.w dest_ext ;then branch 119 cmpi.l #1,d0 ;if dest format is single 120 beq.b short_dest_sgl ;then branch 121* 122* fall through to dest_dbl 123* 124 125* 126* dest_dbl --- write double precision value to user space 127* 128*Input 129* a0 -> destination address 130* a1 -> source in extended precision 131*Output 132* a0 -> destroyed 133* a1 -> destroyed 134* d0 -> 0 135* 136*Changes extended precision to double precision. 137* Note: no attempt is made to round the extended value to double. 138* dbl_sign = ext_sign 139* dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias) 140* get rid of ext integer bit 141* dbl_mant = ext_mant{62:12} 142* 143* --------------- --------------- --------------- 144* extended -> |s| exp | |1| ms mant | | ls mant | 145* --------------- --------------- --------------- 146* 95 64 63 62 32 31 11 0 147* | | 148* | | 149* | | 150* v v 151* --------------- --------------- 152* double -> |s|exp| mant | | mant | 153* --------------- --------------- 154* 63 51 32 31 0 155* 156dest_dbl: 157 clr.l d0 ;clear d0 158 move.w LOCAL_EX(a1),d0 ;get exponent 159 sub.w #$3fff,d0 ;subtract extended precision bias 160 cmp.w #$4000,d0 ;check if inf 161 beq.b inf ;if so, special case 162 add.w #$3ff,d0 ;add double precision bias 163 swap d0 ;d0 now in upper word 164 lsl.l #4,d0 ;d0 now in proper place for dbl prec exp 165 tst.b LOCAL_SGN(a1) 166 beq.b get_mant ;if postive, go process mantissa 167 bset.l #31,d0 ;if negative, put in sign information 168* ; before continuing 169 bra.b get_mant ;go process mantissa 170inf: 171 move.l #$7ff00000,d0 ;load dbl inf exponent 172 clr.l LOCAL_HI(a1) ;clear msb 173 tst.b LOCAL_SGN(a1) 174 beq.b dbl_inf ;if positive, go ahead and write it 175 bset.l #31,d0 ;if negative put in sign information 176dbl_inf: 177 move.l d0,LOCAL_EX(a1) ;put the new exp back on the stack 178 bra.b dbl_wrt 179get_mant: 180 move.l LOCAL_HI(a1),d1 ;get ms mantissa 181 bfextu d1{1:20},d1 ;get upper 20 bits of ms 182 or.l d1,d0 ;put these bits in ms word of double 183 move.l d0,LOCAL_EX(a1) ;put the new exp back on the stack 184 move.l LOCAL_HI(a1),d1 ;get ms mantissa 185 move.l #21,d0 ;load shift count 186 lsl.l d0,d1 ;put lower 11 bits in upper bits 187 move.l d1,LOCAL_HI(a1) ;build lower lword in memory 188 move.l LOCAL_LO(a1),d1 ;get ls mantissa 189 bfextu d1{0:21},d0 ;get ls 21 bits of double 190 or.l d0,LOCAL_HI(a1) ;put them in double result 191dbl_wrt: 192 move.l #$8,d0 ;byte count for double precision number 193 exg a0,a1 ;a0=supervisor source, a1=user dest 194 bsr.l mem_write ;move the number to the user's memory 195 rts 196* 197* dest_sgl --- write single precision value to user space 198* 199*Input 200* a0 -> destination address 201* a1 -> source in extended precision 202* 203*Output 204* a0 -> destroyed 205* a1 -> destroyed 206* d0 -> 0 207* 208*Changes extended precision to single precision. 209* sgl_sign = ext_sign 210* sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias) 211* get rid of ext integer bit 212* sgl_mant = ext_mant{62:12} 213* 214* --------------- --------------- --------------- 215* extended -> |s| exp | |1| ms mant | | ls mant | 216* --------------- --------------- --------------- 217* 95 64 63 62 40 32 31 12 0 218* | | 219* | | 220* | | 221* v v 222* --------------- 223* single -> |s|exp| mant | 224* --------------- 225* 31 22 0 226* 227dest_sgl: 228short_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 241sinf: 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 248get_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 253sgl_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 262sgl_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 270dest_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) 274dstx_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 283