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