1 * $NetBSD: x_snan.sa,v 1.3 1994/10/26 07:50:28 cgd 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_snan.sa 3.3 7/1/91
36 * fpsp_snan --- FPSP handler for signalling NAN exception
38 * SNAN for float -> integer conversions (integer conversion of
39 * an SNAN) is a non-maskable run-time exception.
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).
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.
54 X_SNAN IDNT 2,1 Motorola 040 Floating Point Software Package
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)
76 * Check if trap enabled
78 btst.b #snan_bit,FPCR_ENABLE(a6)
79 bne.b ena ;If enabled, then branch
81 bsr.l move_out ;else SNAN disabled
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
89 move.b FPCR_ENABLE(a6),d0
90 and.b FPSR_EXCEPT(a6),d0
94 * Inexact enabled and reported, and we must take an inexact exception.
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
105 * SNAN is enabled. Check if inst is move_out.
106 * Make any corrections to the 040 output as necessary.
109 btst.b #5,CMDREG1B(a6) ;if set, inst is move out
115 move.b (a7),VER_TMP(a6)
116 cmpi.b #VER_40,(a7) ;test for orig unimp frame
118 moveq.l #13,d0 ;need to zero 14 lwords
121 moveq.l #11,d0 ;need to zero 12 lwords
125 clr.l -(a7) ;clear and dec a7
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
138 * Exit snan handler by expanding the unimp frame into a busy frame
141 bclr.b #E1,E_BYTE(a6)
143 move.b (a7),VER_TMP(a6)
144 cmpi.b #VER_40,(a7) ;test for orig unimp frame
146 moveq.l #13,d0 ;need to zero 14 lwords
149 moveq.l #11,d0 ;need to zero 12 lwords
153 clr.l -(a7) ;clear and dec a7
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
170 move.l EXC_EA(a6),a0 ;get <ea> from exc frame
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
176 cmpi.l #4,d0 ;check for word
177 beq.b sto_word ;branch if move_out word
179 cmpi.l #6,d0 ;check for byte
180 beq.b sto_byte ;branch if move_out byte
183 * Not byte, word or long
187 * Get the 32 most significant bits of etemp mantissa
190 move.l ETEMP_HI(a6),d1
191 move.l #4,d0 ;load byte count
193 * Set signalling nan bit
197 * Store to the users destination address
199 tst.l a0 ;check if <ea> is 0
200 beq.b wrt_dn ;destination is a data register
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
209 * Get the 16 most significant bits of etemp mantissa
212 move.l ETEMP_HI(a6),d1
213 move.l #2,d0 ;load byte count
215 * Set signalling nan bit
219 * Store to the users destination address
221 tst.l a0 ;check if <ea> is 0
222 beq.b wrt_dn ;destination is a data register
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
231 * Get the 8 most significant bits of etemp mantissa
234 move.l ETEMP_HI(a6),d1
235 move.l #1,d0 ;load byte count
237 * Set signalling nan bit
241 * Store to the users destination address
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
253 * wrt_dn --- write to a data register
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.
259 move.l d1,L_SCR1(a6) ;data
260 move.l d0,-(a7) ;size
261 bsr.l get_fline ;returns fline word in d0
263 andi.l #$7,d1 ;d1 now holds register number
264 move.l (sp)+,d0 ;get original size
278 * Check if it is a src nan or dst nan
282 bfextu d0{0:3},d0 ;isolate dtag in lsbs
284 cmpi.b #3,d0 ;check for nan in destination
285 bne.b issrc ;destination nan has priority
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
292 move.w ETEMP_EX(a6),d0
294 btst.l #15,d0 ;test for sign of snan
296 bset.b #neg_bit,FPSR_CC(a6)
299 bclr.b #neg_bit,FPSR_CC(a6)