/js/lib/Socket.IO-node/support/expresso/deps/jscoverage/js/jslong.cpp

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs · C++ · 264 lines · 149 code · 33 blank · 82 comment · 45 complexity · 30322b36e9f7d921d1dabb88fc0b4567 MD5 · raw file

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * The Original Code is Mozilla Communicator client code, released
  16. * March 31, 1998.
  17. *
  18. * The Initial Developer of the Original Code is
  19. * Netscape Communications Corporation.
  20. * Portions created by the Initial Developer are Copyright (C) 1998
  21. * the Initial Developer. All Rights Reserved.
  22. *
  23. * Contributor(s):
  24. *
  25. * Alternatively, the contents of this file may be used under the terms of
  26. * either of the GNU General Public License Version 2 or later (the "GPL"),
  27. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28. * in which case the provisions of the GPL or the LGPL are applicable instead
  29. * of those above. If you wish to allow use of your version of this file only
  30. * under the terms of either the GPL or the LGPL, and not to allow others to
  31. * use your version of this file under the terms of the MPL, indicate your
  32. * decision by deleting the provisions above and replace them with the notice
  33. * and other provisions required by the GPL or the LGPL. If you do not delete
  34. * the provisions above, a recipient may use your version of this file under
  35. * the terms of any one of the MPL, the GPL or the LGPL.
  36. *
  37. * ***** END LICENSE BLOCK ***** */
  38. #include "jsstddef.h"
  39. #include "jstypes.h"
  40. #include "jslong.h"
  41. #ifndef JS_HAVE_LONG_LONG
  42. /*
  43. ** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1.
  44. */
  45. static void norm_udivmod32(JSUint32 *qp, JSUint32 *rp, JSUint64 a, JSUint32 b)
  46. {
  47. JSUint32 d1, d0, q1, q0;
  48. JSUint32 r1, r0, m;
  49. d1 = jshi16(b);
  50. d0 = jslo16(b);
  51. r1 = a.hi % d1;
  52. q1 = a.hi / d1;
  53. m = q1 * d0;
  54. r1 = (r1 << 16) | jshi16(a.lo);
  55. if (r1 < m) {
  56. q1--, r1 += b;
  57. if (r1 >= b /* i.e., we didn't get a carry when adding to r1 */
  58. && r1 < m) {
  59. q1--, r1 += b;
  60. }
  61. }
  62. r1 -= m;
  63. r0 = r1 % d1;
  64. q0 = r1 / d1;
  65. m = q0 * d0;
  66. r0 = (r0 << 16) | jslo16(a.lo);
  67. if (r0 < m) {
  68. q0--, r0 += b;
  69. if (r0 >= b
  70. && r0 < m) {
  71. q0--, r0 += b;
  72. }
  73. }
  74. *qp = (q1 << 16) | q0;
  75. *rp = r0 - m;
  76. }
  77. static JSUint32 CountLeadingZeros(JSUint32 a)
  78. {
  79. JSUint32 t;
  80. JSUint32 r = 32;
  81. if ((t = a >> 16) != 0)
  82. r -= 16, a = t;
  83. if ((t = a >> 8) != 0)
  84. r -= 8, a = t;
  85. if ((t = a >> 4) != 0)
  86. r -= 4, a = t;
  87. if ((t = a >> 2) != 0)
  88. r -= 2, a = t;
  89. if ((t = a >> 1) != 0)
  90. r -= 1, a = t;
  91. if (a & 1)
  92. r--;
  93. return r;
  94. }
  95. JS_PUBLIC_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b)
  96. {
  97. JSUint32 n0, n1, n2;
  98. JSUint32 q0, q1;
  99. JSUint32 rsh, lsh;
  100. n0 = a.lo;
  101. n1 = a.hi;
  102. if (b.hi == 0) {
  103. if (b.lo > n1) {
  104. /* (0 q0) = (n1 n0) / (0 D0) */
  105. lsh = CountLeadingZeros(b.lo);
  106. if (lsh) {
  107. /*
  108. * Normalize, i.e. make the most significant bit of the
  109. * denominator be set.
  110. */
  111. b.lo = b.lo << lsh;
  112. n1 = (n1 << lsh) | (n0 >> (32 - lsh));
  113. n0 = n0 << lsh;
  114. }
  115. a.lo = n0, a.hi = n1;
  116. norm_udivmod32(&q0, &n0, a, b.lo);
  117. q1 = 0;
  118. /* remainder is in n0 >> lsh */
  119. } else {
  120. /* (q1 q0) = (n1 n0) / (0 d0) */
  121. if (b.lo == 0) /* user wants to divide by zero! */
  122. b.lo = 1 / b.lo; /* so go ahead and crash */
  123. lsh = CountLeadingZeros(b.lo);
  124. if (lsh == 0) {
  125. /*
  126. * From (n1 >= b.lo)
  127. * && (the most significant bit of b.lo is set),
  128. * conclude that
  129. * (the most significant bit of n1 is set)
  130. * && (the leading quotient digit q1 = 1).
  131. *
  132. * This special case is necessary, not an optimization
  133. * (Shifts counts of 32 are undefined).
  134. */
  135. n1 -= b.lo;
  136. q1 = 1;
  137. } else {
  138. /*
  139. * Normalize.
  140. */
  141. rsh = 32 - lsh;
  142. b.lo = b.lo << lsh;
  143. n2 = n1 >> rsh;
  144. n1 = (n1 << lsh) | (n0 >> rsh);
  145. n0 = n0 << lsh;
  146. a.lo = n1, a.hi = n2;
  147. norm_udivmod32(&q1, &n1, a, b.lo);
  148. }
  149. /* n1 != b.lo... */
  150. a.lo = n0, a.hi = n1;
  151. norm_udivmod32(&q0, &n0, a, b.lo);
  152. /* remainder in n0 >> lsh */
  153. }
  154. if (rp) {
  155. rp->lo = n0 >> lsh;
  156. rp->hi = 0;
  157. }
  158. } else {
  159. if (b.hi > n1) {
  160. /* (0 0) = (n1 n0) / (D1 d0) */
  161. q0 = 0;
  162. q1 = 0;
  163. /* remainder in (n1 n0) */
  164. if (rp) {
  165. rp->lo = n0;
  166. rp->hi = n1;
  167. }
  168. } else {
  169. /* (0 q0) = (n1 n0) / (d1 d0) */
  170. lsh = CountLeadingZeros(b.hi);
  171. if (lsh == 0) {
  172. /*
  173. * From (n1 >= b.hi)
  174. * && (the most significant bit of b.hi is set),
  175. * conclude that
  176. * (the most significant bit of n1 is set)
  177. * && (the quotient digit q0 = 0 or 1).
  178. *
  179. * This special case is necessary, not an optimization.
  180. */
  181. /*
  182. * The condition on the next line takes advantage of that
  183. * n1 >= b.hi (true due to control flow).
  184. */
  185. if (n1 > b.hi || n0 >= b.lo) {
  186. q0 = 1;
  187. a.lo = n0, a.hi = n1;
  188. JSLL_SUB(a, a, b);
  189. } else {
  190. q0 = 0;
  191. }
  192. q1 = 0;
  193. if (rp) {
  194. rp->lo = n0;
  195. rp->hi = n1;
  196. }
  197. } else {
  198. JSInt64 m;
  199. /*
  200. * Normalize.
  201. */
  202. rsh = 32 - lsh;
  203. b.hi = (b.hi << lsh) | (b.lo >> rsh);
  204. b.lo = b.lo << lsh;
  205. n2 = n1 >> rsh;
  206. n1 = (n1 << lsh) | (n0 >> rsh);
  207. n0 = n0 << lsh;
  208. a.lo = n1, a.hi = n2;
  209. norm_udivmod32(&q0, &n1, a, b.hi);
  210. JSLL_MUL32(m, q0, b.lo);
  211. if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) {
  212. q0--;
  213. JSLL_SUB(m, m, b);
  214. }
  215. q1 = 0;
  216. /* Remainder is ((n1 n0) - (m1 m0)) >> lsh */
  217. if (rp) {
  218. a.lo = n0, a.hi = n1;
  219. JSLL_SUB(a, a, m);
  220. rp->lo = (a.hi << rsh) | (a.lo >> lsh);
  221. rp->hi = a.hi >> lsh;
  222. }
  223. }
  224. }
  225. }
  226. if (qp) {
  227. qp->lo = q0;
  228. qp->hi = q1;
  229. }
  230. }
  231. #endif /* !JS_HAVE_LONG_LONG */