1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
4 *
5 * Floating-point emulation code
6 * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
7 */
8 /*
9 * BEGIN_DESC
10 *
11 * File:
12 * @(#) pa/spmath/fcnvfut.c $Revision: 1.1 $
13 *
14 * Purpose:
15 * Floating-point to Unsigned Fixed-point Converts with Truncation
16 *
17 * External Interfaces:
18 * dbl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status)
19 * dbl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status)
20 * sgl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status)
21 * sgl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status)
22 *
23 * Internal Interfaces:
24 *
25 * Theory:
26 * <<please update with a overview of the operation of this file>>
27 *
28 * END_DESC
29 */
30
31
32 #include "float.h"
33 #include "sgl_float.h"
34 #include "dbl_float.h"
35 #include "cnv_float.h"
36
37 /************************************************************************
38 * Floating-point to Unsigned Fixed-point Converts with Truncation *
39 ************************************************************************/
40
41 /*
42 * Convert single floating-point to single fixed-point format
43 * with truncated result
44 */
45 /*ARGSUSED*/
46 int
sgl_to_sgl_fcnvfut(sgl_floating_point * srcptr,unsigned int * nullptr,unsigned int * dstptr,unsigned int * status)47 sgl_to_sgl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
48 unsigned int *dstptr, unsigned int *status)
49 {
50 register unsigned int src, result;
51 register int src_exponent;
52
53 src = *srcptr;
54 src_exponent = Sgl_exponent(src) - SGL_BIAS;
55
56 /*
57 * Test for overflow
58 */
59 if (src_exponent > SGL_FX_MAX_EXP + 1) {
60 if (Sgl_isone_sign(src)) {
61 result = 0;
62 } else {
63 result = 0xffffffff;
64 }
65 if (Is_invalidtrap_enabled()) {
66 return(INVALIDEXCEPTION);
67 }
68 Set_invalidflag();
69 *dstptr = result;
70 return(NOEXCEPTION);
71 }
72 /*
73 * Generate result
74 */
75 if (src_exponent >= 0) {
76 /*
77 * Check sign.
78 * If negative, trap unimplemented.
79 */
80 if (Sgl_isone_sign(src)) {
81 result = 0;
82 if (Is_invalidtrap_enabled()) {
83 return(INVALIDEXCEPTION);
84 }
85 Set_invalidflag();
86 *dstptr = result;
87 return(NOEXCEPTION);
88 }
89 Sgl_clear_signexponent_set_hidden(src);
90 Suint_from_sgl_mantissa(src,src_exponent,result);
91 *dstptr = result;
92
93 /* check for inexact */
94 if (Sgl_isinexact_to_unsigned(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 Unsigned Fixed
113 */
114 /*ARGSUSED*/
115 int
sgl_to_dbl_fcnvfut(sgl_floating_point * srcptr,unsigned int * nullptr,dbl_unsigned * dstptr,unsigned int * status)116 sgl_to_dbl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
117 dbl_unsigned * dstptr, unsigned int *status)
118 {
119 register int src_exponent;
120 register unsigned int src, resultp1, resultp2;
121
122 src = *srcptr;
123 src_exponent = Sgl_exponent(src) - SGL_BIAS;
124
125 /*
126 * Test for overflow
127 */
128 if (src_exponent > DBL_FX_MAX_EXP + 1) {
129 if (Sgl_isone_sign(src)) {
130 resultp1 = resultp2 = 0;
131 } else {
132 resultp1 = resultp2 = 0xffffffff;
133 }
134 if (Is_invalidtrap_enabled()) {
135 return(INVALIDEXCEPTION);
136 }
137 Set_invalidflag();
138 Duint_copytoptr(resultp1,resultp2,dstptr);
139 return(NOEXCEPTION);
140 }
141 /*
142 * Generate result
143 */
144 if (src_exponent >= 0) {
145 /*
146 * Check sign.
147 * If negative, trap unimplemented.
148 */
149 if (Sgl_isone_sign(src)) {
150 resultp1 = resultp2 = 0;
151 if (Is_invalidtrap_enabled()) {
152 return(INVALIDEXCEPTION);
153 }
154 Set_invalidflag();
155 Duint_copytoptr(resultp1,resultp2,dstptr);
156 return(NOEXCEPTION);
157 }
158 Sgl_clear_signexponent_set_hidden(src);
159 Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2);
160 Duint_copytoptr(resultp1,resultp2,dstptr);
161
162 /* check for inexact */
163 if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
164 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
165 else Set_inexactflag();
166 }
167 }
168 else {
169 Duint_setzero(resultp1,resultp2);
170 Duint_copytoptr(resultp1,resultp2,dstptr);
171
172 /* check for inexact */
173 if (Sgl_isnotzero_exponentmantissa(src)) {
174 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
175 else Set_inexactflag();
176 }
177 }
178 return(NOEXCEPTION);
179 }
180
181 /*
182 * Double Floating-point to Single Unsigned Fixed
183 */
184 /*ARGSUSED*/
185 int
dbl_to_sgl_fcnvfut(dbl_floating_point * srcptr,unsigned int * nullptr,unsigned int * dstptr,unsigned int * status)186 dbl_to_sgl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
187 unsigned int *dstptr, unsigned int *status)
188 {
189 register unsigned int srcp1, srcp2, result;
190 register int src_exponent;
191
192 Dbl_copyfromptr(srcptr,srcp1,srcp2);
193 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
194
195 /*
196 * Test for overflow
197 */
198 if (src_exponent > SGL_FX_MAX_EXP + 1) {
199 if (Dbl_isone_sign(srcp1)) {
200 result = 0;
201 } else {
202 result = 0xffffffff;
203 }
204 if (Is_invalidtrap_enabled()) {
205 return(INVALIDEXCEPTION);
206 }
207 Set_invalidflag();
208 *dstptr = result;
209 return(NOEXCEPTION);
210 }
211 /*
212 * Generate result
213 */
214 if (src_exponent >= 0) {
215 /*
216 * Check sign.
217 * If negative, trap unimplemented.
218 */
219 if (Dbl_isone_sign(srcp1)) {
220 result = 0;
221 if (Is_invalidtrap_enabled()) {
222 return(INVALIDEXCEPTION);
223 }
224 Set_invalidflag();
225 *dstptr = result;
226 return(NOEXCEPTION);
227 }
228 Dbl_clear_signexponent_set_hidden(srcp1);
229 Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result);
230 *dstptr = result;
231
232 /* check for inexact */
233 if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
234 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
235 else Set_inexactflag();
236 }
237 }
238 else {
239 *dstptr = 0;
240
241 /* check for inexact */
242 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
243 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
244 else Set_inexactflag();
245 }
246 }
247 return(NOEXCEPTION);
248 }
249
250 /*
251 * Double Floating-point to Double Unsigned Fixed
252 */
253 /*ARGSUSED*/
254 int
dbl_to_dbl_fcnvfut(dbl_floating_point * srcptr,unsigned int * nullptr,dbl_unsigned * dstptr,unsigned int * status)255 dbl_to_dbl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
256 dbl_unsigned * dstptr, unsigned int *status)
257 {
258 register int src_exponent;
259 register unsigned int srcp1, srcp2, resultp1, resultp2;
260
261 Dbl_copyfromptr(srcptr,srcp1,srcp2);
262 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
263
264 /*
265 * Test for overflow
266 */
267 if (src_exponent > DBL_FX_MAX_EXP + 1) {
268 if (Dbl_isone_sign(srcp1)) {
269 resultp1 = resultp2 = 0;
270 } else {
271 resultp1 = resultp2 = 0xffffffff;
272 }
273 if (Is_invalidtrap_enabled()) {
274 return(INVALIDEXCEPTION);
275 }
276 Set_invalidflag();
277 Duint_copytoptr(resultp1,resultp2,dstptr);
278 return(NOEXCEPTION);
279 }
280 /*
281 * Generate result
282 */
283 if (src_exponent >= 0) {
284 /*
285 * Check sign.
286 * If negative, trap unimplemented.
287 */
288 if (Dbl_isone_sign(srcp1)) {
289 resultp1 = resultp2 = 0;
290 if (Is_invalidtrap_enabled()) {
291 return(INVALIDEXCEPTION);
292 }
293 Set_invalidflag();
294 Duint_copytoptr(resultp1,resultp2,dstptr);
295 return(NOEXCEPTION);
296 }
297 Dbl_clear_signexponent_set_hidden(srcp1);
298 Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent,
299 resultp1,resultp2);
300 Duint_copytoptr(resultp1,resultp2,dstptr);
301
302 /* check for inexact */
303 if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
304 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
305 else Set_inexactflag();
306 }
307 }
308 else {
309 Duint_setzero(resultp1,resultp2);
310 Duint_copytoptr(resultp1,resultp2,dstptr);
311
312 /* check for inexact */
313 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
314 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
315 else Set_inexactflag();
316 }
317 }
318 return(NOEXCEPTION);
319 }
320