Bug 996076: Add SIMD.int32x4.{shiftLeft,shiftRight,shiftRightLogical} to the interpreter; r=nmatsakis
authorBenjamin Bouvier <benj@benj.me>
Fri, 02 May 2014 13:11:19 +0200
changeset 201653 8eddc5ea91ba64b346bfe15783c5c4ad58cfbfec
parent 201652 ab9a69f74b98611067c029d05a72cb340489e5d0
child 201654 d97263d58ac5ee88e526e8b080211e1ab96c89c2
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnmatsakis
bugs996076
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 996076: Add SIMD.int32x4.{shiftLeft,shiftRight,shiftRightLogical} to the interpreter; r=nmatsakis
js/src/builtin/SIMD.cpp
js/src/builtin/SIMD.h
js/src/tests/ecma_6/TypedObject/simd/int32x4lsh.js
js/src/tests/ecma_6/TypedObject/simd/int32x4rsh.js
js/src/tests/ecma_6/TypedObject/simd/int32x4ursh.js
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -549,16 +549,25 @@ struct WithFlagZ {
 template<typename T, typename V>
 struct WithFlagW {
     static inline T apply(T l, T f, T x) { return V::toType(l == 3 ? (f ? 0xFFFFFFFF : 0x0) : x); }
 };
 template<typename T, typename V>
 struct Shuffle {
     static inline int32_t apply(int32_t l, int32_t mask) { return V::toType((mask >> l) & 0x3); }
 };
+struct ShiftLeft {
+    static inline int32_t apply(int32_t v, int32_t bits) { return v << bits; }
+};
+struct ShiftRight {
+    static inline int32_t apply(int32_t v, int32_t bits) { return v >> bits; }
+};
+struct ShiftRightLogical {
+    static inline int32_t apply(int32_t v, int32_t bits) { return uint32_t(v) >> (bits & 31); }
+};
 }
 
 static inline bool
 ErrorBadArgs(JSContext *cx)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
     return false;
 }
@@ -694,16 +703,44 @@ FuncShuffle(JSContext *cx, unsigned argc
     RootedObject obj(cx, Create<Vret>(cx, result));
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
     return true;
 }
 
