diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-06-02 16:40:48 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-06-02 16:40:48 -0700 |
commit | a4393330dbe425ee5253812738e2dfaed631f9b1 (patch) | |
tree | 57558e773b25397bc96b629fcf8d98f52aac921b | |
parent | a0ca1cd1d41195ce61da397a82ef815d15d41fc9 (diff) | |
parent | 8823b6305fa8f488c587018afe84210eca1150a8 (diff) |
Merge branch 'update_simd' of github.com:huningxin/emscripten into incoming
Conflicts:
AUTHORS
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | src/jsifier.js | 10 | ||||
-rw-r--r-- | src/parseTools.js | 4 | ||||
-rw-r--r-- | src/simd.js | 1643 |
4 files changed, 916 insertions, 742 deletions
@@ -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 |