xref: /netbsd/sys/arch/hppa/spmath/fcnvfxt.c (revision c4a72b64)
1 /*	$NetBSD: fcnvfxt.c,v 1.1 2002/06/05 01:04:25 fredette 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 "../spmath/float.h"
45 #include "../spmath/sgl_float.h"
46 #include "../spmath/dbl_float.h"
47 #include "../spmath/cnv_float.h"
48 
49 /*
50  *  Convert single floating-point to single fixed-point format
51  *  with truncated result
52  */
53 /*ARGSUSED*/
54 int
55 sgl_to_sgl_fcnvfxt(srcptr,dstptr,status)
56 
57 sgl_floating_point *srcptr;
58 int *dstptr;
59 unsigned int *status;
60 {
61 	register unsigned int src, temp;
62 	register int src_exponent, result;
63 
64 	src = *srcptr;
65 	src_exponent = Sgl_exponent(src) - SGL_BIAS;
66 
67 	/*
68 	 * Test for overflow
69 	 */
70 	if (src_exponent > SGL_FX_MAX_EXP) {
71 		/* check for MININT */
72 		if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
73 		Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
74 			/*
75 			 * Since source is a number which cannot be
76 			 * represented in fixed-point format, return
77 			 * largest (or smallest) fixed-point number.
78 			 */
79 			Sgl_return_overflow(src,dstptr);
80 		}
81 	}
82 	/*
83 	 * Generate result
84 	 */
85 	if (src_exponent >= 0) {
86 		temp = src;
87 		Sgl_clear_signexponent_set_hidden(temp);
88 		Int_from_sgl_mantissa(temp,src_exponent);
89 		if (Sgl_isone_sign(src))  result = -Sgl_all(temp);
90 		else result = Sgl_all(temp);
91 		*dstptr = result;
92 
93 		/* check for inexact */
94 		if (Sgl_isinexact_to_fix(src,src_exponent)) {
95 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
96 			else Set_inexactflag();
97 		}
98 	}
99 	else {
100 		*dstptr = 0;
101 
102 		/* check for inexact */
103 		if (Sgl_isnotzero_exponentmantissa(src)) {
104 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
105 			else Set_inexactflag();
106 		}
107 	}
108 	return(NOEXCEPTION);
109 }
110 
111 /*
112  *  Single Floating-point to Double Fixed-point
113  */
114 /*ARGSUSED*/
115 int
116 sgl_to_dbl_fcnvfxt(srcptr,dstptr,status)
117 
118 sgl_floating_point *srcptr;
119 dbl_integer *dstptr;
120 unsigned int *status;
121 {
122 	register int src_exponent, resultp1;
123 	register unsigned int src, temp, resultp2;
124 
125 	src = *srcptr;
126 	src_exponent = Sgl_exponent(src) - SGL_BIAS;
127 
128 	/*
129 	 * Test for overflow
130 	 */
131 	if (src_exponent > DBL_FX_MAX_EXP) {
132 		/* check for MININT */
133 		if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
134 		Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
135 			/*
136 			 * Since source is a number which cannot be
137 			 * represented in fixed-point format, return
138 			 * largest (or smallest) fixed-point number.
139 			 */
140 			Sgl_return_overflow_dbl(src,dstptr);
141 		}
142 		Dint_set_minint(resultp1,resultp2);
143 		Dint_copytoptr(resultp1,resultp2,dstptr);
144 		return(NOEXCEPTION);
145 	}
146 	/*
147 	 * Generate result
148 	 */
149 	if (src_exponent >= 0) {
150 		temp = src;
151 		Sgl_clear_signexponent_set_hidden(temp);
152 		Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
153 		if (Sgl_isone_sign(src)) {
154 			Dint_setone_sign(resultp1,resultp2);
155 		}
156 		Dint_copytoptr(resultp1,resultp2,dstptr);
157 
158 		/* check for inexact */
159 		if (Sgl_isinexact_to_fix(src,src_exponent)) {
160 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
161 			else Set_inexactflag();
162 		}
163 	}
164 	else {
165 		Dint_setzero(resultp1,resultp2);
166 		Dint_copytoptr(resultp1,resultp2,dstptr);
167 
168 		/* check for inexact */
169 		if (Sgl_isnotzero_exponentmantissa(src)) {
170 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
171 			else Set_inexactflag();
172 		}
173 	}
174 	return(NOEXCEPTION);
175 }
176 
177 /*
178  *  Double Floating-point to Single Fixed-point
179  */
180 /*ARGSUSED*/
181 int
182 dbl_to_sgl_fcnvfxt(srcptr,dstptr,status)
183 
184 dbl_floating_point *srcptr;
185 int *dstptr;
186 unsigned int *status;
187 {
188 	register unsigned int srcp1, srcp2, tempp1, tempp2;
189 	register int src_exponent, result;
190 
191 	Dbl_copyfromptr(srcptr,srcp1,srcp2);
192 	src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
193 
194 	/*
195 	 * Test for overflow
196 	 */
197 	if (src_exponent > SGL_FX_MAX_EXP) {
198 		/* check for MININT */
199 		if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
200 			Dbl_return_overflow(srcp1,srcp2,dstptr);
201 		}
202 	}
203 	/*
204 	 * Generate result
205 	 */
206 	if (src_exponent >= 0) {
207 		tempp1 = srcp1;
208 		tempp2 = srcp2;
209 		Dbl_clear_signexponent_set_hidden(tempp1);
210 		Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
211 		if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
212 			result = -Dbl_allp1(tempp1);
213 		else result = Dbl_allp1(tempp1);
214 		*dstptr = result;
215 
216 		/* check for inexact */
217 		if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
218 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
219 			else Set_inexactflag();
220 		}
221 	}
222 	else {
223 		*dstptr = 0;
224 
225 		/* check for inexact */
226 		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
227 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
228 			else Set_inexactflag();
229 		}
230 	}
231 	return(NOEXCEPTION);
232 }
233 
234 /*
235  *  Double Floating-point to Double Fixed-point
236  */
237 /*ARGSUSED*/
238 int
239 dbl_to_dbl_fcnvfxt(srcptr,dstptr,status)
240 
241 dbl_floating_point *srcptr;
242 dbl_integer *dstptr;
243 unsigned int *status;
244 {
245 	register int src_exponent, resultp1;
246 	register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
247 
248 	Dbl_copyfromptr(srcptr,srcp1,srcp2);
249 	src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
250 
251 	/*
252 	 * Test for overflow
253 	 */
254 	if (src_exponent > DBL_FX_MAX_EXP) {
255 		/* check for MININT */
256 		if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
257 		Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
258 			/*
259 			 * Since source is a number which cannot be
260 			 * represented in fixed-point format, return
261 			 * largest (or smallest) fixed-point number.
262 			 */
263 			Dbl_return_overflow_dbl(srcp1,srcp2,dstptr);
264 		}
265 	}
266 	/*
267 	 * Generate result
268 	 */
269 	if (src_exponent >= 0) {
270 		tempp1 = srcp1;
271 		tempp2 = srcp2;
272 		Dbl_clear_signexponent_set_hidden(tempp1);
273 		Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
274 		resultp1,resultp2);
275 		if (Dbl_isone_sign(srcp1)) {
276 			Dint_setone_sign(resultp1,resultp2);
277 		}
278 		Dint_copytoptr(resultp1,resultp2,dstptr);
279 
280 		/* check for inexact */
281 		if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
282 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
283 			else Set_inexactflag();
284 		}
285 	}
286 	else {
287 		Dint_setzero(resultp1,resultp2);
288 		Dint_copytoptr(resultp1,resultp2,dstptr);
289 
290 		/* check for inexact */
291 		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
292 			if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
293 			else Set_inexactflag();
294 		}
295 	}
296 	return(NOEXCEPTION);
297 }
298