xref: /netbsd/sys/arch/m68k/fpsp/l_support.sa (revision 6550d01e)
1*	$NetBSD: l_support.sa,v 1.3 1994/10/26 07:49:16 cgd 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*	l_support.sa 1.2 5/1/91
35*
36
37L_SUPPORT    IDNT    2,1 Motorola 040 Floating Point Software Package
38
39	section    8
40
41mns_one  dc.l $bfff0000,$80000000,$00000000
42pls_one  dc.l $3fff0000,$80000000,$00000000
43pls_inf  dc.l $7fff0000,$00000000,$00000000
44pls_huge dc.l $7ffe0000,$ffffffff,$ffffffff
45mns_huge dc.l $fffe0000,$ffffffff,$ffffffff
46pls_tiny dc.l $00000000,$80000000,$00000000
47mns_tiny dc.l $80000000,$80000000,$00000000
48small    dc.l $20000000,$80000000,$00000000
49pls_zero dc.l $00000000,$00000000,$00000000
50
51	include	l_fpsp.h
52
53*
54* 	tag --- determine the type of an extended precision operand
55*
56*	The tag values returned match the way the 68040 would have
57*	tagged them.
58*
59*	Input:	a0 points to operand
60*
61*	Output	d0.b	= $00 norm
62*			  $20 zero
63*			  $40 inf
64*			  $60 nan
65*			  $80 denorm
66*		All other registers are unchanged
67*
68	xdef	tag
69tag:
70	move.w	LOCAL_EX(a0),d0
71	andi.w	#$7fff,d0
72	beq.b	chk_zro
73	cmpi.w	#$7fff,d0
74	beq.b	chk_inf
75tag_nrm:
76	clr.b	d0
77	rts
78tag_nan:
79	move.b	#$60,d0
80	rts
81tag_dnrm:
82	move.b	#$80,d0
83	rts
84chk_zro:
85	btst.b	#7,LOCAL_HI(a0)	# check if J-bit is set
86	bne.b	tag_nrm
87	tst.l	LOCAL_HI(a0)
88	bne.b	tag_dnrm
89	tst.l	LOCAL_LO(a0)
90	bne.b	tag_dnrm
91tag_zero:
92	move.b	#$20,d0
93	rts
94chk_inf:
95	tst.l	LOCAL_HI(a0)
96	bne.b	tag_nan
97	tst.l	LOCAL_LO(a0)
98	bne.b	tag_nan
99tag_inf:
100	move.b	#$40,d0
101	rts
102
103*
104*	t_dz, t_dz2 --- divide by zero exception
105*
106* t_dz2 is used by monadic functions such as flogn (from do_func).
107* t_dz is used by monadic functions such as satanh (from the
108* transcendental function).
109*
110	xdef    t_dz2
111t_dz2:
112	fmovem.x	mns_one,fp0
113	fmove.l	d1,fpcr
114	fdiv.x		pls_zero,fp0
115	rts
116
117	xdef	t_dz
118t_dz:
119	btst.b	#sign_bit,ETEMP_EX(a6)	;check sign for neg or pos
120	beq.b	p_inf			;branch if pos sign
121m_inf:
122	fmovem.x mns_one,fp0
123	fmove.l	d1,fpcr
124	fdiv.x		pls_zero,fp0
125	rts
126p_inf:
127	fmovem.x pls_one,fp0
128	fmove.l	d1,fpcr
129	fdiv.x		pls_zero,fp0
130	rts
131*
132*	t_operr --- Operand Error exception
133*
134	xdef    t_operr
135t_operr:
136	fmovem.x	pls_inf,fp0
137	fmove.l	d1,fpcr
138	fmul.x		pls_zero,fp0
139	rts
140
141*
142*	t_unfl --- UNFL exception
143*
144	xdef    t_unfl
145t_unfl:
146	btst.b	#sign_bit,ETEMP(a6)
147	beq.b	unf_pos
148unf_neg:
149	fmovem.x	mns_tiny,fp0
150	fmove.l	d1,fpcr
151	fmul.x	pls_tiny,fp0
152	rts
153
154unf_pos:
155	fmovem.x	pls_tiny,fp0
156	fmove.l	d1,fpcr
157	fmul.x	fp0,fp0
158	rts
159*
160*	t_ovfl --- OVFL exception
161*
162*	t_ovfl is called as an exit for monadic functions.  t_ovfl2
163*	is for dyadic exits.
164*
165	xdef   		t_ovfl
166t_ovfl:
167	xdef   		t_ovfl2
168	move.l		d1,USER_FPCR(a6)	user's control register
169	move.l		#ovfinx_mask,d0
170	bra.b		t_work
171t_ovfl2:
172	move.l		#ovfl_inx_mask,d0
173t_work:
174	btst.b		#sign_bit,ETEMP(a6)
175	beq.b		ovf_pos
176ovf_neg:
177	fmovem.x	mns_huge,fp0
178	fmove.l		USER_FPCR(a6),fpcr
179	fmul.x		pls_huge,fp0
180	fmove.l		fpsr,d1
181	or.l		d1,d0
182	fmove.l		d0,fpsr
183	rts
184ovf_pos:
185	fmovem.x	pls_huge,fp0
186	fmove.l		USER_FPCR(a6),fpcr
187	fmul.x		pls_huge,fp0
188	fmove.l		fpsr,d1
189	or.l		d1,d0
190	fmove.l		d0,fpsr
191	rts
192*
193*	t_inx2 --- INEX2 exception (correct fpcr is in USER_FPCR(a6))
194*
195	xdef    t_inx2
196t_inx2:
197	fmove.l		fpsr,USER_FPSR(a6)	capture incoming fpsr
198	fmove.l		USER_FPCR(a6),fpcr
199*
200* create an inex2 exception by adding two numbers with very different exponents
201* do the add in fp1 so as to not disturb the result sitting in fp0
202*
203	fmove.x		pls_one,fp1
204	fadd.x		small,fp1
205*
206	or.l	#inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
207	fmove.l	USER_FPSR(a6),fpsr
208	rts
209*
210*	t_frcinx --- Force Inex2 (for monadic functions)
211*
212	xdef	t_frcinx
213t_frcinx:
214	fmove.l		fpsr,USER_FPSR(a6)	capture incoming fpsr
215	fmove.l		d1,fpcr
216*
217* create an inex2 exception by adding two numbers with very different exponents
218* do the add in fp1 so as to not disturb the result sitting in fp0
219*
220	fmove.x		pls_one,fp1
221	fadd.x		small,fp1
222*
223	or.l	#inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
224	btst.b	#unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set
225	beq.b	no_uacc1		;if clear, do not set aunfl
226	bset.b	#aunfl_bit,FPSR_AEXCEPT(a6)
227no_uacc1:
228	fmove.l	USER_FPSR(a6),fpsr
229	rts
230*
231*	dst_nan --- force result when destination is a NaN
232*
233	xdef	dst_nan
234dst_nan:
235	fmove.l	USER_FPCR(a6),fpcr
236	fmove.x FPTEMP(a6),fp0
237	rts
238
239*
240*	src_nan --- force result when source is a NaN
241*
242	xdef	src_nan
243src_nan:
244	fmove.l	USER_FPCR(a6),fpcr
245	fmove.x	ETEMP(a6),fp0
246	rts
247*
248*	mon_nan --- force result when source is a NaN (monadic version)
249*
250*	This is the same as src_nan except that the user's fpcr comes
251*	in via d1, not USER_FPCR(a6).
252*
253	xdef	mon_nan
254mon_nan:
255	fmove.l	d1,fpcr
256	fmove.x	ETEMP(a6),fp0
257	rts
258*
259*	t_extdnrm, t_resdnrm --- generate results for denorm inputs
260*
261*	For all functions that have a denormalized input and that f(x)=x,
262*	this is the entry point.
263*
264	xdef	t_extdnrm
265t_extdnrm:
266	fmove.l	d1,fpcr
267	fmove.x	LOCAL_EX(a0),fp0
268	fmove.l		fpsr,d0
269	or.l		#unfinx_mask,d0
270	fmove.l		d0,fpsr
271	rts
272
273	xdef	t_resdnrm
274t_resdnrm:
275	fmove.l	USER_FPCR(a6),fpcr
276	fmove.x	LOCAL_EX(a0),fp0
277	fmove.l		fpsr,d0
278	or.l		#unfl_mask,d0
279	fmove.l		d0,fpsr
280	rts
281*
282*
283*
284	xdef	t_avoid_unsupp
285t_avoid_unsupp:
286	fmove.x	fp0,fp0
287	rts
288
289	xdef	sto_cos
290sto_cos:
291	fmovem.x LOCAL_EX(a0),fp1
292	rts
293*
294*	Native instruction support
295*
296*	Some systems may need entry points even for 68040 native
297*	instructions.  These routines are provided for
298*	convenience.
299*
300	xdef	sadd
301sadd:
302	fmovem.x	FPTEMP(a6),fp0
303	fmove.l	USER_FPCR(a6),fpcr
304	fadd.x	ETEMP(a6),fp0
305	rts
306
307	xdef	ssub
308ssub:
309	fmovem.x	FPTEMP(a6),fp0
310	fmove.l	USER_FPCR(a6),fpcr
311	fsub.x	ETEMP(a6),fp0
312	rts
313
314	xdef	smul
315smul:
316	fmovem.x	FPTEMP(a6),fp0
317	fmove.l	USER_FPCR(a6),fpcr
318	fmul.x	ETEMP(a6),fp0
319	rts
320
321	xdef	sdiv
322sdiv:
323	fmovem.x	FPTEMP(a6),fp0
324	fmove.l	USER_FPCR(a6),fpcr
325	fdiv.x	ETEMP(a6),fp0
326	rts
327
328	xdef	sabs
329sabs:
330	fmovem.x	ETEMP(a6),fp0
331	fmove.l	d1,fpcr
332	fabs.x	fp0
333	rts
334
335	xdef	sneg
336sneg:
337	fmovem.x	ETEMP(a6),fp0
338	fmove.l	d1,fpcr
339	fneg.x	fp0
340	rts
341
342	xdef	ssqrt
343ssqrt:
344	fmovem.x	ETEMP(a6),fp0
345	fmove.l	d1,fpcr
346	fsqrt.x	fp0
347	rts
348
349*
350*	l_sint,l_sintrz,l_sintd --- special wrapper for fint and fintrz
351*
352*	On entry, move the user's FPCR to USER_FPCR.
353*
354*	On return from, we need to pickup the INEX2/AINEX bits
355*	that are in USER_FPSR.
356*
357	xref	sint
358	xref	sintrz
359	xref	sintd
360
361	xdef	l_sint
362l_sint:
363	move.l	d1,USER_FPCR(a6)
364	jsr	sint
365	fmove.l	fpsr,d0
366	or.l	USER_FPSR(a6),d0
367	fmove.l	d0,fpsr
368	rts
369
370	xdef	l_sintrz
371l_sintrz:
372	move.l	d1,USER_FPCR(a6)
373	jsr	sintrz
374	fmove.l	fpsr,d0
375	or.l	USER_FPSR(a6),d0
376	fmove.l	d0,fpsr
377	rts
378
379	xdef	l_sintd
380l_sintd:
381	move.l	d1,USER_FPCR(a6)
382	jsr	sintd
383	fmove.l	fpsr,d0
384	or.l	USER_FPSR(a6),d0
385	fmove.l	d0,fpsr
386	rts
387
388	end
389