xref: /openbmc/linux/arch/parisc/math-emu/fcnvfu.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*660662f8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Floating-point emulation code
61da177e4SLinus Torvalds  *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
71da177e4SLinus Torvalds  */
81da177e4SLinus Torvalds /*
91da177e4SLinus Torvalds  * BEGIN_DESC
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  *  File:
121da177e4SLinus Torvalds  *	@(#)	pa/spmath/fcnvfu.c		$Revision: 1.1 $
131da177e4SLinus Torvalds  *
141da177e4SLinus Torvalds  *  Purpose:
151da177e4SLinus Torvalds  *	Floating-point to Unsigned Fixed-point Converts
161da177e4SLinus Torvalds  *
171da177e4SLinus Torvalds  *  External Interfaces:
181da177e4SLinus Torvalds  *	dbl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
191da177e4SLinus Torvalds  *	dbl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
201da177e4SLinus Torvalds  *	sgl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
211da177e4SLinus Torvalds  *	sgl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
221da177e4SLinus Torvalds  *
231da177e4SLinus Torvalds  *  Internal Interfaces:
241da177e4SLinus Torvalds  *
251da177e4SLinus Torvalds  *  Theory:
261da177e4SLinus Torvalds  *	<<please update with a overview of the operation of this file>>
271da177e4SLinus Torvalds  *
281da177e4SLinus Torvalds  * END_DESC
291da177e4SLinus Torvalds */
301da177e4SLinus Torvalds 
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds #include "float.h"
331da177e4SLinus Torvalds #include "sgl_float.h"
341da177e4SLinus Torvalds #include "dbl_float.h"
351da177e4SLinus Torvalds #include "cnv_float.h"
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds /************************************************************************
381da177e4SLinus Torvalds  *  Floating-point to Unsigned Fixed-point Converts			*
391da177e4SLinus Torvalds  ************************************************************************/
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds /*
421da177e4SLinus Torvalds  *  Single Floating-point to Single Unsigned Fixed
431da177e4SLinus Torvalds  */
441da177e4SLinus Torvalds /*ARGSUSED*/
451da177e4SLinus Torvalds int
sgl_to_sgl_fcnvfu(sgl_floating_point * srcptr,unsigned int * nullptr,unsigned int * dstptr,unsigned int * status)461da177e4SLinus Torvalds sgl_to_sgl_fcnvfu(
471da177e4SLinus Torvalds 			sgl_floating_point *srcptr,
481da177e4SLinus Torvalds 			unsigned int *nullptr,
491da177e4SLinus Torvalds 			unsigned int *dstptr,
501da177e4SLinus Torvalds 			unsigned int *status)
511da177e4SLinus Torvalds {
521da177e4SLinus Torvalds 	register unsigned int src, result;
531da177e4SLinus Torvalds 	register int src_exponent;
541da177e4SLinus Torvalds 	register boolean inexact = FALSE;
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds 	src = *srcptr;
571da177e4SLinus Torvalds 	src_exponent = Sgl_exponent(src) - SGL_BIAS;
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds 	/*
601da177e4SLinus Torvalds 	 * Test for overflow
611da177e4SLinus Torvalds 	 */
621da177e4SLinus Torvalds 	if (src_exponent > SGL_FX_MAX_EXP + 1) {
631da177e4SLinus Torvalds 		if (Sgl_isone_sign(src)) {
641da177e4SLinus Torvalds 			result = 0;
651da177e4SLinus Torvalds 		} else {
661da177e4SLinus Torvalds 			result = 0xffffffff;
671da177e4SLinus Torvalds 		}
681da177e4SLinus Torvalds 		if (Is_invalidtrap_enabled()) {
691da177e4SLinus Torvalds 			return(INVALIDEXCEPTION);
701da177e4SLinus Torvalds 		}
711da177e4SLinus Torvalds 		Set_invalidflag();
721da177e4SLinus Torvalds 		*dstptr = result;
731da177e4SLinus Torvalds 		return(NOEXCEPTION);
741da177e4SLinus Torvalds 	}
751da177e4SLinus Torvalds 	/*
761da177e4SLinus Torvalds 	 * Generate result
771da177e4SLinus Torvalds 	 */
781da177e4SLinus Torvalds 	if (src_exponent >= 0) {
791da177e4SLinus Torvalds 		/*
801da177e4SLinus Torvalds 		 * Check sign.
811da177e4SLinus Torvalds 		 * If negative, trap unimplemented.
821da177e4SLinus Torvalds 		 */
831da177e4SLinus Torvalds 		if (Sgl_isone_sign(src)) {
841da177e4SLinus Torvalds 			result = 0;
851da177e4SLinus Torvalds 			if (Is_invalidtrap_enabled()) {
861da177e4SLinus Torvalds 				return(INVALIDEXCEPTION);
871da177e4SLinus Torvalds 			}
881da177e4SLinus Torvalds 			Set_invalidflag();
891da177e4SLinus Torvalds 			*dstptr = result;
901da177e4SLinus Torvalds 			return(NOEXCEPTION);
911da177e4SLinus Torvalds 		}
921da177e4SLinus Torvalds 		Sgl_clear_signexponent_set_hidden(src);
931da177e4SLinus Torvalds 		Suint_from_sgl_mantissa(src,src_exponent,result);
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds 		/* check for inexact */
961da177e4SLinus Torvalds 		if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
971da177e4SLinus Torvalds 			inexact = TRUE;
981da177e4SLinus Torvalds 			/*  round result  */
991da177e4SLinus Torvalds 			switch (Rounding_mode()) {
1001da177e4SLinus Torvalds 			case ROUNDPLUS:
1011da177e4SLinus Torvalds 				result++;
1021da177e4SLinus Torvalds 				break;
1031da177e4SLinus Torvalds 			case ROUNDMINUS: /* never negative */
1041da177e4SLinus Torvalds 				break;
1051da177e4SLinus Torvalds 			case ROUNDNEAREST:
1061da177e4SLinus Torvalds 				if (Sgl_isone_roundbit(src,src_exponent) &&
1071da177e4SLinus Torvalds 				    (Sgl_isone_stickybit(src,src_exponent) ||
1081da177e4SLinus Torvalds 				     (result & 1))) {
1091da177e4SLinus Torvalds 			     		result++;
1101da177e4SLinus Torvalds 				}
1111da177e4SLinus Torvalds 				break;
1121da177e4SLinus Torvalds 			}
1131da177e4SLinus Torvalds 		}
1141da177e4SLinus Torvalds 	} else {
1151da177e4SLinus Torvalds 		result = 0;
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds 		/* check for inexact */
1181da177e4SLinus Torvalds 		if (Sgl_isnotzero_exponentmantissa(src)) {
1191da177e4SLinus Torvalds 			inexact = TRUE;
1201da177e4SLinus Torvalds 			/*  round result  */
1211da177e4SLinus Torvalds 			switch (Rounding_mode()) {
1221da177e4SLinus Torvalds 			case ROUNDPLUS:
1231da177e4SLinus Torvalds 				if (Sgl_iszero_sign(src)) {
1241da177e4SLinus Torvalds 					result++;
1251da177e4SLinus Torvalds 				}
1261da177e4SLinus Torvalds 				break;
1271da177e4SLinus Torvalds 			case ROUNDMINUS:
1281da177e4SLinus Torvalds 				if (Sgl_isone_sign(src)) {
1291da177e4SLinus Torvalds 					result = 0;
1301da177e4SLinus Torvalds 					if (Is_invalidtrap_enabled()) {
1311da177e4SLinus Torvalds 						return(INVALIDEXCEPTION);
1321da177e4SLinus Torvalds 					}
1331da177e4SLinus Torvalds 					Set_invalidflag();
1341da177e4SLinus Torvalds 					inexact = FALSE;
1351da177e4SLinus Torvalds 				}
1361da177e4SLinus Torvalds 				break;
1371da177e4SLinus Torvalds 			case ROUNDNEAREST:
1381da177e4SLinus Torvalds 				if (src_exponent == -1 &&
1391da177e4SLinus Torvalds 				    Sgl_isnotzero_mantissa(src)) {
1401da177e4SLinus Torvalds 					if (Sgl_isone_sign(src)) {
1411da177e4SLinus Torvalds 						result = 0;
1421da177e4SLinus Torvalds 						if (Is_invalidtrap_enabled()) {
1431da177e4SLinus Torvalds 							return(INVALIDEXCEPTION);
1441da177e4SLinus Torvalds 						}
1451da177e4SLinus Torvalds 						Set_invalidflag();
1461da177e4SLinus Torvalds 						inexact = FALSE;
1471da177e4SLinus Torvalds 					}
1481da177e4SLinus Torvalds 			      		else result++;
1491da177e4SLinus Torvalds 				}
1501da177e4SLinus Torvalds 				break;
1511da177e4SLinus Torvalds 			}
1521da177e4SLinus Torvalds 		}
1531da177e4SLinus Torvalds 	}
1541da177e4SLinus Torvalds 	*dstptr = result;
1551da177e4SLinus Torvalds 	if (inexact) {
1561da177e4SLinus Torvalds 		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
1571da177e4SLinus Torvalds 		else Set_inexactflag();
1581da177e4SLinus Torvalds 	}
1591da177e4SLinus Torvalds 	return(NOEXCEPTION);
1601da177e4SLinus Torvalds }
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds /*
1631da177e4SLinus Torvalds  *  Single Floating-point to Double Unsigned Fixed
1641da177e4SLinus Torvalds  */
1651da177e4SLinus Torvalds /*ARGSUSED*/
1661da177e4SLinus Torvalds int
sgl_to_dbl_fcnvfu(sgl_floating_point * srcptr,unsigned int * nullptr,dbl_unsigned * dstptr,unsigned int * status)1671da177e4SLinus Torvalds sgl_to_dbl_fcnvfu(
1681da177e4SLinus Torvalds 		    sgl_floating_point *srcptr,
1691da177e4SLinus Torvalds 		    unsigned int *nullptr,
1701da177e4SLinus Torvalds 		    dbl_unsigned *dstptr,
1711da177e4SLinus Torvalds 		    unsigned int *status)
1721da177e4SLinus Torvalds {
1731da177e4SLinus Torvalds 	register int src_exponent;
1741da177e4SLinus Torvalds 	register unsigned int src, resultp1, resultp2;
1751da177e4SLinus Torvalds 	register boolean inexact = FALSE;
1761da177e4SLinus Torvalds 
1771da177e4SLinus Torvalds 	src = *srcptr;
1781da177e4SLinus Torvalds 	src_exponent = Sgl_exponent(src) - SGL_BIAS;
1791da177e4SLinus Torvalds 
1801da177e4SLinus Torvalds 	/*
1811da177e4SLinus Torvalds 	 * Test for overflow
1821da177e4SLinus Torvalds 	 */
1831da177e4SLinus Torvalds 	if (src_exponent > DBL_FX_MAX_EXP + 1) {
1841da177e4SLinus Torvalds 		if (Sgl_isone_sign(src)) {
1851da177e4SLinus Torvalds 			resultp1 = resultp2 = 0;
1861da177e4SLinus Torvalds 		} else {
1871da177e4SLinus Torvalds 			resultp1 = resultp2 = 0xffffffff;
1881da177e4SLinus Torvalds 		}
1891da177e4SLinus Torvalds 		if (Is_invalidtrap_enabled()) {
1901da177e4SLinus Torvalds 			return(INVALIDEXCEPTION);
1911da177e4SLinus Torvalds 		}
1921da177e4SLinus Torvalds 		Set_invalidflag();
1931da177e4SLinus Torvalds     		Duint_copytoptr(resultp1,resultp2,dstptr);
1941da177e4SLinus Torvalds 		return(NOEXCEPTION);
1951da177e4SLinus Torvalds 	}
1961da177e4SLinus Torvalds 	/*
1971da177e4SLinus Torvalds 	 * Generate result
1981da177e4SLinus Torvalds 	 */
1991da177e4SLinus Torvalds 	if (src_exponent >= 0) {
2001da177e4SLinus Torvalds 		/*
2011da177e4SLinus Torvalds 		 * Check sign.
2021da177e4SLinus Torvalds 		 * If negative, trap unimplemented.
2031da177e4SLinus Torvalds 		 */
2041da177e4SLinus Torvalds 		if (Sgl_isone_sign(src)) {
2051da177e4SLinus Torvalds 			resultp1 = resultp2 = 0;
2061da177e4SLinus Torvalds 			if (Is_invalidtrap_enabled()) {
2071da177e4SLinus Torvalds 				return(INVALIDEXCEPTION);
2081da177e4SLinus Torvalds 			}
2091da177e4SLinus Torvalds 			Set_invalidflag();
2101da177e4SLinus Torvalds     			Duint_copytoptr(resultp1,resultp2,dstptr);
2111da177e4SLinus Torvalds 			return(NOEXCEPTION);
2121da177e4SLinus Torvalds 		}
2131da177e4SLinus Torvalds 		Sgl_clear_signexponent_set_hidden(src);
2141da177e4SLinus Torvalds 		Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2);
2151da177e4SLinus Torvalds 
2161da177e4SLinus Torvalds 		/* check for inexact */
2171da177e4SLinus Torvalds 		if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
2181da177e4SLinus Torvalds 			inexact = TRUE;
2191da177e4SLinus Torvalds 			/*  round result  */
2201da177e4SLinus Torvalds 			switch (Rounding_mode()) {
2211da177e4SLinus Torvalds 			case ROUNDPLUS:
2221da177e4SLinus Torvalds 				Duint_increment(resultp1,resultp2);
2231da177e4SLinus Torvalds 				break;
2241da177e4SLinus Torvalds 			case ROUNDMINUS: /* never negative */
2251da177e4SLinus Torvalds 				break;
2261da177e4SLinus Torvalds 			case ROUNDNEAREST:
2271da177e4SLinus Torvalds 				if (Sgl_isone_roundbit(src,src_exponent) &&
2281da177e4SLinus Torvalds 				    (Sgl_isone_stickybit(src,src_exponent) ||
2291da177e4SLinus Torvalds 				     Duint_isone_lowp2(resultp2))) {
2301da177e4SLinus Torvalds 					Duint_increment(resultp1,resultp2);
2311da177e4SLinus Torvalds 				}
2321da177e4SLinus Torvalds 				break;
2331da177e4SLinus Torvalds 			}
2341da177e4SLinus Torvalds 		}
2351da177e4SLinus Torvalds 	} else {
2361da177e4SLinus Torvalds 		Duint_setzero(resultp1,resultp2);
2371da177e4SLinus Torvalds 
2381da177e4SLinus Torvalds 		/* check for inexact */
2391da177e4SLinus Torvalds 		if (Sgl_isnotzero_exponentmantissa(src)) {
2401da177e4SLinus Torvalds 			inexact = TRUE;
2411da177e4SLinus Torvalds 			/*  round result  */
2421da177e4SLinus Torvalds 			switch (Rounding_mode()) {
2431da177e4SLinus Torvalds 			case ROUNDPLUS:
2441da177e4SLinus Torvalds 				if (Sgl_iszero_sign(src)) {
2451da177e4SLinus Torvalds 					Duint_increment(resultp1,resultp2);
2461da177e4SLinus Torvalds 				}
2471da177e4SLinus Torvalds 				break;
2481da177e4SLinus Torvalds 			case ROUNDMINUS:
2491da177e4SLinus Torvalds 				if (Sgl_isone_sign(src)) {
2501da177e4SLinus Torvalds 					resultp1 = resultp2 = 0;
2511da177e4SLinus Torvalds 					if (Is_invalidtrap_enabled()) {
2521da177e4SLinus Torvalds 						return(INVALIDEXCEPTION);
2531da177e4SLinus Torvalds 					}
2541da177e4SLinus Torvalds 					Set_invalidflag();
2551da177e4SLinus Torvalds 					inexact = FALSE;
2561da177e4SLinus Torvalds 				}
2571da177e4SLinus Torvalds 				break;
2581da177e4SLinus Torvalds 			case ROUNDNEAREST:
2591da177e4SLinus Torvalds 				if (src_exponent == -1 &&
2601da177e4SLinus Torvalds 				    Sgl_isnotzero_mantissa(src)) {
2611da177e4SLinus Torvalds 					if (Sgl_isone_sign(src)) {
2621da177e4SLinus Torvalds 						resultp1 = 0;
2631da177e4SLinus Torvalds 						resultp2 = 0;
2641da177e4SLinus Torvalds 						if (Is_invalidtrap_enabled()) {
2651da177e4SLinus Torvalds 							return(INVALIDEXCEPTION);
2661da177e4SLinus Torvalds 						}
2671da177e4SLinus Torvalds 						Set_invalidflag();
2681da177e4SLinus Torvalds 						inexact = FALSE;
2691da177e4SLinus Torvalds 					}
2701da177e4SLinus Torvalds 					else Duint_increment(resultp1,resultp2);
2711da177e4SLinus Torvalds 				}
2721da177e4SLinus Torvalds 			}
2731da177e4SLinus Torvalds 		}
2741da177e4SLinus Torvalds 	}
2751da177e4SLinus Torvalds 	Duint_copytoptr(resultp1,resultp2,dstptr);
2761da177e4SLinus Torvalds 	if (inexact) {
2771da177e4SLinus Torvalds 		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
2781da177e4SLinus Torvalds 		else Set_inexactflag();
2791da177e4SLinus Torvalds 	}
2801da177e4SLinus Torvalds 	return(NOEXCEPTION);
2811da177e4SLinus Torvalds }
2821da177e4SLinus Torvalds 
2831da177e4SLinus Torvalds /*
2841da177e4SLinus Torvalds  *  Double Floating-point to Single Unsigned Fixed
2851da177e4SLinus Torvalds  */
2861da177e4SLinus Torvalds /*ARGSUSED*/
2871da177e4SLinus Torvalds int
dbl_to_sgl_fcnvfu(dbl_floating_point * srcptr,unsigned int * nullptr,unsigned int * dstptr,unsigned int * status)2881da177e4SLinus Torvalds dbl_to_sgl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr,
2891da177e4SLinus Torvalds 		   unsigned int *dstptr, unsigned int *status)
2901da177e4SLinus Torvalds {
2911da177e4SLinus Torvalds 	register unsigned int srcp1, srcp2, result;
2921da177e4SLinus Torvalds 	register int src_exponent;
2931da177e4SLinus Torvalds 	register boolean inexact = FALSE;
2941da177e4SLinus Torvalds 
2951da177e4SLinus Torvalds 	Dbl_copyfromptr(srcptr,srcp1,srcp2);
2961da177e4SLinus Torvalds 	src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
2971da177e4SLinus Torvalds 
2981da177e4SLinus Torvalds 	/*
2991da177e4SLinus Torvalds 	 * Test for overflow
3001da177e4SLinus Torvalds 	 */
3011da177e4SLinus Torvalds 	if (src_exponent > SGL_FX_MAX_EXP + 1) {
3021da177e4SLinus Torvalds 		if (Dbl_isone_sign(srcp1)) {
3031da177e4SLinus Torvalds 			result = 0;
3041da177e4SLinus Torvalds 		} else {
3051da177e4SLinus Torvalds 			result = 0xffffffff;
3061da177e4SLinus Torvalds 		}
3071da177e4SLinus Torvalds 		if (Is_invalidtrap_enabled()) {
3081da177e4SLinus Torvalds 			return(INVALIDEXCEPTION);
3091da177e4SLinus Torvalds 		}
3101da177e4SLinus Torvalds 		Set_invalidflag();
3111da177e4SLinus Torvalds 		*dstptr = result;
3121da177e4SLinus Torvalds 		return(NOEXCEPTION);
3131da177e4SLinus Torvalds 	}
3141da177e4SLinus Torvalds 	/*
3151da177e4SLinus Torvalds 	 * Generate result
3161da177e4SLinus Torvalds 	 */
3171da177e4SLinus Torvalds 	if (src_exponent >= 0) {
3181da177e4SLinus Torvalds 		/*
3191da177e4SLinus Torvalds 		 * Check sign.
3201da177e4SLinus Torvalds 		 * If negative, trap unimplemented.
3211da177e4SLinus Torvalds 		 */
3221da177e4SLinus Torvalds 		if (Dbl_isone_sign(srcp1)) {
3231da177e4SLinus Torvalds 			result = 0;
3241da177e4SLinus Torvalds 			if (Is_invalidtrap_enabled()) {
3251da177e4SLinus Torvalds 				return(INVALIDEXCEPTION);
3261da177e4SLinus Torvalds 			}
3271da177e4SLinus Torvalds 			Set_invalidflag();
3281da177e4SLinus Torvalds 			*dstptr = result;
3291da177e4SLinus Torvalds 			return(NOEXCEPTION);
3301da177e4SLinus Torvalds 		}
3311da177e4SLinus Torvalds 		Dbl_clear_signexponent_set_hidden(srcp1);
3321da177e4SLinus Torvalds 		Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result);
3331da177e4SLinus Torvalds 
3341da177e4SLinus Torvalds 		/* check for inexact */
3351da177e4SLinus Torvalds 		if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
3361da177e4SLinus Torvalds 			inexact = TRUE;
3371da177e4SLinus Torvalds 			/*  round result  */
3381da177e4SLinus Torvalds 			switch (Rounding_mode()) {
3391da177e4SLinus Torvalds 			case ROUNDPLUS:
3401da177e4SLinus Torvalds 			     result++;
3411da177e4SLinus Torvalds 			     break;
3421da177e4SLinus Torvalds 			case ROUNDMINUS: /* never negative */
3431da177e4SLinus Torvalds 			     break;
3441da177e4SLinus Torvalds 			case ROUNDNEAREST:
3451da177e4SLinus Torvalds 			     if(Dbl_isone_roundbit(srcp1,srcp2,src_exponent) &&
3461da177e4SLinus Torvalds 				(Dbl_isone_stickybit(srcp1,srcp2,src_exponent)||
3471da177e4SLinus Torvalds 				 result&1))
3481da177e4SLinus Torvalds 				   result++;
3491da177e4SLinus Torvalds 			     break;
3501da177e4SLinus Torvalds 			}
3511da177e4SLinus Torvalds 			/* check for overflow */
3521da177e4SLinus Torvalds 			if (result == 0) {
3531da177e4SLinus Torvalds 				result = 0xffffffff;
3541da177e4SLinus Torvalds 				if (Is_invalidtrap_enabled()) {
3551da177e4SLinus Torvalds 					return(INVALIDEXCEPTION);
3561da177e4SLinus Torvalds 				}
3571da177e4SLinus Torvalds 				Set_invalidflag();
3581da177e4SLinus Torvalds 				*dstptr = result;
3591da177e4SLinus Torvalds 				return(NOEXCEPTION);
3601da177e4SLinus Torvalds 			}
3611da177e4SLinus Torvalds 		}
3621da177e4SLinus Torvalds 	} else {
3631da177e4SLinus Torvalds 		result = 0;
3641da177e4SLinus Torvalds 
3651da177e4SLinus Torvalds 		/* check for inexact */
3661da177e4SLinus Torvalds 		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
3671da177e4SLinus Torvalds 			inexact = TRUE;
3681da177e4SLinus Torvalds 			/*  round result  */
3691da177e4SLinus Torvalds 			switch (Rounding_mode()) {
3701da177e4SLinus Torvalds 			case ROUNDPLUS:
3711da177e4SLinus Torvalds 				if (Dbl_iszero_sign(srcp1)) result++;
3721da177e4SLinus Torvalds 				break;
3731da177e4SLinus Torvalds 			case ROUNDMINUS:
3741da177e4SLinus Torvalds 				if (Dbl_isone_sign(srcp1)) {
3751da177e4SLinus Torvalds 					result = 0;
3761da177e4SLinus Torvalds 					if (Is_invalidtrap_enabled()) {
3771da177e4SLinus Torvalds 						return(INVALIDEXCEPTION);
3781da177e4SLinus Torvalds 					}
3791da177e4SLinus Torvalds 					Set_invalidflag();
3801da177e4SLinus Torvalds 					inexact = FALSE;
3811da177e4SLinus Torvalds 				}
3821da177e4SLinus Torvalds 				break;
3831da177e4SLinus Torvalds 			case ROUNDNEAREST:
3841da177e4SLinus Torvalds 				if (src_exponent == -1 &&
3851da177e4SLinus Torvalds 				    Dbl_isnotzero_mantissa(srcp1,srcp2))
3861da177e4SLinus Torvalds 					if (Dbl_isone_sign(srcp1)) {
3871da177e4SLinus Torvalds 						result = 0;
3881da177e4SLinus Torvalds 						if (Is_invalidtrap_enabled()) {
3891da177e4SLinus Torvalds 							return(INVALIDEXCEPTION);
3901da177e4SLinus Torvalds 						}
3911da177e4SLinus Torvalds 						Set_invalidflag();
3921da177e4SLinus Torvalds 						inexact = FALSE;
3931da177e4SLinus Torvalds 					}
3941da177e4SLinus Torvalds 					else result++;
3951da177e4SLinus Torvalds 			}
3961da177e4SLinus Torvalds 		}
3971da177e4SLinus Torvalds 	}
3981da177e4SLinus Torvalds 	*dstptr = result;
3991da177e4SLinus Torvalds 	if (inexact) {
4001da177e4SLinus Torvalds 		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
4011da177e4SLinus Torvalds 		else Set_inexactflag();
4021da177e4SLinus Torvalds 	}
4031da177e4SLinus Torvalds 	return(NOEXCEPTION);
4041da177e4SLinus Torvalds }
4051da177e4SLinus Torvalds 
4061da177e4SLinus Torvalds /*
4071da177e4SLinus Torvalds  *  Double Floating-point to Double Unsigned Fixed
4081da177e4SLinus Torvalds  */
4091da177e4SLinus Torvalds /*ARGSUSED*/
4101da177e4SLinus Torvalds int
dbl_to_dbl_fcnvfu(dbl_floating_point * srcptr,unsigned int * nullptr,dbl_unsigned * dstptr,unsigned int * status)4111da177e4SLinus Torvalds dbl_to_dbl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr,
4121da177e4SLinus Torvalds 		   dbl_unsigned * dstptr, unsigned int *status)
4131da177e4SLinus Torvalds {
4141da177e4SLinus Torvalds 	register int src_exponent;
4151da177e4SLinus Torvalds 	register unsigned int srcp1, srcp2, resultp1, resultp2;
4161da177e4SLinus Torvalds 	register boolean inexact = FALSE;
4171da177e4SLinus Torvalds 
4181da177e4SLinus Torvalds 	Dbl_copyfromptr(srcptr,srcp1,srcp2);
4191da177e4SLinus Torvalds 	src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
4201da177e4SLinus Torvalds 
4211da177e4SLinus Torvalds 	/*
4221da177e4SLinus Torvalds 	 * Test for overflow
4231da177e4SLinus Torvalds 	 */
4241da177e4SLinus Torvalds 	if (src_exponent > DBL_FX_MAX_EXP + 1) {
4251da177e4SLinus Torvalds 		if (Dbl_isone_sign(srcp1)) {
4261da177e4SLinus Torvalds 			resultp1 = resultp2 = 0;
4271da177e4SLinus Torvalds 		} else {
4281da177e4SLinus Torvalds 			resultp1 = resultp2 = 0xffffffff;
4291da177e4SLinus Torvalds 		}
4301da177e4SLinus Torvalds 		if (Is_invalidtrap_enabled()) {
4311da177e4SLinus Torvalds 			return(INVALIDEXCEPTION);
4321da177e4SLinus Torvalds 		}
4331da177e4SLinus Torvalds 		Set_invalidflag();
4341da177e4SLinus Torvalds     		Duint_copytoptr(resultp1,resultp2,dstptr);
4351da177e4SLinus Torvalds 		return(NOEXCEPTION);
4361da177e4SLinus Torvalds 	}
4371da177e4SLinus Torvalds 
4381da177e4SLinus Torvalds 	/*
4391da177e4SLinus Torvalds 	 * Generate result
4401da177e4SLinus Torvalds 	 */
4411da177e4SLinus Torvalds 	if (src_exponent >= 0) {
4421da177e4SLinus Torvalds 		/*
4431da177e4SLinus Torvalds 		 * Check sign.
4441da177e4SLinus Torvalds 		 * If negative, trap unimplemented.
4451da177e4SLinus Torvalds 		 */
4461da177e4SLinus Torvalds 		if (Dbl_isone_sign(srcp1)) {
4471da177e4SLinus Torvalds 			resultp1 = resultp2 = 0;
4481da177e4SLinus Torvalds 			if (Is_invalidtrap_enabled()) {
4491da177e4SLinus Torvalds 				return(INVALIDEXCEPTION);
4501da177e4SLinus Torvalds 			}
4511da177e4SLinus Torvalds 			Set_invalidflag();
4521da177e4SLinus Torvalds     			Duint_copytoptr(resultp1,resultp2,dstptr);
4531da177e4SLinus Torvalds 			return(NOEXCEPTION);
4541da177e4SLinus Torvalds 		}
4551da177e4SLinus Torvalds 		Dbl_clear_signexponent_set_hidden(srcp1);
4561da177e4SLinus Torvalds 		Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent,resultp1,
4571da177e4SLinus Torvalds 		  resultp2);
4581da177e4SLinus Torvalds 
4591da177e4SLinus Torvalds 		/* check for inexact */
4601da177e4SLinus Torvalds 		if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
4611da177e4SLinus Torvalds 			inexact = TRUE;
4621da177e4SLinus Torvalds 			/*  round result  */
4631da177e4SLinus Torvalds 			switch (Rounding_mode()) {
4641da177e4SLinus Torvalds 			case ROUNDPLUS:
4651da177e4SLinus Torvalds 				Duint_increment(resultp1,resultp2);
4661da177e4SLinus Torvalds 				break;
4671da177e4SLinus Torvalds 			case ROUNDMINUS: /* never negative */
4681da177e4SLinus Torvalds 				break;
4691da177e4SLinus Torvalds 			case ROUNDNEAREST:
4701da177e4SLinus Torvalds 				if(Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
4711da177e4SLinus Torvalds 				  if(Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
4721da177e4SLinus Torvalds 				     Duint_isone_lowp2(resultp2))
4731da177e4SLinus Torvalds 					Duint_increment(resultp1,resultp2);
4741da177e4SLinus Torvalds 			}
4751da177e4SLinus Torvalds 		}
4761da177e4SLinus Torvalds 	} else {
4771da177e4SLinus Torvalds 		Duint_setzero(resultp1,resultp2);
4781da177e4SLinus Torvalds 
4791da177e4SLinus Torvalds 		/* check for inexact */
4801da177e4SLinus Torvalds 		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
4811da177e4SLinus Torvalds 			inexact = TRUE;
4821da177e4SLinus Torvalds 			/*  round result  */
4831da177e4SLinus Torvalds 			switch (Rounding_mode()) {
4841da177e4SLinus Torvalds 			case ROUNDPLUS:
4851da177e4SLinus Torvalds 				if (Dbl_iszero_sign(srcp1)) {
4861da177e4SLinus Torvalds 					Duint_increment(resultp1,resultp2);
4871da177e4SLinus Torvalds 				}
4881da177e4SLinus Torvalds 				break;
4891da177e4SLinus Torvalds 			case ROUNDMINUS:
4901da177e4SLinus Torvalds 				if (Dbl_isone_sign(srcp1)) {
4911da177e4SLinus Torvalds 					resultp1 = resultp2 = 0;
4921da177e4SLinus Torvalds 					if (Is_invalidtrap_enabled()) {
4931da177e4SLinus Torvalds 						return(INVALIDEXCEPTION);
4941da177e4SLinus Torvalds 					}
4951da177e4SLinus Torvalds 					Set_invalidflag();
4961da177e4SLinus Torvalds 					inexact = FALSE;
4971da177e4SLinus Torvalds 				}
4981da177e4SLinus Torvalds 				break;
4991da177e4SLinus Torvalds 			case ROUNDNEAREST:
5001da177e4SLinus Torvalds 				if (src_exponent == -1 &&
5011da177e4SLinus Torvalds 				    Dbl_isnotzero_mantissa(srcp1,srcp2))
5021da177e4SLinus Torvalds 					if (Dbl_iszero_sign(srcp1)) {
5031da177e4SLinus Torvalds 						Duint_increment(resultp1,resultp2);
5041da177e4SLinus Torvalds 					} else {
5051da177e4SLinus Torvalds 						resultp1 = 0;
5061da177e4SLinus Torvalds 						resultp2 = 0;
5071da177e4SLinus Torvalds 						if (Is_invalidtrap_enabled()) {
5081da177e4SLinus Torvalds 							return(INVALIDEXCEPTION);
5091da177e4SLinus Torvalds 						}
5101da177e4SLinus Torvalds 						Set_invalidflag();
5111da177e4SLinus Torvalds 						inexact = FALSE;
5121da177e4SLinus Torvalds 					}
5131da177e4SLinus Torvalds 			}
5141da177e4SLinus Torvalds 		}
5151da177e4SLinus Torvalds 	}
5161da177e4SLinus Torvalds 	Duint_copytoptr(resultp1,resultp2,dstptr);
5171da177e4SLinus Torvalds 	if (inexact) {
5181da177e4SLinus Torvalds 		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
5191da177e4SLinus Torvalds 		else Set_inexactflag();
5201da177e4SLinus Torvalds 	}
5211da177e4SLinus Torvalds 	return(NOEXCEPTION);
5221da177e4SLinus Torvalds }
5231da177e4SLinus Torvalds 
524