+template<typename Op>
+static bool
+Int32x4BinaryScalar(JSContext *cx, unsigned argc, Value *vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+    if (args.length() != 2)
+        return ErrorBadArgs(cx);
+
+    int32_t result[4];
+    if (!IsVectorObject<Int32x4>(args[0]) || !args[1].isNumber())
+        return ErrorBadArgs(cx);
+
+    int32_t *val = TypedObjectMemory<int32_t *>(args[0]);;
+    int32_t bits;
+    if (!ToInt32(cx, args[1], &bits))
+        return false;
+
+    for (unsigned i = 0; i < 4; i++)
+        result[i] = Op::apply(val[i], bits);
+
+    RootedObject obj(cx, Create<Int32x4>(cx, result));
+    if (!obj)
+        return false;
+
+    args.rval().setObject(*obj);
+    return true;
+}
+
 template<typename V, typename Vret>
 static bool
 FuncConvert(JSContext *cx, unsigned argc, Value *vp)
 {
     typedef typename V::Elem Elem;
     typedef typename Vret::Elem RetElem;
 
     CallArgs args = CallArgsFromVp(argc, vp);
--- a/js/src/builtin/SIMD.h
+++ b/js/src/builtin/SIMD.h
@@ -79,16 +79,19 @@
   V(add, (Func<Int32x4, Add<int32_t, Int32x4>, Int32x4>), 2, 0, Add)                                              \
   V(and, (Func<Int32x4, And<int32_t, Int32x4>, Int32x4>), 2, 0, And)                                              \
   V(equal, (Func<Int32x4, Equal<int32_t, Int32x4>, Int32x4>), 2, 0, Equal)                                        \
   V(greaterThan, (Func<Int32x4, GreaterThan<int32_t, Int32x4>, Int32x4>), 2, 0, GreaterThan)                      \
   V(lessThan, (Func<Int32x4, LessThan<int32_t, Int32x4>, Int32x4>), 2, 0, LessThan)                               \
   V(mul, (Func<Int32x4, Mul<int32_t, Int32x4>, Int32x4>), 2, 0, Mul)                                              \
   V(or, (Func<Int32x4, Or<int32_t, Int32x4>, Int32x4>), 2, 0, Or)                                                 \
   V(sub, (Func<Int32x4, Sub<int32_t, Int32x4>, Int32x4>), 2, 0, Sub)                                              \
+  V(shiftLeft, (Int32x4BinaryScalar<ShiftLeft>), 2, 0, ShiftLeft)                                                 \
+  V(shiftRight, (Int32x4BinaryScalar<ShiftRight>), 2, 0, ShiftRight)                                              \
+  V(shiftRightLogical, (Int32x4BinaryScalar<ShiftRightLogical>), 2, 0, ShiftRightLogical)                         \
   V(shuffle, (FuncShuffle<Int32x4, Shuffle<int32_t, Int32x4>, Int32x4>), 2, 0, Shuffle)                           \
   V(withFlagX, (FuncWith<Int32x4, WithFlagX<int32_t, Int32x4>, Int32x4>), 2, 0, WithFlagX)                        \
   V(withFlagY, (FuncWith<Int32x4, WithFlagY<int32_t, Int32x4>, Int32x4>), 2, 0, WithFlagY)                        \
   V(withFlagZ, (FuncWith<Int32x4, WithFlagZ<int32_t, Int32x4>, Int32x4>), 2, 0, WithFlagZ)                        \
   V(withFlagW, (FuncWith<Int32x4, WithFlagW<int32_t, Int32x4>, Int32x4>), 2, 0, WithFlagW)                        \
   V(withX, (FuncWith<Int32x4, WithX<int32_t, Int32x4>, Int32x4>), 2, 0, WithX)                                    \
   V(withY, (FuncWith<Int32x4, WithY<int32_t, Int32x4>, Int32x4>), 2, 0, WithY)                                    \
   V(withZ, (FuncWith<Int32x4, WithZ<int32_t, Int32x4>, Int32x4>), 2, 0, WithZ)                                    \
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/simd/int32x4lsh.js
@@ -0,0 +1,27 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var BUGNUMBER = 996076;
+var float32x4 = SIMD.float32x4;
+var int32x4 = SIMD.int32x4;
+
+var summary = 'int32x4 lsh';
+
+function test() {
+  print(BUGNUMBER + ": " + summary);
+
+  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
+
+  for (var bits = 0; bits < 32; bits++) {
+      var a = int32x4(-1, 2, -3, 4);
+      var c = SIMD.int32x4.shiftLeft(a, bits);
+      assertEq(c.x, -1 << bits);
+      assertEq(c.y, 2 << bits);
+      assertEq(c.z, -3 << bits);
+      assertEq(c.w, 4 << bits);
+  }
+
+  if (typeof reportCompare === "function")
+    reportCompare(true, true);
+}
+
+test();
+
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/simd/int32x4rsh.js
@@ -0,0 +1,27 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var BUGNUMBER = 996076;
+var float32x4 = SIMD.float32x4;
+var int32x4 = SIMD.int32x4;
+
+var summary = 'int32x4 rsh';
+
+function test() {
+  print(BUGNUMBER + ": " + summary);
+
+  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
+
+  for (var bits = 0; bits < 32; bits++) {
+      var a = int32x4(-1, 2, -3, 4);
+      var c = SIMD.int32x4.shiftRight(a, bits);
+      assertEq(c.x, -1 >> bits);
+      assertEq(c.y, 2 >> bits);
+      assertEq(c.z, -3 >> bits);
+      assertEq(c.w, 4 >> bits);
+  }
+
+  if (typeof reportCompare === "function")
+    reportCompare(true, true);
+}
+
+test();
+
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/simd/int32x4ursh.js
@@ -0,0 +1,27 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var BUGNUMBER = 996076;
+var float32x4 = SIMD.float32x4;
+var int32x4 = SIMD.int32x4;
+
+var summary = 'int32x4 ursh';
+
+function test() {
+  print(BUGNUMBER + ": " + summary);
+
+  // FIXME -- Bug 948379: Amend to check for correctness of border cases.
+
+  for (var bits = 0; bits < 32; bits++) {
+      var a = int32x4(-1, 2, -3, 4);
+      var c = SIMD.int32x4.shiftRightLogical(a, bits);
+      assertEq(c.x >>> 0, -1 >>> bits);
+      assertEq(c.y >>> 0, 2 >>> bits);
+      assertEq(c.z >>> 0, -3 >>> bits);
+      assertEq(c.w >>> 0, 4 >>> bits);
+  }
+
+  if (typeof reportCompare === "function")
+    reportCompare(true, true);
+}
+
+test();
+