xref: /netbsd/sys/arch/m68k/fpsp/sint.sa (revision bf9ec67e)
1*	$NetBSD: sint.sa,v 1.2 1994/10/26 07:49:48 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*	sint.sa 3.1 12/10/90
35*
36*	The entry point sINT computes the rounded integer
37*	equivalent of the input argument, sINTRZ computes
38*	the integer rounded to zero of the input argument.
39*
40*	Entry points sint and sintrz are called from do_func
41*	to emulate the fint and fintrz unimplemented instructions,
42*	respectively.  Entry point sintdo is used by bindec.
43*
44*	Input: (Entry points sint and sintrz) Double-extended
45*		number X in the ETEMP space in the floating-point
46*		save stack.
47*	       (Entry point sintdo) Double-extended number X in
48*		location pointed to by the address register a0.
49*	       (Entry point sintd) Double-extended denormalized
50*		number X in the ETEMP space in the floating-point
51*		save stack.
52*
53*	Output: The function returns int(X) or intrz(X) in fp0.
54*
55*	Modifies: fp0.
56*
57*	Algorithm: (sint and sintrz)
58*
59*	1. If exp(X) >= 63, return X.
60*	   If exp(X) < 0, return +/- 0 or +/- 1, according to
61*	   the rounding mode.
62*
63*	2. (X is in range) set rsc = 63 - exp(X). Unnormalize the
64*	   result to the exponent $403e.
65*
66*	3. Round the result in the mode given in USER_FPCR. For
67*	   sintrz, force round-to-zero mode.
68*
69*	4. Normalize the rounded result; store in fp0.
70*
71*	For the denormalized cases, force the correct result
72*	for the given sign and rounding mode.
73*
74*		        Sign(X)
75*		RMODE   +    -
76*		-----  --------
77*		 RN    +0   -0
78*		 RZ    +0   -0
79*		 RM    +0   -1
80*		 RP    +1   -0
81*
82
83SINT    IDNT    2,1 Motorola 040 Floating Point Software Package
84
85	section	8
86
87	include	fpsp.h
88
89	xref	dnrm_lp
90	xref	nrm_set
91	xref	round
92	xref	t_inx2
93	xref	ld_pone
94	xref	ld_mone
95	xref	ld_pzero
96	xref	ld_mzero
97	xref	snzrinx
98
99*
100*	FINT
101*
102	xdef	sint
103sint:
104	bfextu	FPCR_MODE(a6){2:2},d1	;use user's mode for rounding
105*					;implicity has extend precision
106*					;in upper word.
107	move.l	d1,L_SCR1(a6)		;save mode bits
108	bra.b	sintexc
109
110*
111*	FINT with extended denorm inputs.
112*
113	xdef	sintd
114sintd:
115	btst.b	#5,FPCR_MODE(a6)
116	beq	snzrinx		;if round nearest or round zero, +/- 0
117	btst.b	#4,FPCR_MODE(a6)
118	beq.b	rnd_mns
119rnd_pls:
120	btst.b	#sign_bit,LOCAL_EX(a0)
121	bne.b	sintmz
122	bsr	ld_pone		;if round plus inf and pos, answer is +1
123	bra	t_inx2
124rnd_mns:
125	btst.b	#sign_bit,LOCAL_EX(a0)
126	beq.b	sintpz
127	bsr	ld_mone		;if round mns inf and neg, answer is -1
128	bra	t_inx2
129sintpz:
130	bsr	ld_pzero
131	bra	t_inx2
132sintmz:
133	bsr	ld_mzero
134	bra	t_inx2
135
136*
137*	FINTRZ
138*
139	xdef	sintrz
140sintrz:
141	move.l	#1,L_SCR1(a6)		;use rz mode for rounding
142*					;implicity has extend precision
143*					;in upper word.
144	bra.b	sintexc
145*
146*	SINTDO
147*
148*	Input:	a0 points to an IEEE extended format operand
149* 	Output:	fp0 has the result
150*
151* Exeptions:
152*
153* If the subroutine results in an inexact operation, the inx2 and
154* ainx bits in the USER_FPSR are set.
155*
156*
157	xdef	sintdo
158sintdo:
159	bfextu	FPCR_MODE(a6){2:2},d1	;use user's mode for rounding
160*					;implicitly has ext precision
161*					;in upper word.
162	move.l	d1,L_SCR1(a6)		;save mode bits
163*
164* Real work of sint is in sintexc
165*
166sintexc:
167	bclr.b	#sign_bit,LOCAL_EX(a0)	;convert to internal extended
168*					;format
169	sne	LOCAL_SGN(a0)
170	cmp.w	#$403e,LOCAL_EX(a0)	;check if (unbiased) exp > 63
171	bgt.b	out_rnge			;branch if exp < 63
172	cmp.w	#$3ffd,LOCAL_EX(a0)	;check if (unbiased) exp < 0
173	bgt.w	in_rnge			;if 63 >= exp > 0, do calc
174*
175* Input is less than zero.  Restore sign, and check for directed
176* rounding modes.  L_SCR1 contains the rmode in the lower byte.
177*
178un_rnge:
179	btst.b	#1,L_SCR1+3(a6)		;check for rn and rz
180	beq.b	un_rnrz
181	tst.b	LOCAL_SGN(a0)		;check for sign
182	bne.b	un_rmrp_neg
183*
184* Sign is +.  If rp, load +1.0, if rm, load +0.0
185*
186	cmpi.b	#3,L_SCR1+3(a6)		;check for rp
187	beq.b	un_ldpone		;if rp, load +1.0
188	bsr	ld_pzero		;if rm, load +0.0
189	bra	t_inx2
190un_ldpone:
191	bsr	ld_pone
192	bra	t_inx2
193*
194* Sign is -.  If rm, load -1.0, if rp, load -0.0
195*
196un_rmrp_neg:
197	cmpi.b	#2,L_SCR1+3(a6)		;check for rm
198	beq.b	un_ldmone		;if rm, load -1.0
199	bsr	ld_mzero		;if rp, load -0.0
200	bra	t_inx2
201un_ldmone:
202	bsr	ld_mone
203	bra	t_inx2
204*
205* Rmode is rn or rz; return signed zero
206*
207un_rnrz:
208	tst.b	LOCAL_SGN(a0)		;check for sign
209	bne.b	un_rnrz_neg
210	bsr	ld_pzero
211	bra	t_inx2
212un_rnrz_neg:
213	bsr	ld_mzero
214	bra	t_inx2
215
216*
217* Input is greater than 2^63.  All bits are significant.  Return
218* the input.
219*
220out_rnge:
221	bfclr	LOCAL_SGN(a0){0:8}	;change back to IEEE ext format
222	beq.b	intps
223	bset.b	#sign_bit,LOCAL_EX(a0)
224intps:
225	fmove.l	fpcr,-(sp)
226	fmove.l	#0,fpcr
227	fmove.x LOCAL_EX(a0),fp0	;if exp > 63
228*					;then return X to the user
229*					;there are no fraction bits
230	fmove.l	(sp)+,fpcr
231	rts
232
233in_rnge:
234* 					;shift off fraction bits
235	clr.l	d0			;clear d0 - initial g,r,s for
236*					;dnrm_lp
237	move.l	#$403e,d1		;set threshold for dnrm_lp
238*					;assumes a0 points to operand
239	bsr	dnrm_lp
240*					;returns unnormalized number
241*					;pointed by a0
242*					;output d0 supplies g,r,s
243*					;used by round
244	move.l	L_SCR1(a6),d1		;use selected rounding mode
245*
246*
247	bsr	round			;round the unnorm based on users
248*					;input	a0 ptr to ext X
249*					;	d0 g,r,s bits
250*					;	d1 PREC/MODE info
251*					;output a0 ptr to rounded result
252*					;inexact flag set in USER_FPSR
253*					;if initial grs set
254*
255* normalize the rounded result and store value in fp0
256*
257	bsr	nrm_set			;normalize the unnorm
258*					;Input: a0 points to operand to
259*					;be normalized
260*					;Output: a0 points to normalized
261*					;result
262	bfclr	LOCAL_SGN(a0){0:8}
263	beq.b	nrmrndp
264	bset.b	#sign_bit,LOCAL_EX(a0)	;return to IEEE extended format
265nrmrndp:
266	fmove.l	fpcr,-(sp)
267	fmove.l	#0,fpcr
268	fmove.x LOCAL_EX(a0),fp0	;move result to fp0
269	fmove.l	(sp)+,fpcr
270	rts
271
272	end
273