162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Linux/PA-RISC Project (http://www.parisc-linux.org/)
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Floating-point emulation code
662306a36Sopenharmony_ci *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci/*
962306a36Sopenharmony_ci * BEGIN_DESC
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci *  File:
1262306a36Sopenharmony_ci *	@(#)	pa/spmath/fcnvfx.c		$Revision: 1.1 $
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci *  Purpose:
1562306a36Sopenharmony_ci *	Single Floating-point to Single Fixed-point
1662306a36Sopenharmony_ci *	Single Floating-point to Double Fixed-point
1762306a36Sopenharmony_ci *	Double Floating-point to Single Fixed-point
1862306a36Sopenharmony_ci *	Double Floating-point to Double Fixed-point
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci *  External Interfaces:
2162306a36Sopenharmony_ci *	dbl_to_dbl_fcnvfx(srcptr,nullptr,dstptr,status)
2262306a36Sopenharmony_ci *	dbl_to_sgl_fcnvfx(srcptr,nullptr,dstptr,status)
2362306a36Sopenharmony_ci *	sgl_to_dbl_fcnvfx(srcptr,nullptr,dstptr,status)
2462306a36Sopenharmony_ci *	sgl_to_sgl_fcnvfx(srcptr,nullptr,dstptr,status)
2562306a36Sopenharmony_ci *
2662306a36Sopenharmony_ci *  Internal Interfaces:
2762306a36Sopenharmony_ci *
2862306a36Sopenharmony_ci *  Theory:
2962306a36Sopenharmony_ci *	<<please update with a overview of the operation of this file>>
3062306a36Sopenharmony_ci *
3162306a36Sopenharmony_ci * END_DESC
3262306a36Sopenharmony_ci*/
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#include "float.h"
3662306a36Sopenharmony_ci#include "sgl_float.h"
3762306a36Sopenharmony_ci#include "dbl_float.h"
3862306a36Sopenharmony_ci#include "cnv_float.h"
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/*
4162306a36Sopenharmony_ci *  Single Floating-point to Single Fixed-point
4262306a36Sopenharmony_ci */
4362306a36Sopenharmony_ci/*ARGSUSED*/
4462306a36Sopenharmony_ciint
4562306a36Sopenharmony_cisgl_to_sgl_fcnvfx(
4662306a36Sopenharmony_ci		    sgl_floating_point *srcptr,
4762306a36Sopenharmony_ci		    sgl_floating_point *nullptr,
4862306a36Sopenharmony_ci		    int *dstptr,
4962306a36Sopenharmony_ci		    sgl_floating_point *status)
5062306a36Sopenharmony_ci{
5162306a36Sopenharmony_ci	register unsigned int src, temp;
5262306a36Sopenharmony_ci	register int src_exponent, result;
5362306a36Sopenharmony_ci	register boolean inexact = FALSE;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	src = *srcptr;
5662306a36Sopenharmony_ci	src_exponent = Sgl_exponent(src) - SGL_BIAS;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	/*
5962306a36Sopenharmony_ci	 * Test for overflow
6062306a36Sopenharmony_ci	 */
6162306a36Sopenharmony_ci	if (src_exponent > SGL_FX_MAX_EXP) {
6262306a36Sopenharmony_ci		/* check for MININT */
6362306a36Sopenharmony_ci		if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
6462306a36Sopenharmony_ci		Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
6562306a36Sopenharmony_ci                        if (Sgl_iszero_sign(src)) result = 0x7fffffff;
6662306a36Sopenharmony_ci                        else result = 0x80000000;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	                if (Is_invalidtrap_enabled()) {
6962306a36Sopenharmony_ci                            return(INVALIDEXCEPTION);
7062306a36Sopenharmony_ci                        }
7162306a36Sopenharmony_ci                        Set_invalidflag();
7262306a36Sopenharmony_ci			*dstptr = result;
7362306a36Sopenharmony_ci			return(NOEXCEPTION);
7462306a36Sopenharmony_ci       		}
7562306a36Sopenharmony_ci	}
7662306a36Sopenharmony_ci	/*
7762306a36Sopenharmony_ci	 * Generate result
7862306a36Sopenharmony_ci	 */
7962306a36Sopenharmony_ci	if (src_exponent >= 0) {
8062306a36Sopenharmony_ci		temp = src;
8162306a36Sopenharmony_ci		Sgl_clear_signexponent_set_hidden(temp);
8262306a36Sopenharmony_ci		Int_from_sgl_mantissa(temp,src_exponent);
8362306a36Sopenharmony_ci		if (Sgl_isone_sign(src))  result = -Sgl_all(temp);
8462306a36Sopenharmony_ci		else result = Sgl_all(temp);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci		/* check for inexact */
8762306a36Sopenharmony_ci		if (Sgl_isinexact_to_fix(src,src_exponent)) {
8862306a36Sopenharmony_ci			inexact = TRUE;
8962306a36Sopenharmony_ci			/*  round result  */
9062306a36Sopenharmony_ci			switch (Rounding_mode()) {
9162306a36Sopenharmony_ci			case ROUNDPLUS:
9262306a36Sopenharmony_ci			     if (Sgl_iszero_sign(src)) result++;
9362306a36Sopenharmony_ci			     break;
9462306a36Sopenharmony_ci			case ROUNDMINUS:
9562306a36Sopenharmony_ci			     if (Sgl_isone_sign(src)) result--;
9662306a36Sopenharmony_ci			     break;
9762306a36Sopenharmony_ci			case ROUNDNEAREST:
9862306a36Sopenharmony_ci			     if (Sgl_isone_roundbit(src,src_exponent)) {
9962306a36Sopenharmony_ci			        if (Sgl_isone_stickybit(src,src_exponent)
10062306a36Sopenharmony_ci				|| (Sgl_isone_lowmantissa(temp)))
10162306a36Sopenharmony_ci			           if (Sgl_iszero_sign(src)) result++;
10262306a36Sopenharmony_ci			           else result--;
10362306a36Sopenharmony_ci			     }
10462306a36Sopenharmony_ci			}
10562306a36Sopenharmony_ci		}
10662306a36Sopenharmony_ci	}
10762306a36Sopenharmony_ci	else {
10862306a36Sopenharmony_ci		result = 0;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci		/* check for inexact */
11162306a36Sopenharmony_ci		if (Sgl_isnotzero_exponentmantissa(src)) {
11262306a36Sopenharmony_ci			inexact = TRUE;
11362306a36Sopenharmony_ci			/*  round result  */
11462306a36Sopenharmony_ci			switch (Rounding_mode()) {
11562306a36Sopenharmony_ci			case ROUNDPLUS:
11662306a36Sopenharmony_ci			     if (Sgl_iszero_sign(src)) result++;
11762306a36Sopenharmony_ci			     break;
11862306a36Sopenharmony_ci			case ROUNDMINUS:
11962306a36Sopenharmony_ci			     if (Sgl_isone_sign(src)) result--;
12062306a36Sopenharmony_ci			     break;
12162306a36Sopenharmony_ci			case ROUNDNEAREST:
12262306a36Sopenharmony_ci			     if (src_exponent == -1)
12362306a36Sopenharmony_ci			        if (Sgl_isnotzero_mantissa(src))
12462306a36Sopenharmony_ci			           if (Sgl_iszero_sign(src)) result++;
12562306a36Sopenharmony_ci			           else result--;
12662306a36Sopenharmony_ci			}
12762306a36Sopenharmony_ci		}
12862306a36Sopenharmony_ci	}
12962306a36Sopenharmony_ci	*dstptr = result;
13062306a36Sopenharmony_ci	if (inexact) {
13162306a36Sopenharmony_ci		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
13262306a36Sopenharmony_ci		else Set_inexactflag();
13362306a36Sopenharmony_ci	}
13462306a36Sopenharmony_ci	return(NOEXCEPTION);
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci/*
13862306a36Sopenharmony_ci *  Single Floating-point to Double Fixed-point
13962306a36Sopenharmony_ci */
14062306a36Sopenharmony_ci/*ARGSUSED*/
14162306a36Sopenharmony_ciint
14262306a36Sopenharmony_cisgl_to_dbl_fcnvfx(
14362306a36Sopenharmony_ci		sgl_floating_point *srcptr,
14462306a36Sopenharmony_ci		unsigned int *nullptr,
14562306a36Sopenharmony_ci		dbl_integer *dstptr,
14662306a36Sopenharmony_ci		unsigned int *status)
14762306a36Sopenharmony_ci{
14862306a36Sopenharmony_ci	register int src_exponent, resultp1;
14962306a36Sopenharmony_ci	register unsigned int src, temp, resultp2;
15062306a36Sopenharmony_ci	register boolean inexact = FALSE;
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	src = *srcptr;
15362306a36Sopenharmony_ci	src_exponent = Sgl_exponent(src) - SGL_BIAS;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	/*
15662306a36Sopenharmony_ci	 * Test for overflow
15762306a36Sopenharmony_ci	 */
15862306a36Sopenharmony_ci	if (src_exponent > DBL_FX_MAX_EXP) {
15962306a36Sopenharmony_ci		/* check for MININT */
16062306a36Sopenharmony_ci		if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
16162306a36Sopenharmony_ci		Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
16262306a36Sopenharmony_ci                        if (Sgl_iszero_sign(src)) {
16362306a36Sopenharmony_ci                              resultp1 = 0x7fffffff;
16462306a36Sopenharmony_ci			      resultp2 = 0xffffffff;
16562306a36Sopenharmony_ci			}
16662306a36Sopenharmony_ci                        else {
16762306a36Sopenharmony_ci			    resultp1 = 0x80000000;
16862306a36Sopenharmony_ci			    resultp2 = 0;
16962306a36Sopenharmony_ci			}
17062306a36Sopenharmony_ci	                if (Is_invalidtrap_enabled()) {
17162306a36Sopenharmony_ci                            return(INVALIDEXCEPTION);
17262306a36Sopenharmony_ci                        }
17362306a36Sopenharmony_ci                        Set_invalidflag();
17462306a36Sopenharmony_ci    		        Dint_copytoptr(resultp1,resultp2,dstptr);
17562306a36Sopenharmony_ci			return(NOEXCEPTION);
17662306a36Sopenharmony_ci		}
17762306a36Sopenharmony_ci		Dint_set_minint(resultp1,resultp2);
17862306a36Sopenharmony_ci		Dint_copytoptr(resultp1,resultp2,dstptr);
17962306a36Sopenharmony_ci		return(NOEXCEPTION);
18062306a36Sopenharmony_ci	}
18162306a36Sopenharmony_ci	/*
18262306a36Sopenharmony_ci	 * Generate result
18362306a36Sopenharmony_ci	 */
18462306a36Sopenharmony_ci	if (src_exponent >= 0) {
18562306a36Sopenharmony_ci		temp = src;
18662306a36Sopenharmony_ci		Sgl_clear_signexponent_set_hidden(temp);
18762306a36Sopenharmony_ci		Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
18862306a36Sopenharmony_ci		if (Sgl_isone_sign(src)) {
18962306a36Sopenharmony_ci			Dint_setone_sign(resultp1,resultp2);
19062306a36Sopenharmony_ci		}
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci		/* check for inexact */
19362306a36Sopenharmony_ci		if (Sgl_isinexact_to_fix(src,src_exponent)) {
19462306a36Sopenharmony_ci			inexact = TRUE;
19562306a36Sopenharmony_ci                        /*  round result  */
19662306a36Sopenharmony_ci                        switch (Rounding_mode()) {
19762306a36Sopenharmony_ci                        case ROUNDPLUS:
19862306a36Sopenharmony_ci                             if (Sgl_iszero_sign(src)) {
19962306a36Sopenharmony_ci				Dint_increment(resultp1,resultp2);
20062306a36Sopenharmony_ci			     }
20162306a36Sopenharmony_ci                             break;
20262306a36Sopenharmony_ci                        case ROUNDMINUS:
20362306a36Sopenharmony_ci                             if (Sgl_isone_sign(src)) {
20462306a36Sopenharmony_ci				Dint_decrement(resultp1,resultp2);
20562306a36Sopenharmony_ci			     }
20662306a36Sopenharmony_ci                             break;
20762306a36Sopenharmony_ci                        case ROUNDNEAREST:
20862306a36Sopenharmony_ci                             if (Sgl_isone_roundbit(src,src_exponent))
20962306a36Sopenharmony_ci                                if (Sgl_isone_stickybit(src,src_exponent) ||
21062306a36Sopenharmony_ci				(Dint_isone_lowp2(resultp2)))
21162306a36Sopenharmony_ci				   if (Sgl_iszero_sign(src)) {
21262306a36Sopenharmony_ci				      Dint_increment(resultp1,resultp2);
21362306a36Sopenharmony_ci				   }
21462306a36Sopenharmony_ci                                   else {
21562306a36Sopenharmony_ci				      Dint_decrement(resultp1,resultp2);
21662306a36Sopenharmony_ci				   }
21762306a36Sopenharmony_ci                        }
21862306a36Sopenharmony_ci                }
21962306a36Sopenharmony_ci        }
22062306a36Sopenharmony_ci	else {
22162306a36Sopenharmony_ci		Dint_setzero(resultp1,resultp2);
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci		/* check for inexact */
22462306a36Sopenharmony_ci		if (Sgl_isnotzero_exponentmantissa(src)) {
22562306a36Sopenharmony_ci			inexact = TRUE;
22662306a36Sopenharmony_ci                        /*  round result  */
22762306a36Sopenharmony_ci                        switch (Rounding_mode()) {
22862306a36Sopenharmony_ci                        case ROUNDPLUS:
22962306a36Sopenharmony_ci                             if (Sgl_iszero_sign(src)) {
23062306a36Sopenharmony_ci				Dint_increment(resultp1,resultp2);
23162306a36Sopenharmony_ci			     }
23262306a36Sopenharmony_ci                             break;
23362306a36Sopenharmony_ci                        case ROUNDMINUS:
23462306a36Sopenharmony_ci                             if (Sgl_isone_sign(src)) {
23562306a36Sopenharmony_ci				Dint_decrement(resultp1,resultp2);
23662306a36Sopenharmony_ci			     }
23762306a36Sopenharmony_ci                             break;
23862306a36Sopenharmony_ci                        case ROUNDNEAREST:
23962306a36Sopenharmony_ci                             if (src_exponent == -1)
24062306a36Sopenharmony_ci                                if (Sgl_isnotzero_mantissa(src))
24162306a36Sopenharmony_ci                                   if (Sgl_iszero_sign(src)) {
24262306a36Sopenharmony_ci				      Dint_increment(resultp1,resultp2);
24362306a36Sopenharmony_ci				   }
24462306a36Sopenharmony_ci                                   else {
24562306a36Sopenharmony_ci				      Dint_decrement(resultp1,resultp2);
24662306a36Sopenharmony_ci				   }
24762306a36Sopenharmony_ci			}
24862306a36Sopenharmony_ci		}
24962306a36Sopenharmony_ci	}
25062306a36Sopenharmony_ci	Dint_copytoptr(resultp1,resultp2,dstptr);
25162306a36Sopenharmony_ci	if (inexact) {
25262306a36Sopenharmony_ci		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
25362306a36Sopenharmony_ci		else Set_inexactflag();
25462306a36Sopenharmony_ci	}
25562306a36Sopenharmony_ci	return(NOEXCEPTION);
25662306a36Sopenharmony_ci}
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci/*
25962306a36Sopenharmony_ci *  Double Floating-point to Single Fixed-point
26062306a36Sopenharmony_ci */
26162306a36Sopenharmony_ci/*ARGSUSED*/
26262306a36Sopenharmony_ciint
26362306a36Sopenharmony_cidbl_to_sgl_fcnvfx(
26462306a36Sopenharmony_ci		    dbl_floating_point *srcptr,
26562306a36Sopenharmony_ci		    unsigned int *nullptr,
26662306a36Sopenharmony_ci		    int *dstptr,
26762306a36Sopenharmony_ci		    unsigned int *status)
26862306a36Sopenharmony_ci{
26962306a36Sopenharmony_ci	register unsigned int srcp1,srcp2, tempp1,tempp2;
27062306a36Sopenharmony_ci	register int src_exponent, result;
27162306a36Sopenharmony_ci	register boolean inexact = FALSE;
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	Dbl_copyfromptr(srcptr,srcp1,srcp2);
27462306a36Sopenharmony_ci	src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	/*
27762306a36Sopenharmony_ci	 * Test for overflow
27862306a36Sopenharmony_ci	 */
27962306a36Sopenharmony_ci	if (src_exponent > SGL_FX_MAX_EXP) {
28062306a36Sopenharmony_ci		/* check for MININT */
28162306a36Sopenharmony_ci		if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
28262306a36Sopenharmony_ci                        if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
28362306a36Sopenharmony_ci                        else result = 0x80000000;
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci	                if (Is_invalidtrap_enabled()) {
28662306a36Sopenharmony_ci                            return(INVALIDEXCEPTION);
28762306a36Sopenharmony_ci                        }
28862306a36Sopenharmony_ci                        Set_invalidflag();
28962306a36Sopenharmony_ci			*dstptr = result;
29062306a36Sopenharmony_ci			return(NOEXCEPTION);
29162306a36Sopenharmony_ci		}
29262306a36Sopenharmony_ci	}
29362306a36Sopenharmony_ci	/*
29462306a36Sopenharmony_ci	 * Generate result
29562306a36Sopenharmony_ci	 */
29662306a36Sopenharmony_ci	if (src_exponent >= 0) {
29762306a36Sopenharmony_ci		tempp1 = srcp1;
29862306a36Sopenharmony_ci		tempp2 = srcp2;
29962306a36Sopenharmony_ci		Dbl_clear_signexponent_set_hidden(tempp1);
30062306a36Sopenharmony_ci		Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
30162306a36Sopenharmony_ci		if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
30262306a36Sopenharmony_ci			result = -Dbl_allp1(tempp1);
30362306a36Sopenharmony_ci		else result = Dbl_allp1(tempp1);
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci		/* check for inexact */
30662306a36Sopenharmony_ci		if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
30762306a36Sopenharmony_ci                        inexact = TRUE;
30862306a36Sopenharmony_ci                        /*  round result  */
30962306a36Sopenharmony_ci                        switch (Rounding_mode()) {
31062306a36Sopenharmony_ci                        case ROUNDPLUS:
31162306a36Sopenharmony_ci                             if (Dbl_iszero_sign(srcp1)) result++;
31262306a36Sopenharmony_ci                             break;
31362306a36Sopenharmony_ci                        case ROUNDMINUS:
31462306a36Sopenharmony_ci                             if (Dbl_isone_sign(srcp1)) result--;
31562306a36Sopenharmony_ci                             break;
31662306a36Sopenharmony_ci                        case ROUNDNEAREST:
31762306a36Sopenharmony_ci                             if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
31862306a36Sopenharmony_ci                                if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
31962306a36Sopenharmony_ci				(Dbl_isone_lowmantissap1(tempp1)))
32062306a36Sopenharmony_ci                                   if (Dbl_iszero_sign(srcp1)) result++;
32162306a36Sopenharmony_ci                                   else result--;
32262306a36Sopenharmony_ci                        }
32362306a36Sopenharmony_ci			/* check for overflow */
32462306a36Sopenharmony_ci			if ((Dbl_iszero_sign(srcp1) && result < 0) ||
32562306a36Sopenharmony_ci			    (Dbl_isone_sign(srcp1) && result > 0)) {
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci                          if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
32862306a36Sopenharmony_ci                          else result = 0x80000000;
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci	                  if (Is_invalidtrap_enabled()) {
33162306a36Sopenharmony_ci                            return(INVALIDEXCEPTION);
33262306a36Sopenharmony_ci                          }
33362306a36Sopenharmony_ci                          Set_invalidflag();
33462306a36Sopenharmony_ci			  *dstptr = result;
33562306a36Sopenharmony_ci			  return(NOEXCEPTION);
33662306a36Sopenharmony_ci			}
33762306a36Sopenharmony_ci                }
33862306a36Sopenharmony_ci	}
33962306a36Sopenharmony_ci	else {
34062306a36Sopenharmony_ci		result = 0;
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci		/* check for inexact */
34362306a36Sopenharmony_ci		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
34462306a36Sopenharmony_ci                        inexact = TRUE;
34562306a36Sopenharmony_ci                        /*  round result  */
34662306a36Sopenharmony_ci                        switch (Rounding_mode()) {
34762306a36Sopenharmony_ci                        case ROUNDPLUS:
34862306a36Sopenharmony_ci                             if (Dbl_iszero_sign(srcp1)) result++;
34962306a36Sopenharmony_ci                             break;
35062306a36Sopenharmony_ci                        case ROUNDMINUS:
35162306a36Sopenharmony_ci                             if (Dbl_isone_sign(srcp1)) result--;
35262306a36Sopenharmony_ci                             break;
35362306a36Sopenharmony_ci                        case ROUNDNEAREST:
35462306a36Sopenharmony_ci                             if (src_exponent == -1)
35562306a36Sopenharmony_ci                                if (Dbl_isnotzero_mantissa(srcp1,srcp2))
35662306a36Sopenharmony_ci                                   if (Dbl_iszero_sign(srcp1)) result++;
35762306a36Sopenharmony_ci                                   else result--;
35862306a36Sopenharmony_ci			}
35962306a36Sopenharmony_ci                }
36062306a36Sopenharmony_ci	}
36162306a36Sopenharmony_ci	*dstptr = result;
36262306a36Sopenharmony_ci        if (inexact) {
36362306a36Sopenharmony_ci                if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
36462306a36Sopenharmony_ci		else Set_inexactflag();
36562306a36Sopenharmony_ci        }
36662306a36Sopenharmony_ci	return(NOEXCEPTION);
36762306a36Sopenharmony_ci}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci/*
37062306a36Sopenharmony_ci *  Double Floating-point to Double Fixed-point
37162306a36Sopenharmony_ci */
37262306a36Sopenharmony_ci/*ARGSUSED*/
37362306a36Sopenharmony_ciint
37462306a36Sopenharmony_cidbl_to_dbl_fcnvfx(
37562306a36Sopenharmony_ci		    dbl_floating_point *srcptr,
37662306a36Sopenharmony_ci		    unsigned int *nullptr,
37762306a36Sopenharmony_ci		    dbl_integer *dstptr,
37862306a36Sopenharmony_ci		    unsigned int *status)
37962306a36Sopenharmony_ci{
38062306a36Sopenharmony_ci	register int src_exponent, resultp1;
38162306a36Sopenharmony_ci	register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
38262306a36Sopenharmony_ci	register boolean inexact = FALSE;
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	Dbl_copyfromptr(srcptr,srcp1,srcp2);
38562306a36Sopenharmony_ci	src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	/*
38862306a36Sopenharmony_ci	 * Test for overflow
38962306a36Sopenharmony_ci	 */
39062306a36Sopenharmony_ci	if (src_exponent > DBL_FX_MAX_EXP) {
39162306a36Sopenharmony_ci		/* check for MININT */
39262306a36Sopenharmony_ci		if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
39362306a36Sopenharmony_ci		Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
39462306a36Sopenharmony_ci                        if (Dbl_iszero_sign(srcp1)) {
39562306a36Sopenharmony_ci                              resultp1 = 0x7fffffff;
39662306a36Sopenharmony_ci			      resultp2 = 0xffffffff;
39762306a36Sopenharmony_ci			}
39862306a36Sopenharmony_ci                        else {
39962306a36Sopenharmony_ci			    resultp1 = 0x80000000;
40062306a36Sopenharmony_ci			    resultp2 = 0;
40162306a36Sopenharmony_ci			}
40262306a36Sopenharmony_ci	                if (Is_invalidtrap_enabled()) {
40362306a36Sopenharmony_ci                            return(INVALIDEXCEPTION);
40462306a36Sopenharmony_ci                        }
40562306a36Sopenharmony_ci                        Set_invalidflag();
40662306a36Sopenharmony_ci    		        Dint_copytoptr(resultp1,resultp2,dstptr);
40762306a36Sopenharmony_ci			return(NOEXCEPTION);
40862306a36Sopenharmony_ci		}
40962306a36Sopenharmony_ci	}
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	/*
41262306a36Sopenharmony_ci	 * Generate result
41362306a36Sopenharmony_ci	 */
41462306a36Sopenharmony_ci	if (src_exponent >= 0) {
41562306a36Sopenharmony_ci		tempp1 = srcp1;
41662306a36Sopenharmony_ci		tempp2 = srcp2;
41762306a36Sopenharmony_ci		Dbl_clear_signexponent_set_hidden(tempp1);
41862306a36Sopenharmony_ci		Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,resultp1,
41962306a36Sopenharmony_ci		resultp2);
42062306a36Sopenharmony_ci		if (Dbl_isone_sign(srcp1)) {
42162306a36Sopenharmony_ci			Dint_setone_sign(resultp1,resultp2);
42262306a36Sopenharmony_ci		}
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci		/* check for inexact */
42562306a36Sopenharmony_ci		if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
42662306a36Sopenharmony_ci                        inexact = TRUE;
42762306a36Sopenharmony_ci                        /*  round result  */
42862306a36Sopenharmony_ci                        switch (Rounding_mode()) {
42962306a36Sopenharmony_ci                        case ROUNDPLUS:
43062306a36Sopenharmony_ci                             if (Dbl_iszero_sign(srcp1)) {
43162306a36Sopenharmony_ci				Dint_increment(resultp1,resultp2);
43262306a36Sopenharmony_ci			     }
43362306a36Sopenharmony_ci                             break;
43462306a36Sopenharmony_ci                        case ROUNDMINUS:
43562306a36Sopenharmony_ci                             if (Dbl_isone_sign(srcp1)) {
43662306a36Sopenharmony_ci				Dint_decrement(resultp1,resultp2);
43762306a36Sopenharmony_ci			     }
43862306a36Sopenharmony_ci                             break;
43962306a36Sopenharmony_ci                        case ROUNDNEAREST:
44062306a36Sopenharmony_ci                             if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
44162306a36Sopenharmony_ci                                if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
44262306a36Sopenharmony_ci				(Dint_isone_lowp2(resultp2)))
44362306a36Sopenharmony_ci                                   if (Dbl_iszero_sign(srcp1)) {
44462306a36Sopenharmony_ci				      Dint_increment(resultp1,resultp2);
44562306a36Sopenharmony_ci				   }
44662306a36Sopenharmony_ci                                   else {
44762306a36Sopenharmony_ci				      Dint_decrement(resultp1,resultp2);
44862306a36Sopenharmony_ci				   }
44962306a36Sopenharmony_ci                        }
45062306a36Sopenharmony_ci                }
45162306a36Sopenharmony_ci	}
45262306a36Sopenharmony_ci	else {
45362306a36Sopenharmony_ci		Dint_setzero(resultp1,resultp2);
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci		/* check for inexact */
45662306a36Sopenharmony_ci		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
45762306a36Sopenharmony_ci                        inexact = TRUE;
45862306a36Sopenharmony_ci                        /*  round result  */
45962306a36Sopenharmony_ci                        switch (Rounding_mode()) {
46062306a36Sopenharmony_ci                        case ROUNDPLUS:
46162306a36Sopenharmony_ci                             if (Dbl_iszero_sign(srcp1)) {
46262306a36Sopenharmony_ci				Dint_increment(resultp1,resultp2);
46362306a36Sopenharmony_ci			     }
46462306a36Sopenharmony_ci                             break;
46562306a36Sopenharmony_ci                        case ROUNDMINUS:
46662306a36Sopenharmony_ci                             if (Dbl_isone_sign(srcp1)) {
46762306a36Sopenharmony_ci				Dint_decrement(resultp1,resultp2);
46862306a36Sopenharmony_ci			     }
46962306a36Sopenharmony_ci                             break;
47062306a36Sopenharmony_ci                        case ROUNDNEAREST:
47162306a36Sopenharmony_ci                             if (src_exponent == -1)
47262306a36Sopenharmony_ci                                if (Dbl_isnotzero_mantissa(srcp1,srcp2))
47362306a36Sopenharmony_ci                                   if (Dbl_iszero_sign(srcp1)) {
47462306a36Sopenharmony_ci				      Dint_increment(resultp1,resultp2);
47562306a36Sopenharmony_ci				   }
47662306a36Sopenharmony_ci                                   else {
47762306a36Sopenharmony_ci				      Dint_decrement(resultp1,resultp2);
47862306a36Sopenharmony_ci				   }
47962306a36Sopenharmony_ci			}
48062306a36Sopenharmony_ci                }
48162306a36Sopenharmony_ci	}
48262306a36Sopenharmony_ci	Dint_copytoptr(resultp1,resultp2,dstptr);
48362306a36Sopenharmony_ci        if (inexact) {
48462306a36Sopenharmony_ci                if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
48562306a36Sopenharmony_ci        	else Set_inexactflag();
48662306a36Sopenharmony_ci        }
48762306a36Sopenharmony_ci	return(NOEXCEPTION);
48862306a36Sopenharmony_ci}
489