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