~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/parisc/math-emu/frnd.c

Version: ~ [ linux-5.6 ] ~ [ linux-5.5.13 ] ~ [ linux-5.4.28 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.113 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.174 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.217 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.217 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.82 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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  *  Purpose:
 25  *      Single Floating-point Round to Integer
 26  *      Double Floating-point Round to Integer
 27  *      Quad Floating-point Round to Integer (returns unimplemented)
 28  *
 29  *  External Interfaces:
 30  *      dbl_frnd(srcptr,nullptr,dstptr,status)
 31  *      sgl_frnd(srcptr,nullptr,dstptr,status)
 32  *
 33  * END_DESC
 34 */
 35 
 36 
 37 #include "float.h"
 38 #include "sgl_float.h"
 39 #include "dbl_float.h"
 40 #include "cnv_float.h"
 41 
 42 /*
 43  *  Single Floating-point Round to Integer
 44  */
 45 
 46 /*ARGSUSED*/
 47 int
 48 sgl_frnd(sgl_floating_point *srcptr,
 49         unsigned int *nullptr,
 50         sgl_floating_point *dstptr,
 51         unsigned int *status)
 52 {
 53         register unsigned int src, result;
 54         register int src_exponent;
 55         register boolean inexact = FALSE;
 56 
 57         src = *srcptr;
 58         /*
 59          * check source operand for NaN or infinity
 60          */
 61         if ((src_exponent = Sgl_exponent(src)) == SGL_INFINITY_EXPONENT) {
 62                 /*
 63                  * is signaling NaN?
 64                  */
 65                 if (Sgl_isone_signaling(src)) {
 66                         /* trap if INVALIDTRAP enabled */
 67                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
 68                         /* make NaN quiet */
 69                         Set_invalidflag();
 70                         Sgl_set_quiet(src);
 71                 }
 72                 /*
 73                  * return quiet NaN or infinity
 74                  */
 75                 *dstptr = src;
 76                 return(NOEXCEPTION);
 77         }
 78         /* 
 79          * Need to round?
 80          */
 81         if ((src_exponent -= SGL_BIAS) >= SGL_P - 1) {
 82                 *dstptr = src;
 83                 return(NOEXCEPTION);
 84         }
 85         /*
 86          * Generate result
 87          */
 88         if (src_exponent >= 0) {
 89                 Sgl_clear_exponent_set_hidden(src);
 90                 result = src;
 91                 Sgl_rightshift(result,(SGL_P-1) - (src_exponent));
 92                 /* check for inexact */
 93                 if (Sgl_isinexact_to_fix(src,src_exponent)) {
 94                         inexact = TRUE;
 95                         /*  round result  */
 96                         switch (Rounding_mode()) {
 97                         case ROUNDPLUS:
 98                              if (Sgl_iszero_sign(src)) Sgl_increment(result);
 99                              break;
100                         case ROUNDMINUS:
101                              if (Sgl_isone_sign(src)) Sgl_increment(result);
102                              break;
103                         case ROUNDNEAREST:
104                              if (Sgl_isone_roundbit(src,src_exponent))
105                                 if (Sgl_isone_stickybit(src,src_exponent) 
106                                 || (Sgl_isone_lowmantissa(result))) 
107                                         Sgl_increment(result);
108                         } 
109                 }
110                 Sgl_leftshift(result,(SGL_P-1) - (src_exponent));
111                 if (Sgl_isone_hiddenoverflow(result)) 
112                         Sgl_set_exponent(result,src_exponent + (SGL_BIAS+1));
113                 else Sgl_set_exponent(result,src_exponent + SGL_BIAS);
114         }
115         else {
116                 result = src;           /* set sign */
117                 Sgl_setzero_exponentmantissa(result);
118                 /* check for inexact */
119                 if (Sgl_isnotzero_exponentmantissa(src)) {
120                         inexact = TRUE;
121                         /*  round result  */
122                         switch (Rounding_mode()) {
123                         case ROUNDPLUS:
124                              if (Sgl_iszero_sign(src)) 
125                                 Sgl_set_exponent(result,SGL_BIAS);
126                              break;
127                         case ROUNDMINUS:
128                              if (Sgl_isone_sign(src)) 
129                                 Sgl_set_exponent(result,SGL_BIAS);
130                              break;
131                         case ROUNDNEAREST:
132                              if (src_exponent == -1)
133                                 if (Sgl_isnotzero_mantissa(src))
134                                    Sgl_set_exponent(result,SGL_BIAS);
135                         } 
136                 }
137         }
138         *dstptr = result;
139         if (inexact) {
140                 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
141                 else Set_inexactflag();
142         }
143         return(NOEXCEPTION);
144 } 
145 
146 /*
147  *  Double Floating-point Round to Integer
148  */
149 
150 /*ARGSUSED*/
151 int
152 dbl_frnd(
153         dbl_floating_point *srcptr,
154         unsigned int *nullptr,
155         dbl_floating_point *dstptr,
156         unsigned int *status)
157 {
158         register unsigned int srcp1, srcp2, resultp1, resultp2;
159         register int src_exponent;
160         register boolean inexact = FALSE;
161 
162         Dbl_copyfromptr(srcptr,srcp1,srcp2);
163         /*
164          * check source operand for NaN or infinity
165          */
166         if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) {
167                 /*
168                  * is signaling NaN?
169                  */
170                 if (Dbl_isone_signaling(srcp1)) {
171                         /* trap if INVALIDTRAP enabled */
172                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
173                         /* make NaN quiet */
174                         Set_invalidflag();
175                         Dbl_set_quiet(srcp1);
176                 }
177                 /*
178                  * return quiet NaN or infinity
179                  */
180                 Dbl_copytoptr(srcp1,srcp2,dstptr);
181                 return(NOEXCEPTION);
182         }
183         /* 
184          * Need to round?
185          */
186         if ((src_exponent -= DBL_BIAS) >= DBL_P - 1) {
187                 Dbl_copytoptr(srcp1,srcp2,dstptr);
188                 return(NOEXCEPTION);
189         }
190         /*
191          * Generate result
192          */
193         if (src_exponent >= 0) {
194                 Dbl_clear_exponent_set_hidden(srcp1);
195                 resultp1 = srcp1;
196                 resultp2 = srcp2;
197                 Dbl_rightshift(resultp1,resultp2,(DBL_P-1) - (src_exponent));
198                 /* check for inexact */
199                 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
200                         inexact = TRUE;
201                         /*  round result  */
202                         switch (Rounding_mode()) {
203                         case ROUNDPLUS:
204                              if (Dbl_iszero_sign(srcp1)) 
205                                 Dbl_increment(resultp1,resultp2);
206                              break;
207                         case ROUNDMINUS:
208                              if (Dbl_isone_sign(srcp1)) 
209                                 Dbl_increment(resultp1,resultp2);
210                              break;
211                         case ROUNDNEAREST:
212                              if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
213                               if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) 
214                                   || (Dbl_isone_lowmantissap2(resultp2))) 
215                                         Dbl_increment(resultp1,resultp2);
216                         } 
217                 }
218                 Dbl_leftshift(resultp1,resultp2,(DBL_P-1) - (src_exponent));
219                 if (Dbl_isone_hiddenoverflow(resultp1))
220                         Dbl_set_exponent(resultp1,src_exponent + (DBL_BIAS+1));
221                 else Dbl_set_exponent(resultp1,src_exponent + DBL_BIAS);
222         }
223         else {
224                 resultp1 = srcp1;  /* set sign */
225                 Dbl_setzero_exponentmantissa(resultp1,resultp2);
226                 /* check for inexact */
227                 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
228                         inexact = TRUE;
229                         /*  round result  */
230                         switch (Rounding_mode()) {
231                         case ROUNDPLUS:
232                              if (Dbl_iszero_sign(srcp1)) 
233                                 Dbl_set_exponent(resultp1,DBL_BIAS);
234                              break;
235                         case ROUNDMINUS:
236                              if (Dbl_isone_sign(srcp1)) 
237                                 Dbl_set_exponent(resultp1,DBL_BIAS);
238                              break;
239                         case ROUNDNEAREST:
240                              if (src_exponent == -1)
241                                 if (Dbl_isnotzero_mantissa(srcp1,srcp2))
242                                    Dbl_set_exponent(resultp1,DBL_BIAS);
243                         } 
244                 }
245         }
246         Dbl_copytoptr(resultp1,resultp2,dstptr);
247         if (inexact) {
248                 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
249                 else Set_inexactflag();
250         }
251         return(NOEXCEPTION);
252 }
253 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp