1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
5 * Floating-point emulation code
6 * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
12 * @(#) pa/spmath/fcnvfu.c $Revision: 1.1 $
15 * Floating-point to Unsigned Fixed-point Converts
17 * External Interfaces:
18 * dbl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
19 * dbl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
20 * sgl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
21 * sgl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
23 * Internal Interfaces:
26 * <<please update with a overview of the operation of this file>>
33 #include "sgl_float.h"
34 #include "dbl_float.h"
35 #include "cnv_float.h"
37 /************************************************************************
38 * Floating-point to Unsigned Fixed-point Converts *
39 ************************************************************************/
42 * Single Floating-point to Single Unsigned Fixed
47 sgl_floating_point
*srcptr
,
48 unsigned int *nullptr,
52 register unsigned int src
, result
;
53 register int src_exponent
;
54 register boolean inexact
= FALSE
;
57 src_exponent
= Sgl_exponent(src
) - SGL_BIAS
;
62 if (src_exponent
> SGL_FX_MAX_EXP
+ 1) {
63 if (Sgl_isone_sign(src
)) {
68 if (Is_invalidtrap_enabled()) {
69 return(INVALIDEXCEPTION
);
78 if (src_exponent
>= 0) {
81 * If negative, trap unimplemented.
83 if (Sgl_isone_sign(src
)) {
85 if (Is_invalidtrap_enabled()) {
86 return(INVALIDEXCEPTION
);
92 Sgl_clear_signexponent_set_hidden(src
);
93 Suint_from_sgl_mantissa(src
,src_exponent
,result
);
95 /* check for inexact */
96 if (Sgl_isinexact_to_unsigned(src
,src_exponent
)) {
99 switch (Rounding_mode()) {
103 case ROUNDMINUS
: /* never negative */
106 if (Sgl_isone_roundbit(src
,src_exponent
) &&
107 (Sgl_isone_stickybit(src
,src_exponent
) ||
117 /* check for inexact */
118 if (Sgl_isnotzero_exponentmantissa(src
)) {
121 switch (Rounding_mode()) {
123 if (Sgl_iszero_sign(src
)) {
128 if (Sgl_isone_sign(src
)) {
130 if (Is_invalidtrap_enabled()) {
131 return(INVALIDEXCEPTION
);
138 if (src_exponent
== -1 &&
139 Sgl_isnotzero_mantissa(src
)) {
140 if (Sgl_isone_sign(src
)) {
142 if (Is_invalidtrap_enabled()) {
143 return(INVALIDEXCEPTION
);
156 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
157 else Set_inexactflag();
163 * Single Floating-point to Double Unsigned Fixed
168 sgl_floating_point
*srcptr
,
169 unsigned int *nullptr,
170 dbl_unsigned
*dstptr
,
171 unsigned int *status
)
173 register int src_exponent
;
174 register unsigned int src
, resultp1
, resultp2
;
175 register boolean inexact
= FALSE
;
178 src_exponent
= Sgl_exponent(src
) - SGL_BIAS
;
183 if (src_exponent
> DBL_FX_MAX_EXP
+ 1) {
184 if (Sgl_isone_sign(src
)) {
185 resultp1
= resultp2
= 0;
187 resultp1
= resultp2
= 0xffffffff;
189 if (Is_invalidtrap_enabled()) {
190 return(INVALIDEXCEPTION
);
193 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
199 if (src_exponent
>= 0) {
202 * If negative, trap unimplemented.
204 if (Sgl_isone_sign(src
)) {
205 resultp1
= resultp2
= 0;
206 if (Is_invalidtrap_enabled()) {
207 return(INVALIDEXCEPTION
);
210 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
213 Sgl_clear_signexponent_set_hidden(src
);
214 Duint_from_sgl_mantissa(src
,src_exponent
,resultp1
,resultp2
);
216 /* check for inexact */
217 if (Sgl_isinexact_to_unsigned(src
,src_exponent
)) {
220 switch (Rounding_mode()) {
222 Duint_increment(resultp1
,resultp2
);
224 case ROUNDMINUS
: /* never negative */
227 if (Sgl_isone_roundbit(src
,src_exponent
) &&
228 (Sgl_isone_stickybit(src
,src_exponent
) ||
229 Duint_isone_lowp2(resultp2
))) {
230 Duint_increment(resultp1
,resultp2
);
236 Duint_setzero(resultp1
,resultp2
);
238 /* check for inexact */
239 if (Sgl_isnotzero_exponentmantissa(src
)) {
242 switch (Rounding_mode()) {
244 if (Sgl_iszero_sign(src
)) {
245 Duint_increment(resultp1
,resultp2
);
249 if (Sgl_isone_sign(src
)) {
250 resultp1
= resultp2
= 0;
251 if (Is_invalidtrap_enabled()) {
252 return(INVALIDEXCEPTION
);
259 if (src_exponent
== -1 &&
260 Sgl_isnotzero_mantissa(src
)) {
261 if (Sgl_isone_sign(src
)) {
264 if (Is_invalidtrap_enabled()) {
265 return(INVALIDEXCEPTION
);
270 else Duint_increment(resultp1
,resultp2
);
275 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
277 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
278 else Set_inexactflag();
284 * Double Floating-point to Single Unsigned Fixed
288 dbl_to_sgl_fcnvfu (dbl_floating_point
* srcptr
, unsigned int *nullptr,
289 unsigned int *dstptr
, unsigned int *status
)
291 register unsigned int srcp1
, srcp2
, result
;
292 register int src_exponent
;
293 register boolean inexact
= FALSE
;
295 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
296 src_exponent
= Dbl_exponent(srcp1
) - DBL_BIAS
;
301 if (src_exponent
> SGL_FX_MAX_EXP
+ 1) {
302 if (Dbl_isone_sign(srcp1
)) {
307 if (Is_invalidtrap_enabled()) {
308 return(INVALIDEXCEPTION
);
317 if (src_exponent
>= 0) {
320 * If negative, trap unimplemented.
322 if (Dbl_isone_sign(srcp1
)) {
324 if (Is_invalidtrap_enabled()) {
325 return(INVALIDEXCEPTION
);
331 Dbl_clear_signexponent_set_hidden(srcp1
);
332 Suint_from_dbl_mantissa(srcp1
,srcp2
,src_exponent
,result
);
334 /* check for inexact */
335 if (Dbl_isinexact_to_unsigned(srcp1
,srcp2
,src_exponent
)) {
338 switch (Rounding_mode()) {
342 case ROUNDMINUS
: /* never negative */
345 if(Dbl_isone_roundbit(srcp1
,srcp2
,src_exponent
) &&
346 (Dbl_isone_stickybit(srcp1
,srcp2
,src_exponent
)||
351 /* check for overflow */
354 if (Is_invalidtrap_enabled()) {
355 return(INVALIDEXCEPTION
);
365 /* check for inexact */
366 if (Dbl_isnotzero_exponentmantissa(srcp1
,srcp2
)) {
369 switch (Rounding_mode()) {
371 if (Dbl_iszero_sign(srcp1
)) result
++;
374 if (Dbl_isone_sign(srcp1
)) {
376 if (Is_invalidtrap_enabled()) {
377 return(INVALIDEXCEPTION
);
384 if (src_exponent
== -1 &&
385 Dbl_isnotzero_mantissa(srcp1
,srcp2
))
386 if (Dbl_isone_sign(srcp1
)) {
388 if (Is_invalidtrap_enabled()) {
389 return(INVALIDEXCEPTION
);
400 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
401 else Set_inexactflag();
407 * Double Floating-point to Double Unsigned Fixed
411 dbl_to_dbl_fcnvfu (dbl_floating_point
* srcptr
, unsigned int *nullptr,
412 dbl_unsigned
* dstptr
, unsigned int *status
)
414 register int src_exponent
;
415 register unsigned int srcp1
, srcp2
, resultp1
, resultp2
;
416 register boolean inexact
= FALSE
;
418 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
419 src_exponent
= Dbl_exponent(srcp1
) - DBL_BIAS
;
424 if (src_exponent
> DBL_FX_MAX_EXP
+ 1) {
425 if (Dbl_isone_sign(srcp1
)) {
426 resultp1
= resultp2
= 0;
428 resultp1
= resultp2
= 0xffffffff;
430 if (Is_invalidtrap_enabled()) {
431 return(INVALIDEXCEPTION
);
434 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
441 if (src_exponent
>= 0) {
444 * If negative, trap unimplemented.
446 if (Dbl_isone_sign(srcp1
)) {
447 resultp1
= resultp2
= 0;
448 if (Is_invalidtrap_enabled()) {
449 return(INVALIDEXCEPTION
);
452 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
455 Dbl_clear_signexponent_set_hidden(srcp1
);
456 Duint_from_dbl_mantissa(srcp1
,srcp2
,src_exponent
,resultp1
,
459 /* check for inexact */
460 if (Dbl_isinexact_to_unsigned(srcp1
,srcp2
,src_exponent
)) {
463 switch (Rounding_mode()) {
465 Duint_increment(resultp1
,resultp2
);
467 case ROUNDMINUS
: /* never negative */
470 if(Dbl_isone_roundbit(srcp1
,srcp2
,src_exponent
))
471 if(Dbl_isone_stickybit(srcp1
,srcp2
,src_exponent
) ||
472 Duint_isone_lowp2(resultp2
))
473 Duint_increment(resultp1
,resultp2
);
477 Duint_setzero(resultp1
,resultp2
);
479 /* check for inexact */
480 if (Dbl_isnotzero_exponentmantissa(srcp1
,srcp2
)) {
483 switch (Rounding_mode()) {
485 if (Dbl_iszero_sign(srcp1
)) {
486 Duint_increment(resultp1
,resultp2
);
490 if (Dbl_isone_sign(srcp1
)) {
491 resultp1
= resultp2
= 0;
492 if (Is_invalidtrap_enabled()) {
493 return(INVALIDEXCEPTION
);
500 if (src_exponent
== -1 &&
501 Dbl_isnotzero_mantissa(srcp1
,srcp2
))
502 if (Dbl_iszero_sign(srcp1
)) {
503 Duint_increment(resultp1
,resultp2
);
507 if (Is_invalidtrap_enabled()) {
508 return(INVALIDEXCEPTION
);
516 Duint_copytoptr(resultp1
,resultp2
,dstptr
);
518 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
519 else Set_inexactflag();