1 /* $NetBSD: fcnvfx.c,v 1.3 2005/12/11 12:17:40 christos Exp $ */
3 /* $OpenBSD: fcnvfx.c,v 1.5 2001/03/29 03:58:18 mickey Exp $ */
6 * Copyright 1996 1995 by Open Software Foundation, Inc.
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.
15 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17 * FOR A PARTICULAR PURPOSE.
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.
30 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
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.
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: fcnvfx.c,v 1.3 2005/12/11 12:17:40 christos Exp $");
47 #include "../spmath/float.h"
48 #include "../spmath/sgl_float.h"
49 #include "../spmath/dbl_float.h"
50 #include "../spmath/cnv_float.h"
53 * Single Floating-point to Single Fixed-point
57 sgl_to_sgl_fcnvfx(srcptr
,dstptr
,status
)
59 sgl_floating_point
*srcptr
;
63 register unsigned int src
, temp
;
64 register int src_exponent
, result
;
65 register int inexact
= false;
68 src_exponent
= Sgl_exponent(src
) - SGL_BIAS
;
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
)) {
78 * Since source is a number which cannot be
79 * represented in fixed-point format, return
80 * largest (or smallest) fixed-point number.
82 Sgl_return_overflow(src
,dstptr
);
88 if (src_exponent
>= 0) {
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
);
95 /* check for inexact */
96 if (Sgl_isinexact_to_fix(src
,src_exponent
)) {
99 switch (Rounding_mode()) {
101 if (Sgl_iszero_sign(src
)) result
++;
104 if (Sgl_isone_sign(src
)) result
--;
107 if (Sgl_isone_roundbit(src
,src_exponent
)) {
108 if (Sgl_isone_stickybit(src
,src_exponent
)
109 || (Sgl_isone_lowmantissa(temp
))) {
110 if (Sgl_iszero_sign(src
)) result
++;
120 /* check for inexact */
121 if (Sgl_isnotzero_exponentmantissa(src
)) {
124 switch (Rounding_mode()) {
126 if (Sgl_iszero_sign(src
)) result
++;
129 if (Sgl_isone_sign(src
)) result
--;
132 if (src_exponent
== -1)
133 if (Sgl_isnotzero_mantissa(src
)) {
134 if (Sgl_iszero_sign(src
)) result
++;
142 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
143 else Set_inexactflag();
149 * Single Floating-point to Double Fixed-point
153 sgl_to_dbl_fcnvfx(srcptr
,dstptr
,status
)
155 sgl_floating_point
*srcptr
;
157 unsigned int *status
;
159 register int src_exponent
, resultp1
;
160 register unsigned int src
, temp
, resultp2
;
161 register int inexact
= false;
164 src_exponent
= Sgl_exponent(src
) - SGL_BIAS
;
169 if (src_exponent
> DBL_FX_MAX_EXP
) {
170 /* check for MININT */
171 if ((src_exponent
> DBL_FX_MAX_EXP
+ 1) ||
172 Sgl_isnotzero_mantissa(src
) || Sgl_iszero_sign(src
)) {
174 * Since source is a number which cannot be
175 * represented in fixed-point format, return
176 * largest (or smallest) fixed-point number.
178 Sgl_return_overflow_dbl(src
,dstptr
);
180 Dint_set_minint(resultp1
,resultp2
);
181 Dint_copytoptr(resultp1
,resultp2
,dstptr
);
187 if (src_exponent
>= 0) {
189 Sgl_clear_signexponent_set_hidden(temp
);
190 Dint_from_sgl_mantissa(temp
,src_exponent
,resultp1
,resultp2
);
191 if (Sgl_isone_sign(src
)) {
192 Dint_setone_sign(resultp1
,resultp2
);
195 /* check for inexact */
196 if (Sgl_isinexact_to_fix(src
,src_exponent
)) {
199 switch (Rounding_mode()) {
201 if (Sgl_iszero_sign(src
)) {
202 Dint_increment(resultp1
,resultp2
);
206 if (Sgl_isone_sign(src
)) {
207 Dint_decrement(resultp1
,resultp2
);
211 if (Sgl_isone_roundbit(src
,src_exponent
))
212 if (Sgl_isone_stickybit(src
,src_exponent
) ||
213 (Dint_isone_lowp2(resultp2
))) {
214 if (Sgl_iszero_sign(src
)) {
215 Dint_increment(resultp1
,resultp2
);
218 Dint_decrement(resultp1
,resultp2
);
225 Dint_setzero(resultp1
,resultp2
);
227 /* check for inexact */
228 if (Sgl_isnotzero_exponentmantissa(src
)) {
231 switch (Rounding_mode()) {
233 if (Sgl_iszero_sign(src
)) {
234 Dint_increment(resultp1
,resultp2
);
238 if (Sgl_isone_sign(src
)) {
239 Dint_decrement(resultp1
,resultp2
);
243 if (src_exponent
== -1)
244 if (Sgl_isnotzero_mantissa(src
)) {
245 if (Sgl_iszero_sign(src
)) {
246 Dint_increment(resultp1
,resultp2
);
249 Dint_decrement(resultp1
,resultp2
);
255 Dint_copytoptr(resultp1
,resultp2
,dstptr
);
257 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
258 else Set_inexactflag();
264 * Double Floating-point to Single Fixed-point
268 dbl_to_sgl_fcnvfx(srcptr
,dstptr
,status
)
270 dbl_floating_point
*srcptr
;
272 unsigned int *status
;
274 register unsigned int srcp1
,srcp2
, tempp1
,tempp2
;
275 register int src_exponent
, result
;
276 register int inexact
= false;
278 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
279 src_exponent
= Dbl_exponent(srcp1
) - DBL_BIAS
;
284 if (src_exponent
> SGL_FX_MAX_EXP
) {
285 /* check for MININT */
286 if (Dbl_isoverflow_to_int(src_exponent
,srcp1
,srcp2
)) {
288 * Since source is a number which cannot be
289 * represented in fixed-point format, return
290 * largest (or smallest) fixed-point number.
292 Dbl_return_overflow(srcp1
,srcp2
,dstptr
);
298 if (src_exponent
>= 0) {
301 Dbl_clear_signexponent_set_hidden(tempp1
);
302 Int_from_dbl_mantissa(tempp1
,tempp2
,src_exponent
);
303 if (Dbl_isone_sign(srcp1
) && (src_exponent
<= SGL_FX_MAX_EXP
))
304 result
= -Dbl_allp1(tempp1
);
305 else result
= Dbl_allp1(tempp1
);
307 /* check for inexact */
308 if (Dbl_isinexact_to_fix(srcp1
,srcp2
,src_exponent
)) {
311 switch (Rounding_mode()) {
313 if (Dbl_iszero_sign(srcp1
)) result
++;
316 if (Dbl_isone_sign(srcp1
)) result
--;
319 if (Dbl_isone_roundbit(srcp1
,srcp2
,src_exponent
))
320 if (Dbl_isone_stickybit(srcp1
,srcp2
,src_exponent
) ||
321 (Dbl_isone_lowmantissap1(tempp1
))) {
322 if (Dbl_iszero_sign(srcp1
)) result
++;
326 /* check for overflow */
327 if ((Dbl_iszero_sign(srcp1
) && result
< 0) ||
328 (Dbl_isone_sign(srcp1
) && result
> 0)) {
329 Dbl_return_overflow(srcp1
,srcp2
,dstptr
);
336 /* check for inexact */
337 if (Dbl_isnotzero_exponentmantissa(srcp1
,srcp2
)) {
340 switch (Rounding_mode()) {
342 if (Dbl_iszero_sign(srcp1
)) result
++;
345 if (Dbl_isone_sign(srcp1
)) result
--;
348 if (src_exponent
== -1)
349 if (Dbl_isnotzero_mantissa(srcp1
,srcp2
)) {
350 if (Dbl_iszero_sign(srcp1
)) result
++;
358 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
359 else Set_inexactflag();
365 * Double Floating-point to Double Fixed-point
369 dbl_to_dbl_fcnvfx(srcptr
,dstptr
,status
)
371 dbl_floating_point
*srcptr
;
373 unsigned int *status
;
375 register int src_exponent
, resultp1
;
376 register unsigned int srcp1
, srcp2
, tempp1
, tempp2
, resultp2
;
377 register int inexact
= false;
379 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
380 src_exponent
= Dbl_exponent(srcp1
) - DBL_BIAS
;
385 if (src_exponent
> DBL_FX_MAX_EXP
) {
386 /* check for MININT */
387 if ((src_exponent
> DBL_FX_MAX_EXP
+ 1) ||
388 Dbl_isnotzero_mantissa(srcp1
,srcp2
) || Dbl_iszero_sign(srcp1
)) {
390 * Since source is a number which cannot be
391 * represented in fixed-point format, return
392 * largest (or smallest) fixed-point number.
394 Dbl_return_overflow_dbl(srcp1
,srcp2
,dstptr
);
401 if (src_exponent
>= 0) {
404 Dbl_clear_signexponent_set_hidden(tempp1
);
405 Dint_from_dbl_mantissa(tempp1
,tempp2
,src_exponent
,
407 if (Dbl_isone_sign(srcp1
)) {
408 Dint_setone_sign(resultp1
,resultp2
);
411 /* check for inexact */
412 if (Dbl_isinexact_to_fix(srcp1
,srcp2
,src_exponent
)) {
415 switch (Rounding_mode()) {
417 if (Dbl_iszero_sign(srcp1
)) {
418 Dint_increment(resultp1
,resultp2
);
422 if (Dbl_isone_sign(srcp1
)) {
423 Dint_decrement(resultp1
,resultp2
);
427 if (Dbl_isone_roundbit(srcp1
,srcp2
,src_exponent
))
428 if (Dbl_isone_stickybit(srcp1
,srcp2
,src_exponent
) ||
429 (Dint_isone_lowp2(resultp2
))) {
430 if (Dbl_iszero_sign(srcp1
)) {
431 Dint_increment(resultp1
,resultp2
);
434 Dint_decrement(resultp1
,resultp2
);
441 Dint_setzero(resultp1
,resultp2
);
443 /* check for inexact */
444 if (Dbl_isnotzero_exponentmantissa(srcp1
,srcp2
)) {
447 switch (Rounding_mode()) {
449 if (Dbl_iszero_sign(srcp1
)) {
450 Dint_increment(resultp1
,resultp2
);
454 if (Dbl_isone_sign(srcp1
)) {
455 Dint_decrement(resultp1
,resultp2
);
459 if (src_exponent
== -1)
460 if (Dbl_isnotzero_mantissa(srcp1
,srcp2
)) {
461 if (Dbl_iszero_sign(srcp1
)) {
462 Dint_increment(resultp1
,resultp2
);
465 Dint_decrement(resultp1
,resultp2
);
471 Dint_copytoptr(resultp1
,resultp2
,dstptr
);
473 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
474 else Set_inexactflag();