1 * $NetBSD: x_store.sa,v 1.4 2001/12/09 01:43:13 briggs Exp $
3 * MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
4 * M68000 Hi-Performance Microprocessor Division
5 * M68040 Software Package
7 * M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
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.
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.
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.
34 * x_store.sa 3.2 1/24/91
36 * store --- store operand to memory or register
38 * Used by underflow and overflow handlers.
40 * a6 = points to fp value to be stored.
43 X_STORE IDNT 2,1 Motorola 040 Floating Point Software Package
48 dc.b $80,$40,$20,$10,$08,$04,$02,$01
67 move.l CMDREG3B(a6),d0
68 bfextu d0{6:3},d0 ;isolate dest. reg from cmdreg3b
71 move.b (a1,d0.w),d0 ;convert reg# to dynamic register mask
74 bset.b #sign_bit,LOCAL_EX(a0)
76 fmovem.x (a0),d0 ;move to correct register
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.
84 fmovem.x fp0,USER_FP0(a6)
89 fmovem.x fp1,USER_FP1(a6)
94 fmovem.x fp2,USER_FP2(a6)
99 fmovem.x fp3,USER_FP3(a6)
105 bsr.l g_opcls ;returns opclass in d0
107 beq opc011 ;branch if opclass 3
108 move.l CMDREG1B(a6),d0
109 bfextu d0{6:3},d0 ;extract destination register
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
122 * fall through to dest_dbl
126 * dest_dbl --- write double precision value to user space
129 * a0 -> destination address
130 * a1 -> source in extended precision
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}
143 * --------------- --------------- ---------------
144 * extended -> |s| exp | |1| ms mant | | ls mant |
145 * --------------- --------------- ---------------
146 * 95 64 63 62 32 31 11 0
151 * --------------- ---------------
152 * double -> |s|exp| mant | | mant |
153 * --------------- ---------------
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
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
171 move.l #$7ff00000,d0 ;load dbl inf exponent
172 clr.l LOCAL_HI(a1) ;clear msb
174 beq.b dbl_inf ;if positive, go ahead and write it
175 bset.l #31,d0 ;if negative put in sign information
177 move.l d0,LOCAL_EX(a1) ;put the new exp back on the stack
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
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
197 * dest_sgl --- write single precision value to user space
200 * a0 -> destination address
201 * a1 -> source in extended precision
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}
214 * --------------- --------------- ---------------
215 * extended -> |s| exp | |1| ms mant | | ls mant |
216 * --------------- --------------- ---------------
217 * 95 64 63 62 40 32 31 12 0
223 * single -> |s|exp| mant |
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
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
242 move.l #$7f800000,d0 ;load single inf exp to d0
244 beq.b sgl_wrt ;if positive, continue
245 bset.l #31,d0 ;if negative, put in sign info
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
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
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
271 tst.b LOCAL_SGN(a1) ;put back sign into exponent word
273 bset.b #sign_bit,LOCAL_EX(a1)
275 clr.b LOCAL_SGN(a1) ;clear out the sign byte
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