Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fcnvfxt.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/fcnvfxt.c $Revision: 1.1 $
26  *
27  * Purpose:
28  * Single Floating-point to Single Fixed-point /w truncated result
29  * Single Floating-point to Double Fixed-point /w truncated result
30  * Double Floating-point to Single Fixed-point /w truncated result
31  * Double Floating-point to Double Fixed-point /w truncated result
32  *
33  * External Interfaces:
34  * dbl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
35  * dbl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
36  * sgl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
37  * sgl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
38  *
39  * Internal Interfaces:
40  *
41  * Theory:
42  * <<please update with a overview of the operation of this file>>
43  *
44  * END_DESC
45 */
46 
47 
48 #include "float.h"
49 #include "sgl_float.h"
50 #include "dbl_float.h"
51 #include "cnv_float.h"
52 
53 /*
54  * Convert single floating-point to single fixed-point format
55  * with truncated result
56  */
57 /*ARGSUSED*/
58 int
60  sgl_floating_point *srcptr,
61  unsigned int *nullptr,
62  int *dstptr,
63  unsigned int *status)
64 {
65  register unsigned int src, temp;
66  register int src_exponent, result;
67 
68  src = *srcptr;
69  src_exponent = Sgl_exponent(src) - SGL_BIAS;
70 
71  /*
72  * Test for overflow
73  */
74  if (src_exponent > SGL_FX_MAX_EXP) {
75  /* check for MININT */
76  if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
78  if (Sgl_iszero_sign(src)) result = 0x7fffffff;
79  else result = 0x80000000;
80 
81  if (Is_invalidtrap_enabled()) {
82  return(INVALIDEXCEPTION);
83  }
85  *dstptr = result;
86  return(NOEXCEPTION);
87  }
88  }
89  /*
90  * Generate result
91  */
92  if (src_exponent >= 0) {
93  temp = src;
95  Int_from_sgl_mantissa(temp,src_exponent);
96  if (Sgl_isone_sign(src)) result = -Sgl_all(temp);
97  else result = Sgl_all(temp);
98  *dstptr = result;
99 
100  /* check for inexact */
101  if (Sgl_isinexact_to_fix(src,src_exponent)) {
103  else Set_inexactflag();
104  }
105  }
106  else {
107  *dstptr = 0;
108 
109  /* check for inexact */
112  else Set_inexactflag();
113  }
114  }
115  return(NOEXCEPTION);
116 }
117 
118 /*
119  * Single Floating-point to Double Fixed-point
120  */
121 /*ARGSUSED*/
122 int
124  sgl_floating_point *srcptr,
125  unsigned int *nullptr,
126  dbl_integer *dstptr,
127  unsigned int *status)
128 {
129  register int src_exponent, resultp1;
130  register unsigned int src, temp, resultp2;
131 
132  src = *srcptr;
133  src_exponent = Sgl_exponent(src) - SGL_BIAS;
134 
135  /*
136  * Test for overflow
137  */
138  if (src_exponent > DBL_FX_MAX_EXP) {
139  /* check for MININT */
140  if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
142  if (Sgl_iszero_sign(src)) {
143  resultp1 = 0x7fffffff;
144  resultp2 = 0xffffffff;
145  }
146  else {
147  resultp1 = 0x80000000;
148  resultp2 = 0;
149  }
150  if (Is_invalidtrap_enabled()) {
151  return(INVALIDEXCEPTION);
152  }
153  Set_invalidflag();
154  Dint_copytoptr(resultp1,resultp2,dstptr);
155  return(NOEXCEPTION);
156  }
157  Dint_set_minint(resultp1,resultp2);
158  Dint_copytoptr(resultp1,resultp2,dstptr);
159  return(NOEXCEPTION);
160  }
161  /*
162  * Generate result
163  */
164  if (src_exponent >= 0) {
165  temp = src;
167  Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
168  if (Sgl_isone_sign(src)) {
169  Dint_setone_sign(resultp1,resultp2);
170  }
171  Dint_copytoptr(resultp1,resultp2,dstptr);
172 
173  /* check for inexact */
174  if (Sgl_isinexact_to_fix(src,src_exponent)) {
176  else Set_inexactflag();
177  }
178  }
179  else {
180  Dint_setzero(resultp1,resultp2);
181  Dint_copytoptr(resultp1,resultp2,dstptr);
182 
183  /* check for inexact */
186  else Set_inexactflag();
187  }
188  }
189  return(NOEXCEPTION);
190 }
191 
192 /*
193  * Double Floating-point to Single Fixed-point
194  */
195 /*ARGSUSED*/
196 int
198  dbl_floating_point *srcptr,
199  unsigned int *nullptr,
200  int *dstptr,
201  unsigned int *status)
202 {
203  register unsigned int srcp1, srcp2, tempp1, tempp2;
204  register int src_exponent, result;
205 
206  Dbl_copyfromptr(srcptr,srcp1,srcp2);
207  src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
208 
209  /*
210  * Test for overflow
211  */
212  if (src_exponent > SGL_FX_MAX_EXP) {
213  /* check for MININT */
214  if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
215  if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
216  else result = 0x80000000;
217 
218  if (Is_invalidtrap_enabled()) {
219  return(INVALIDEXCEPTION);
220  }
221  Set_invalidflag();
222  *dstptr = result;
223  return(NOEXCEPTION);
224  }
225  }
226  /*
227  * Generate result
228  */
229  if (src_exponent >= 0) {
230  tempp1 = srcp1;
231  tempp2 = srcp2;
233  Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
234  if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
235  result = -Dbl_allp1(tempp1);
236  else result = Dbl_allp1(tempp1);
237  *dstptr = result;
238 
239  /* check for inexact */
240  if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
242  else Set_inexactflag();
243  }
244  }
245  else {
246  *dstptr = 0;
247 
248  /* check for inexact */
249  if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
251  else Set_inexactflag();
252  }
253  }
254  return(NOEXCEPTION);
255 }
256 
257 /*
258  * Double Floating-point to Double Fixed-point
259  */
260 /*ARGSUSED*/
261 int
263  dbl_floating_point *srcptr,
264  unsigned int *nullptr,
265  dbl_integer *dstptr,
266  unsigned int *status)
267 {
268  register int src_exponent, resultp1;
269  register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
270 
271  Dbl_copyfromptr(srcptr,srcp1,srcp2);
272  src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
273 
274  /*
275  * Test for overflow
276  */
277  if (src_exponent > DBL_FX_MAX_EXP) {
278  /* check for MININT */
279  if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
280  Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
281  if (Dbl_iszero_sign(srcp1)) {
282  resultp1 = 0x7fffffff;
283  resultp2 = 0xffffffff;
284  }
285  else {
286  resultp1 = 0x80000000;
287  resultp2 = 0;
288  }
289  if (Is_invalidtrap_enabled()) {
290  return(INVALIDEXCEPTION);
291  }
292  Set_invalidflag();
293  Dint_copytoptr(resultp1,resultp2,dstptr);
294  return(NOEXCEPTION);
295  }
296  }
297  /*
298  * Generate result
299  */
300  if (src_exponent >= 0) {
301  tempp1 = srcp1;
302  tempp2 = srcp2;
304  Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
305  resultp1,resultp2);
306  if (Dbl_isone_sign(srcp1)) {
307  Dint_setone_sign(resultp1,resultp2);
308  }
309  Dint_copytoptr(resultp1,resultp2,dstptr);
310 
311  /* check for inexact */
312  if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
314  else Set_inexactflag();
315  }
316  }
317  else {
318  Dint_setzero(resultp1,resultp2);
319  Dint_copytoptr(resultp1,resultp2,dstptr);
320 
321  /* check for inexact */
322  if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
324  else Set_inexactflag();
325  }
326  }
327  return(NOEXCEPTION);
328 }