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