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