PageRenderTime 53ms CodeModel.GetById 24ms app.highlight 25ms RepoModel.GetById 2ms app.codeStats 0ms

/arch/parisc/math-emu/fcnvff.c

https://github.com/aicjofs/android_kernel_lge_v500_20d_f2fs
C | 309 lines | 165 code | 10 blank | 134 comment | 52 complexity | 0ffdfb4a6cf608d0a5df2b03c3630c3c MD5 | raw 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) <bame@debian.org>
  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/fcnvff.c		$Revision: 1.1 $
 26 *
 27 *  Purpose:
 28 *	Single Floating-point to Double Floating-point
 29 *	Double Floating-point to Single Floating-point
 30 *
 31 *  External Interfaces:
 32 *	dbl_to_sgl_fcnvff(srcptr,nullptr,dstptr,status)
 33 *	sgl_to_dbl_fcnvff(srcptr,nullptr,dstptr,status)
 34 *
 35 *  Internal Interfaces:
 36 *
 37 *  Theory:
 38 *	<<please update with a overview of the operation of this file>>
 39 *
 40 * END_DESC
 41*/
 42
 43
 44#include "float.h"
 45#include "sgl_float.h"
 46#include "dbl_float.h"
 47#include "cnv_float.h"
 48
 49/*
 50 *  Single Floating-point to Double Floating-point 
 51 */
 52/*ARGSUSED*/
 53int
 54sgl_to_dbl_fcnvff(
 55	    sgl_floating_point *srcptr,
 56	    unsigned int *nullptr,
 57	    dbl_floating_point *dstptr,
 58	    unsigned int *status)
 59{
 60	register unsigned int src, resultp1, resultp2;
 61	register int src_exponent;
 62
 63	src = *srcptr;
 64	src_exponent = Sgl_exponent(src);
 65	Dbl_allp1(resultp1) = Sgl_all(src);  /* set sign of result */
 66	/* 
 67 	 * Test for NaN or infinity
 68 	 */
 69	if (src_exponent == SGL_INFINITY_EXPONENT) {
 70		/*
 71		 * determine if NaN or infinity
 72		 */
 73		if (Sgl_iszero_mantissa(src)) {
 74			/*
 75			 * is infinity; want to return double infinity
 76			 */
 77			Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
 78			Dbl_copytoptr(resultp1,resultp2,dstptr);
 79			return(NOEXCEPTION);
 80		}
 81		else {
 82			/* 
 83			 * is NaN; signaling or quiet?
 84			 */
 85			if (Sgl_isone_signaling(src)) {
 86				/* trap if INVALIDTRAP enabled */
 87				if (Is_invalidtrap_enabled())
 88					return(INVALIDEXCEPTION);
 89				/* make NaN quiet */
 90				else {
 91					Set_invalidflag();
 92					Sgl_set_quiet(src);
 93				}
 94			}
 95			/* 
 96			 * NaN is quiet, return as double NaN 
 97			 */
 98			Dbl_setinfinity_exponent(resultp1);
 99			Sgl_to_dbl_mantissa(src,resultp1,resultp2);
100			Dbl_copytoptr(resultp1,resultp2,dstptr);
101			return(NOEXCEPTION);
102		}
103	}
104	/* 
105 	 * Test for zero or denormalized
106 	 */
107	if (src_exponent == 0) {
108		/*
109		 * determine if zero or denormalized
110		 */
111		if (Sgl_isnotzero_mantissa(src)) {
112			/*
113			 * is denormalized; want to normalize
114			 */
115			Sgl_clear_signexponent(src);
116			Sgl_leftshiftby1(src);
117			Sgl_normalize(src,src_exponent);
118			Sgl_to_dbl_exponent(src_exponent,resultp1);
119			Sgl_to_dbl_mantissa(src,resultp1,resultp2);
120		}
121		else {
122			Dbl_setzero_exponentmantissa(resultp1,resultp2);
123		}
124		Dbl_copytoptr(resultp1,resultp2,dstptr);
125		return(NOEXCEPTION);
126	}
127	/*
128	 * No special cases, just complete the conversion
129	 */
130	Sgl_to_dbl_exponent(src_exponent, resultp1);
131	Sgl_to_dbl_mantissa(Sgl_mantissa(src), resultp1,resultp2);
132	Dbl_copytoptr(resultp1,resultp2,dstptr);
133	return(NOEXCEPTION);
134}
135
136/*
137 *  Double Floating-point to Single Floating-point 
138 */
139/*ARGSUSED*/
140int
141dbl_to_sgl_fcnvff(
142		    dbl_floating_point *srcptr,
143		    unsigned int *nullptr,
144		    sgl_floating_point *dstptr,
145		    unsigned int *status)
146{
147        register unsigned int srcp1, srcp2, result;
148        register int src_exponent, dest_exponent, dest_mantissa;
149        register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
150	register boolean lsb_odd = FALSE;
151	boolean is_tiny;
152
153	Dbl_copyfromptr(srcptr,srcp1,srcp2);
154        src_exponent = Dbl_exponent(srcp1);
155	Sgl_all(result) = Dbl_allp1(srcp1);  /* set sign of result */
156        /* 
157         * Test for NaN or infinity
158         */
159        if (src_exponent == DBL_INFINITY_EXPONENT) {
160                /*
161                 * determine if NaN or infinity
162                 */
163                if (Dbl_iszero_mantissa(srcp1,srcp2)) {
164                        /*
165                         * is infinity; want to return single infinity
166                         */
167                        Sgl_setinfinity_exponentmantissa(result);
168                        *dstptr = result;
169                        return(NOEXCEPTION);
170                }
171                /* 
172                 * is NaN; signaling or quiet?
173                 */
174                if (Dbl_isone_signaling(srcp1)) {
175                        /* trap if INVALIDTRAP enabled */
176                        if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
177                        else {
178				Set_invalidflag();
179                        	/* make NaN quiet */
180                        	Dbl_set_quiet(srcp1);
181			}
182                }
183                /* 
184                 * NaN is quiet, return as single NaN 
185                 */
186                Sgl_setinfinity_exponent(result);
187		Sgl_set_mantissa(result,Dallp1(srcp1)<<3 | Dallp2(srcp2)>>29);
188		if (Sgl_iszero_mantissa(result)) Sgl_set_quiet(result);
189                *dstptr = result;
190                return(NOEXCEPTION);
191        }
192        /*
193         * Generate result
194         */
195        Dbl_to_sgl_exponent(src_exponent,dest_exponent);
196	if (dest_exponent > 0) {
197        	Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,guardbit, 
198		stickybit,lsb_odd);
199	}
200	else {
201		if (Dbl_iszero_exponentmantissa(srcp1,srcp2)){
202			Sgl_setzero_exponentmantissa(result);
203			*dstptr = result;
204			return(NOEXCEPTION);
205		}
206                if (Is_underflowtrap_enabled()) {
207			Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,
208			guardbit,stickybit,lsb_odd);
209                }
210		else {
211			/* compute result, determine inexact info,
212			 * and set Underflowflag if appropriate
213			 */
214			Dbl_to_sgl_denormalized(srcp1,srcp2,dest_exponent,
215			dest_mantissa,inexact,guardbit,stickybit,lsb_odd,
216			is_tiny);
217		}
218	}
219        /* 
220         * Now round result if not exact
221         */
222        if (inexact) {
223                switch (Rounding_mode()) {
224                        case ROUNDPLUS: 
225                                if (Sgl_iszero_sign(result)) dest_mantissa++;
226                                break;
227                        case ROUNDMINUS: 
228                                if (Sgl_isone_sign(result)) dest_mantissa++;
229                                break;
230                        case ROUNDNEAREST:
231                                if (guardbit) {
232                                   if (stickybit || lsb_odd) dest_mantissa++;
233                                   }
234                }
235        }
236        Sgl_set_exponentmantissa(result,dest_mantissa);
237
238        /*
239         * check for mantissa overflow after rounding
240         */
241        if ((dest_exponent>0 || Is_underflowtrap_enabled()) && 
242	    Sgl_isone_hidden(result)) dest_exponent++;
243
244        /* 
245         * Test for overflow
246         */
247        if (dest_exponent >= SGL_INFINITY_EXPONENT) {
248                /* trap if OVERFLOWTRAP enabled */
249                if (Is_overflowtrap_enabled()) {
250                        /* 
251                         * Check for gross overflow
252                         */
253                        if (dest_exponent >= SGL_INFINITY_EXPONENT+SGL_WRAP) 
254                        	return(UNIMPLEMENTEDEXCEPTION);
255                        
256                        /*
257                         * Adjust bias of result
258                         */
259			Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
260			*dstptr = result;
261			if (inexact) 
262			    if (Is_inexacttrap_enabled())
263				return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
264			    else Set_inexactflag();
265                        return(OVERFLOWEXCEPTION);
266                }
267                Set_overflowflag();
268		inexact = TRUE;
269		/* set result to infinity or largest number */
270		Sgl_setoverflow(result);
271        }
272        /* 
273         * Test for underflow
274         */
275        else if (dest_exponent <= 0) {
276                /* trap if UNDERFLOWTRAP enabled */
277                if (Is_underflowtrap_enabled()) {
278                        /* 
279                         * Check for gross underflow
280                         */
281                        if (dest_exponent <= -(SGL_WRAP))
282                        	return(UNIMPLEMENTEDEXCEPTION);
283                        /*
284                         * Adjust bias of result
285                         */
286			Sgl_setwrapped_exponent(result,dest_exponent,unfl);
287			*dstptr = result;
288			if (inexact) 
289			    if (Is_inexacttrap_enabled())
290				return(UNDERFLOWEXCEPTION|INEXACTEXCEPTION);
291			    else Set_inexactflag();
292                        return(UNDERFLOWEXCEPTION);
293                }
294                 /* 
295                  * result is denormalized or signed zero
296                  */
297               if (inexact && is_tiny) Set_underflowflag();
298
299        }
300	else Sgl_set_exponent(result,dest_exponent);
301	*dstptr = result;
302        /* 
303         * Trap if inexact trap is enabled
304         */
305        if (inexact)
306        	if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
307        	else Set_inexactflag();
308        return(NOEXCEPTION);
309}