sint.sa revision 1.1
1*	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
2*	M68000 Hi-Performance Microprocessor Division
3*	M68040 Software Package 
4*
5*	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
6*	All rights reserved.
7*
8*	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
9*	To the maximum extent permitted by applicable law,
10*	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
11*	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
12*	PARTICULAR PURPOSE and any warranty against infringement with
13*	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
14*	and any accompanying written materials. 
15*
16*	To the maximum extent permitted by applicable law,
17*	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
18*	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
19*	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
20*	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
21*	SOFTWARE.  Motorola assumes no responsibility for the maintenance
22*	and support of the SOFTWARE.  
23*
24*	You are hereby granted a copyright license to use, modify, and
25*	distribute the SOFTWARE so long as this entire notice is retained
26*	without alteration in any modified and/or redistributed versions,
27*	and that such modified versions are clearly identified as such.
28*	No licenses are granted by implication, estoppel or otherwise
29*	under any patents or trademarks of Motorola, Inc.
30
31*
32*	sint.sa 3.1 12/10/90
33*
34*	The entry point sINT computes the rounded integer 
35*	equivalent of the input argument, sINTRZ computes 
36*	the integer rounded to zero of the input argument.
37*
38*	Entry points sint and sintrz are called from do_func
39*	to emulate the fint and fintrz unimplemented instructions,
40*	respectively.  Entry point sintdo is used by bindec.
41*
42*	Input: (Entry points sint and sintrz) Double-extended
43*		number X in the ETEMP space in the floating-point
44*		save stack.
45*	       (Entry point sintdo) Double-extended number X in
46*		location pointed to by the address register a0.
47*	       (Entry point sintd) Double-extended denormalized
48*		number X in the ETEMP space in the floating-point
49*		save stack.
50*
51*	Output: The function returns int(X) or intrz(X) in fp0.
52*
53*	Modifies: fp0.
54*
55*	Algorithm: (sint and sintrz)
56*
57*	1. If exp(X) >= 63, return X. 
58*	   If exp(X) < 0, return +/- 0 or +/- 1, according to
59*	   the rounding mode.
60*	
61*	2. (X is in range) set rsc = 63 - exp(X). Unnormalize the
62*	   result to the exponent $403e.
63*
64*	3. Round the result in the mode given in USER_FPCR. For
65*	   sintrz, force round-to-zero mode.
66*
67*	4. Normalize the rounded result; store in fp0.
68*
69*	For the denormalized cases, force the correct result
70*	for the given sign and rounding mode.
71*
72*		        Sign(X)
73*		RMODE   +    -
74*		-----  --------
75*		 RN    +0   -0
76*		 RZ    +0   -0
77*		 RM    +0   -1
78*		 RP    +1   -0
79*
80
81SINT    IDNT    2,1 Motorola 040 Floating Point Software Package
82
83	section	8
84
85	include	fpsp.h
86
87	xref	dnrm_lp
88	xref	nrm_set
89	xref	round
90	xref	t_inx2
91	xref	ld_pone
92	xref	ld_mone
93	xref	ld_pzero
94	xref	ld_mzero
95	xref	snzrinx
96
97*
98*	FINT
99*
100	xdef	sint
101sint:
102	bfextu	FPCR_MODE(a6){2:2},d1	;use user's mode for rounding
103*					;implicity has extend precision
104*					;in upper word. 
105	move.l	d1,L_SCR1(a6)		;save mode bits
106	bra.b	sintexc			
107
108*
109*	FINT with extended denorm inputs.
110*
111	xdef	sintd
112sintd:
113	btst.b	#5,FPCR_MODE(a6)
114	beq	snzrinx		;if round nearest or round zero, +/- 0
115	btst.b	#4,FPCR_MODE(a6)
116	beq.b	rnd_mns
117rnd_pls:
118	btst.b	#sign_bit,LOCAL_EX(a0)
119	bne.b	sintmz
120	bsr	ld_pone		;if round plus inf and pos, answer is +1
121	bra	t_inx2
122rnd_mns:
123	btst.b	#sign_bit,LOCAL_EX(a0)
124	beq.b	sintpz
125	bsr	ld_mone		;if round mns inf and neg, answer is -1
126	bra	t_inx2
127sintpz:
128	bsr	ld_pzero
129	bra	t_inx2
130sintmz:
131	bsr	ld_mzero
132	bra	t_inx2
133
134*
135*	FINTRZ
136*
137	xdef	sintrz
138sintrz:
139	move.l	#1,L_SCR1(a6)		;use rz mode for rounding
140*					;implicity has extend precision
141*					;in upper word. 
142	bra.b	sintexc			
143*
144*	SINTDO
145*
146*	Input:	a0 points to an IEEE extended format operand
147* 	Output:	fp0 has the result 
148*
149* Exeptions:
150*
151* If the subroutine results in an inexact operation, the inx2 and
152* ainx bits in the USER_FPSR are set.
153*
154*
155	xdef	sintdo
156sintdo:
157	bfextu	FPCR_MODE(a6){2:2},d1	;use user's mode for rounding
158*					;implicitly has ext precision
159*					;in upper word. 
160	move.l	d1,L_SCR1(a6)		;save mode bits
161*
162* Real work of sint is in sintexc
163*
164sintexc:
165	bclr.b	#sign_bit,LOCAL_EX(a0)	;convert to internal extended
166*					;format
167	sne	LOCAL_SGN(a0)		
168	cmp.w	#$403e,LOCAL_EX(a0)	;check if (unbiased) exp > 63
169	bgt.b	out_rnge			;branch if exp < 63
170	cmp.w	#$3ffd,LOCAL_EX(a0)	;check if (unbiased) exp < 0
171	bgt.w	in_rnge			;if 63 >= exp > 0, do calc
172*
173* Input is less than zero.  Restore sign, and check for directed
174* rounding modes.  L_SCR1 contains the rmode in the lower byte.
175*
176un_rnge:
177	btst.b	#1,L_SCR1+3(a6)		;check for rn and rz
178	beq.b	un_rnrz
179	tst.b	LOCAL_SGN(a0)		;check for sign
180	bne.b	un_rmrp_neg
181*
182* Sign is +.  If rp, load +1.0, if rm, load +0.0
183*
184	cmpi.b	#3,L_SCR1+3(a6)		;check for rp
185	beq.b	un_ldpone		;if rp, load +1.0
186	bsr	ld_pzero		;if rm, load +0.0
187	bra	t_inx2
188un_ldpone:
189	bsr	ld_pone
190	bra	t_inx2
191*
192* Sign is -.  If rm, load -1.0, if rp, load -0.0
193*
194un_rmrp_neg:
195	cmpi.b	#2,L_SCR1+3(a6)		;check for rm
196	beq.b	un_ldmone		;if rm, load -1.0
197	bsr	ld_mzero		;if rp, load -0.0
198	bra	t_inx2
199un_ldmone:
200	bsr	ld_mone
201	bra	t_inx2
202*
203* Rmode is rn or rz; return signed zero
204*
205un_rnrz:
206	tst.b	LOCAL_SGN(a0)		;check for sign
207	bne.b	un_rnrz_neg
208	bsr	ld_pzero
209	bra	t_inx2
210un_rnrz_neg:
211	bsr	ld_mzero
212	bra	t_inx2
213	
214*
215* Input is greater than 2^63.  All bits are significant.  Return
216* the input.
217*
218out_rnge:
219	bfclr	LOCAL_SGN(a0){0:8}	;change back to IEEE ext format
220	beq.b	intps
221	bset.b	#sign_bit,LOCAL_EX(a0)
222intps:
223	fmove.l	fpcr,-(sp)
224	fmove.l	#0,fpcr
225	fmove.x LOCAL_EX(a0),fp0	;if exp > 63
226*					;then return X to the user
227*					;there are no fraction bits
228	fmove.l	(sp)+,fpcr
229	rts
230
231in_rnge:
232* 					;shift off fraction bits
233	clr.l	d0			;clear d0 - initial g,r,s for
234*					;dnrm_lp
235	move.l	#$403e,d1		;set threshold for dnrm_lp
236*					;assumes a0 points to operand
237	bsr	dnrm_lp
238*					;returns unnormalized number
239*					;pointed by a0
240*					;output d0 supplies g,r,s
241*					;used by round
242	move.l	L_SCR1(a6),d1		;use selected rounding mode
243*
244*
245	bsr	round			;round the unnorm based on users
246*					;input	a0 ptr to ext X
247*					;	d0 g,r,s bits
248*					;	d1 PREC/MODE info
249*					;output a0 ptr to rounded result
250*					;inexact flag set in USER_FPSR
251*					;if initial grs set
252*
253* normalize the rounded result and store value in fp0
254*
255	bsr	nrm_set			;normalize the unnorm
256*					;Input: a0 points to operand to
257*					;be normalized
258*					;Output: a0 points to normalized
259*					;result
260	bfclr	LOCAL_SGN(a0){0:8}
261	beq.b	nrmrndp
262	bset.b	#sign_bit,LOCAL_EX(a0)	;return to IEEE extended format
263nrmrndp:
264	fmove.l	fpcr,-(sp)
265	fmove.l	#0,fpcr
266	fmove.x LOCAL_EX(a0),fp0	;move result to fp0
267	fmove.l	(sp)+,fpcr
268	rts
269
270	end
271