Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
6.1 KiB

  1. /***
  2. *tenpow.c - multiply a _LDBL12 by a power of 10
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *
  8. *Revision History:
  9. * 07-17-91 GDP Initial version (ported from assembly)
  10. * 11-15-93 GJF Merged in NT SDK verions. Replaced MIPS and _ALPHA_
  11. * by _M_MRX000 and _M_ALPHA (resp.).
  12. * 10-02-94 BWT PPC changes
  13. * 07-15-96 GJF Added parantheses to fix precedence problem in expr.
  14. * Also, detab-ed.
  15. * 05-05-99 RDL Added _M_IA64 to #if def's for alignment.
  16. *
  17. *******************************************************************************/
  18. #include <cv.h>
  19. extern _LDBL12 _pow10pos[];
  20. extern _LDBL12 _pow10neg[];
  21. /***
  22. *void _CALLTYPE5 __ld12mul(_LDBL12 *px, _LDBL12 *py) -
  23. * _LDBL12 multiplication
  24. *
  25. *Purpose: multiply two _LDBL12 numbers
  26. *
  27. *Entry: px,py: pointers to the _LDBL12 operands
  28. *
  29. *Exit: *px contains the product
  30. *
  31. *Exceptions:
  32. *
  33. *******************************************************************************/
  34. void _CALLTYPE5 __ld12mul(_LDBL12 *px, _LDBL12 *py)
  35. {
  36. u_short sign = 0;
  37. _LDBL12 tempman; /*this is actually a 12-byte mantissa,
  38. not a 12-byte long double */
  39. int i;
  40. u_short expx, expy, expsum;
  41. int roffs,poffs,qoffs;
  42. int sticky = 0;
  43. *UL_LO_12(&tempman) = 0;
  44. *UL_MED_12(&tempman) = 0;
  45. *UL_HI_12(&tempman) = 0;
  46. expx = *U_EXP_12(px);
  47. expy = *U_EXP_12(py);
  48. sign = (expx ^ expy) & (u_short)0x8000;
  49. expx &= 0x7fff;
  50. expy &= 0x7fff;
  51. expsum = expx+expy;
  52. if (expx >= LD_MAXEXP
  53. || expy >= LD_MAXEXP
  54. || expsum > LD_MAXEXP+ LD_BIASM1){
  55. /* overflow to infinity */
  56. PUT_INF_12(px,sign);
  57. return;
  58. }
  59. if (expsum <= LD_BIASM1-63) {
  60. /* underflow to zero */
  61. PUT_ZERO_12(px);
  62. return;
  63. }
  64. if (expx == 0) {
  65. /*
  66. * If this is a denormal temp real then the mantissa
  67. * was shifted right once to set bit 63 to zero.
  68. */
  69. expsum++; /* Correct for this */
  70. if (ISZERO_12(px)) {
  71. /* put positive sign */
  72. *U_EXP_12(px) = 0;
  73. return;
  74. }
  75. }
  76. if (expy == 0) {
  77. expsum++; /* because arg2 is denormal */
  78. if (ISZERO_12(py)) {
  79. PUT_ZERO_12(px);
  80. return;
  81. }
  82. }
  83. roffs = 0;
  84. for (i=0;i<5;i++) {
  85. int j;
  86. poffs = i<<1;
  87. qoffs = 8;
  88. for (j=5-i;j>0;j--) {
  89. u_long prod;
  90. #if defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC) || defined(_M_IA64)
  91. /* a variable to hold temprary sums */
  92. u_long sum;
  93. #endif
  94. int carry;
  95. u_short *p, *q;
  96. u_long *r;
  97. p = USHORT_12(px,poffs);
  98. q = USHORT_12(py,qoffs);
  99. r = ULONG_12(&tempman,roffs);
  100. prod = (u_long)*p * (u_long)*q;
  101. #if defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC) || defined(_M_IA64)
  102. /* handle misalignment problems */
  103. if (i&0x1){ /* i is odd */
  104. carry = __addl(*ALIGN(r), prod, &sum);
  105. *ALIGN(r) = sum;
  106. }
  107. else /* i is even */
  108. carry = __addl(*r, prod, r);
  109. #else
  110. carry = __addl(*r,prod,r);
  111. #endif
  112. if (carry) {
  113. /* roffs should be less than 8 in this case */
  114. (*USHORT_12(&tempman,roffs+4))++;
  115. }
  116. poffs+=2;
  117. qoffs-=2;
  118. }
  119. roffs+=2;
  120. }
  121. expsum -= LD_BIASM1;
  122. /* normalize */
  123. while ((s_short)expsum > 0 &&
  124. ((*UL_HI_12(&tempman) & MSB_ULONG) == 0)) {
  125. __shl_12(&tempman);
  126. expsum--;
  127. }
  128. if ((s_short)expsum <= 0) {
  129. expsum--;
  130. while ((s_short)expsum < 0) {
  131. if (*U_XT_12(&tempman) & 0x1)
  132. sticky++;
  133. __shr_12(&tempman);
  134. expsum++;
  135. }
  136. if (sticky)
  137. *U_XT_12(&tempman) |= 0x1;
  138. }
  139. if (*U_XT_12(&tempman) > 0x8000 ||
  140. ((*UL_LO_12(&tempman) & 0x1ffff) == 0x18000)) {
  141. /* round up */
  142. if (*UL_MANLO_12(&tempman) == MAX_ULONG) {
  143. *UL_MANLO_12(&tempman) = 0;
  144. if (*UL_MANHI_12(&tempman) == MAX_ULONG) {
  145. *UL_MANHI_12(&tempman) = 0;
  146. if (*U_EXP_12(&tempman) == MAX_USHORT) {
  147. /* 12-byte mantissa overflow */
  148. *U_EXP_12(&tempman) = MSB_USHORT;
  149. expsum++;
  150. }
  151. else
  152. (*U_EXP_12(&tempman))++;
  153. }
  154. else
  155. (*UL_MANHI_12(&tempman))++;
  156. }
  157. else
  158. (*UL_MANLO_12(&tempman))++;
  159. }
  160. /* check for exponent overflow */
  161. if (expsum >= 0x7fff){
  162. PUT_INF_12(px, sign);
  163. return;
  164. }
  165. /* put result in px */
  166. *U_XT_12(px) = *USHORT_12(&tempman,2);
  167. *UL_MANLO_12(px) = *UL_MED_12(&tempman);
  168. *UL_MANHI_12(px) = *UL_HI_12(&tempman);
  169. *U_EXP_12(px) = expsum | sign;
  170. }
  171. void _CALLTYPE5
  172. __multtenpow12(_LDBL12 *pld12, int pow, unsigned mult12)
  173. {
  174. _LDBL12 *pow_10p = _pow10pos-8;
  175. if (pow == 0)
  176. return;
  177. if (pow < 0) {
  178. pow = -pow;
  179. pow_10p = _pow10neg-8;
  180. }
  181. if (!mult12)
  182. *U_XT_12(pld12) = 0;
  183. while (pow) {
  184. int last3; /* the 3 LSBits of pow */
  185. _LDBL12 unround;
  186. _LDBL12 *py;
  187. pow_10p += 7;
  188. last3 = pow & 0x7;
  189. pow >>= 3;
  190. if (last3 == 0)
  191. continue;
  192. py = pow_10p + last3;
  193. #ifdef _LDSUPPORT
  194. if (mult12) {
  195. #endif
  196. /* do an exact 12byte multiplication */
  197. if (*U_XT_12(py) >= 0x8000) {
  198. /* copy number */
  199. unround = *py;
  200. /* unround adjacent byte */
  201. (*UL_MANLO_12(&unround))--;
  202. /* point to new operand */
  203. py = &unround;
  204. }
  205. __ld12mul(pld12,py);
  206. #ifdef _LDSUPPORT
  207. }
  208. else {
  209. /* do a 10byte multiplication */
  210. py = (_LDBL12 *)TEN_BYTE_PART(py);
  211. *(long double *)TEN_BYTE_PART(pld12) *=
  212. *(long double *)py;
  213. }
  214. #endif
  215. }
  216. }