1 /*
2 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
3 *
4 * Floating-point emulation code
5 * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 /*
22 * BEGIN_DESC
23 *
24 * File:
25 * @(#) pa/spmath/fcnvfut.c $Revision: $
26 *
27 * Purpose:
28 * Floating-point to Unsigned Fixed-point Converts with Truncation
29 *
30 * External Interfaces:
31 * dbl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status)
32 * dbl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status)
33 * sgl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status)
34 * sgl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status)
35 *
36 * Internal Interfaces:
37 *
38 * Theory:
39 * <<please update with a overview of the operation of this file>>
40 *
41 * END_DESC
42 */
43
44
45 #include "float.h"
46 #include "sgl_float.h"
47 #include "dbl_float.h"
48 #include "cnv_float.h"
49
50 /************************************************************************
51 * Floating-point to Unsigned Fixed-point Converts with Truncation *
52 ************************************************************************/
53
54 /*
55 * Convert single floating-point to single fixed-point format
56 * with truncated result
57 */
58 /*ARGSUSED*/
59 int
sgl_to_sgl_fcnvfut(sgl_floating_point * srcptr,unsigned int * nullptr,unsigned int * dstptr,unsigned int * status)60 sgl_to_sgl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
61 unsigned int *dstptr, unsigned int *status)
62 {
63 register unsigned int src, result;
64 register int src_exponent;
65
66 src = *srcptr;
67 src_exponent = Sgl_exponent(src) - SGL_BIAS;
68
69 /*
70 * Test for overflow
71 */
72 if (src_exponent > SGL_FX_MAX_EXP + 1) {
73 if (Sgl_isone_sign(src)) {
74 result = 0;
75 } else {
76 result = 0xffffffff;
77 }
78 if (Is_invalidtrap_enabled()) {
79 return(INVALIDEXCEPTION);
80 }
81 Set_invalidflag();
82 *dstptr = result;
83 return(NOEXCEPTION);
84 }
85 /*
86 * Generate result
87 */
88 if (src_exponent >= 0) {
89 /*
90 * Check sign.
91 * If negative, trap unimplemented.
92 */
93 if (Sgl_isone_sign(src)) {
94 result = 0;
95 if (Is_invalidtrap_enabled()) {
96 return(INVALIDEXCEPTION);
97 }
98 Set_invalidflag();
99 *dstptr = result;
100 return(NOEXCEPTION);
101 }
102 Sgl_clear_signexponent_set_hidden(src);
103 Suint_from_sgl_mantissa(src,src_exponent,result);
104 *dstptr = result;
105
106 /* check for inexact */
107 if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
108 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
109 else Set_inexactflag();
110 }
111 }
112 else {
113 *dstptr = 0;
114
115 /* check for inexact */
116 if (Sgl_isnotzero_exponentmantissa(src)) {
117 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
118 else Set_inexactflag();
119 }
120 }
121 return(NOEXCEPTION);
122 }
123
124 /*
125 * Single Floating-point to Double Unsigned Fixed
126 */
127 /*ARGSUSED*/
128 int
sgl_to_dbl_fcnvfut(sgl_floating_point * srcptr,unsigned int * nullptr,dbl_unsigned * dstptr,unsigned int * status)129 sgl_to_dbl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
130 dbl_unsigned * dstptr, unsigned int *status)
131 {
132 register int src_exponent;
133 register unsigned int src, resultp1, resultp2;
134
135 src = *srcptr;
136 src_exponent = Sgl_exponent(src) - SGL_BIAS;
137
138 /*
139 * Test for overflow
140 */
141 if (src_exponent > DBL_FX_MAX_EXP + 1) {
142 if (Sgl_isone_sign(src)) {
143 resultp1 = resultp2 = 0;
144 } else {
145 resultp1 = resultp2 = 0xffffffff;
146 }
147 if (Is_invalidtrap_enabled()) {
148 return(INVALIDEXCEPTION);
149 }
150 Set_invalidflag();
151 Duint_copytoptr(resultp1,resultp2,dstptr);
152 return(NOEXCEPTION);
153 }
154 /*
155 * Generate result
156 */
157 if (src_exponent >= 0) {
158 /*
159 * Check sign.
160 * If negative, trap unimplemented.
161 */
162 if (Sgl_isone_sign(src)) {
163 resultp1 = resultp2 = 0;
164 if (Is_invalidtrap_enabled()) {
165 return(INVALIDEXCEPTION);
166 }
167 Set_invalidflag();
168 Duint_copytoptr(resultp1,resultp2,dstptr);
169 return(NOEXCEPTION);
170 }
171 Sgl_clear_signexponent_set_hidden(src);
172 Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2);
173 Duint_copytoptr(resultp1,resultp2,dstptr);
174
175 /* check for inexact */
176 if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
177 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
178 else Set_inexactflag();
179 }
180 }
181 else {
182 Duint_setzero(resultp1,resultp2);
183 Duint_copytoptr(resultp1,resultp2,dstptr);
184
185 /* check for inexact */
186 if (Sgl_isnotzero_exponentmantissa(src)) {
187 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
188 else Set_inexactflag();
189 }
190 }
191 return(NOEXCEPTION);
192 }
193
194 /*
195 * Double Floating-point to Single Unsigned Fixed
196 */
197 /*ARGSUSED*/
198 int
dbl_to_sgl_fcnvfut(dbl_floating_point * srcptr,unsigned int * nullptr,unsigned int * dstptr,unsigned int * status)199 dbl_to_sgl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
200 unsigned int *dstptr, unsigned int *status)
201 {
202 register unsigned int srcp1, srcp2, result;
203 register int src_exponent;
204
205 Dbl_copyfromptr(srcptr,srcp1,srcp2);
206 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
207
208 /*
209 * Test for overflow
210 */
211 if (src_exponent > SGL_FX_MAX_EXP + 1) {
212 if (Dbl_isone_sign(srcp1)) {
213 result = 0;
214 } else {
215 result = 0xffffffff;
216 }
217 if (Is_invalidtrap_enabled()) {
218 return(INVALIDEXCEPTION);
219 }
220 Set_invalidflag();
221 *dstptr = result;
222 return(NOEXCEPTION);
223 }
224 /*
225 * Generate result
226 */
227 if (src_exponent >= 0) {
228 /*
229 * Check sign.
230 * If negative, trap unimplemented.
231 */
232 if (Dbl_isone_sign(srcp1)) {
233 result = 0;
234 if (Is_invalidtrap_enabled()) {
235 return(INVALIDEXCEPTION);
236 }
237 Set_invalidflag();
238 *dstptr = result;
239 return(NOEXCEPTION);
240 }
241 Dbl_clear_signexponent_set_hidden(srcp1);
242 Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result);
243 *dstptr = result;
244
245 /* check for inexact */
246 if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
247 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
248 else Set_inexactflag();
249 }
250 }
251 else {
252 *dstptr = 0;
253
254 /* check for inexact */
255 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
256 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
257 else Set_inexactflag();
258 }
259 }
260 return(NOEXCEPTION);
261 }
262
263 /*
264 * Double Floating-point to Double Unsigned Fixed
265 */
266 /*ARGSUSED*/
267 int
dbl_to_dbl_fcnvfut(dbl_floating_point * srcptr,unsigned int * nullptr,dbl_unsigned * dstptr,unsigned int * status)268 dbl_to_dbl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
269 dbl_unsigned * dstptr, unsigned int *status)
270 {
271 register int src_exponent;
272 register unsigned int srcp1, srcp2, resultp1, resultp2;
273
274 Dbl_copyfromptr(srcptr,srcp1,srcp2);
275 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
276
277 /*
278 * Test for overflow
279 */
280 if (src_exponent > DBL_FX_MAX_EXP + 1) {
281 if (Dbl_isone_sign(srcp1)) {
282 resultp1 = resultp2 = 0;
283 } else {
284 resultp1 = resultp2 = 0xffffffff;
285 }
286 if (Is_invalidtrap_enabled()) {
287 return(INVALIDEXCEPTION);
288 }
289 Set_invalidflag();
290 Duint_copytoptr(resultp1,resultp2,dstptr);
291 return(NOEXCEPTION);
292 }
293 /*
294 * Generate result
295 */
296 if (src_exponent >= 0) {
297 /*
298 * Check sign.
299 * If negative, trap unimplemented.
300 */
301 if (Dbl_isone_sign(srcp1)) {
302 resultp1 = resultp2 = 0;
303 if (Is_invalidtrap_enabled()) {
304 return(INVALIDEXCEPTION);
305 }
306 Set_invalidflag();
307 Duint_copytoptr(resultp1,resultp2,dstptr);
308 return(NOEXCEPTION);
309 }
310 Dbl_clear_signexponent_set_hidden(srcp1);
311 Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent,
312 resultp1,resultp2);
313 Duint_copytoptr(resultp1,resultp2,dstptr);
314
315 /* check for inexact */
316 if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
317 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
318 else Set_inexactflag();
319 }
320 }
321 else {
322 Duint_setzero(resultp1,resultp2);
323 Duint_copytoptr(resultp1,resultp2,dstptr);
324
325 /* check for inexact */
326 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
327 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
328 else Set_inexactflag();
329 }
330 }
331 return(NOEXCEPTION);
332 }
333