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