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 |
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 |
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 |
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 |
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 | |