Merge remote-tracking branch 'net/master'
[linux-2.6/next.git] / arch / parisc / math-emu / fcnvfxt.c
blob8b9010c4690e0c00ff15910e3ec6cb86092a7657
1 /*
2 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
4 * Floating-point emulation code
5 * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
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.
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.
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
22 * BEGIN_DESC
24 * File:
25 * @(#) pa/spmath/fcnvfxt.c $Revision: 1.1 $
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
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)
39 * Internal Interfaces:
41 * Theory:
42 * <<please update with a overview of the operation of this file>>
44 * END_DESC
48 #include "float.h"
49 #include "sgl_float.h"
50 #include "dbl_float.h"
51 #include "cnv_float.h"
54 * Convert single floating-point to single fixed-point format
55 * with truncated result
57 /*ARGSUSED*/
58 int
59 sgl_to_sgl_fcnvfxt(
60 sgl_floating_point *srcptr,
61 unsigned int *nullptr,
62 int *dstptr,
63 unsigned int *status)
65 register unsigned int src, temp;
66 register int src_exponent, result;
68 src = *srcptr;
69 src_exponent = Sgl_exponent(src) - SGL_BIAS;
71 /*
72 * Test for overflow
74 if (src_exponent > SGL_FX_MAX_EXP) {
75 /* check for MININT */
76 if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
77 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
78 if (Sgl_iszero_sign(src)) result = 0x7fffffff;
79 else result = 0x80000000;
81 if (Is_invalidtrap_enabled()) {
82 return(INVALIDEXCEPTION);
84 Set_invalidflag();
85 *dstptr = result;
86 return(NOEXCEPTION);
90 * Generate result
92 if (src_exponent >= 0) {
93 temp = src;
94 Sgl_clear_signexponent_set_hidden(temp);
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;
100 /* check for inexact */
101 if (Sgl_isinexact_to_fix(src,src_exponent)) {
102 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
103 else Set_inexactflag();
106 else {
107 *dstptr = 0;
109 /* check for inexact */
110 if (Sgl_isnotzero_exponentmantissa(src)) {
111 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
112 else Set_inexactflag();
115 return(NOEXCEPTION);
119 * Single Floating-point to Double Fixed-point
121 /*ARGSUSED*/
123 sgl_to_dbl_fcnvfxt(
124 sgl_floating_point *srcptr,
125 unsigned int *nullptr,
126 dbl_integer *dstptr,
127 unsigned int *status)
129 register int src_exponent, resultp1;
130 register unsigned int src, temp, resultp2;
132 src = *srcptr;
133 src_exponent = Sgl_exponent(src) - SGL_BIAS;
136 * Test for overflow
138 if (src_exponent > DBL_FX_MAX_EXP) {
139 /* check for MININT */
140 if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
141 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
142 if (Sgl_iszero_sign(src)) {
143 resultp1 = 0x7fffffff;
144 resultp2 = 0xffffffff;
146 else {
147 resultp1 = 0x80000000;
148 resultp2 = 0;
150 if (Is_invalidtrap_enabled()) {
151 return(INVALIDEXCEPTION);
153 Set_invalidflag();
154 Dint_copytoptr(resultp1,resultp2,dstptr);
155 return(NOEXCEPTION);
157 Dint_set_minint(resultp1,resultp2);
158 Dint_copytoptr(resultp1,resultp2,dstptr);
159 return(NOEXCEPTION);
162 * Generate result
164 if (src_exponent >= 0) {
165 temp = src;
166 Sgl_clear_signexponent_set_hidden(temp);
167 Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
168 if (Sgl_isone_sign(src)) {
169 Dint_setone_sign(resultp1,resultp2);
171 Dint_copytoptr(resultp1,resultp2,dstptr);
173 /* check for inexact */
174 if (Sgl_isinexact_to_fix(src,src_exponent)) {
175 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
176 else Set_inexactflag();
179 else {
180 Dint_setzero(resultp1,resultp2);
181 Dint_copytoptr(resultp1,resultp2,dstptr);
183 /* check for inexact */
184 if (Sgl_isnotzero_exponentmantissa(src)) {
185 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
186 else Set_inexactflag();
189 return(NOEXCEPTION);
193 * Double Floating-point to Single Fixed-point
195 /*ARGSUSED*/
197 dbl_to_sgl_fcnvfxt(
198 dbl_floating_point *srcptr,
199 unsigned int *nullptr,
200 int *dstptr,
201 unsigned int *status)
203 register unsigned int srcp1, srcp2, tempp1, tempp2;
204 register int src_exponent, result;
206 Dbl_copyfromptr(srcptr,srcp1,srcp2);
207 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
210 * Test for overflow
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;
218 if (Is_invalidtrap_enabled()) {
219 return(INVALIDEXCEPTION);
221 Set_invalidflag();
222 *dstptr = result;
223 return(NOEXCEPTION);
227 * Generate result
229 if (src_exponent >= 0) {
230 tempp1 = srcp1;
231 tempp2 = srcp2;
232 Dbl_clear_signexponent_set_hidden(tempp1);
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;
239 /* check for inexact */
240 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
241 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
242 else Set_inexactflag();
245 else {
246 *dstptr = 0;
248 /* check for inexact */
249 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
250 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
251 else Set_inexactflag();
254 return(NOEXCEPTION);
258 * Double Floating-point to Double Fixed-point
260 /*ARGSUSED*/
262 dbl_to_dbl_fcnvfxt(
263 dbl_floating_point *srcptr,
264 unsigned int *nullptr,
265 dbl_integer *dstptr,
266 unsigned int *status)
268 register int src_exponent, resultp1;
269 register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
271 Dbl_copyfromptr(srcptr,srcp1,srcp2);
272 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
275 * Test for overflow
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;
285 else {
286 resultp1 = 0x80000000;
287 resultp2 = 0;
289 if (Is_invalidtrap_enabled()) {
290 return(INVALIDEXCEPTION);
292 Set_invalidflag();
293 Dint_copytoptr(resultp1,resultp2,dstptr);
294 return(NOEXCEPTION);
298 * Generate result
300 if (src_exponent >= 0) {
301 tempp1 = srcp1;
302 tempp2 = srcp2;
303 Dbl_clear_signexponent_set_hidden(tempp1);
304 Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
305 resultp1,resultp2);
306 if (Dbl_isone_sign(srcp1)) {
307 Dint_setone_sign(resultp1,resultp2);
309 Dint_copytoptr(resultp1,resultp2,dstptr);
311 /* check for inexact */
312 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
313 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
314 else Set_inexactflag();
317 else {
318 Dint_setzero(resultp1,resultp2);
319 Dint_copytoptr(resultp1,resultp2,dstptr);
321 /* check for inexact */
322 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
323 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
324 else Set_inexactflag();
327 return(NOEXCEPTION);