2 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
4 * Floating-point emulation code
5 * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
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)
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * @(#) pa/spmath/fcnvfu.c $Revision: 1.1 $
28 * Floating-point to Unsigned Fixed-point Converts
30 * External Interfaces:
31 * dbl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
32 * dbl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
33 * sgl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
34 * sgl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
36 * Internal Interfaces:
39 * <<please update with a overview of the operation of this file>>
46 #include "sgl_float.h"
47 #include "dbl_float.h"
48 #include "cnv_float.h"
50 /************************************************************************
51 * Floating-point to Unsigned Fixed-point Converts *
52 ************************************************************************/
55 * Single Floating-point to Single Unsigned Fixed
60 sgl_floating_point
*srcptr
,
61 unsigned int *nullptr,
65 register unsigned int src
, result
;
66 register int src_exponent
;
67 register boolean inexact
= FALSE
;
70 src_exponent
= Sgl_exponent(src
) - SGL_BIAS
;
75 if (src_exponent
> SGL_FX_MAX_EXP
+ 1) {
76 if (Sgl_isone_sign(src
)) {
81 if (Is_invalidtrap_enabled()) {
82 return(INVALIDEXCEPTION
);
91 if (src_exponent
>= 0) {
94 * If negative, trap unimplemented.
96 if (Sgl_isone_sign(src
)) {
98 if (Is_invalidtrap_enabled()) {
99 return(INVALIDEXCEPTION
);
105 Sgl_clear_signexponent_set_hidden(src
);
106 Suint_from_sgl_mantissa(src
,src_exponent
,result
);
108 /* check for inexact */
109 if (Sgl_isinexact_to_unsigned(src
,src_exponent
)) {
112 switch (Rounding_mode()) {
116 case ROUNDMINUS
: /* never negative */
119 if (Sgl_isone_roundbit(src
,src_exponent
) &&
120 (Sgl_isone_stickybit(src
,src_exponent
) ||
130 /* check for inexact */
131 if (Sgl_isnotzero_exponentmantissa(src
)) {
134 switch (Rounding_mode()) {
136 if (Sgl_iszero_sign(src
)) {
141 if (Sgl_isone_sign(src
)) {
143 if (Is_invalidtrap_enabled()) {
144 return(INVALIDEXCEPTION
);
151 if (src_exponent
== -1 &&
152 Sgl_isnotzero_mantissa(src
)) {
153 if (Sgl_isone_sign(src
)) {
155 if (Is_invalidtrap_enabled()) {
156 return(INVALIDEXCEPTION
);
169 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
170 else Set_inexactflag();
176 * Single Floating-point to Double Unsigned Fixed
181 sgl_floating_point
*srcptr
,
182 unsigned int *nullptr,
183 dbl_unsigned
*dstptr
,
184 unsigned int *status
)
186 register int src_exponent
;
187 register unsigned int src
, resultp1
, resultp2
;
188 register boolean inexact
= FALSE
;
191 src_exponent
= Sgl_exponent(src
) - SGL_BIAS
;
196 if (src_exponent
> DBL_FX_MAX_EXP
+ 1) {
197 if (Sgl_isone_sign(src
)) {
198 resultp1
= resultp2
= 0;
200 resultp1
= resultp2
= 0xffffffff;
202 if (Is_invalidtrap_enabled()) {
203 return(INVALIDEXCEPTION
);
206 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
212 if (src_exponent
>= 0) {
215 * If negative, trap unimplemented.
217 if (Sgl_isone_sign(src
)) {
218 resultp1
= resultp2
= 0;
219 if (Is_invalidtrap_enabled()) {
220 return(INVALIDEXCEPTION
);
223 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
226 Sgl_clear_signexponent_set_hidden(src
);
227 Duint_from_sgl_mantissa(src
,src_exponent
,resultp1
,resultp2
);
229 /* check for inexact */
230 if (Sgl_isinexact_to_unsigned(src
,src_exponent
)) {
233 switch (Rounding_mode()) {
235 Duint_increment(resultp1
,resultp2
);
237 case ROUNDMINUS
: /* never negative */
240 if (Sgl_isone_roundbit(src
,src_exponent
) &&
241 (Sgl_isone_stickybit(src
,src_exponent
) ||
242 Duint_isone_lowp2(resultp2
))) {
243 Duint_increment(resultp1
,resultp2
);
249 Duint_setzero(resultp1
,resultp2
);
251 /* check for inexact */
252 if (Sgl_isnotzero_exponentmantissa(src
)) {
255 switch (Rounding_mode()) {
257 if (Sgl_iszero_sign(src
)) {
258 Duint_increment(resultp1
,resultp2
);
262 if (Sgl_isone_sign(src
)) {
263 resultp1
= resultp2
= 0;
264 if (Is_invalidtrap_enabled()) {
265 return(INVALIDEXCEPTION
);
272 if (src_exponent
== -1 &&
273 Sgl_isnotzero_mantissa(src
)) {
274 if (Sgl_isone_sign(src
)) {
277 if (Is_invalidtrap_enabled()) {
278 return(INVALIDEXCEPTION
);
283 else Duint_increment(resultp1
,resultp2
);
288 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
290 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
291 else Set_inexactflag();
297 * Double Floating-point to Single Unsigned Fixed
301 dbl_to_sgl_fcnvfu (dbl_floating_point
* srcptr
, unsigned int *nullptr,
302 unsigned int *dstptr
, unsigned int *status
)
304 register unsigned int srcp1
, srcp2
, result
;
305 register int src_exponent
;
306 register boolean inexact
= FALSE
;
308 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
309 src_exponent
= Dbl_exponent(srcp1
) - DBL_BIAS
;
314 if (src_exponent
> SGL_FX_MAX_EXP
+ 1) {
315 if (Dbl_isone_sign(srcp1
)) {
320 if (Is_invalidtrap_enabled()) {
321 return(INVALIDEXCEPTION
);
330 if (src_exponent
>= 0) {
333 * If negative, trap unimplemented.
335 if (Dbl_isone_sign(srcp1
)) {
337 if (Is_invalidtrap_enabled()) {
338 return(INVALIDEXCEPTION
);
344 Dbl_clear_signexponent_set_hidden(srcp1
);
345 Suint_from_dbl_mantissa(srcp1
,srcp2
,src_exponent
,result
);
347 /* check for inexact */
348 if (Dbl_isinexact_to_unsigned(srcp1
,srcp2
,src_exponent
)) {
351 switch (Rounding_mode()) {
355 case ROUNDMINUS
: /* never negative */
358 if(Dbl_isone_roundbit(srcp1
,srcp2
,src_exponent
) &&
359 (Dbl_isone_stickybit(srcp1
,srcp2
,src_exponent
)||
364 /* check for overflow */
367 if (Is_invalidtrap_enabled()) {
368 return(INVALIDEXCEPTION
);
378 /* check for inexact */
379 if (Dbl_isnotzero_exponentmantissa(srcp1
,srcp2
)) {
382 switch (Rounding_mode()) {
384 if (Dbl_iszero_sign(srcp1
)) result
++;
387 if (Dbl_isone_sign(srcp1
)) {
389 if (Is_invalidtrap_enabled()) {
390 return(INVALIDEXCEPTION
);
397 if (src_exponent
== -1 &&
398 Dbl_isnotzero_mantissa(srcp1
,srcp2
))
399 if (Dbl_isone_sign(srcp1
)) {
401 if (Is_invalidtrap_enabled()) {
402 return(INVALIDEXCEPTION
);
413 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
414 else Set_inexactflag();
420 * Double Floating-point to Double Unsigned Fixed
424 dbl_to_dbl_fcnvfu (dbl_floating_point
* srcptr
, unsigned int *nullptr,
425 dbl_unsigned
* dstptr
, unsigned int *status
)
427 register int src_exponent
;
428 register unsigned int srcp1
, srcp2
, resultp1
, resultp2
;
429 register boolean inexact
= FALSE
;
431 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
432 src_exponent
= Dbl_exponent(srcp1
) - DBL_BIAS
;
437 if (src_exponent
> DBL_FX_MAX_EXP
+ 1) {
438 if (Dbl_isone_sign(srcp1
)) {
439 resultp1
= resultp2
= 0;
441 resultp1
= resultp2
= 0xffffffff;
443 if (Is_invalidtrap_enabled()) {
444 return(INVALIDEXCEPTION
);
447 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
454 if (src_exponent
>= 0) {
457 * If negative, trap unimplemented.
459 if (Dbl_isone_sign(srcp1
)) {
460 resultp1
= resultp2
= 0;
461 if (Is_invalidtrap_enabled()) {
462 return(INVALIDEXCEPTION
);
465 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
468 Dbl_clear_signexponent_set_hidden(srcp1
);
469 Duint_from_dbl_mantissa(srcp1
,srcp2
,src_exponent
,resultp1
,
472 /* check for inexact */
473 if (Dbl_isinexact_to_unsigned(srcp1
,srcp2
,src_exponent
)) {
476 switch (Rounding_mode()) {
478 Duint_increment(resultp1
,resultp2
);
480 case ROUNDMINUS
: /* never negative */
483 if(Dbl_isone_roundbit(srcp1
,srcp2
,src_exponent
))
484 if(Dbl_isone_stickybit(srcp1
,srcp2
,src_exponent
) ||
485 Duint_isone_lowp2(resultp2
))
486 Duint_increment(resultp1
,resultp2
);
490 Duint_setzero(resultp1
,resultp2
);
492 /* check for inexact */
493 if (Dbl_isnotzero_exponentmantissa(srcp1
,srcp2
)) {
496 switch (Rounding_mode()) {
498 if (Dbl_iszero_sign(srcp1
)) {
499 Duint_increment(resultp1
,resultp2
);
503 if (Dbl_isone_sign(srcp1
)) {
504 resultp1
= resultp2
= 0;
505 if (Is_invalidtrap_enabled()) {
506 return(INVALIDEXCEPTION
);
513 if (src_exponent
== -1 &&
514 Dbl_isnotzero_mantissa(srcp1
,srcp2
))
515 if (Dbl_iszero_sign(srcp1
)) {
516 Duint_increment(resultp1
,resultp2
);
520 if (Is_invalidtrap_enabled()) {
521 return(INVALIDEXCEPTION
);
529 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
531 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
532 else Set_inexactflag();