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