fcnvfxt.c revision 1.4 1 /* $NetBSD: fcnvfxt.c,v 1.4 2012/01/01 20:04:36 skrll Exp $ */
2
3 /* $OpenBSD: fcnvfxt.c,v 1.8 2010/07/30 18:05:23 kettenis Exp $ */
4
5 /*
6 * Copyright 1996 1995 by Open Software Foundation, Inc.
7 * All Rights Reserved
8 *
9 * Permission to use, copy, modify, and distribute this software and
10 * its documentation for any purpose and without fee is hereby granted,
11 * provided that the above copyright notice appears in all copies and
12 * that both the copyright notice and this permission notice appear in
13 * supporting documentation.
14 *
15 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17 * FOR A PARTICULAR PURPOSE.
18 *
19 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
22 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
23 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 *
25 */
26 /*
27 * pmk1.1
28 */
29 /*
30 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
31 *
32 * To anyone who acknowledges that this file is provided "AS IS"
33 * without any express or implied warranty:
34 * permission to use, copy, modify, and distribute this file
35 * for any purpose is hereby granted without fee, provided that
36 * the above copyright notice and this notice appears in all
37 * copies, and that the name of Hewlett-Packard Company not be
38 * used in advertising or publicity pertaining to distribution
39 * of the software without specific, written prior permission.
40 * Hewlett-Packard Company makes no representations about the
41 * suitability of this software for any purpose.
42 */
43
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: fcnvfxt.c,v 1.4 2012/01/01 20:04:36 skrll Exp $");
46
47 #include "../spmath/float.h"
48 #include "../spmath/sgl_float.h"
49 #include "../spmath/dbl_float.h"
50 #include "../spmath/cnv_float.h"
51
52 /*
53 * Convert single floating-point to single fixed-point format
54 * with truncated result
55 */
56 /*ARGSUSED*/
57 int
58 sgl_to_sgl_fcnvfxt(srcptr,dstptr,status)
59
60 sgl_floating_point *srcptr;
61 int *dstptr;
62 unsigned int *status;
63 {
64 register unsigned int src, temp;
65 register int src_exponent, result;
66
67 src = *srcptr;
68 src_exponent = Sgl_exponent(src) - SGL_BIAS;
69
70 /*
71 * Test for overflow
72 */
73 if (src_exponent > SGL_FX_MAX_EXP) {
74 /* check for MININT */
75 if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
76 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
77 if (Sgl_iszero_sign(src)) result = 0x7fffffff;
78 else result = 0x80000000;
79
80 if (Is_invalidtrap_enabled()) {
81 return(INVALIDEXCEPTION);
82 }
83 Set_invalidflag();
84 *dstptr = result;
85 return(NOEXCEPTION);
86 }
87 }
88 /*
89 * Generate result
90 */
91 if (src_exponent >= 0) {
92 temp = src;
93 Sgl_clear_signexponent_set_hidden(temp);
94 Int_from_sgl_mantissa(temp,src_exponent);
95 if (Sgl_isone_sign(src)) result = -Sgl_all(temp);
96 else result = Sgl_all(temp);
97 *dstptr = result;
98
99 /* check for inexact */
100 if (Sgl_isinexact_to_fix(src,src_exponent)) {
101 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
102 else Set_inexactflag();
103 }
104 }
105 else {
106 *dstptr = 0;
107
108 /* check for inexact */
109 if (Sgl_isnotzero_exponentmantissa(src)) {
110 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
111 else Set_inexactflag();
112 }
113 }
114 return(NOEXCEPTION);
115 }
116
117 /*
118 * Single Floating-point to Double Fixed-point
119 */
120 /*ARGSUSED*/
121 int
122 sgl_to_dbl_fcnvfxt(srcptr,dstptr,status)
123
124 sgl_floating_point *srcptr;
125 dbl_integer *dstptr;
126 unsigned int *status;
127 {
128 register int src_exponent, resultp1;
129 register unsigned int src, temp, resultp2;
130
131 src = *srcptr;
132 src_exponent = Sgl_exponent(src) - SGL_BIAS;
133
134 /*
135 * Test for overflow
136 */
137 if (src_exponent > DBL_FX_MAX_EXP) {
138 /* check for MININT */
139 if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
140 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
141 if (Sgl_iszero_sign(src)) {
142 resultp1 = 0x7fffffff;
143 resultp2 = 0xffffffff;
144 }
145 else {
146 resultp1 = 0x80000000;
147 resultp2 = 0;
148 }
149
150 if (Is_invalidtrap_enabled()) {
151 return(INVALIDEXCEPTION);
152 }
153 Set_invalidflag();
154 Dint_copytoptr(resultp1,resultp2,dstptr);
155 return(NOEXCEPTION);
156 }
157 Dint_set_minint(resultp1,resultp2);
158 Dint_copytoptr(resultp1,resultp2,dstptr);
159 return(NOEXCEPTION);
160 }
161 /*
162 * Generate result
163 */
164 if (src_exponent >= 0) {
165 temp = src;
166 Sgl_clear_signexponent_set_hidden(temp);
167 Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
168 if (Sgl_isone_sign(src)) {
169 Dint_setone_sign(resultp1,resultp2);
170 }
171 Dint_copytoptr(resultp1,resultp2,dstptr);
172
173 /* check for inexact */
174 if (Sgl_isinexact_to_fix(src,src_exponent)) {
175 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
176 else Set_inexactflag();
177 }
178 }
179 else {
180 Dint_setzero(resultp1,resultp2);
181 Dint_copytoptr(resultp1,resultp2,dstptr);
182
183 /* check for inexact */
184 if (Sgl_isnotzero_exponentmantissa(src)) {
185 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
186 else Set_inexactflag();
187 }
188 }
189 return(NOEXCEPTION);
190 }
191
192 /*
193 * Double Floating-point to Single Fixed-point
194 */
195 /*ARGSUSED*/
196 int
197 dbl_to_sgl_fcnvfxt(srcptr,dstptr,status)
198
199 dbl_floating_point *srcptr;
200 int *dstptr;
201 unsigned int *status;
202 {
203 register unsigned int srcp1, srcp2, tempp1, tempp2;
204 register int src_exponent, result;
205
206 Dbl_copyfromptr(srcptr,srcp1,srcp2);
207 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
208
209 /*
210 * Test for overflow
211 */
212 if (src_exponent > SGL_FX_MAX_EXP) {
213 /* check for MININT */
214 if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
215 if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
216 else result = 0x80000000;
217
218 if (Is_invalidtrap_enabled()) {
219 return(INVALIDEXCEPTION);
220 }
221 Set_invalidflag();
222 *dstptr = result;
223 return(NOEXCEPTION);
224 }
225 }
226 /*
227 * Generate result
228 */
229 if (src_exponent >= 0) {
230 tempp1 = srcp1;
231 tempp2 = srcp2;
232 Dbl_clear_signexponent_set_hidden(tempp1);
233 Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
234 if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
235 result = -Dbl_allp1(tempp1);
236 else result = Dbl_allp1(tempp1);
237 *dstptr = result;
238
239 /* check for inexact */
240 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
241 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
242 else Set_inexactflag();
243 }
244 }
245 else {
246 *dstptr = 0;
247
248 /* check for inexact */
249 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
250 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
251 else Set_inexactflag();
252 }
253 }
254 return(NOEXCEPTION);
255 }
256
257 /*
258 * Double Floating-point to Double Fixed-point
259 */
260 /*ARGSUSED*/
261 int
262 dbl_to_dbl_fcnvfxt(srcptr,dstptr,status)
263
264 dbl_floating_point *srcptr;
265 dbl_integer *dstptr;
266 unsigned int *status;
267 {
268 register int src_exponent, resultp1;
269 register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
270
271 Dbl_copyfromptr(srcptr,srcp1,srcp2);
272 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
273
274 /*
275 * Test for overflow
276 */
277 if (src_exponent > DBL_FX_MAX_EXP) {
278 /* check for MININT */
279 if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
280 Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
281 if (Dbl_iszero_sign(srcp1)) {
282 resultp1 = 0x7fffffff;
283 resultp2 = 0xffffffff;
284 }
285 else {
286 resultp1 = 0x80000000;
287 resultp2 = 0;
288 }
289
290 if (Is_invalidtrap_enabled()) {
291 return(INVALIDEXCEPTION);
292 }
293 Set_invalidflag();
294 Dint_copytoptr(resultp1,resultp2,dstptr);
295 return(NOEXCEPTION);
296 }
297 }
298 /*
299 * Generate result
300 */
301 if (src_exponent >= 0) {
302 tempp1 = srcp1;
303 tempp2 = srcp2;
304 Dbl_clear_signexponent_set_hidden(tempp1);
305 Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
306 resultp1,resultp2);
307 if (Dbl_isone_sign(srcp1)) {
308 Dint_setone_sign(resultp1,resultp2);
309 }
310 Dint_copytoptr(resultp1,resultp2,dstptr);
311
312 /* check for inexact */
313 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
314 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
315 else Set_inexactflag();
316 }
317 }
318 else {
319 Dint_setzero(resultp1,resultp2);
320 Dint_copytoptr(resultp1,resultp2,dstptr);
321
322 /* check for inexact */
323 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
324 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
325 else Set_inexactflag();
326 }
327 }
328 return(NOEXCEPTION);
329 }
330