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

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

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ 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/dfsqrt.c              $Revision: 1.1 $
 13  *
 14  *  Purpose:
 15  *      Double Floating-point Square Root
 16  *
 17  *  External Interfaces:
 18  *      dbl_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 "dbl_float.h"
 31 
 32 /*
 33  *  Double Floating-point Square Root
 34  */
 35 
 36 /*ARGSUSED*/
 37 unsigned int
 38 dbl_fsqrt(
 39             dbl_floating_point *srcptr,
 40             unsigned int *_nullptr,
 41             dbl_floating_point *dstptr,
 42             unsigned int *status)
 43 {
 44         register unsigned int srcp1, srcp2, resultp1, resultp2;
 45         register unsigned int newbitp1, newbitp2, sump1, sump2;
 46         register int src_exponent;
 47         register boolean guardbit = FALSE, even_exponent;
 48 
 49         Dbl_copyfromptr(srcptr,srcp1,srcp2);
 50         /*
 51          * check source operand for NaN or infinity
 52          */
 53         if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) {
 54                 /*
 55                  * is signaling NaN?
 56                  */
 57                 if (Dbl_isone_signaling(srcp1)) {
 58                         /* trap if INVALIDTRAP enabled */
 59                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
 60                         /* make NaN quiet */
 61                         Set_invalidflag();
 62                         Dbl_set_quiet(srcp1);
 63                 }
 64                 /*
 65                  * Return quiet NaN or positive infinity.
 66                  *  Fall through to negative test if negative infinity.
 67                  */
 68                 if (Dbl_iszero_sign(srcp1) || 
 69                     Dbl_isnotzero_mantissa(srcp1,srcp2)) {
 70                         Dbl_copytoptr(srcp1,srcp2,dstptr);
 71                         return(NOEXCEPTION);
 72                 }
 73         }
 74 
 75         /*
 76          * check for zero source operand
 77          */
 78         if (Dbl_iszero_exponentmantissa(srcp1,srcp2)) {
 79                 Dbl_copytoptr(srcp1,srcp2,dstptr);
 80                 return(NOEXCEPTION);
 81         }
 82 
 83         /*
 84          * check for negative source operand 
 85          */
 86         if (Dbl_isone_sign(srcp1)) {
 87                 /* trap if INVALIDTRAP enabled */
 88                 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
 89                 /* make NaN quiet */
 90                 Set_invalidflag();
 91                 Dbl_makequietnan(srcp1,srcp2);
 92                 Dbl_copytoptr(srcp1,srcp2,dstptr);
 93                 return(NOEXCEPTION);
 94         }
 95 
 96         /*
 97          * Generate result
 98          */
 99         if (src_exponent > 0) {
100                 even_exponent = Dbl_hidden(srcp1);
101                 Dbl_clear_signexponent_set_hidden(srcp1);
102         }
103         else {
104                 /* normalize operand */
105                 Dbl_clear_signexponent(srcp1);
106                 src_exponent++;
107                 Dbl_normalize(srcp1,srcp2,src_exponent);
108                 even_exponent = src_exponent & 1;
109         }
110         if (even_exponent) {
111                 /* exponent is even */
112                 /* Add comment here.  Explain why odd exponent needs correction */
113                 Dbl_leftshiftby1(srcp1,srcp2);
114         }
115         /*
116          * Add comment here.  Explain following algorithm.
117          * 
118          * Trust me, it works.
119          *
120          */
121         Dbl_setzero(resultp1,resultp2);
122         Dbl_allp1(newbitp1) = 1 << (DBL_P - 32);
123         Dbl_setzero_mantissap2(newbitp2);
124         while (Dbl_isnotzero(newbitp1,newbitp2) && Dbl_isnotzero(srcp1,srcp2)) {
125                 Dbl_addition(resultp1,resultp2,newbitp1,newbitp2,sump1,sump2);
126                 if(Dbl_isnotgreaterthan(sump1,sump2,srcp1,srcp2)) {
127                         Dbl_leftshiftby1(newbitp1,newbitp2);
128                         /* update result */
129                         Dbl_addition(resultp1,resultp2,newbitp1,newbitp2,
130                          resultp1,resultp2);  
131                         Dbl_subtract(srcp1,srcp2,sump1,sump2,srcp1,srcp2);
132                         Dbl_rightshiftby2(newbitp1,newbitp2);
133                 }
134                 else {
135                         Dbl_rightshiftby1(newbitp1,newbitp2);
136                 }
137                 Dbl_leftshiftby1(srcp1,srcp2);
138         }
139         /* correct exponent for pre-shift */
140         if (even_exponent) {
141                 Dbl_rightshiftby1(resultp1,resultp2);
142         }
143 
144         /* check for inexact */
145         if (Dbl_isnotzero(srcp1,srcp2)) {
146                 if (!even_exponent && Dbl_islessthan(resultp1,resultp2,srcp1,srcp2)) {
147                         Dbl_increment(resultp1,resultp2);
148                 }
149                 guardbit = Dbl_lowmantissap2(resultp2);
150                 Dbl_rightshiftby1(resultp1,resultp2);
151 
152                 /*  now round result  */
153                 switch (Rounding_mode()) {
154                 case ROUNDPLUS:
155                      Dbl_increment(resultp1,resultp2);
156                      break;
157                 case ROUNDNEAREST:
158                      /* stickybit is always true, so guardbit 
159                       * is enough to determine rounding */
160                      if (guardbit) {
161                             Dbl_increment(resultp1,resultp2);
162                      }
163                      break;
164                 }
165                 /* increment result exponent by 1 if mantissa overflowed */
166                 if (Dbl_isone_hiddenoverflow(resultp1)) src_exponent+=2;
167 
168                 if (Is_inexacttrap_enabled()) {
169                         Dbl_set_exponent(resultp1,
170                          ((src_exponent-DBL_BIAS)>>1)+DBL_BIAS);
171                         Dbl_copytoptr(resultp1,resultp2,dstptr);
172                         return(INEXACTEXCEPTION);
173                 }
174                 else Set_inexactflag();
175         }
176         else {
177                 Dbl_rightshiftby1(resultp1,resultp2);
178         }
179         Dbl_set_exponent(resultp1,((src_exponent-DBL_BIAS)>>1)+DBL_BIAS);
180         Dbl_copytoptr(resultp1,resultp2,dstptr);
181         return(NOEXCEPTION);
182 }
183 

~ [ 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