1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
5 * Floating-point emulation code
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();