xref: /netbsd/sys/arch/m68k/fpsp/x_snan.sa (revision bf9ec67e)
1*	$NetBSD: x_snan.sa,v 1.4 2001/09/16 16:34:32 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
54X_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
68fpsp_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*
88ck_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*
96take_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*
108ena:
109	btst.b		#5,CMDREG1B(a6) ;if set, inst is move out
110	beq.w		not_out
111
112	bsr.l		move_out
113
114report_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
120ck_rev:
121	moveq.l		#11,d0		;need to zero 12 lwords
122rep_con:
123	clr.l		(a7)
124loop1:
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*
140end_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
148ck_rev2:
149	moveq.l		#11,d0		;need to zero 12 lwords
150rep_con2:
151	clr.l		(a7)
152loop2:
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*
169move_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*
189sto_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*
211sto_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*
233sto_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*
258wrt_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
269wrt_word:
270	or.l		#$8,d1
271	bra.l		reg_dest
272wrt_long:
273	or.l		#$10,d1
274	bra.l		reg_dest
275wrt_byte:
276	bra.l		reg_dest
277*
278* Check if it is a src nan or dst nan
279*
280not_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
286dst_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
291issrc:
292	move.w		ETEMP_EX(a6),d0
293cont:
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
298clr_neg:
299	bclr.b		#neg_bit,FPSR_CC(a6)
300	bra.w		report_snan
301
302	end
303