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