1 /* $NetBSD: fcnvfxt.c,v 1.5 2012/02/04 17:03:09 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.5 2012/02/04 17:03:09 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
sgl_to_sgl_fcnvfxt(sgl_floating_point * srcptr,int * dstptr,unsigned int * status)58 sgl_to_sgl_fcnvfxt(sgl_floating_point *srcptr, int *dstptr,
59 unsigned int *status)
60 {
61 register unsigned int src, temp;
62 register int src_exponent, result;
63
64 src = *srcptr;
65 src_exponent = Sgl_exponent(src) - SGL_BIAS;
66
67 /*
68 * Test for overflow
69 */
70 if (src_exponent > SGL_FX_MAX_EXP) {
71 /* check for MININT */
72 if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
73 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
74 if (Sgl_iszero_sign(src)) result = 0x7fffffff;
75 else result = 0x80000000;
76
77 if (Is_invalidtrap_enabled()) {
78 return(INVALIDEXCEPTION);
79 }
80 Set_invalidflag();
81 *dstptr = result;
82 return(NOEXCEPTION);
83 }
84 }
85 /*
86 * Generate result
87 */
88 if (src_exponent >= 0) {
89 temp = src;
90 Sgl_clear_signexponent_set_hidden(temp);
91 Int_from_sgl_mantissa(temp,src_exponent);
92 if (Sgl_isone_sign(src)) result = -Sgl_all(temp);
93 else result = Sgl_all(temp);
94 *dstptr = result;
95
96 /* check for inexact */
97 if (Sgl_isinexact_to_fix(src,src_exponent)) {
98 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
99 else Set_inexactflag();
100 }
101 }
102 else {
103 *dstptr = 0;
104
105 /* check for inexact */
106 if (Sgl_isnotzero_exponentmantissa(src)) {
107 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
108 else Set_inexactflag();
109 }
110 }
111 return(NOEXCEPTION);
112 }
113
114 /*
115 * Single Floating-point to Double Fixed-point
116 */
117 /*ARGSUSED*/
118 int
sgl_to_dbl_fcnvfxt(sgl_floating_point * srcptr,dbl_integer * dstptr,unsigned int * status)119 sgl_to_dbl_fcnvfxt(sgl_floating_point *srcptr, dbl_integer *dstptr,
120 unsigned int *status)
121 {
122 register int src_exponent, resultp1;
123 register unsigned int src, temp, resultp2;
124
125 src = *srcptr;
126 src_exponent = Sgl_exponent(src) - SGL_BIAS;
127
128 /*
129 * Test for overflow
130 */
131 if (src_exponent > DBL_FX_MAX_EXP) {
132 /* check for MININT */
133 if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
134 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
135 if (Sgl_iszero_sign(src)) {
136 resultp1 = 0x7fffffff;
137 resultp2 = 0xffffffff;
138 }
139 else {
140 resultp1 = 0x80000000;
141 resultp2 = 0;
142 }
143
144 if (Is_invalidtrap_enabled()) {
145 return(INVALIDEXCEPTION);
146 }
147 Set_invalidflag();
148 Dint_copytoptr(resultp1,resultp2,dstptr);
149 return(NOEXCEPTION);
150 }
151 Dint_set_minint(resultp1,resultp2);
152 Dint_copytoptr(resultp1,resultp2,dstptr);
153 return(NOEXCEPTION);
154 }
155 /*
156 * Generate result
157 */
158 if (src_exponent >= 0) {
159 temp = src;
160 Sgl_clear_signexponent_set_hidden(temp);
161 Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
162 if (Sgl_isone_sign(src)) {
163 Dint_setone_sign(resultp1,resultp2);
164 }
165 Dint_copytoptr(resultp1,resultp2,dstptr);
166
167 /* check for inexact */
168 if (Sgl_isinexact_to_fix(src,src_exponent)) {
169 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
170 else Set_inexactflag();
171 }
172 }
173 else {
174 Dint_setzero(resultp1,resultp2);
175 Dint_copytoptr(resultp1,resultp2,dstptr);
176
177 /* check for inexact */
178 if (Sgl_isnotzero_exponentmantissa(src)) {
179 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
180 else Set_inexactflag();
181 }
182 }
183 return(NOEXCEPTION);
184 }
185
186 /*
187 * Double Floating-point to Single Fixed-point
188 */
189 /*ARGSUSED*/
190 int
dbl_to_sgl_fcnvfxt(dbl_floating_point * srcptr,int * dstptr,unsigned int * status)191 dbl_to_sgl_fcnvfxt(dbl_floating_point *srcptr, int *dstptr,
192 unsigned int *status)
193 {
194 register unsigned int srcp1, srcp2, tempp1, tempp2;
195 register int src_exponent, result;
196
197 Dbl_copyfromptr(srcptr,srcp1,srcp2);
198 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
199
200 /*
201 * Test for overflow
202 */
203 if (src_exponent > SGL_FX_MAX_EXP) {
204 /* check for MININT */
205 if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
206 if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
207 else result = 0x80000000;
208
209 if (Is_invalidtrap_enabled()) {
210 return(INVALIDEXCEPTION);
211 }
212 Set_invalidflag();
213 *dstptr = result;
214 return(NOEXCEPTION);
215 }
216 }
217 /*
218 * Generate result
219 */
220 if (src_exponent >= 0) {
221 tempp1 = srcp1;
222 tempp2 = srcp2;
223 Dbl_clear_signexponent_set_hidden(tempp1);
224 Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
225 if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
226 result = -Dbl_allp1(tempp1);
227 else result = Dbl_allp1(tempp1);
228 *dstptr = result;
229
230 /* check for inexact */
231 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
232 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
233 else Set_inexactflag();
234 }
235 }
236 else {
237 *dstptr = 0;
238
239 /* check for inexact */
240 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
241 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
242 else Set_inexactflag();
243 }
244 }
245 return(NOEXCEPTION);
246 }
247
248 /*
249 * Double Floating-point to Double Fixed-point
250 */
251 /*ARGSUSED*/
252 int
dbl_to_dbl_fcnvfxt(dbl_floating_point * srcptr,dbl_integer * dstptr,unsigned int * status)253 dbl_to_dbl_fcnvfxt(dbl_floating_point *srcptr, dbl_integer *dstptr,
254 unsigned int *status)
255 {
256 register int src_exponent, resultp1;
257 register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
258
259 Dbl_copyfromptr(srcptr,srcp1,srcp2);
260 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
261
262 /*
263 * Test for overflow
264 */
265 if (src_exponent > DBL_FX_MAX_EXP) {
266 /* check for MININT */
267 if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
268 Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
269 if (Dbl_iszero_sign(srcp1)) {
270 resultp1 = 0x7fffffff;
271 resultp2 = 0xffffffff;
272 }
273 else {
274 resultp1 = 0x80000000;
275 resultp2 = 0;
276 }
277
278 if (Is_invalidtrap_enabled()) {
279 return(INVALIDEXCEPTION);
280 }
281 Set_invalidflag();
282 Dint_copytoptr(resultp1,resultp2,dstptr);
283 return(NOEXCEPTION);
284 }
285 }
286 /*
287 * Generate result
288 */
289 if (src_exponent >= 0) {
290 tempp1 = srcp1;
291 tempp2 = srcp2;
292 Dbl_clear_signexponent_set_hidden(tempp1);
293 Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
294 resultp1,resultp2);
295 if (Dbl_isone_sign(srcp1)) {
296 Dint_setone_sign(resultp1,resultp2);
297 }
298 Dint_copytoptr(resultp1,resultp2,dstptr);
299
300 /* check for inexact */
301 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
302 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
303 else Set_inexactflag();
304 }
305 }
306 else {
307 Dint_setzero(resultp1,resultp2);
308 Dint_copytoptr(resultp1,resultp2,dstptr);
309
310 /* check for inexact */
311 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
312 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
313 else Set_inexactflag();
314 }
315 }
316 return(NOEXCEPTION);
317 }
318