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

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

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
  4  *
  5  * Floating-point emulation code
  6  *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
  7  */
  8 /*
  9  * BEGIN_DESC
 10  *
 11  *  File:
 12  *      @(#)    pa/spmath/sfsqrt.c              $Revision: 1.1 $
 13  *
 14  *  Purpose:
 15  *      Single Floating-point Square Root
 16  *
 17  *  External Interfaces:
 18  *      sgl_fsqrt(srcptr,_nullptr,dstptr,status)
 19  *
 20  *  Internal Interfaces:
 21  *
 22  *  Theory:
 23  *      <<please update with a overview of the operation of this file>>
 24  *
 25  * END_DESC
 26 */
 27 
 28 
 29 #include "float.h"
 30 #include "sgl_float.h"
 31 
 32 /*
 33  *  Single Floating-point Square Root
 34  */
 35 
 36 /*ARGSUSED*/
 37 unsigned int
 38 sgl_fsqrt(
 39     sgl_floating_point *srcptr,
 40     unsigned int *_nullptr,
 41     sgl_floating_point *dstptr,
 42     unsigned int *status)
 43 {
 44         register unsigned int src, result;
 45         register int src_exponent;
 46         register unsigned int newbit, sum;
 47         register boolean guardbit = FALSE, even_exponent;
 48 
 49         src = *srcptr;
 50         /*
 51          * check source operand for NaN or infinity
 52          */
 53         if ((src_exponent = Sgl_exponent(src)) == SGL_INFINITY_EXPONENT) {
 54                 /*
 55                  * is signaling NaN?
 56                  */
 57                 if (Sgl_isone_signaling(src)) {
 58                         /* trap if INVALIDTRAP enabled */
 59                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
 60                         /* make NaN quiet */
 61                         Set_invalidflag();
 62                         Sgl_set_quiet(src);
 63                 }
 64                 /*
 65                  * Return quiet NaN or positive infinity.
 66                  *  Fall through to negative test if negative infinity.
 67                  */
 68                 if (Sgl_iszero_sign(src) || Sgl_isnotzero_mantissa(src)) {
 69                         *dstptr = src;
 70                         return(NOEXCEPTION);
 71                 }
 72         }
 73 
 74         /*
 75          * check for zero source operand
 76          */
 77         if (Sgl_iszero_exponentmantissa(src)) {
 78                 *dstptr = src;
 79                 return(NOEXCEPTION);
 80         }
 81 
 82         /*
 83          * check for negative source operand 
 84          */
 85         if (Sgl_isone_sign(src)) {
 86                 /* trap if INVALIDTRAP enabled */
 87                 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
 88                 /* make NaN quiet */
 89                 Set_invalidflag();
 90                 Sgl_makequietnan(src);
 91                 *dstptr = src;
 92                 return(NOEXCEPTION);
 93         }
 94 
 95         /*
 96          * Generate result
 97          */
 98         if (src_exponent > 0) {
 99                 even_exponent = Sgl_hidden(src);
100                 Sgl_clear_signexponent_set_hidden(src);
101         }
102         else {
103                 /* normalize operand */
104                 Sgl_clear_signexponent(src);
105                 src_exponent++;
106                 Sgl_normalize(src,src_exponent);
107                 even_exponent = src_exponent & 1;
108         }
109         if (even_exponent) {
110                 /* exponent is even */
111                 /* Add comment here.  Explain why odd exponent needs correction */
112                 Sgl_leftshiftby1(src);
113         }
114         /*
115          * Add comment here.  Explain following algorithm.
116          * 
117          * Trust me, it works.
118          *
119          */
120         Sgl_setzero(result);
121         newbit = 1 << SGL_P;
122         while (newbit && Sgl_isnotzero(src)) {
123                 Sgl_addition(result,newbit,sum);
124                 if(sum <= Sgl_all(src)) {
125                         /* update result */
126                         Sgl_addition(result,(newbit<<1),result);
127                         Sgl_subtract(src,sum,src);
128                 }
129                 Sgl_rightshiftby1(newbit);
130                 Sgl_leftshiftby1(src);
131         }
132         /* correct exponent for pre-shift */
133         if (even_exponent) {
134                 Sgl_rightshiftby1(result);
135         }
136 
137         /* check for inexact */
138         if (Sgl_isnotzero(src)) {
139                 if (!even_exponent && Sgl_islessthan(result,src)) 
140                         Sgl_increment(result);
141                 guardbit = Sgl_lowmantissa(result);
142                 Sgl_rightshiftby1(result);
143 
144                 /*  now round result  */
145                 switch (Rounding_mode()) {
146                 case ROUNDPLUS:
147                      Sgl_increment(result);
148                      break;
149                 case ROUNDNEAREST:
150                      /* stickybit is always true, so guardbit 
151                       * is enough to determine rounding */
152                      if (guardbit) {
153                         Sgl_increment(result);
154                      }
155                      break;
156                 }
157                 /* increment result exponent by 1 if mantissa overflowed */
158                 if (Sgl_isone_hiddenoverflow(result)) src_exponent+=2;
159 
160                 if (Is_inexacttrap_enabled()) {
161                         Sgl_set_exponent(result,
162                          ((src_exponent-SGL_BIAS)>>1)+SGL_BIAS);
163                         *dstptr = result;
164                         return(INEXACTEXCEPTION);
165                 }
166                 else Set_inexactflag();
167         }
168         else {
169                 Sgl_rightshiftby1(result);
170         }
171         Sgl_set_exponent(result,((src_exponent-SGL_BIAS)>>1)+SGL_BIAS);
172         *dstptr = result;
173         return(NOEXCEPTION);
174 }
175 

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php