Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fcnvfut.c
Go to the documentation of this file.
1 /*
2  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
3  *
4  * Floating-point emulation code
5  * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 /*
22  * BEGIN_DESC
23  *
24  * File:
25  * @(#) pa/spmath/fcnvfut.c $Revision: 1.1 $
26  *
27  * Purpose:
28  * Floating-point to Unsigned Fixed-point Converts with Truncation
29  *
30  * External Interfaces:
31  * dbl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status)
32  * dbl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status)
33  * sgl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status)
34  * sgl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status)
35  *
36  * Internal Interfaces:
37  *
38  * Theory:
39  * <<please update with a overview of the operation of this file>>
40  *
41  * END_DESC
42 */
43 
44 
45 #include "float.h"
46 #include "sgl_float.h"
47 #include "dbl_float.h"
48 #include "cnv_float.h"
49 
50 /************************************************************************
51  * Floating-point to Unsigned Fixed-point Converts with Truncation *
52  ************************************************************************/
53 
54 /*
55  * Convert single floating-point to single fixed-point format
56  * with truncated result
57  */
58 /*ARGSUSED*/
59 int
60 sgl_to_sgl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
61  unsigned int *dstptr, unsigned int *status)
62 {
63  register unsigned int src, result;
64  register int src_exponent;
65 
66  src = *srcptr;
67  src_exponent = Sgl_exponent(src) - SGL_BIAS;
68 
69  /*
70  * Test for overflow
71  */
72  if (src_exponent > SGL_FX_MAX_EXP + 1) {
73  if (Sgl_isone_sign(src)) {
74  result = 0;
75  } else {
76  result = 0xffffffff;
77  }
78  if (Is_invalidtrap_enabled()) {
79  return(INVALIDEXCEPTION);
80  }
82  *dstptr = result;
83  return(NOEXCEPTION);
84  }
85  /*
86  * Generate result
87  */
88  if (src_exponent >= 0) {
89  /*
90  * Check sign.
91  * If negative, trap unimplemented.
92  */
93  if (Sgl_isone_sign(src)) {
94  result = 0;
95  if (Is_invalidtrap_enabled()) {
96  return(INVALIDEXCEPTION);
97  }
99  *dstptr = result;
100  return(NOEXCEPTION);
101  }
103  Suint_from_sgl_mantissa(src,src_exponent,result);
104  *dstptr = result;
105 
106  /* check for inexact */
107  if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
109  else Set_inexactflag();
110  }
111  }
112  else {
113  *dstptr = 0;
114 
115  /* check for inexact */
118  else Set_inexactflag();
119  }
120  }
121  return(NOEXCEPTION);
122 }
123 
124 /*
125  * Single Floating-point to Double Unsigned Fixed
126  */
127 /*ARGSUSED*/
128 int
129 sgl_to_dbl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
130  dbl_unsigned * dstptr, unsigned int *status)
131 {
132  register int src_exponent;
133  register unsigned int src, resultp1, resultp2;
134 
135  src = *srcptr;
136  src_exponent = Sgl_exponent(src) - SGL_BIAS;
137 
138  /*
139  * Test for overflow
140  */
141  if (src_exponent > DBL_FX_MAX_EXP + 1) {
142  if (Sgl_isone_sign(src)) {
143  resultp1 = resultp2 = 0;
144  } else {
145  resultp1 = resultp2 = 0xffffffff;
146  }
147  if (Is_invalidtrap_enabled()) {
148  return(INVALIDEXCEPTION);
149  }
150  Set_invalidflag();
151  Duint_copytoptr(resultp1,resultp2,dstptr);
152  return(NOEXCEPTION);
153  }
154  /*
155  * Generate result
156  */
157  if (src_exponent >= 0) {
158  /*
159  * Check sign.
160  * If negative, trap unimplemented.
161  */
162  if (Sgl_isone_sign(src)) {
163  resultp1 = resultp2 = 0;
164  if (Is_invalidtrap_enabled()) {
165  return(INVALIDEXCEPTION);
166  }
167  Set_invalidflag();
168  Duint_copytoptr(resultp1,resultp2,dstptr);
169  return(NOEXCEPTION);
170  }
172  Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2);
173  Duint_copytoptr(resultp1,resultp2,dstptr);
174 
175  /* check for inexact */
176  if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
178  else Set_inexactflag();
179  }
180  }
181  else {
182  Duint_setzero(resultp1,resultp2);
183  Duint_copytoptr(resultp1,resultp2,dstptr);
184 
185  /* check for inexact */
188  else Set_inexactflag();
189  }
190  }
191  return(NOEXCEPTION);
192 }
193 
194 /*
195  * Double Floating-point to Single Unsigned Fixed
196  */
197 /*ARGSUSED*/
198 int
199 dbl_to_sgl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
200  unsigned int *dstptr, unsigned int *status)
201 {
202  register unsigned int srcp1, srcp2, result;
203  register int src_exponent;
204 
205  Dbl_copyfromptr(srcptr,srcp1,srcp2);
206  src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
207 
208  /*
209  * Test for overflow
210  */
211  if (src_exponent > SGL_FX_MAX_EXP + 1) {
212  if (Dbl_isone_sign(srcp1)) {
213  result = 0;
214  } else {
215  result = 0xffffffff;
216  }
217  if (Is_invalidtrap_enabled()) {
218  return(INVALIDEXCEPTION);
219  }
220  Set_invalidflag();
221  *dstptr = result;
222  return(NOEXCEPTION);
223  }
224  /*
225  * Generate result
226  */
227  if (src_exponent >= 0) {
228  /*
229  * Check sign.
230  * If negative, trap unimplemented.
231  */
232  if (Dbl_isone_sign(srcp1)) {
233  result = 0;
234  if (Is_invalidtrap_enabled()) {
235  return(INVALIDEXCEPTION);
236  }
237  Set_invalidflag();
238  *dstptr = result;
239  return(NOEXCEPTION);
240  }
242  Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result);
243  *dstptr = result;
244 
245  /* check for inexact */
246  if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
248  else Set_inexactflag();
249  }
250  }
251  else {
252  *dstptr = 0;
253 
254  /* check for inexact */
255  if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
257  else Set_inexactflag();
258  }
259  }
260  return(NOEXCEPTION);
261 }
262 
263 /*
264  * Double Floating-point to Double Unsigned Fixed
265  */
266 /*ARGSUSED*/
267 int
268 dbl_to_dbl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
269  dbl_unsigned * dstptr, unsigned int *status)
270 {
271  register int src_exponent;
272  register unsigned int srcp1, srcp2, resultp1, resultp2;
273 
274  Dbl_copyfromptr(srcptr,srcp1,srcp2);
275  src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
276 
277  /*
278  * Test for overflow
279  */
280  if (src_exponent > DBL_FX_MAX_EXP + 1) {
281  if (Dbl_isone_sign(srcp1)) {
282  resultp1 = resultp2 = 0;
283  } else {
284  resultp1 = resultp2 = 0xffffffff;
285  }
286  if (Is_invalidtrap_enabled()) {
287  return(INVALIDEXCEPTION);
288  }
289  Set_invalidflag();
290  Duint_copytoptr(resultp1,resultp2,dstptr);
291  return(NOEXCEPTION);
292  }
293  /*
294  * Generate result
295  */
296  if (src_exponent >= 0) {
297  /*
298  * Check sign.
299  * If negative, trap unimplemented.
300  */
301  if (Dbl_isone_sign(srcp1)) {
302  resultp1 = resultp2 = 0;
303  if (Is_invalidtrap_enabled()) {
304  return(INVALIDEXCEPTION);
305  }
306  Set_invalidflag();
307  Duint_copytoptr(resultp1,resultp2,dstptr);
308  return(NOEXCEPTION);
309  }
311  Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent,
312  resultp1,resultp2);
313  Duint_copytoptr(resultp1,resultp2,dstptr);
314 
315  /* check for inexact */
316  if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
318  else Set_inexactflag();
319  }
320  }
321  else {
322  Duint_setzero(resultp1,resultp2);
323  Duint_copytoptr(resultp1,resultp2,dstptr);
324 
325  /* check for inexact */
326  if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
328  else Set_inexactflag();
329  }
330  }
331  return(NOEXCEPTION);
332 }