xref: /netbsd-src/sys/arch/hppa/spmath/fcnvfxt.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*	$NetBSD: fcnvfxt.c,v 1.3 2005/12/11 12:17:40 christos Exp $	*/
2 
3 /*	$OpenBSD: fcnvfxt.c,v 1.5 2001/03/29 03:58:18 mickey Exp $	*/
4 
5 /*
6  * Copyright 1996 1995 by Open Software Foundation, Inc.
7  *              All Rights Reserved
8  *
9  * Permission to use, copy, modify, and distribute this software and
10  * its documentation for any purpose and without fee is hereby granted,
11  * provided that the above copyright notice appears in all copies and
12  * that both the copyright notice and this permission notice appear in
13  * supporting documentation.
14  *
15  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17  * FOR A PARTICULAR PURPOSE.
18  *
19  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
20  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
22  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
23  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24  *
25  */
26 /*
27  * pmk1.1
28  */
29 /*
30  * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
31  *
32  * To anyone who acknowledges that this file is provided "AS IS"
33  * without any express or implied warranty:
34  *     permission to use, copy, modify, and distribute this file
35  * for any purpose is hereby granted without fee, provided that
36  * the above copyright notice and this notice appears in all
37  * copies, and that the name of Hewlett-Packard Company not be
38  * used in advertising or publicity pertaining to distribution
39  * of the software without specific, written prior permission.
40  * Hewlett-Packard Company makes no representations about the
41  * suitability of this software for any purpose.
42  */
43 
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: fcnvfxt.c,v 1.3 2005/12/11 12:17:40 christos Exp $");
46 
47 #include "../spmath/float.h"
48 #include "../spmath/sgl_float.h"
49 #include "../spmath/dbl_float.h"
50 #include "../spmath/cnv_float.h"
51 
52 /*
53  *  Convert single floating-point to single fixed-point format
54  *  with truncated result
55  */
56 /*ARGSUSED*/
57 int
58 sgl_to_sgl_fcnvfxt(srcptr,dstptr,status)
59 
60 sgl_floating_point *srcptr;
61 int *dstptr;
62 unsigned int *status;
63 {
64 	register unsigned int src, temp;
65 	register int src_exponent, result;
66 
67 	src = *srcptr;
68 	src_exponent = Sgl_exponent(src) - SGL_BIAS;
69 
70 	/*
71 	 * Test for overflow
72 	 */
73 	if (src_exponent > SGL_FX_MAX_EXP) {
74 		/* check for MININT */
75 		if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
76 		Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
77 			/*
78 			 * Since source is a number which cannot be
79 			 * represented in fixed-point format, return
80 			 * largest (or smallest) fixed-point number.
81 			 */
82 			Sgl_return_overflow(src,dstptr);
83 		}
84 	}
85 	/*
86 	 * Generate result
87 	 */
88 	if (src_exponent >= 0) {
89 		temp = src;
90 		Sgl_clear_signexponent_set_hidden(temp);
91 		Int_from_sgl_mantissa(temp,src_exponent);
92 		if (Sgl_isone_sign(src))  result = -Sgl_all(temp);
93 		else result = Sgl_all(temp);
94 		*dstptr = result;
95 
96 		/* check for inexact */
97 		if (Sgl_isinexact_to_fix(src,src_exponent)) {
98 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
99 			else Set_inexactflag();
100 		}
101 	}
102 	else {
103 		*dstptr = 0;
104 
105 		/* check for inexact */
106 		if (Sgl_isnotzero_exponentmantissa(src)) {
107 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
108 			else Set_inexactflag();
109 		}
110 	}
111 	return(NOEXCEPTION);
112 }
113 
114 /*
115  *  Single Floating-point to Double Fixed-point
116  */
117 /*ARGSUSED*/
118 int
119 sgl_to_dbl_fcnvfxt(srcptr,dstptr,status)
120 
121 sgl_floating_point *srcptr;
122 dbl_integer *dstptr;
123 unsigned int *status;
124 {
125 	register int src_exponent, resultp1;
126 	register unsigned int src, temp, resultp2;
127 
128 	src = *srcptr;
129 	src_exponent = Sgl_exponent(src) - SGL_BIAS;
130 
131 	/*
132 	 * Test for overflow
133 	 */
134 	if (src_exponent > DBL_FX_MAX_EXP) {
135 		/* check for MININT */
136 		if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
137 		Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
138 			/*
139 			 * Since source is a number which cannot be
140 			 * represented in fixed-point format, return
141 			 * largest (or smallest) fixed-point number.
142 			 */
143 			Sgl_return_overflow_dbl(src,dstptr);
144 		}
145 		Dint_set_minint(resultp1,resultp2);
146 		Dint_copytoptr(resultp1,resultp2,dstptr);
147 		return(NOEXCEPTION);
148 	}
149 	/*
150 	 * Generate result
151 	 */
152 	if (src_exponent >= 0) {
153 		temp = src;
154 		Sgl_clear_signexponent_set_hidden(temp);
155 		Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
156 		if (Sgl_isone_sign(src)) {
157 			Dint_setone_sign(resultp1,resultp2);
158 		}
159 		Dint_copytoptr(resultp1,resultp2,dstptr);
160 
161 		/* check for inexact */
162 		if (Sgl_isinexact_to_fix(src,src_exponent)) {
163 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
164 			else Set_inexactflag();
165 		}
166 	}
167 	else {
168 		Dint_setzero(resultp1,resultp2);
169 		Dint_copytoptr(resultp1,resultp2,dstptr);
170 
171 		/* check for inexact */
172 		if (Sgl_isnotzero_exponentmantissa(src)) {
173 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
174 			else Set_inexactflag();
175 		}
176 	}
177 	return(NOEXCEPTION);
178 }
179 
180 /*
181  *  Double Floating-point to Single Fixed-point
182  */
183 /*ARGSUSED*/
184 int
185 dbl_to_sgl_fcnvfxt(srcptr,dstptr,status)
186 
187 dbl_floating_point *srcptr;
188 int *dstptr;
189 unsigned int *status;
190 {
191 	register unsigned int srcp1, srcp2, tempp1, tempp2;
192 	register int src_exponent, result;
193 
194 	Dbl_copyfromptr(srcptr,srcp1,srcp2);
195 	src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
196 
197 	/*
198 	 * Test for overflow
199 	 */
200 	if (src_exponent > SGL_FX_MAX_EXP) {
201 		/* check for MININT */
202 		if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
203 			Dbl_return_overflow(srcp1,srcp2,dstptr);
204 		}
205 	}
206 	/*
207 	 * Generate result
208 	 */
209 	if (src_exponent >= 0) {
210 		tempp1 = srcp1;
211 		tempp2 = srcp2;
212 		Dbl_clear_signexponent_set_hidden(tempp1);
213 		Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
214 		if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
215 			result = -Dbl_allp1(tempp1);
216 		else result = Dbl_allp1(tempp1);
217 		*dstptr = result;
218 
219 		/* check for inexact */
220 		if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
221 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
222 			else Set_inexactflag();
223 		}
224 	}
225 	else {
226 		*dstptr = 0;
227 
228 		/* check for inexact */
229 		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
230 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
231 			else Set_inexactflag();
232 		}
233 	}
234 	return(NOEXCEPTION);
235 }
236 
237 /*
238  *  Double Floating-point to Double Fixed-point
239  */
240 /*ARGSUSED*/
241 int
242 dbl_to_dbl_fcnvfxt(srcptr,dstptr,status)
243 
244 dbl_floating_point *srcptr;
245 dbl_integer *dstptr;
246 unsigned int *status;
247 {
248 	register int src_exponent, resultp1;
249 	register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
250 
251 	Dbl_copyfromptr(srcptr,srcp1,srcp2);
252 	src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
253 
254 	/*
255 	 * Test for overflow
256 	 */
257 	if (src_exponent > DBL_FX_MAX_EXP) {
258 		/* check for MININT */
259 		if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
260 		Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
261 			/*
262 			 * Since source is a number which cannot be
263 			 * represented in fixed-point format, return
264 			 * largest (or smallest) fixed-point number.
265 			 */
266 			Dbl_return_overflow_dbl(srcp1,srcp2,dstptr);
267 		}
268 	}
269 	/*
270 	 * Generate result
271 	 */
272 	if (src_exponent >= 0) {
273 		tempp1 = srcp1;
274 		tempp2 = srcp2;
275 		Dbl_clear_signexponent_set_hidden(tempp1);
276 		Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
277 		resultp1,resultp2);
278 		if (Dbl_isone_sign(srcp1)) {
279 			Dint_setone_sign(resultp1,resultp2);
280 		}
281 		Dint_copytoptr(resultp1,resultp2,dstptr);
282 
283 		/* check for inexact */
284 		if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
285 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
286 			else Set_inexactflag();
287 		}
288 	}
289 	else {
290 		Dint_setzero(resultp1,resultp2);
291 		Dint_copytoptr(resultp1,resultp2,dstptr);
292 
293 		/* check for inexact */
294 		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
295 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
296 			else Set_inexactflag();
297 		}
298 	}
299 	return(NOEXCEPTION);
300 }
301