dfsqrt.c 4.7 KB

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