Harmony: implement Math.clz32
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 18 Feb 2014 10:49:35 +0000 (10:49 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 18 Feb 2014 10:49:35 +0000 (10:49 +0000)
R=dslomov@chromium.org, svenpanne@chromium.org
BUG=v8:2938
LOG=N

Review URL: https://codereview.chromium.org/169783002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19435 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/harmony-math.js
test/mjsunit/harmony/math-clz32.js [new file with mode: 0644]

index 4265f17..c856ce7 100644 (file)
@@ -160,6 +160,20 @@ function MathFround(x) {
 }
 
 
+function MathClz32(x) {
+  x = ToUint32(TO_NUMBER_INLINE(x));
+  if (x == 0) return 32;
+  var result = 0;
+  // Binary search.
+  if ((x & 0xFFFF0000) === 0) { x <<= 16; result += 16; };
+  if ((x & 0xFF000000) === 0) { x <<=  8; result +=  8; };
+  if ((x & 0xF0000000) === 0) { x <<=  4; result +=  4; };
+  if ((x & 0xC0000000) === 0) { x <<=  2; result +=  2; };
+  if ((x & 0x80000000) === 0) { x <<=  1; result +=  1; };
+  return result;
+}
+
+
 function ExtendMath() {
   %CheckIsBootstrapping();
 
@@ -176,8 +190,10 @@ function ExtendMath() {
     "log10", MathLog10,
     "log2", MathLog2,
     "hypot", MathHypot,
-    "fround", MathFround
+    "fround", MathFround,
+    "clz32", MathClz32
   ));
 }
 
+
 ExtendMath();
diff --git a/test/mjsunit/harmony/math-clz32.js b/test/mjsunit/harmony/math-clz32.js
new file mode 100644 (file)
index 0000000..bc15ad2
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-maths
+
+[NaN, Infinity, -Infinity, 0, -0, "abc", "Infinity", "-Infinity", {}].forEach(
+  function(x) {
+    assertEquals(32, Math.clz32(x));
+  }
+);
+
+function testclz(x) {
+  for (var i = 0; i < 33; i++) {
+    if (x & 0x80000000) return i;
+    x <<= 1;
+  }
+  return 32;
+}
+
+var max = Math.pow(2, 40);
+for (var x = 0; x < max; x = x * 1.01 + 1) {
+  assertEquals(testclz(x), Math.clz32(x));
+  assertEquals(testclz(-x), Math.clz32(-x));
+  assertEquals(testclz(x), Math.clz32({ valueOf: function() { return x; } }));
+  assertEquals(testclz(-x),
+               Math.clz32({ toString: function() { return -x; } }));
+}