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)
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
25 * @(#) pa/spmath/fcnvfxt.c $Revision: 1.1 $
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:
42 * <<please update with a overview of the operation of this file>>
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
60 sgl_floating_point *srcptr,
61 unsigned int *nullptr,
65 register unsigned int src, temp;
66 register int src_exponent, result;
69 src_exponent = Sgl_exponent(src) - SGL_BIAS;
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);
92 if (src_exponent >= 0) {
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);
100 /* check for inexact */
101 if (Sgl_isinexact_to_fix(src,src_exponent)) {
102 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
103 else Set_inexactflag();
109 /* check for inexact */
110 if (Sgl_isnotzero_exponentmantissa(src)) {
111 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
112 else Set_inexactflag();
119 * Single Floating-point to Double Fixed-point
124 sgl_floating_point *srcptr,
125 unsigned int *nullptr,
127 unsigned int *status)
129 register int src_exponent, resultp1;
130 register unsigned int src, temp, resultp2;
133 src_exponent = Sgl_exponent(src) - SGL_BIAS;
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;
147 resultp1 = 0x80000000;
150 if (Is_invalidtrap_enabled()) {
151 return(INVALIDEXCEPTION);
154 Dint_copytoptr(resultp1,resultp2,dstptr);
157 Dint_set_minint(resultp1,resultp2);
158 Dint_copytoptr(resultp1,resultp2,dstptr);
164 if (src_exponent >= 0) {
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();
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();
193 * Double Floating-point to Single Fixed-point
198 dbl_floating_point *srcptr,
199 unsigned int *nullptr,
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;
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);
229 if (src_exponent >= 0) {
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);
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();
248 /* check for inexact */
249 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
250 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
251 else Set_inexactflag();
258 * Double Floating-point to Double Fixed-point
263 dbl_floating_point *srcptr,
264 unsigned int *nullptr,
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;
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;
286 resultp1 = 0x80000000;
289 if (Is_invalidtrap_enabled()) {
290 return(INVALIDEXCEPTION);
293 Dint_copytoptr(resultp1,resultp2,dstptr);
300 if (src_exponent >= 0) {
303 Dbl_clear_signexponent_set_hidden(tempp1);
304 Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
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();
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();