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();