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/fcnvfx.c $Revision: 1.1 $
15 * Single Floating-point to Single Fixed-point
16 * Single Floating-point to Double Fixed-point
17 * Double Floating-point to Single Fixed-point
18 * Double Floating-point to Double Fixed-point
20 * External Interfaces:
21 * dbl_to_dbl_fcnvfx(srcptr,nullptr,dstptr,status)
22 * dbl_to_sgl_fcnvfx(srcptr,nullptr,dstptr,status)
23 * sgl_to_dbl_fcnvfx(srcptr,nullptr,dstptr,status)
24 * sgl_to_sgl_fcnvfx(srcptr,nullptr,dstptr,status)
26 * Internal Interfaces:
29 * <<please update with a overview of the operation of this file>>
36 #include "sgl_float.h"
37 #include "dbl_float.h"
38 #include "cnv_float.h"
41 * Single Floating-point to Single Fixed-point
46 sgl_floating_point
*srcptr
,
47 sgl_floating_point
*nullptr,
49 sgl_floating_point
*status
)
51 register unsigned int src
, temp
;
52 register int src_exponent
, result
;
53 register boolean inexact
= FALSE
;
56 src_exponent
= Sgl_exponent(src
) - SGL_BIAS
;
61 if (src_exponent
> SGL_FX_MAX_EXP
) {
62 /* check for MININT */
63 if ((src_exponent
> SGL_FX_MAX_EXP
+ 1) ||
64 Sgl_isnotzero_mantissa(src
) || Sgl_iszero_sign(src
)) {
65 if (Sgl_iszero_sign(src
)) result
= 0x7fffffff;
66 else result
= 0x80000000;
68 if (Is_invalidtrap_enabled()) {
69 return(INVALIDEXCEPTION
);
79 if (src_exponent
>= 0) {
81 Sgl_clear_signexponent_set_hidden(temp
);
82 Int_from_sgl_mantissa(temp
,src_exponent
);
83 if (Sgl_isone_sign(src
)) result
= -Sgl_all(temp
);
84 else result
= Sgl_all(temp
);
86 /* check for inexact */
87 if (Sgl_isinexact_to_fix(src
,src_exponent
)) {
90 switch (Rounding_mode()) {
92 if (Sgl_iszero_sign(src
)) result
++;
95 if (Sgl_isone_sign(src
)) result
--;
98 if (Sgl_isone_roundbit(src
,src_exponent
)) {
99 if (Sgl_isone_stickybit(src
,src_exponent
)
100 || (Sgl_isone_lowmantissa(temp
)))
101 if (Sgl_iszero_sign(src
)) result
++;
110 /* check for inexact */
111 if (Sgl_isnotzero_exponentmantissa(src
)) {
114 switch (Rounding_mode()) {
116 if (Sgl_iszero_sign(src
)) result
++;
119 if (Sgl_isone_sign(src
)) result
--;
122 if (src_exponent
== -1)
123 if (Sgl_isnotzero_mantissa(src
))
124 if (Sgl_iszero_sign(src
)) result
++;
131 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
132 else Set_inexactflag();
138 * Single Floating-point to Double Fixed-point
143 sgl_floating_point
*srcptr
,
144 unsigned int *nullptr,
146 unsigned int *status
)
148 register int src_exponent
, resultp1
;
149 register unsigned int src
, temp
, resultp2
;
150 register boolean inexact
= FALSE
;
153 src_exponent
= Sgl_exponent(src
) - SGL_BIAS
;
158 if (src_exponent
> DBL_FX_MAX_EXP
) {
159 /* check for MININT */
160 if ((src_exponent
> DBL_FX_MAX_EXP
+ 1) ||
161 Sgl_isnotzero_mantissa(src
) || Sgl_iszero_sign(src
)) {
162 if (Sgl_iszero_sign(src
)) {
163 resultp1
= 0x7fffffff;
164 resultp2
= 0xffffffff;
167 resultp1
= 0x80000000;
170 if (Is_invalidtrap_enabled()) {
171 return(INVALIDEXCEPTION
);
174 Dint_copytoptr(resultp1
,resultp2
,dstptr
);
177 Dint_set_minint(resultp1
,resultp2
);
178 Dint_copytoptr(resultp1
,resultp2
,dstptr
);
184 if (src_exponent
>= 0) {
186 Sgl_clear_signexponent_set_hidden(temp
);
187 Dint_from_sgl_mantissa(temp
,src_exponent
,resultp1
,resultp2
);
188 if (Sgl_isone_sign(src
)) {
189 Dint_setone_sign(resultp1
,resultp2
);
192 /* check for inexact */
193 if (Sgl_isinexact_to_fix(src
,src_exponent
)) {
196 switch (Rounding_mode()) {
198 if (Sgl_iszero_sign(src
)) {
199 Dint_increment(resultp1
,resultp2
);
203 if (Sgl_isone_sign(src
)) {
204 Dint_decrement(resultp1
,resultp2
);
208 if (Sgl_isone_roundbit(src
,src_exponent
))
209 if (Sgl_isone_stickybit(src
,src_exponent
) ||
210 (Dint_isone_lowp2(resultp2
)))
211 if (Sgl_iszero_sign(src
)) {
212 Dint_increment(resultp1
,resultp2
);
215 Dint_decrement(resultp1
,resultp2
);
221 Dint_setzero(resultp1
,resultp2
);
223 /* check for inexact */
224 if (Sgl_isnotzero_exponentmantissa(src
)) {
227 switch (Rounding_mode()) {
229 if (Sgl_iszero_sign(src
)) {
230 Dint_increment(resultp1
,resultp2
);
234 if (Sgl_isone_sign(src
)) {
235 Dint_decrement(resultp1
,resultp2
);
239 if (src_exponent
== -1)
240 if (Sgl_isnotzero_mantissa(src
))
241 if (Sgl_iszero_sign(src
)) {
242 Dint_increment(resultp1
,resultp2
);
245 Dint_decrement(resultp1
,resultp2
);
250 Dint_copytoptr(resultp1
,resultp2
,dstptr
);
252 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
253 else Set_inexactflag();
259 * Double Floating-point to Single Fixed-point
264 dbl_floating_point
*srcptr
,
265 unsigned int *nullptr,
267 unsigned int *status
)
269 register unsigned int srcp1
,srcp2
, tempp1
,tempp2
;
270 register int src_exponent
, result
;
271 register boolean inexact
= FALSE
;
273 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
274 src_exponent
= Dbl_exponent(srcp1
) - DBL_BIAS
;
279 if (src_exponent
> SGL_FX_MAX_EXP
) {
280 /* check for MININT */
281 if (Dbl_isoverflow_to_int(src_exponent
,srcp1
,srcp2
)) {
282 if (Dbl_iszero_sign(srcp1
)) result
= 0x7fffffff;
283 else result
= 0x80000000;
285 if (Is_invalidtrap_enabled()) {
286 return(INVALIDEXCEPTION
);
296 if (src_exponent
>= 0) {
299 Dbl_clear_signexponent_set_hidden(tempp1
);
300 Int_from_dbl_mantissa(tempp1
,tempp2
,src_exponent
);
301 if (Dbl_isone_sign(srcp1
) && (src_exponent
<= SGL_FX_MAX_EXP
))
302 result
= -Dbl_allp1(tempp1
);
303 else result
= Dbl_allp1(tempp1
);
305 /* check for inexact */
306 if (Dbl_isinexact_to_fix(srcp1
,srcp2
,src_exponent
)) {
309 switch (Rounding_mode()) {
311 if (Dbl_iszero_sign(srcp1
)) result
++;
314 if (Dbl_isone_sign(srcp1
)) result
--;
317 if (Dbl_isone_roundbit(srcp1
,srcp2
,src_exponent
))
318 if (Dbl_isone_stickybit(srcp1
,srcp2
,src_exponent
) ||
319 (Dbl_isone_lowmantissap1(tempp1
)))
320 if (Dbl_iszero_sign(srcp1
)) result
++;
323 /* check for overflow */
324 if ((Dbl_iszero_sign(srcp1
) && result
< 0) ||
325 (Dbl_isone_sign(srcp1
) && result
> 0)) {
327 if (Dbl_iszero_sign(srcp1
)) result
= 0x7fffffff;
328 else result
= 0x80000000;
330 if (Is_invalidtrap_enabled()) {
331 return(INVALIDEXCEPTION
);
342 /* check for inexact */
343 if (Dbl_isnotzero_exponentmantissa(srcp1
,srcp2
)) {
346 switch (Rounding_mode()) {
348 if (Dbl_iszero_sign(srcp1
)) result
++;
351 if (Dbl_isone_sign(srcp1
)) result
--;
354 if (src_exponent
== -1)
355 if (Dbl_isnotzero_mantissa(srcp1
,srcp2
))
356 if (Dbl_iszero_sign(srcp1
)) result
++;
363 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
364 else Set_inexactflag();
370 * Double Floating-point to Double Fixed-point
375 dbl_floating_point
*srcptr
,
376 unsigned int *nullptr,
378 unsigned int *status
)
380 register int src_exponent
, resultp1
;
381 register unsigned int srcp1
, srcp2
, tempp1
, tempp2
, resultp2
;
382 register boolean inexact
= FALSE
;
384 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
385 src_exponent
= Dbl_exponent(srcp1
) - DBL_BIAS
;
390 if (src_exponent
> DBL_FX_MAX_EXP
) {
391 /* check for MININT */
392 if ((src_exponent
> DBL_FX_MAX_EXP
+ 1) ||
393 Dbl_isnotzero_mantissa(srcp1
,srcp2
) || Dbl_iszero_sign(srcp1
)) {
394 if (Dbl_iszero_sign(srcp1
)) {
395 resultp1
= 0x7fffffff;
396 resultp2
= 0xffffffff;
399 resultp1
= 0x80000000;
402 if (Is_invalidtrap_enabled()) {
403 return(INVALIDEXCEPTION
);
406 Dint_copytoptr(resultp1
,resultp2
,dstptr
);
414 if (src_exponent
>= 0) {
417 Dbl_clear_signexponent_set_hidden(tempp1
);
418 Dint_from_dbl_mantissa(tempp1
,tempp2
,src_exponent
,resultp1
,
420 if (Dbl_isone_sign(srcp1
)) {
421 Dint_setone_sign(resultp1
,resultp2
);
424 /* check for inexact */
425 if (Dbl_isinexact_to_fix(srcp1
,srcp2
,src_exponent
)) {
428 switch (Rounding_mode()) {
430 if (Dbl_iszero_sign(srcp1
)) {
431 Dint_increment(resultp1
,resultp2
);
435 if (Dbl_isone_sign(srcp1
)) {
436 Dint_decrement(resultp1
,resultp2
);
440 if (Dbl_isone_roundbit(srcp1
,srcp2
,src_exponent
))
441 if (Dbl_isone_stickybit(srcp1
,srcp2
,src_exponent
) ||
442 (Dint_isone_lowp2(resultp2
)))
443 if (Dbl_iszero_sign(srcp1
)) {
444 Dint_increment(resultp1
,resultp2
);
447 Dint_decrement(resultp1
,resultp2
);
453 Dint_setzero(resultp1
,resultp2
);
455 /* check for inexact */
456 if (Dbl_isnotzero_exponentmantissa(srcp1
,srcp2
)) {
459 switch (Rounding_mode()) {
461 if (Dbl_iszero_sign(srcp1
)) {
462 Dint_increment(resultp1
,resultp2
);
466 if (Dbl_isone_sign(srcp1
)) {
467 Dint_decrement(resultp1
,resultp2
);
471 if (src_exponent
== -1)
472 if (Dbl_isnotzero_mantissa(srcp1
,srcp2
))
473 if (Dbl_iszero_sign(srcp1
)) {
474 Dint_increment(resultp1
,resultp2
);
477 Dint_decrement(resultp1
,resultp2
);
482 Dint_copytoptr(resultp1
,resultp2
,dstptr
);
484 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
485 else Set_inexactflag();