revert between 56095 -> 55830 in arch
[AROS.git] / arch / m68k-all / m680x0 / fpsp / x_snan.sa
blobe5d6fac270dc88dccd9c30a232752b1dfee8b13f
1 *       $NetBSD: x_snan.sa,v 1.4 2001/09/16 16:34:32 wiz 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.
8 *       All rights reserved.
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
56         section 8
58         include fpsp.h
60         xref    get_fline
61         xref    mem_write
62         xref    real_snan
63         xref    real_inex
64         xref    fpsp_done
65         xref    reg_dest
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)
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
86 * real inex handler.
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
94 * Inexact enabled and reported, and we must take an inexact exception.
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
105 * SNAN is enabled.  Check if inst is move_out.
106 * Make any corrections to the 040 output as necessary.
108 ena:
109         btst.b          #5,CMDREG1B(a6) ;if set, inst is move out
110         beq.w           not_out
112         bsr.l           move_out
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
138 * Exit snan handler by expanding the unimp frame into a busy frame
140 end_snan:
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
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
167 * Move_out 
169 move_out:
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
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         
183 * Not byte, word or long
185         rts
186 *       
187 * Get the 32 most significant bits of etemp mantissa
189 sto_long:
190         move.l          ETEMP_HI(a6),d1
191         move.l          #4,d0           ;load byte count
193 * Set signalling nan bit
195         bset.l          #30,d1                  
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
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
209 * Get the 16 most significant bits of etemp mantissa
211 sto_word:
212         move.l          ETEMP_HI(a6),d1
213         move.l          #2,d0           ;load byte count
215 * Set signalling nan bit
217         bset.l          #30,d1                  
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
229         rts
231 * Get the 8 most significant bits of etemp mantissa
233 sto_byte:
234         move.l          ETEMP_HI(a6),d1
235         move.l          #1,d0           ;load byte count
237 * Set signalling nan bit
239         bset.l          #30,d1                  
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
250         rts
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.
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
278 * Check if it is a src nan or dst nan
280 not_out:
281         move.l          DTAG(a6),d0     
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
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
302         end