xref: /OK3568_Linux_fs/kernel/arch/parisc/math-emu/fcnvfu.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Floating-point emulation code
6*4882a593Smuzhiyun  *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun  * BEGIN_DESC
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  *  File:
12*4882a593Smuzhiyun  *	@(#)	pa/spmath/fcnvfu.c		$Revision: 1.1 $
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *  Purpose:
15*4882a593Smuzhiyun  *	Floating-point to Unsigned Fixed-point Converts
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  *  External Interfaces:
18*4882a593Smuzhiyun  *	dbl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
19*4882a593Smuzhiyun  *	dbl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
20*4882a593Smuzhiyun  *	sgl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
21*4882a593Smuzhiyun  *	sgl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  *  Internal Interfaces:
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  *  Theory:
26*4882a593Smuzhiyun  *	<<please update with a overview of the operation of this file>>
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * END_DESC
29*4882a593Smuzhiyun */
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #include "float.h"
33*4882a593Smuzhiyun #include "sgl_float.h"
34*4882a593Smuzhiyun #include "dbl_float.h"
35*4882a593Smuzhiyun #include "cnv_float.h"
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /************************************************************************
38*4882a593Smuzhiyun  *  Floating-point to Unsigned Fixed-point Converts			*
39*4882a593Smuzhiyun  ************************************************************************/
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /*
42*4882a593Smuzhiyun  *  Single Floating-point to Single Unsigned Fixed
43*4882a593Smuzhiyun  */
44*4882a593Smuzhiyun /*ARGSUSED*/
45*4882a593Smuzhiyun int
sgl_to_sgl_fcnvfu(sgl_floating_point * srcptr,unsigned int * nullptr,unsigned int * dstptr,unsigned int * status)46*4882a593Smuzhiyun sgl_to_sgl_fcnvfu(
47*4882a593Smuzhiyun 			sgl_floating_point *srcptr,
48*4882a593Smuzhiyun 			unsigned int *nullptr,
49*4882a593Smuzhiyun 			unsigned int *dstptr,
50*4882a593Smuzhiyun 			unsigned int *status)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	register unsigned int src, result;
53*4882a593Smuzhiyun 	register int src_exponent;
54*4882a593Smuzhiyun 	register boolean inexact = FALSE;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	src = *srcptr;
57*4882a593Smuzhiyun 	src_exponent = Sgl_exponent(src) - SGL_BIAS;
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	/*
60*4882a593Smuzhiyun 	 * Test for overflow
61*4882a593Smuzhiyun 	 */
62*4882a593Smuzhiyun 	if (src_exponent > SGL_FX_MAX_EXP + 1) {
63*4882a593Smuzhiyun 		if (Sgl_isone_sign(src)) {
64*4882a593Smuzhiyun 			result = 0;
65*4882a593Smuzhiyun 		} else {
66*4882a593Smuzhiyun 			result = 0xffffffff;
67*4882a593Smuzhiyun 		}
68*4882a593Smuzhiyun 		if (Is_invalidtrap_enabled()) {
69*4882a593Smuzhiyun 			return(INVALIDEXCEPTION);
70*4882a593Smuzhiyun 		}
71*4882a593Smuzhiyun 		Set_invalidflag();
72*4882a593Smuzhiyun 		*dstptr = result;
73*4882a593Smuzhiyun 		return(NOEXCEPTION);
74*4882a593Smuzhiyun 	}
75*4882a593Smuzhiyun 	/*
76*4882a593Smuzhiyun 	 * Generate result
77*4882a593Smuzhiyun 	 */
78*4882a593Smuzhiyun 	if (src_exponent >= 0) {
79*4882a593Smuzhiyun 		/*
80*4882a593Smuzhiyun 		 * Check sign.
81*4882a593Smuzhiyun 		 * If negative, trap unimplemented.
82*4882a593Smuzhiyun 		 */
83*4882a593Smuzhiyun 		if (Sgl_isone_sign(src)) {
84*4882a593Smuzhiyun 			result = 0;
85*4882a593Smuzhiyun 			if (Is_invalidtrap_enabled()) {
86*4882a593Smuzhiyun 				return(INVALIDEXCEPTION);
87*4882a593Smuzhiyun 			}
88*4882a593Smuzhiyun 			Set_invalidflag();
89*4882a593Smuzhiyun 			*dstptr = result;
90*4882a593Smuzhiyun 			return(NOEXCEPTION);
91*4882a593Smuzhiyun 		}
92*4882a593Smuzhiyun 		Sgl_clear_signexponent_set_hidden(src);
93*4882a593Smuzhiyun 		Suint_from_sgl_mantissa(src,src_exponent,result);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 		/* check for inexact */
96*4882a593Smuzhiyun 		if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
97*4882a593Smuzhiyun 			inexact = TRUE;
98*4882a593Smuzhiyun 			/*  round result  */
99*4882a593Smuzhiyun 			switch (Rounding_mode()) {
100*4882a593Smuzhiyun 			case ROUNDPLUS:
101*4882a593Smuzhiyun 				result++;
102*4882a593Smuzhiyun 				break;
103*4882a593Smuzhiyun 			case ROUNDMINUS: /* never negative */
104*4882a593Smuzhiyun 				break;
105*4882a593Smuzhiyun 			case ROUNDNEAREST:
106*4882a593Smuzhiyun 				if (Sgl_isone_roundbit(src,src_exponent) &&
107*4882a593Smuzhiyun 				    (Sgl_isone_stickybit(src,src_exponent) ||
108*4882a593Smuzhiyun 				     (result & 1))) {
109*4882a593Smuzhiyun 			     		result++;
110*4882a593Smuzhiyun 				}
111*4882a593Smuzhiyun 				break;
112*4882a593Smuzhiyun 			}
113*4882a593Smuzhiyun 		}
114*4882a593Smuzhiyun 	} else {
115*4882a593Smuzhiyun 		result = 0;
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 		/* check for inexact */
118*4882a593Smuzhiyun 		if (Sgl_isnotzero_exponentmantissa(src)) {
119*4882a593Smuzhiyun 			inexact = TRUE;
120*4882a593Smuzhiyun 			/*  round result  */
121*4882a593Smuzhiyun 			switch (Rounding_mode()) {
122*4882a593Smuzhiyun 			case ROUNDPLUS:
123*4882a593Smuzhiyun 				if (Sgl_iszero_sign(src)) {
124*4882a593Smuzhiyun 					result++;
125*4882a593Smuzhiyun 				}
126*4882a593Smuzhiyun 				break;
127*4882a593Smuzhiyun 			case ROUNDMINUS:
128*4882a593Smuzhiyun 				if (Sgl_isone_sign(src)) {
129*4882a593Smuzhiyun 					result = 0;
130*4882a593Smuzhiyun 					if (Is_invalidtrap_enabled()) {
131*4882a593Smuzhiyun 						return(INVALIDEXCEPTION);
132*4882a593Smuzhiyun 					}
133*4882a593Smuzhiyun 					Set_invalidflag();
134*4882a593Smuzhiyun 					inexact = FALSE;
135*4882a593Smuzhiyun 				}
136*4882a593Smuzhiyun 				break;
137*4882a593Smuzhiyun 			case ROUNDNEAREST:
138*4882a593Smuzhiyun 				if (src_exponent == -1 &&
139*4882a593Smuzhiyun 				    Sgl_isnotzero_mantissa(src)) {
140*4882a593Smuzhiyun 					if (Sgl_isone_sign(src)) {
141*4882a593Smuzhiyun 						result = 0;
142*4882a593Smuzhiyun 						if (Is_invalidtrap_enabled()) {
143*4882a593Smuzhiyun 							return(INVALIDEXCEPTION);
144*4882a593Smuzhiyun 						}
145*4882a593Smuzhiyun 						Set_invalidflag();
146*4882a593Smuzhiyun 						inexact = FALSE;
147*4882a593Smuzhiyun 					}
148*4882a593Smuzhiyun 			      		else result++;
149*4882a593Smuzhiyun 				}
150*4882a593Smuzhiyun 				break;
151*4882a593Smuzhiyun 			}
152*4882a593Smuzhiyun 		}
153*4882a593Smuzhiyun 	}
154*4882a593Smuzhiyun 	*dstptr = result;
155*4882a593Smuzhiyun 	if (inexact) {
156*4882a593Smuzhiyun 		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
157*4882a593Smuzhiyun 		else Set_inexactflag();
158*4882a593Smuzhiyun 	}
159*4882a593Smuzhiyun 	return(NOEXCEPTION);
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun /*
163*4882a593Smuzhiyun  *  Single Floating-point to Double Unsigned Fixed
164*4882a593Smuzhiyun  */
165*4882a593Smuzhiyun /*ARGSUSED*/
166*4882a593Smuzhiyun int
sgl_to_dbl_fcnvfu(sgl_floating_point * srcptr,unsigned int * nullptr,dbl_unsigned * dstptr,unsigned int * status)167*4882a593Smuzhiyun sgl_to_dbl_fcnvfu(
168*4882a593Smuzhiyun 		    sgl_floating_point *srcptr,
169*4882a593Smuzhiyun 		    unsigned int *nullptr,
170*4882a593Smuzhiyun 		    dbl_unsigned *dstptr,
171*4882a593Smuzhiyun 		    unsigned int *status)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun 	register int src_exponent;
174*4882a593Smuzhiyun 	register unsigned int src, resultp1, resultp2;
175*4882a593Smuzhiyun 	register boolean inexact = FALSE;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	src = *srcptr;
178*4882a593Smuzhiyun 	src_exponent = Sgl_exponent(src) - SGL_BIAS;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	/*
181*4882a593Smuzhiyun 	 * Test for overflow
182*4882a593Smuzhiyun 	 */
183*4882a593Smuzhiyun 	if (src_exponent > DBL_FX_MAX_EXP + 1) {
184*4882a593Smuzhiyun 		if (Sgl_isone_sign(src)) {
185*4882a593Smuzhiyun 			resultp1 = resultp2 = 0;
186*4882a593Smuzhiyun 		} else {
187*4882a593Smuzhiyun 			resultp1 = resultp2 = 0xffffffff;
188*4882a593Smuzhiyun 		}
189*4882a593Smuzhiyun 		if (Is_invalidtrap_enabled()) {
190*4882a593Smuzhiyun 			return(INVALIDEXCEPTION);
191*4882a593Smuzhiyun 		}
192*4882a593Smuzhiyun 		Set_invalidflag();
193*4882a593Smuzhiyun     		Duint_copytoptr(resultp1,resultp2,dstptr);
194*4882a593Smuzhiyun 		return(NOEXCEPTION);
195*4882a593Smuzhiyun 	}
196*4882a593Smuzhiyun 	/*
197*4882a593Smuzhiyun 	 * Generate result
198*4882a593Smuzhiyun 	 */
199*4882a593Smuzhiyun 	if (src_exponent >= 0) {
200*4882a593Smuzhiyun 		/*
201*4882a593Smuzhiyun 		 * Check sign.
202*4882a593Smuzhiyun 		 * If negative, trap unimplemented.
203*4882a593Smuzhiyun 		 */
204*4882a593Smuzhiyun 		if (Sgl_isone_sign(src)) {
205*4882a593Smuzhiyun 			resultp1 = resultp2 = 0;
206*4882a593Smuzhiyun 			if (Is_invalidtrap_enabled()) {
207*4882a593Smuzhiyun 				return(INVALIDEXCEPTION);
208*4882a593Smuzhiyun 			}
209*4882a593Smuzhiyun 			Set_invalidflag();
210*4882a593Smuzhiyun     			Duint_copytoptr(resultp1,resultp2,dstptr);
211*4882a593Smuzhiyun 			return(NOEXCEPTION);
212*4882a593Smuzhiyun 		}
213*4882a593Smuzhiyun 		Sgl_clear_signexponent_set_hidden(src);
214*4882a593Smuzhiyun 		Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2);
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 		/* check for inexact */
217*4882a593Smuzhiyun 		if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
218*4882a593Smuzhiyun 			inexact = TRUE;
219*4882a593Smuzhiyun 			/*  round result  */
220*4882a593Smuzhiyun 			switch (Rounding_mode()) {
221*4882a593Smuzhiyun 			case ROUNDPLUS:
222*4882a593Smuzhiyun 				Duint_increment(resultp1,resultp2);
223*4882a593Smuzhiyun 				break;
224*4882a593Smuzhiyun 			case ROUNDMINUS: /* never negative */
225*4882a593Smuzhiyun 				break;
226*4882a593Smuzhiyun 			case ROUNDNEAREST:
227*4882a593Smuzhiyun 				if (Sgl_isone_roundbit(src,src_exponent) &&
228*4882a593Smuzhiyun 				    (Sgl_isone_stickybit(src,src_exponent) ||
229*4882a593Smuzhiyun 				     Duint_isone_lowp2(resultp2))) {
230*4882a593Smuzhiyun 					Duint_increment(resultp1,resultp2);
231*4882a593Smuzhiyun 				}
232*4882a593Smuzhiyun 				break;
233*4882a593Smuzhiyun 			}
234*4882a593Smuzhiyun 		}
235*4882a593Smuzhiyun 	} else {
236*4882a593Smuzhiyun 		Duint_setzero(resultp1,resultp2);
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 		/* check for inexact */
239*4882a593Smuzhiyun 		if (Sgl_isnotzero_exponentmantissa(src)) {
240*4882a593Smuzhiyun 			inexact = TRUE;
241*4882a593Smuzhiyun 			/*  round result  */
242*4882a593Smuzhiyun 			switch (Rounding_mode()) {
243*4882a593Smuzhiyun 			case ROUNDPLUS:
244*4882a593Smuzhiyun 				if (Sgl_iszero_sign(src)) {
245*4882a593Smuzhiyun 					Duint_increment(resultp1,resultp2);
246*4882a593Smuzhiyun 				}
247*4882a593Smuzhiyun 				break;
248*4882a593Smuzhiyun 			case ROUNDMINUS:
249*4882a593Smuzhiyun 				if (Sgl_isone_sign(src)) {
250*4882a593Smuzhiyun 					resultp1 = resultp2 = 0;
251*4882a593Smuzhiyun 					if (Is_invalidtrap_enabled()) {
252*4882a593Smuzhiyun 						return(INVALIDEXCEPTION);
253*4882a593Smuzhiyun 					}
254*4882a593Smuzhiyun 					Set_invalidflag();
255*4882a593Smuzhiyun 					inexact = FALSE;
256*4882a593Smuzhiyun 				}
257*4882a593Smuzhiyun 				break;
258*4882a593Smuzhiyun 			case ROUNDNEAREST:
259*4882a593Smuzhiyun 				if (src_exponent == -1 &&
260*4882a593Smuzhiyun 				    Sgl_isnotzero_mantissa(src)) {
261*4882a593Smuzhiyun 					if (Sgl_isone_sign(src)) {
262*4882a593Smuzhiyun 						resultp1 = 0;
263*4882a593Smuzhiyun 						resultp2 = 0;
264*4882a593Smuzhiyun 						if (Is_invalidtrap_enabled()) {
265*4882a593Smuzhiyun 							return(INVALIDEXCEPTION);
266*4882a593Smuzhiyun 						}
267*4882a593Smuzhiyun 						Set_invalidflag();
268*4882a593Smuzhiyun 						inexact = FALSE;
269*4882a593Smuzhiyun 					}
270*4882a593Smuzhiyun 					else Duint_increment(resultp1,resultp2);
271*4882a593Smuzhiyun 				}
272*4882a593Smuzhiyun 			}
273*4882a593Smuzhiyun 		}
274*4882a593Smuzhiyun 	}
275*4882a593Smuzhiyun 	Duint_copytoptr(resultp1,resultp2,dstptr);
276*4882a593Smuzhiyun 	if (inexact) {
277*4882a593Smuzhiyun 		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
278*4882a593Smuzhiyun 		else Set_inexactflag();
279*4882a593Smuzhiyun 	}
280*4882a593Smuzhiyun 	return(NOEXCEPTION);
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun /*
284*4882a593Smuzhiyun  *  Double Floating-point to Single Unsigned Fixed
285*4882a593Smuzhiyun  */
286*4882a593Smuzhiyun /*ARGSUSED*/
287*4882a593Smuzhiyun int
dbl_to_sgl_fcnvfu(dbl_floating_point * srcptr,unsigned int * nullptr,unsigned int * dstptr,unsigned int * status)288*4882a593Smuzhiyun dbl_to_sgl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr,
289*4882a593Smuzhiyun 		   unsigned int *dstptr, unsigned int *status)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	register unsigned int srcp1, srcp2, result;
292*4882a593Smuzhiyun 	register int src_exponent;
293*4882a593Smuzhiyun 	register boolean inexact = FALSE;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	Dbl_copyfromptr(srcptr,srcp1,srcp2);
296*4882a593Smuzhiyun 	src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	/*
299*4882a593Smuzhiyun 	 * Test for overflow
300*4882a593Smuzhiyun 	 */
301*4882a593Smuzhiyun 	if (src_exponent > SGL_FX_MAX_EXP + 1) {
302*4882a593Smuzhiyun 		if (Dbl_isone_sign(srcp1)) {
303*4882a593Smuzhiyun 			result = 0;
304*4882a593Smuzhiyun 		} else {
305*4882a593Smuzhiyun 			result = 0xffffffff;
306*4882a593Smuzhiyun 		}
307*4882a593Smuzhiyun 		if (Is_invalidtrap_enabled()) {
308*4882a593Smuzhiyun 			return(INVALIDEXCEPTION);
309*4882a593Smuzhiyun 		}
310*4882a593Smuzhiyun 		Set_invalidflag();
311*4882a593Smuzhiyun 		*dstptr = result;
312*4882a593Smuzhiyun 		return(NOEXCEPTION);
313*4882a593Smuzhiyun 	}
314*4882a593Smuzhiyun 	/*
315*4882a593Smuzhiyun 	 * Generate result
316*4882a593Smuzhiyun 	 */
317*4882a593Smuzhiyun 	if (src_exponent >= 0) {
318*4882a593Smuzhiyun 		/*
319*4882a593Smuzhiyun 		 * Check sign.
320*4882a593Smuzhiyun 		 * If negative, trap unimplemented.
321*4882a593Smuzhiyun 		 */
322*4882a593Smuzhiyun 		if (Dbl_isone_sign(srcp1)) {
323*4882a593Smuzhiyun 			result = 0;
324*4882a593Smuzhiyun 			if (Is_invalidtrap_enabled()) {
325*4882a593Smuzhiyun 				return(INVALIDEXCEPTION);
326*4882a593Smuzhiyun 			}
327*4882a593Smuzhiyun 			Set_invalidflag();
328*4882a593Smuzhiyun 			*dstptr = result;
329*4882a593Smuzhiyun 			return(NOEXCEPTION);
330*4882a593Smuzhiyun 		}
331*4882a593Smuzhiyun 		Dbl_clear_signexponent_set_hidden(srcp1);
332*4882a593Smuzhiyun 		Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result);
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 		/* check for inexact */
335*4882a593Smuzhiyun 		if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
336*4882a593Smuzhiyun 			inexact = TRUE;
337*4882a593Smuzhiyun 			/*  round result  */
338*4882a593Smuzhiyun 			switch (Rounding_mode()) {
339*4882a593Smuzhiyun 			case ROUNDPLUS:
340*4882a593Smuzhiyun 			     result++;
341*4882a593Smuzhiyun 			     break;
342*4882a593Smuzhiyun 			case ROUNDMINUS: /* never negative */
343*4882a593Smuzhiyun 			     break;
344*4882a593Smuzhiyun 			case ROUNDNEAREST:
345*4882a593Smuzhiyun 			     if(Dbl_isone_roundbit(srcp1,srcp2,src_exponent) &&
346*4882a593Smuzhiyun 				(Dbl_isone_stickybit(srcp1,srcp2,src_exponent)||
347*4882a593Smuzhiyun 				 result&1))
348*4882a593Smuzhiyun 				   result++;
349*4882a593Smuzhiyun 			     break;
350*4882a593Smuzhiyun 			}
351*4882a593Smuzhiyun 			/* check for overflow */
352*4882a593Smuzhiyun 			if (result == 0) {
353*4882a593Smuzhiyun 				result = 0xffffffff;
354*4882a593Smuzhiyun 				if (Is_invalidtrap_enabled()) {
355*4882a593Smuzhiyun 					return(INVALIDEXCEPTION);
356*4882a593Smuzhiyun 				}
357*4882a593Smuzhiyun 				Set_invalidflag();
358*4882a593Smuzhiyun 				*dstptr = result;
359*4882a593Smuzhiyun 				return(NOEXCEPTION);
360*4882a593Smuzhiyun 			}
361*4882a593Smuzhiyun 		}
362*4882a593Smuzhiyun 	} else {
363*4882a593Smuzhiyun 		result = 0;
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 		/* check for inexact */
366*4882a593Smuzhiyun 		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
367*4882a593Smuzhiyun 			inexact = TRUE;
368*4882a593Smuzhiyun 			/*  round result  */
369*4882a593Smuzhiyun 			switch (Rounding_mode()) {
370*4882a593Smuzhiyun 			case ROUNDPLUS:
371*4882a593Smuzhiyun 				if (Dbl_iszero_sign(srcp1)) result++;
372*4882a593Smuzhiyun 				break;
373*4882a593Smuzhiyun 			case ROUNDMINUS:
374*4882a593Smuzhiyun 				if (Dbl_isone_sign(srcp1)) {
375*4882a593Smuzhiyun 					result = 0;
376*4882a593Smuzhiyun 					if (Is_invalidtrap_enabled()) {
377*4882a593Smuzhiyun 						return(INVALIDEXCEPTION);
378*4882a593Smuzhiyun 					}
379*4882a593Smuzhiyun 					Set_invalidflag();
380*4882a593Smuzhiyun 					inexact = FALSE;
381*4882a593Smuzhiyun 				}
382*4882a593Smuzhiyun 				break;
383*4882a593Smuzhiyun 			case ROUNDNEAREST:
384*4882a593Smuzhiyun 				if (src_exponent == -1 &&
385*4882a593Smuzhiyun 				    Dbl_isnotzero_mantissa(srcp1,srcp2))
386*4882a593Smuzhiyun 					if (Dbl_isone_sign(srcp1)) {
387*4882a593Smuzhiyun 						result = 0;
388*4882a593Smuzhiyun 						if (Is_invalidtrap_enabled()) {
389*4882a593Smuzhiyun 							return(INVALIDEXCEPTION);
390*4882a593Smuzhiyun 						}
391*4882a593Smuzhiyun 						Set_invalidflag();
392*4882a593Smuzhiyun 						inexact = FALSE;
393*4882a593Smuzhiyun 					}
394*4882a593Smuzhiyun 					else result++;
395*4882a593Smuzhiyun 			}
396*4882a593Smuzhiyun 		}
397*4882a593Smuzhiyun 	}
398*4882a593Smuzhiyun 	*dstptr = result;
399*4882a593Smuzhiyun 	if (inexact) {
400*4882a593Smuzhiyun 		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
401*4882a593Smuzhiyun 		else Set_inexactflag();
402*4882a593Smuzhiyun 	}
403*4882a593Smuzhiyun 	return(NOEXCEPTION);
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun /*
407*4882a593Smuzhiyun  *  Double Floating-point to Double Unsigned Fixed
408*4882a593Smuzhiyun  */
409*4882a593Smuzhiyun /*ARGSUSED*/
410*4882a593Smuzhiyun int
dbl_to_dbl_fcnvfu(dbl_floating_point * srcptr,unsigned int * nullptr,dbl_unsigned * dstptr,unsigned int * status)411*4882a593Smuzhiyun dbl_to_dbl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr,
412*4882a593Smuzhiyun 		   dbl_unsigned * dstptr, unsigned int *status)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun 	register int src_exponent;
415*4882a593Smuzhiyun 	register unsigned int srcp1, srcp2, resultp1, resultp2;
416*4882a593Smuzhiyun 	register boolean inexact = FALSE;
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	Dbl_copyfromptr(srcptr,srcp1,srcp2);
419*4882a593Smuzhiyun 	src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	/*
422*4882a593Smuzhiyun 	 * Test for overflow
423*4882a593Smuzhiyun 	 */
424*4882a593Smuzhiyun 	if (src_exponent > DBL_FX_MAX_EXP + 1) {
425*4882a593Smuzhiyun 		if (Dbl_isone_sign(srcp1)) {
426*4882a593Smuzhiyun 			resultp1 = resultp2 = 0;
427*4882a593Smuzhiyun 		} else {
428*4882a593Smuzhiyun 			resultp1 = resultp2 = 0xffffffff;
429*4882a593Smuzhiyun 		}
430*4882a593Smuzhiyun 		if (Is_invalidtrap_enabled()) {
431*4882a593Smuzhiyun 			return(INVALIDEXCEPTION);
432*4882a593Smuzhiyun 		}
433*4882a593Smuzhiyun 		Set_invalidflag();
434*4882a593Smuzhiyun     		Duint_copytoptr(resultp1,resultp2,dstptr);
435*4882a593Smuzhiyun 		return(NOEXCEPTION);
436*4882a593Smuzhiyun 	}
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	/*
439*4882a593Smuzhiyun 	 * Generate result
440*4882a593Smuzhiyun 	 */
441*4882a593Smuzhiyun 	if (src_exponent >= 0) {
442*4882a593Smuzhiyun 		/*
443*4882a593Smuzhiyun 		 * Check sign.
444*4882a593Smuzhiyun 		 * If negative, trap unimplemented.
445*4882a593Smuzhiyun 		 */
446*4882a593Smuzhiyun 		if (Dbl_isone_sign(srcp1)) {
447*4882a593Smuzhiyun 			resultp1 = resultp2 = 0;
448*4882a593Smuzhiyun 			if (Is_invalidtrap_enabled()) {
449*4882a593Smuzhiyun 				return(INVALIDEXCEPTION);
450*4882a593Smuzhiyun 			}
451*4882a593Smuzhiyun 			Set_invalidflag();
452*4882a593Smuzhiyun     			Duint_copytoptr(resultp1,resultp2,dstptr);
453*4882a593Smuzhiyun 			return(NOEXCEPTION);
454*4882a593Smuzhiyun 		}
455*4882a593Smuzhiyun 		Dbl_clear_signexponent_set_hidden(srcp1);
456*4882a593Smuzhiyun 		Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent,resultp1,
457*4882a593Smuzhiyun 		  resultp2);
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 		/* check for inexact */
460*4882a593Smuzhiyun 		if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
461*4882a593Smuzhiyun 			inexact = TRUE;
462*4882a593Smuzhiyun 			/*  round result  */
463*4882a593Smuzhiyun 			switch (Rounding_mode()) {
464*4882a593Smuzhiyun 			case ROUNDPLUS:
465*4882a593Smuzhiyun 				Duint_increment(resultp1,resultp2);
466*4882a593Smuzhiyun 				break;
467*4882a593Smuzhiyun 			case ROUNDMINUS: /* never negative */
468*4882a593Smuzhiyun 				break;
469*4882a593Smuzhiyun 			case ROUNDNEAREST:
470*4882a593Smuzhiyun 				if(Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
471*4882a593Smuzhiyun 				  if(Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
472*4882a593Smuzhiyun 				     Duint_isone_lowp2(resultp2))
473*4882a593Smuzhiyun 					Duint_increment(resultp1,resultp2);
474*4882a593Smuzhiyun 			}
475*4882a593Smuzhiyun 		}
476*4882a593Smuzhiyun 	} else {
477*4882a593Smuzhiyun 		Duint_setzero(resultp1,resultp2);
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 		/* check for inexact */
480*4882a593Smuzhiyun 		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
481*4882a593Smuzhiyun 			inexact = TRUE;
482*4882a593Smuzhiyun 			/*  round result  */
483*4882a593Smuzhiyun 			switch (Rounding_mode()) {
484*4882a593Smuzhiyun 			case ROUNDPLUS:
485*4882a593Smuzhiyun 				if (Dbl_iszero_sign(srcp1)) {
486*4882a593Smuzhiyun 					Duint_increment(resultp1,resultp2);
487*4882a593Smuzhiyun 				}
488*4882a593Smuzhiyun 				break;
489*4882a593Smuzhiyun 			case ROUNDMINUS:
490*4882a593Smuzhiyun 				if (Dbl_isone_sign(srcp1)) {
491*4882a593Smuzhiyun 					resultp1 = resultp2 = 0;
492*4882a593Smuzhiyun 					if (Is_invalidtrap_enabled()) {
493*4882a593Smuzhiyun 						return(INVALIDEXCEPTION);
494*4882a593Smuzhiyun 					}
495*4882a593Smuzhiyun 					Set_invalidflag();
496*4882a593Smuzhiyun 					inexact = FALSE;
497*4882a593Smuzhiyun 				}
498*4882a593Smuzhiyun 				break;
499*4882a593Smuzhiyun 			case ROUNDNEAREST:
500*4882a593Smuzhiyun 				if (src_exponent == -1 &&
501*4882a593Smuzhiyun 				    Dbl_isnotzero_mantissa(srcp1,srcp2))
502*4882a593Smuzhiyun 					if (Dbl_iszero_sign(srcp1)) {
503*4882a593Smuzhiyun 						Duint_increment(resultp1,resultp2);
504*4882a593Smuzhiyun 					} else {
505*4882a593Smuzhiyun 						resultp1 = 0;
506*4882a593Smuzhiyun 						resultp2 = 0;
507*4882a593Smuzhiyun 						if (Is_invalidtrap_enabled()) {
508*4882a593Smuzhiyun 							return(INVALIDEXCEPTION);
509*4882a593Smuzhiyun 						}
510*4882a593Smuzhiyun 						Set_invalidflag();
511*4882a593Smuzhiyun 						inexact = FALSE;
512*4882a593Smuzhiyun 					}
513*4882a593Smuzhiyun 			}
514*4882a593Smuzhiyun 		}
515*4882a593Smuzhiyun 	}
516*4882a593Smuzhiyun 	Duint_copytoptr(resultp1,resultp2,dstptr);
517*4882a593Smuzhiyun 	if (inexact) {
518*4882a593Smuzhiyun 		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
519*4882a593Smuzhiyun 		else Set_inexactflag();
520*4882a593Smuzhiyun 	}
521*4882a593Smuzhiyun 	return(NOEXCEPTION);
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun 
524