aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-06-02 16:40:48 -0700
committerAlon Zakai <alonzakai@gmail.com>2014-06-02 16:40:48 -0700
commita4393330dbe425ee5253812738e2dfaed631f9b1 (patch)
tree57558e773b25397bc96b629fcf8d98f52aac921b
parenta0ca1cd1d41195ce61da397a82ef815d15d41fc9 (diff)
parent8823b6305fa8f488c587018afe84210eca1150a8 (diff)
Merge branch 'update_simd' of github.com:huningxin/emscripten into incoming
Conflicts: AUTHORS
-rw-r--r--AUTHORS1
-rw-r--r--src/jsifier.js10
-rw-r--r--src/parseTools.js4
-rw-r--r--src/simd.js1643
4 files changed, 916 insertions, 742 deletions
diff --git a/AUTHORS b/AUTHORS
index 2ff3bd94..8f38c6fb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -142,4 +142,5 @@ a license to everyone to use it as detailed in LICENSE.)
* Ophir Lojkine <ophir.lojkine@eleves.ec-nantes.fr>
* Ryan Sturgell <ryan.sturgell@gmail.com> (copyright owned by Google, Inc.)
* Jason Green <jason@transgaming.com> (copyright owned by TransGaming, Inc.)
+* Ningxin Hu <ningxin.hu@intel.com> (copyright owned by Intel)
diff --git a/src/jsifier.js b/src/jsifier.js
index 065c66a8..791273f4 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1321,10 +1321,10 @@ function JSify(data, functionsOnly) {
// vector load
var native = getVectorNativeType(item.valueType);
var base = getSIMDName(native);
- return base + '32x4(' + makeGetValue(value, 0, native, 0, item.unsigned, 0, item.align) + ',' +
- makeGetValue(value, 4, native, 0, item.unsigned, 0, item.align) + ',' +
- makeGetValue(value, 8, native, 0, item.unsigned, 0, item.align) + ',' +
- makeGetValue(value, 12, native, 0, item.unsigned, 0, item.align) + ');';
+ return 'SIMD.' + base + '32x4(' + makeGetValue(value, 0, native, 0, item.unsigned, 0, item.align) + ',' +
+ makeGetValue(value, 4, native, 0, item.unsigned, 0, item.align) + ',' +
+ makeGetValue(value, 8, native, 0, item.unsigned, 0, item.align) + ',' +
+ makeGetValue(value, 12, native, 0, item.unsigned, 0, item.align) + ');';
}
var impl = item.ident ? getVarImpl(item.funcData, item.ident) : VAR_EMULATED;
switch (impl) {
@@ -1395,7 +1395,7 @@ function JSify(data, functionsOnly) {
}
for (var i = 0; i < 4; i++) assert(mask[0] == 0 || mask == 1);
i = 0;
- return base + '32x4(' + mask.map(function(m) {
+ return 'SIMD.' + base + '32x4(' + mask.map(function(m) {
return (m == 1 ? second : first) + '.' + simdLane[i++];
}).join(',') + ')';
}
diff --git a/src/parseTools.js b/src/parseTools.js
index 0c413afa..ececf477 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2035,7 +2035,7 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) {
} else if (param.intertype == 'mathop') {
return processMathop(param);
} else if (param.intertype === 'vector') {
- return getVectorBaseType(param.type) + '32x4(' + param.idents.join(',') + ')';
+ return 'SIMD.' + getVectorBaseType(param.type) + '32x4(' + param.idents.join(',') + ')';
} else {
throw 'invalid llvm parameter: ' + param.intertype;
}
@@ -2700,7 +2700,7 @@ var simdLane = ['x', 'y', 'z', 'w'];
function ensureVector(ident, base) {
Types.usesSIMD = true;
- return ident == 0 ? base + '32x4.splat(0)' : ident;
+ return ident == 0 ? 'SIMD.' + base + '32x4.splat(0)' : ident;
}
function ensureValidFFIType(type) {
diff --git a/src/simd.js b/src/simd.js
index 6e3e3675..d5ff8b15 100644
--- a/src/simd.js
+++ b/src/simd.js
@@ -22,6 +22,9 @@
"use strict";
+// SIMD module.
+var SIMD = {};
+
/**
* Construct a new instance of float32x4 number.
* @param {double} value used for x lane.
@@ -30,9 +33,9 @@
* @param {double} value used for w lane.
* @constructor
*/
-function float32x4(x, y, z, w) {
- if (!(this instanceof float32x4)) {
- return new float32x4(x, y, z, w);
+SIMD.float32x4 = function(x, y, z, w) {
+ if (!(this instanceof SIMD.float32x4)) {
+ return new SIMD.float32x4(x, y, z, w);
}
this.storage_ = new Float32Array(4);
this.storage_[0] = x;
@@ -45,8 +48,8 @@ function float32x4(x, y, z, w) {
* Construct a new instance of float32x4 number with 0.0 in all lanes.
* @constructor
*/
-float32x4.zero = function() {
- return float32x4(0.0, 0.0, 0.0, 0.0);
+SIMD.float32x4.zero = function() {
+ return SIMD.float32x4(0.0, 0.0, 0.0, 0.0);
}
/**
@@ -55,38 +58,10 @@ float32x4.zero = function() {
* @param {double} value used for all lanes.
* @constructor
*/
-float32x4.splat = function(s) {
- return float32x4(s, s, s, s);
+SIMD.float32x4.splat = function(s) {
+ return SIMD.float32x4(s, s, s, s);
}
-Object.defineProperty(float32x4.prototype, 'x', {
- get: function() { return this.storage_[0]; }
-});
-
-Object.defineProperty(float32x4.prototype, 'y', {
- get: function() { return this.storage_[1]; }
-});
-
-Object.defineProperty(float32x4.prototype, 'z', {
- get: function() { return this.storage_[2]; }
-});
-
-Object.defineProperty(float32x4.prototype, 'w',
- { get: function() { return this.storage_[3]; }
-});
-
-/**
- * Extract the sign bit from each lane return them in the first 4 bits.
- */
-Object.defineProperty(float32x4.prototype, 'signMask', {
- get: function() {
- var mx = this.x < 0.0 ? 1 : 0;
- var my = this.y < 0.0 ? 1 : 0;
- var mz = this.z < 0.0 ? 1 : 0;
- var mw = this.w < 0.0 ? 1 : 0;
- return mx | my << 1 | mz << 2 | mw << 3;
- }
-});
/**
* Construct a new instance of int32x4 number.
@@ -96,9 +71,9 @@ Object.defineProperty(float32x4.prototype, 'signMask', {
* @param {integer} 32-bit unsigned value used for w lane.
* @constructor
*/
-function int32x4(x, y, z, w) {
- if (!(this instanceof int32x4)) {
- return new int32x4(x, y, z, w);
+SIMD.int32x4 = function(x, y, z, w) {
+ if (!(this instanceof SIMD.int32x4)) {
+ return new SIMD.int32x4(x, y, z, w);
}
this.storage_ = new Int32Array(4);
this.storage_[0] = x;
@@ -108,6 +83,14 @@ function int32x4(x, y, z, w) {
}
/**
+ * Construct a new instance of int32x4 number with 0 in all lanes.
+ * @constructor
+ */
+SIMD.int32x4.zero = function() {
+ return SIMD.int32x4(0, 0, 0, 0);
+}
+
+/**
* Construct a new instance of int32x4 number with 0xFFFFFFFF or 0x0 in each
* lane, depending on the truth value in x, y, z, and w.
* @param {boolean} flag used for x lane.
@@ -116,11 +99,11 @@ function int32x4(x, y, z, w) {
* @param {boolean} flag used for w lane.
* @constructor
*/
-int32x4.bool = function(x, y, z, w) {
- return int32x4(x ? -1 : 0x0,
- y ? -1 : 0x0,
- z ? -1 : 0x0,
- w ? -1 : 0x0);
+SIMD.int32x4.bool = function(x, y, z, w) {
+ return SIMD.int32x4(x ? -1 : 0x0,
+ y ? -1 : 0x0,
+ z ? -1 : 0x0,
+ w ? -1 : 0x0);
}
/**
@@ -129,746 +112,637 @@ int32x4.bool = function(x, y, z, w) {
* @param {integer} value used for all lanes.
* @constructor
*/
-int32x4.splat = function(s) {
- return int32x4(s, s, s, s);
+SIMD.int32x4.splat = function(s) {
+ return SIMD.int32x4(s, s, s, s);
}
-Object.defineProperty(int32x4.prototype, 'x', {
- get: function() { return this.storage_[0]; }
-});
+/**
+* @return {float32x4} New instance of float32x4 with absolute values of
+* t.
+*/
+SIMD.float32x4.abs = function(t) {
+ return SIMD.float32x4(Math.abs(t.x), Math.abs(t.y), Math.abs(t.z),
+ Math.abs(t.w));
+}
-Object.defineProperty(int32x4.prototype, 'y', {
- get: function() { return this.storage_[1]; }
-});
+/**
+ * @return {float32x4} New instance of float32x4 with negated values of
+ * t.
+ */
+SIMD.float32x4.neg = function(t) {
+ return SIMD.float32x4(-t.x, -t.y, -t.z, -t.w);
+}
-Object.defineProperty(int32x4.prototype, 'z', {
- get: function() { return this.storage_[2]; }
-});
+/**
+ * @return {float32x4} New instance of float32x4 with a + b.
+ */
+SIMD.float32x4.add = function(a, b) {
+ return SIMD.float32x4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
+}
-Object.defineProperty(int32x4.prototype, 'w',
- { get: function() { return this.storage_[3]; }
-});
+/**
+ * @return {float32x4} New instance of float32x4 with a - b.
+ */
+SIMD.float32x4.sub = function(a, b) {
+ return SIMD.float32x4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
+}
-Object.defineProperty(int32x4.prototype, 'flagX', {
- get: function() { return this.storage_[0] != 0x0; }
-});
+/**
+ * @return {float32x4} New instance of float32x4 with a * b.
+ */
+SIMD.float32x4.mul = function(a, b) {
+ return SIMD.float32x4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
+}
-Object.defineProperty(int32x4.prototype, 'flagY', {
- get: function() { return this.storage_[1] != 0x0; }
-});
+/**
+ * @return {float32x4} New instance of float32x4 with a / b.
+ */
+SIMD.float32x4.div = function(a, b) {
+ return SIMD.float32x4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
+}
-Object.defineProperty(int32x4.prototype, 'flagZ', {
- get: function() { return this.storage_[2] != 0x0; }
-});
+/**
+ * @return {float32x4} New instance of float32x4 with t's values clamped
+ * between lowerLimit and upperLimit.
+ */
+SIMD.float32x4.clamp = function(t, lowerLimit, upperLimit) {
+ var cx = t.x < lowerLimit.x ? lowerLimit.x : t.x;
+ var cy = t.y < lowerLimit.y ? lowerLimit.y : t.y;
+ var cz = t.z < lowerLimit.z ? lowerLimit.z : t.z;
+ var cw = t.w < lowerLimit.w ? lowerLimit.w : t.w;
+ cx = cx > upperLimit.x ? upperLimit.x : cx;
+ cy = cy > upperLimit.y ? upperLimit.y : cy;
+ cz = cz > upperLimit.z ? upperLimit.z : cz;
+ cw = cw > upperLimit.w ? upperLimit.w : cw;
+ return SIMD.float32x4(cx, cy, cz, cw);
+}
-Object.defineProperty(int32x4.prototype, 'flagW',
- { get: function() { return this.storage_[3] != 0x0; }
-});
+/**
+ * @return {float32x4} New instance of float32x4 with the minimum value of
+ * t and other.
+ */
+SIMD.float32x4.min = function(t, other) {
+ var cx = t.x > other.x ? other.x : t.x;
+ var cy = t.y > other.y ? other.y : t.y;
+ var cz = t.z > other.z ? other.z : t.z;
+ var cw = t.w > other.w ? other.w : t.w;
+ return SIMD.float32x4(cx, cy, cz, cw);
+}
/**
- * Extract the sign bit from each lane return them in the first 4 bits.
+ * @return {float32x4} New instance of float32x4 with the maximum value of
+ * t and other.
*/
-Object.defineProperty(int32x4.prototype, 'signMask', {
- get: function() {
- var mx = (this.storage_[0] & 0x80000000) >>> 31;
- var my = (this.storage_[1] & 0x80000000) >>> 31;
- var mz = (this.storage_[2] & 0x80000000) >>> 31;
- var mw = (this.storage_[3] & 0x80000000) >>> 31;
- return mx | my << 1 | mz << 2 | mw << 3;
- }
-});
+SIMD.float32x4.max = function(t, other) {
+ var cx = t.x < other.x ? other.x : t.x;
+ var cy = t.y < other.y ? other.y : t.y;
+ var cz = t.z < other.z ? other.z : t.z;
+ var cw = t.w < other.w ? other.w : t.w;
+ return SIMD.float32x4(cx, cy, cz, cw);
+}
-function isNumber(o) {
- return typeof o == "number" || (typeof o == "object" && o.constructor === Number);
+/**
+ * @return {float32x4} New instance of float32x4 with reciprocal value of
+ * t.
+ */
+SIMD.float32x4.reciprocal = function(t) {
+ return SIMD.float32x4(1.0 / t.x, 1.0 / t.y, 1.0 / t.z, 1.0 / t.w);
}
-function isTypedArray(o) {
- return (o instanceof Int8Array) ||
- (o instanceof Uint8Array) ||
- (o instanceof Uint8ClampedArray) ||
- (o instanceof Int16Array) ||
- (o instanceof Uint16Array) ||
- (o instanceof Int32Array) ||
- (o instanceof Uint32Array) ||
- (o instanceof Float32Array) ||
- (o instanceof Float64Array) ||
- (o instanceof Float32x4Array);
+/**
+ * @return {float32x4} New instance of float32x4 with square root of the
+ * reciprocal value of t.
+ */
+SIMD.float32x4.reciprocalSqrt = function(t) {
+ return SIMD.float32x4(Math.sqrt(1.0 / t.x), Math.sqrt(1.0 / t.y),
+ Math.sqrt(1.0 / t.z), Math.sqrt(1.0 / t.w));
+}
+/**
+ * @return {float32x4} New instance of float32x4 with values of t
+ * scaled by s.
+ */
+SIMD.float32x4.scale = function(t, s) {
+ return SIMD.float32x4(s * t.x, s * t.y, s * t.z, s * t.w);
}
-function isArrayBuffer(o) {
- return (o instanceof ArrayBuffer);
+/**
+ * @return {float32x4} New instance of float32x4 with square root of
+ * values of t.
+ */
+SIMD.float32x4.sqrt = function(t) {
+ return SIMD.float32x4(Math.sqrt(t.x), Math.sqrt(t.y),
+ Math.sqrt(t.z), Math.sqrt(t.w));
}
-function Float32x4Array(a, b, c) {
- if (isNumber(a)) {
- this.storage_ = new Float32Array(a*4);
- this.length_ = a;
- this.byteOffset_ = 0;
- return;
- } else if (isTypedArray(a)) {
- if (!(a instanceof Float32x4Array)) {
- throw "Copying typed array of non-Float32x4Array is unimplemented.";
- }
- this.storage_ = new Float32Array(a.length * 4);
- this.length_ = a.length;
- this.byteOffset_ = 0;
- // Copy floats.
- for (var i = 0; i < a.length*4; i++) {
- this.storage_[i] = a.storage_[i];
- }
- } else if (isArrayBuffer(a)) {
- if ((b != undefined) && (b % Float32x4Array.BYTES_PER_ELEMENT) != 0) {
- throw "byteOffset must be a multiple of 16.";
- }
- if (c != undefined) {
- c *= 4;
- this.storage_ = new Float32Array(a, b, c);
- }
- else {
- // Note: new Float32Array(a, b) is NOT equivalent to new Float32Array(a, b, undefined)
- this.storage_ = new Float32Array(a, b);
- }
- this.length_ = this.storage_.length / 4;
- this.byteOffset_ = b != undefined ? b : 0;
- } else {
- throw "Unknown type of first argument.";
- }
+/**
+ * @param {float32x4} t An instance of float32x4 to be shuffled.
+ * @param {integer} mask One of the 256 shuffle masks, for example, SIMD.XXXX.
+ * @return {float32x4} New instance of float32x4 with lanes shuffled.
+ */
+SIMD.float32x4.shuffle = function(t, mask) {
+ var _x = (mask) & 0x3;
+ var _y = (mask >> 2) & 0x3;
+ var _z = (mask >> 4) & 0x3;
+ var _w = (mask >> 6) & 0x3;
+ return SIMD.float32x4(t.storage_[_x], t.storage_[_y], t.storage_[_z],
+ t.storage_[_w]);
}
-Object.defineProperty(Float32x4Array.prototype, 'length',
- { get: function() { return this.length_; }
-});
+/**
+ * @param {float32x4} t1 An instance of float32x4 to be shuffled. XY lanes in result
+ * @param {float32x4} t2 An instance of float32x4 to be shuffled. ZW lanes in result
+ * @param {integer} mask One of the 256 shuffle masks, for example, SIMD.XXXX.
+ * @return {float32x4} New instance of float32x4 with lanes shuffled.
+ */
+SIMD.float32x4.shuffleMix = function(t1, t2, mask) {
+ var _x = (mask) & 0x3;
+ var _y = (mask >> 2) & 0x3;
+ var _z = (mask >> 4) & 0x3;
+ var _w = (mask >> 6) & 0x3;
+ return SIMD.float32x4(t1.storage_[_x], t1.storage_[_y], t2.storage_[_z],
+ t2.storage_[_w]);
+}
-Object.defineProperty(Float32x4Array.prototype, 'byteLength',
- { get: function() { return this.length_ * Float32x4Array.BYTES_PER_ELEMENT; }
-});
+/**
+ * @param {double} value used for x lane.
+ * @return {float32x4} New instance of float32x4 with the values in t and
+ * x replaced with {x}.
+ */
+SIMD.float32x4.withX = function(t, x) {
+ return SIMD.float32x4(x, t.y, t.z, t.w);
+}
-Object.defineProperty(Float32x4Array, 'BYTES_PER_ELEMENT',
- { get: function() { return 16; }
-});
+/**
+ * @param {double} value used for y lane.
+ * @return {float32x4} New instance of float32x4 with the values in t and
+ * y replaced with {y}.
+ */
+SIMD.float32x4.withY = function(t, y) {
+ return SIMD.float32x4(t.x, y, t.z, t.w);
+}
-Object.defineProperty(Float32x4Array.prototype, 'BYTES_PER_ELEMENT',
- { get: function() { return 16; }
-});
+/**
+ * @param {double} value used for z lane.
+ * @return {float32x4} New instance of float32x4 with the values in t and
+ * z replaced with {z}.
+ */
+SIMD.float32x4.withZ = function(t, z) {
+ return SIMD.float32x4(t.x, t.y, z, t.w);
+}
-Object.defineProperty(Float32x4Array.prototype, 'byteOffset',
- { get: function() { return this.byteOffset_; }
-});
+/**
+ * @param {double} value used for w lane.
+ * @return {float32x4} New instance of float32x4 with the values in t and
+ * w replaced with {w}.
+ */
+SIMD.float32x4.withW = function(t, w) {
+ return SIMD.float32x4(t.x, t.y, t.z, w);
+}
-Object.defineProperty(Float32x4Array.prototype, 'buffer',
- { get: function() { return this.storage_.buffer; }
-});
+/**
+ * @param {float32x4} t An instance of float32x4.
+ * @param {float32x4} other An instance of float32x4.
+ * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
+ * the result of t < other.
+ */
+SIMD.float32x4.lessThan = function(t, other) {
+ var cx = t.x < other.x;
+ var cy = t.y < other.y;
+ var cz = t.z < other.z;
+ var cw = t.w < other.w;
+ return SIMD.int32x4.bool(cx, cy, cz, cw);
+}
-Float32x4Array.prototype.getAt = function(i) {
- if (i < 0) {
- throw "Index must be >= 0.";
- }
- if (i >= this.length) {
- throw "Index out of bounds.";
- }
- var x = this.storage_[i*4+0];
- var y = this.storage_[i*4+1];
- var z = this.storage_[i*4+2];
- var w = this.storage_[i*4+3];
- return float32x4(x, y, z, w);
+/**
+ * @param {float32x4} t An instance of float32x4.
+ * @param {float32x4} other An instance of float32x4.
+ * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
+ * the result of t <= other.
+ */
+SIMD.float32x4.lessThanOrEqual = function(t, other) {
+ var cx = t.x <= other.x;
+ var cy = t.y <= other.y;
+ var cz = t.z <= other.z;
+ var cw = t.w <= other.w;
+ return SIMD.int32x4.bool(cx, cy, cz, cw);
}
-Float32x4Array.prototype.setAt = function(i, v) {
- if (i < 0) {
- throw "Index must be >= 0.";
- }
- if (i >= this.length) {
- throw "Index out of bounds.";
- }
- if (!(v instanceof float32x4)) {
- throw "Value is not a float32x4.";
- }
- this.storage_[i*4+0] = v.x;
- this.storage_[i*4+1] = v.y;
- this.storage_[i*4+2] = v.z;
- this.storage_[i*4+3] = v.w;
+/**
+ * @param {float32x4} t An instance of float32x4.
+ * @param {float32x4} other An instance of float32x4.
+ * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
+ * the result of t == other.
+ */
+SIMD.float32x4.equal = function(t, other) {
+ var cx = t.x == other.x;
+ var cy = t.y == other.y;
+ var cz = t.z == other.z;
+ var cw = t.w == other.w;
+ return SIMD.int32x4.bool(cx, cy, cz, cw);
}
+/**
+ * @param {float32x4} t An instance of float32x4.
+ * @param {float32x4} other An instance of float32x4.
+ * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
+ * the result of t != other.
+ */
+SIMD.float32x4.notEqual = function(t, other) {
+ var cx = t.x != other.x;
+ var cy = t.y != other.y;
+ var cz = t.z != other.z;
+ var cw = t.w != other.w;
+ return SIMD.int32x4.bool(cx, cy, cz, cw);
+}
-function Int32x4Array(a, b, c) {
+/**
+ * @param {float32x4} t An instance of float32x4.
+ * @param {float32x4} other An instance of float32x4.
+ * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
+ * the result of t >= other.
+ */
+SIMD.float32x4.greaterThanOrEqual = function(t, other) {
+ var cx = t.x >= other.x;
+ var cy = t.y >= other.y;
+ var cz = t.z >= other.z;
+ var cw = t.w >= other.w;
+ return SIMD.int32x4.bool(cx, cy, cz, cw);
+}
- function isNumber(o) {
- return typeof o == "number" || (typeof o == "object" && o.constructor === Number);
- }
+/**
+ * @param {float32x4} t An instance of float32x4.
+ * @param {float32x4} other An instance of float32x4.
+ * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
+ * the result of t > other.
+ */
+SIMD.float32x4.greaterThan = function(t, other) {
+ var cx = t.x > other.x;
+ var cy = t.y > other.y;
+ var cz = t.z > other.z;
+ var cw = t.w > other.w;
+ return SIMD.int32x4.bool(cx, cy, cz, cw);
+}
- function isTypedArray(o) {
- return (o instanceof Int8Array) ||
- (o instanceof Uint8Array) ||
- (o instanceof Uint8ClampedArray) ||
- (o instanceof Int16Array) ||
- (o instanceof Uint16Array) ||
- (o instanceof Int32Array) ||
- (o instanceof Uint32Array) ||
- (o instanceof Float32Array) ||
- (o instanceof Float64Array) ||
- (o instanceof Int32x4Array) ||
- (o instanceof Float32x4Array);
- }
+/**
+ * @param {float32x4} t An instance of float32x4.
+ * @return {int32x4} a bit-wise copy of t as a int32x4.
+ */
+SIMD.float32x4.bitsToInt32x4 = function(t) {
+ var alias = new Int32Array(t.storage_.buffer);
+ return SIMD.int32x4(alias[0], alias[1], alias[2], alias[3]);
+}
- function isArrayBuffer(o) {
- return (o instanceof ArrayBuffer);
- }
+/**
+ * @param {float32x4} t An instance of float32x4.
+ * @return {int32x4} with a integer to float conversion of t.
+ */
+SIMD.float32x4.toInt32x4 = function(t) {
+ var a = SIMD.int32x4(t.storage_[0], t.storage_[1], t.storage_[2],
+ t.storage_[3]);
+ return a;
+}
- if (isNumber(a)) {
- this.storage_ = new Int32Array(a*4);
- this.length_ = a;
- this.byteOffset_ = 0;
- return;
- } else if (isTypedArray(a)) {
- if (!(a instanceof Int32x4Array)) {
- throw "Copying typed array of non-Int32x4Array is unimplemented.";
- }
- this.storage_ = new Int32Array(a.length * 4);
- this.length_ = a.length;
- this.byteOffset_ = 0;
- // Copy floats.
- for (var i = 0; i < a.length*4; i++) {
- this.storage_[i] = a.storage_[i];
- }
- } else if (isArrayBuffer(a)) {
- if ((b != undefined) && (b % Int32x4Array.BYTES_PER_ELEMENT) != 0) {
- throw "byteOffset must be a multiple of 16.";
- }
- if (c != undefined) {
- c *= 4;
- this.storage_ = new Int32Array(a, b, c);
- }
- else {
- // Note: new Int32Array(a, b) is NOT equivalent to new Float32Array(a, b, undefined)
- this.storage_ = new Int32Array(a, b);
- }
- this.length_ = this.storage_.length / 4;
- this.byteOffset_ = b != undefined ? b : 0;
- } else {
- throw "Unknown type of first argument.";
- }
+/**
+ * @param {float32x4} a An instance of float32x4.
+ * @param {float32x4} b An instance of float32x4.
+ * @return {float32x4} New instance of float32x4 with values of a & b.
+ */
+SIMD.float32x4.and = function(a, b) {
+ var aInt = SIMD.float32x4.bitsToInt32x4(a);
+ var bInt = SIMD.float32x4.bitsToInt32x4(b);
+ return SIMD.int32x4.bitsToFloat32x4(SIMD.int32x4.and(aInt, bInt));
}
-Object.defineProperty(Int32x4Array.prototype, 'length',
- { get: function() { return this.length_; }
-});
+/**
+ * @param {float32x4} a An instance of float32x4.
+ * @param {float32x4} b An instance of float32x4.
+ * @return {float32x4} New instance of float32x4 with values of a | b.
+ */
+SIMD.float32x4.or = function(a, b) {
+ var aInt = SIMD.float32x4.bitsToInt32x4(a);
+ var bInt = SIMD.float32x4.bitsToInt32x4(b);
+ return SIMD.int32x4.bitsToFloat32x4(SIMD.int32x4.or(aInt, bInt));
+}
-Object.defineProperty(Int32x4Array.prototype, 'byteLength',
- { get: function() { return this.length_ * Int32x4Array.BYTES_PER_ELEMENT; }
-});
+/**
+ * @param {float32x4} a An instance of float32x4.
+ * @param {float32x4} b An instance of float32x4.
+ * @return {float32x4} New instance of float32x4 with values of a ^ b.
+ */
+SIMD.float32x4.xor = function(a, b) {
+ var aInt = SIMD.float32x4.bitsToInt32x4(a);
+ var bInt = SIMD.float32x4.bitsToInt32x4(b);
+ return SIMD.int32x4.bitsToFloat32x4(SIMD.int32x4.xor(aInt, bInt));
+}
-Object.defineProperty(Int32x4Array, 'BYTES_PER_ELEMENT',
- { get: function() { return 16; }
-});
+/**
+ * @param {float32x4} a An instance of float32x4.
+ * @return {float32x4} New instance of float32x4 with values of ~a.
+ */
+SIMD.float32x4.not = function(a) {
+ var aInt = SIMD.float32x4.bitsToInt32x4(a);
+ return SIMD.int32x4.bitsToFloat32x4(SIMD.int32x4.not(aInt));
+}
-Object.defineProperty(Int32x4Array.prototype, 'BYTES_PER_ELEMENT',
- { get: function() { return 16; }
-});
+/**
+ * @param {int32x4} a An instance of int32x4.
+ * @param {int32x4} b An instance of int32x4.
+ * @return {int32x4} New instance of int32x4 with values of a & b.
+ */
+SIMD.int32x4.and = function(a, b) {
+ return SIMD.int32x4(a.x & b.x, a.y & b.y, a.z & b.z, a.w & b.w);
+}
-Object.defineProperty(Int32x4Array.prototype, 'byteOffset',
- { get: function() { return this.byteOffset_; }
-});
+/**
+ * @param {int32x4} a An instance of int32x4.
+ * @param {int32x4} b An instance of int32x4.
+ * @return {int32x4} New instance of int32x4 with values of a | b.
+ */
+SIMD.int32x4.or = function(a, b) {
+ return SIMD.int32x4(a.x | b.x, a.y | b.y, a.z | b.z, a.w | b.w);
+}
-Object.defineProperty(Int32x4Array.prototype, 'buffer',
- { get: function() { return this.storage_.buffer; }
-});
+/**
+ * @param {int32x4} a An instance of int32x4.
+ * @param {int32x4} b An instance of int32x4.
+ * @return {int32x4} New instance of int32x4 with values of a ^ b.
+ */
+SIMD.int32x4.xor = function(a, b) {
+ return SIMD.int32x4(a.x ^ b.x, a.y ^ b.y, a.z ^ b.z, a.w ^ b.w);
+}
-Int32x4Array.prototype.getAt = function(i) {
- if (i < 0) {
- throw "Index must be >= 0.";
- }
- if (i >= this.length) {
- throw "Index out of bounds.";
- }
- var x = this.storage_[i*4+0];
- var y = this.storage_[i*4+1];
- var z = this.storage_[i*4+2];
- var w = this.storage_[i*4+3];
- return float32x4(x, y, z, w);
+/**
+ * @param {int32x4} t An instance of int32x4.
+ * @return {int32x4} New instance of int32x4 with values of ~t
+ */
+SIMD.int32x4.not = function(t) {
+ return SIMD.int32x4(~t.x, ~t.y, ~t.z, ~t.w);
}
-Int32x4Array.prototype.setAt = function(i, v) {
- if (i < 0) {
- throw "Index must be >= 0.";
- }
- if (i >= this.length) {
- throw "Index out of bounds.";
- }
- if (!(v instanceof int32x4)) {
- throw "Value is not a int32x4.";
- }
- this.storage_[i*4+0] = v.x;
- this.storage_[i*4+1] = v.y;
- this.storage_[i*4+2] = v.z;
- this.storage_[i*4+3] = v.w;
+/**
+ * @param {int32x4} t An instance of int32x4.
+ * @return {int32x4} New instance of int32x4 with values of -t
+ */
+SIMD.int32x4.neg = function(t) {
+ return SIMD.int32x4(-t.x, -t.y, -t.z, -t.w);
}
-var SIMD = (function () {
- return {
- float32x4: {
- /**
- * @return {float32x4} New instance of float32x4 with absolute values of
- * t.
- */
- abs: function(t) {
- return new float32x4(Math.abs(t.x), Math.abs(t.y), Math.abs(t.z),
- Math.abs(t.w));
- },
- /**
- * @return {float32x4} New instance of float32x4 with negated values of
- * t.
- */
- neg: function(t) {
- return new float32x4(-t.x, -t.y, -t.z, -t.w);
- },
- /**
- * @return {float32x4} New instance of float32x4 with a + b.
- */
- add: function(a, b) {
- return new float32x4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
- },
- /**
- * @return {float32x4} New instance of float32x4 with a - b.
- */
- sub: function(a, b) {
- return new float32x4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
- },
- /**
- * @return {float32x4} New instance of float32x4 with a * b.
- */
- mul: function(a, b) {
- return new float32x4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
- },
- /**
- * @return {float32x4} New instance of float32x4 with a / b.
- */
- div: function(a, b) {
- return new float32x4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
- },
- /**
- * @return {float32x4} New instance of float32x4 with t's values clamped
- * between lowerLimit and upperLimit.
- */
- clamp: function(t, lowerLimit, upperLimit) {
- var cx = t.x < lowerLimit.x ? lowerLimit.x : t.x;
- var cy = t.y < lowerLimit.y ? lowerLimit.y : t.y;
- var cz = t.z < lowerLimit.z ? lowerLimit.z : t.z;
- var cw = t.w < lowerLimit.w ? lowerLimit.w : t.w;
- cx = cx > upperLimit.x ? upperLimit.x : cx;
- cy = cy > upperLimit.y ? upperLimit.y : cy;
- cz = cz > upperLimit.z ? upperLimit.z : cz;
- cw = cw > upperLimit.w ? upperLimit.w : cw;
- return new float32x4(cx, cy, cz, cw);
- },
- /**
- * @return {float32x4} New instance of float32x4 with the minimum value of
- * t and other.
- */
- min: function(t, other) {
- var cx = t.x > other.x ? other.x : t.x;
- var cy = t.y > other.y ? other.y : t.y;
- var cz = t.z > other.z ? other.z : t.z;
- var cw = t.w > other.w ? other.w : t.w;
- return new float32x4(cx, cy, cz, cw);
- },
- /**
- * @return {float32x4} New instance of float32x4 with the maximum value of
- * t and other.
- */
- max: function(t, other) {
- var cx = t.x < other.x ? other.x : t.x;
- var cy = t.y < other.y ? other.y : t.y;
- var cz = t.z < other.z ? other.z : t.z;
- var cw = t.w < other.w ? other.w : t.w;
- return new float32x4(cx, cy, cz, cw);
- },
- /**
- * @return {float32x4} New instance of float32x4 with reciprocal value of
- * t.
- */
- reciprocal: function(t) {
- return new float32x4(1.0 / t.x, 1.0 / t.y, 1.0 / t.z, 1.0 / t.w);
- },
- /**
- * @return {float32x4} New instance of float32x4 with square root of the
- * reciprocal value of t.
- */
- reciprocalSqrt: function(t) {
- return new float32x4(Math.sqrt(1.0 / t.x), Math.sqrt(1.0 / t.y),
- Math.sqrt(1.0 / t.z), Math.sqrt(1.0 / t.w));
- },
- /**
- * @return {float32x4} New instance of float32x4 with values of t
- * scaled by s.
- */
- scale: function(t, s) {
- return new float32x4(s * t.x, s * t.y, s * t.z, s * t.w);
- },
- /**
- * @return {float32x4} New instance of float32x4 with square root of
- * values of t.
- */
- sqrt: function(t) {
- return new float32x4(Math.sqrt(t.x), Math.sqrt(t.y),
- Math.sqrt(t.z), Math.sqrt(t.w));
- },
- /**
- * @param {float32x4} t An instance of float32x4 to be shuffled.
- * @param {integer} mask One of the 256 shuffle masks, for example, SIMD.XXXX.
- * @return {float32x4} New instance of float32x4 with lanes shuffled.
- */
- shuffle: function(t, mask) {
- var _x = (mask) & 0x3;
- var _y = (mask >> 2) & 0x3;
- var _z = (mask >> 4) & 0x3;
- var _w = (mask >> 6) & 0x3;
- return new float32x4(t.storage_[_x], t.storage_[_y], t.storage_[_z],
- t.storage_[_w]);
- },
- /**
- * @param {float32x4} t1 An instance of float32x4 to be shuffled. XY lanes in result
- * @param {float32x4} t2 An instance of float32x4 to be shuffled. ZW lanes in result
- * @param {integer} mask One of the 256 shuffle masks, for example, SIMD.XXXX.
- * @return {float32x4} New instance of float32x4 with lanes shuffled.
- */
- shuffleMix: function(t1, t2, mask) {
- var _x = (mask) & 0x3;
- var _y = (mask >> 2) & 0x3;
- var _z = (mask >> 4) & 0x3;
- var _w = (mask >> 6) & 0x3;
- return new float32x4(t1.storage_[_x], t1.storage_[_y], t2.storage_[_z],
- t2.storage_[_w]);
- },
- /**
- * @param {double} value used for x lane.
- * @return {float32x4} New instance of float32x4 with the values in t and
- * x replaced with {x}.
- */
- withX: function(t, x) {
- return new float32x4(x, t.y, t.z, t.w);
- },
- /**
- * @param {double} value used for y lane.
- * @return {float32x4} New instance of float32x4 with the values in t and
- * y replaced with {y}.
- */
- withY: function(t, y) {
- return new float32x4(t.x, y, t.z, t.w);
- },
- /**
- * @param {double} value used for z lane.
- * @return {float32x4} New instance of float32x4 with the values in t and
- * z replaced with {z}.
- */
- withZ: function(t, z) {
- return new float32x4(t.x, t.y, z, t.w);
- },
- /**
- * @param {double} value used for w lane.
- * @return {float32x4} New instance of float32x4 with the values in t and
- * w replaced with {w}.
- */
- withW: function(t, w) {
- return new float32x4(t.x, t.y, t.z, w);
- },
- /**
- * @param {float32x4} t An instance of float32x4.
- * @param {float32x4} other An instance of float32x4.
- * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
- * the result of t < other.
- */
- lessThan: function(t, other) {
- var cx = t.x < other.x;
- var cy = t.y < other.y;
- var cz = t.z < other.z;
- var cw = t.w < other.w;
- return int32x4.bool(cx, cy, cz, cw);
- },
- /**
- * @param {float32x4} t An instance of float32x4.
- * @param {float32x4} other An instance of float32x4.
- * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
- * the result of t <= other.
- */
- lessThanOrEqual: function(t, other) {
- var cx = t.x <= other.x;
- var cy = t.y <= other.y;
- var cz = t.z <= other.z;
- var cw = t.w <= other.w;
- return int32x4.bool(cx, cy, cz, cw);
- },
- /**
- * @param {float32x4} t An instance of float32x4.
- * @param {float32x4} other An instance of float32x4.
- * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
- * the result of t == other.
- */
- equal: function(t, other) {
- var cx = t.x == other.x;
- var cy = t.y == other.y;
- var cz = t.z == other.z;
- var cw = t.w == other.w;
- return int32x4.bool(cx, cy, cz, cw);
- },
- /**
- * @param {float32x4} t An instance of float32x4.
- * @param {float32x4} other An instance of float32x4.
- * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
- * the result of t != other.
- */
- notEqual: function(t, other) {
- var cx = t.x != other.x;
- var cy = t.y != other.y;
- var cz = t.z != other.z;
- var cw = t.w != other.w;
- return int32x4.bool(cx, cy, cz, cw);
- },
- /**
- * @param {float32x4} t An instance of float32x4.
- * @param {float32x4} other An instance of float32x4.
- * @return {int32x4} 0xFFFFFFFF or 0x0 in each lane depending on
- * the result of t >= othe