1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 * vim: set ts=8 sts=4 et sw=4 tw=99: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef builtin_SIMD_h 8 #define builtin_SIMD_h 9 10 #include "jsapi.h" 11 #include "jsobj.h" 12 13 #include "builtin/TypedObject.h" 14 #include "js/Conversions.h" 15 #include "vm/GlobalObject.h" 16 17 /* 18 * JS SIMD functions. 19 * Spec matching polyfill: 20 * https://github.com/johnmccutchan/ecmascript_simd/blob/master/src/ecmascript_simd.js 21 */ 22 23 #define FLOAT32X4_UNARY_FUNCTION_LIST(V) \ 24 V(abs, (UnaryFunc<Float32x4, Abs, Float32x4>), 1) \ 25 V(check, (UnaryFunc<Float32x4, Identity, Float32x4>), 1) \ 26 V(fromFloat64x2, (FuncConvert<Float64x2, Float32x4> ), 1) \ 27 V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Float32x4>), 1) \ 28 V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Float32x4>), 1) \ 29 V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Float32x4>), 1) \ 30 V(fromInt32x4, (FuncConvert<Int32x4, Float32x4> ), 1) \ 31 V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float32x4>), 1) \ 32 V(neg, (UnaryFunc<Float32x4, Neg, Float32x4>), 1) \ 33 V(not, (CoercedUnaryFunc<Float32x4, Int32x4, Not, Float32x4>), 1) \ 34 V(reciprocalApproximation, (UnaryFunc<Float32x4, RecApprox, Float32x4>), 1) \ 35 V(reciprocalSqrtApproximation, (UnaryFunc<Float32x4, RecSqrtApprox, Float32x4>), 1) \ 36 V(splat, (FuncSplat<Float32x4>), 1) \ 37 V(sqrt, (UnaryFunc<Float32x4, Sqrt, Float32x4>), 1) 38 39 #define FLOAT32X4_BINARY_FUNCTION_LIST(V) \ 40 V(add, (BinaryFunc<Float32x4, Add, Float32x4>), 2) \ 41 V(and, (CoercedBinaryFunc<Float32x4, Int32x4, And, Float32x4>), 2) \ 42 V(div, (BinaryFunc<Float32x4, Div, Float32x4>), 2) \ 43 V(equal, (CompareFunc<Float32x4, Equal, Int32x4>), 2) \ 44 V(extractLane, (ExtractLane<Float32x4>), 2) \ 45 V(greaterThan, (CompareFunc<Float32x4, GreaterThan, Int32x4>), 2) \ 46 V(greaterThanOrEqual, (CompareFunc<Float32x4, GreaterThanOrEqual, Int32x4>), 2) \ 47 V(lessThan, (CompareFunc<Float32x4, LessThan, Int32x4>), 2) \ 48 V(lessThanOrEqual, (CompareFunc<Float32x4, LessThanOrEqual, Int32x4>), 2) \ 49 V(load, (Load<Float32x4, 4>), 2) \ 50 V(load3, (Load<Float32x4, 3>), 2) \ 51 V(load2, (Load<Float32x4, 2>), 2) \ 52 V(load1, (Load<Float32x4, 1>), 2) \ 53 V(max, (BinaryFunc<Float32x4, Maximum, Float32x4>), 2) \ 54 V(maxNum, (BinaryFunc<Float32x4, MaxNum, Float32x4>), 2) \ 55 V(min, (BinaryFunc<Float32x4, Minimum, Float32x4>), 2) \ 56 V(minNum, (BinaryFunc<Float32x4, MinNum, Float32x4>), 2) \ 57 V(mul, (BinaryFunc<Float32x4, Mul, Float32x4>), 2) \ 58 V(notEqual, (CompareFunc<Float32x4, NotEqual, Int32x4>), 2) \ 59 V(or, (CoercedBinaryFunc<Float32x4, Int32x4, Or, Float32x4>), 2) \ 60 V(sub, (BinaryFunc<Float32x4, Sub, Float32x4>), 2) \ 61 V(xor, (CoercedBinaryFunc<Float32x4, Int32x4, Xor, Float32x4>), 2) 62 63 #define FLOAT32X4_TERNARY_FUNCTION_LIST(V) \ 64 V(replaceLane, (ReplaceLane<Float32x4>), 3) \ 65 V(select, (Select<Float32x4, Int32x4>), 3) \ 66 V(store, (Store<Float32x4, 4>), 3) \ 67 V(store3, (Store<Float32x4, 3>), 3) \ 68 V(store2, (Store<Float32x4, 2>), 3) \ 69 V(store1, (Store<Float32x4, 1>), 3) 70 71 #define FLOAT32X4_SHUFFLE_FUNCTION_LIST(V) \ 72 V(swizzle, Swizzle<Float32x4>, 5) \ 73 V(shuffle, Shuffle<Float32x4>, 6) 74 75 #define FLOAT32X4_FUNCTION_LIST(V) \ 76 FLOAT32X4_UNARY_FUNCTION_LIST(V) \ 77 FLOAT32X4_BINARY_FUNCTION_LIST(V) \ 78 FLOAT32X4_TERNARY_FUNCTION_LIST(V) \ 79 FLOAT32X4_SHUFFLE_FUNCTION_LIST(V) 80 81 #define FLOAT64X2_UNARY_FUNCTION_LIST(V) \ 82 V(abs, (UnaryFunc<Float64x2, Abs, Float64x2>), 1) \ 83 V(check, (UnaryFunc<Float64x2, Identity, Float64x2>), 1) \ 84 V(fromFloat32x4, (FuncConvert<Float32x4, Float64x2> ), 1) \ 85 V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Float64x2>), 1) \ 86 V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Float64x2>), 1) \ 87 V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Float64x2>), 1) \ 88 V(fromInt32x4, (FuncConvert<Int32x4, Float64x2> ), 1) \ 89 V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float64x2>), 1) \ 90 V(neg, (UnaryFunc<Float64x2, Neg, Float64x2>), 1) \ 91 V(reciprocalApproximation, (UnaryFunc<Float64x2, RecApprox, Float64x2>), 1) \ 92 V(reciprocalSqrtApproximation, (UnaryFunc<Float64x2, RecSqrtApprox, Float64x2>), 1) \ 93 V(splat, (FuncSplat<Float64x2>), 1) \ 94 V(sqrt, (UnaryFunc<Float64x2, Sqrt, Float64x2>), 1) 95 96 #define FLOAT64X2_BINARY_FUNCTION_LIST(V) \ 97 V(add, (BinaryFunc<Float64x2, Add, Float64x2>), 2) \ 98 V(div, (BinaryFunc<Float64x2, Div, Float64x2>), 2) \ 99 V(equal, (CompareFunc<Float64x2, Equal, Int32x4>), 2) \ 100 V(extractLane, (ExtractLane<Float64x2>), 2) \ 101 V(greaterThan, (CompareFunc<Float64x2, GreaterThan, Int32x4>), 2) \ 102 V(greaterThanOrEqual, (CompareFunc<Float64x2, GreaterThanOrEqual, Int32x4>), 2) \ 103 V(lessThan, (CompareFunc<Float64x2, LessThan, Int32x4>), 2) \ 104 V(lessThanOrEqual, (CompareFunc<Float64x2, LessThanOrEqual, Int32x4>), 2) \ 105 V(load, (Load<Float64x2, 2>), 2) \ 106 V(load1, (Load<Float64x2, 1>), 2) \ 107 V(max, (BinaryFunc<Float64x2, Maximum, Float64x2>), 2) \ 108 V(maxNum, (BinaryFunc<Float64x2, MaxNum, Float64x2>), 2) \ 109 V(min, (BinaryFunc<Float64x2, Minimum, Float64x2>), 2) \ 110 V(minNum, (BinaryFunc<Float64x2, MinNum, Float64x2>), 2) \ 111 V(mul, (BinaryFunc<Float64x2, Mul, Float64x2>), 2) \ 112 V(notEqual, (CompareFunc<Float64x2, NotEqual, Int32x4>), 2) \ 113 V(sub, (BinaryFunc<Float64x2, Sub, Float64x2>), 2) 114 115 #define FLOAT64X2_TERNARY_FUNCTION_LIST(V) \ 116 V(replaceLane, (ReplaceLane<Float64x2>), 3) \ 117 V(select, (Select<Float64x2, Int32x4>), 3) \ 118 V(store, (Store<Float64x2, 2>), 3) \ 119 V(store1, (Store<Float64x2, 1>), 3) 120 121 #define FLOAT64X2_SHUFFLE_FUNCTION_LIST(V) \ 122 V(swizzle, Swizzle<Float64x2>, 3) \ 123 V(shuffle, Shuffle<Float64x2>, 4) 124 125 #define FLOAT64X2_FUNCTION_LIST(V) \ 126 FLOAT64X2_UNARY_FUNCTION_LIST(V) \ 127 FLOAT64X2_BINARY_FUNCTION_LIST(V) \ 128 FLOAT64X2_TERNARY_FUNCTION_LIST(V) \ 129 FLOAT64X2_SHUFFLE_FUNCTION_LIST(V) 130 131 #define INT8X16_UNARY_FUNCTION_LIST(V) \ 132 V(check, (UnaryFunc<Int8x16, Identity, Int8x16>), 1) \ 133 V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int8x16>), 1) \ 134 V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int8x16>), 1) \ 135 V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Int8x16>), 1) \ 136 V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Int8x16>), 1) \ 137 V(neg, (UnaryFunc<Int8x16, Neg, Int8x16>), 1) \ 138 V(not, (UnaryFunc<Int8x16, Not, Int8x16>), 1) \ 139 V(splat, (FuncSplat<Int8x16>), 1) 140 141 #define INT8X16_BINARY_FUNCTION_LIST(V) \ 142 V(add, (BinaryFunc<Int8x16, Add, Int8x16>), 2) \ 143 V(and, (BinaryFunc<Int8x16, And, Int8x16>), 2) \ 144 V(equal, (CompareFunc<Int8x16, Equal, Int8x16>), 2) \ 145 V(extractLane, (ExtractLane<Int8x16>), 2) \ 146 V(greaterThan, (CompareFunc<Int8x16, GreaterThan, Int8x16>), 2) \ 147 V(greaterThanOrEqual, (CompareFunc<Int8x16, GreaterThanOrEqual, Int8x16>), 2) \ 148 V(lessThan, (CompareFunc<Int8x16, LessThan, Int8x16>), 2) \ 149 V(lessThanOrEqual, (CompareFunc<Int8x16, LessThanOrEqual, Int8x16>), 2) \ 150 V(load, (Load<Int8x16, 16>), 2) \ 151 V(mul, (BinaryFunc<Int8x16, Mul, Int8x16>), 2) \ 152 V(notEqual, (CompareFunc<Int8x16, NotEqual, Int8x16>), 2) \ 153 V(or, (BinaryFunc<Int8x16, Or, Int8x16>), 2) \ 154 V(sub, (BinaryFunc<Int8x16, Sub, Int8x16>), 2) \ 155 V(shiftLeftByScalar, (BinaryScalar<Int8x16, ShiftLeft>), 2) \ 156 V(shiftRightArithmeticByScalar, (BinaryScalar<Int8x16, ShiftRightArithmetic>), 2) \ 157 V(shiftRightLogicalByScalar, (BinaryScalar<Int8x16, ShiftRightLogical>), 2) \ 158 V(xor, (BinaryFunc<Int8x16, Xor, Int8x16>), 2) 159 160 #define INT8X16_TERNARY_FUNCTION_LIST(V) \ 161 V(replaceLane, (ReplaceLane<Int8x16>), 3) \ 162 V(select, (Select<Int8x16, Int8x16>), 3) \ 163 V(selectBits, (SelectBits<Int8x16, Int8x16>), 3) \ 164 V(store, (Store<Int8x16, 16>), 3) 165 166 #define INT8X16_SHUFFLE_FUNCTION_LIST(V) \ 167 V(swizzle, Swizzle<Int8x16>, 17) \ 168 V(shuffle, Shuffle<Int8x16>, 18) 169 170 #define INT8X16_FUNCTION_LIST(V) \ 171 INT8X16_UNARY_FUNCTION_LIST(V) \ 172 INT8X16_BINARY_FUNCTION_LIST(V) \ 173 INT8X16_TERNARY_FUNCTION_LIST(V) \ 174 INT8X16_SHUFFLE_FUNCTION_LIST(V) 175 176 #define INT16X8_UNARY_FUNCTION_LIST(V) \ 177 V(check, (UnaryFunc<Int16x8, Identity, Int16x8>), 1) \ 178 V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int16x8>), 1) \ 179 V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int16x8>), 1) \ 180 V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Int16x8>), 1) \ 181 V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Int16x8>), 1) \ 182 V(neg, (UnaryFunc<Int16x8, Neg, Int16x8>), 1) \ 183 V(not, (UnaryFunc<Int16x8, Not, Int16x8>), 1) \ 184 V(splat, (FuncSplat<Int16x8>), 1) 185 186 #define INT16X8_BINARY_FUNCTION_LIST(V) \ 187 V(add, (BinaryFunc<Int16x8, Add, Int16x8>), 2) \ 188 V(and, (BinaryFunc<Int16x8, And, Int16x8>), 2) \ 189 V(equal, (CompareFunc<Int16x8, Equal, Int16x8>), 2) \ 190 V(extractLane, (ExtractLane<Int16x8>), 2) \ 191 V(greaterThan, (CompareFunc<Int16x8, GreaterThan, Int16x8>), 2) \ 192 V(greaterThanOrEqual, (CompareFunc<Int16x8, GreaterThanOrEqual, Int16x8>), 2) \ 193 V(lessThan, (CompareFunc<Int16x8, LessThan, Int16x8>), 2) \ 194 V(lessThanOrEqual, (CompareFunc<Int16x8, LessThanOrEqual, Int16x8>), 2) \ 195 V(load, (Load<Int16x8, 8>), 2) \ 196 V(mul, (BinaryFunc<Int16x8, Mul, Int16x8>), 2) \ 197 V(notEqual, (CompareFunc<Int16x8, NotEqual, Int16x8>), 2) \ 198 V(or, (BinaryFunc<Int16x8, Or, Int16x8>), 2) \ 199 V(sub, (BinaryFunc<Int16x8, Sub, Int16x8>), 2) \ 200 V(shiftLeftByScalar, (BinaryScalar<Int16x8, ShiftLeft>), 2) \ 201 V(shiftRightArithmeticByScalar, (BinaryScalar<Int16x8, ShiftRightArithmetic>), 2) \ 202 V(shiftRightLogicalByScalar, (BinaryScalar<Int16x8, ShiftRightLogical>), 2) \ 203 V(xor, (BinaryFunc<Int16x8, Xor, Int16x8>), 2) 204 205 #define INT16X8_TERNARY_FUNCTION_LIST(V) \ 206 V(replaceLane, (ReplaceLane<Int16x8>), 3) \ 207 V(select, (Select<Int16x8, Int16x8>), 3) \ 208 V(selectBits, (SelectBits<Int16x8, Int16x8>), 3) \ 209 V(store, (Store<Int16x8, 8>), 3) 210 211 #define INT16X8_SHUFFLE_FUNCTION_LIST(V) \ 212 V(swizzle, Swizzle<Int16x8>, 9) \ 213 V(shuffle, Shuffle<Int16x8>, 10) 214 215 #define INT16X8_FUNCTION_LIST(V) \ 216 INT16X8_UNARY_FUNCTION_LIST(V) \ 217 INT16X8_BINARY_FUNCTION_LIST(V) \ 218 INT16X8_TERNARY_FUNCTION_LIST(V) \ 219 INT16X8_SHUFFLE_FUNCTION_LIST(V) 220 221 #define INT32X4_UNARY_FUNCTION_LIST(V) \ 222 V(check, (UnaryFunc<Int32x4, Identity, Int32x4>), 1) \ 223 V(fromFloat32x4, (FuncConvert<Float32x4, Int32x4>), 1) \ 224 V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int32x4>), 1) \ 225 V(fromFloat64x2, (FuncConvert<Float64x2, Int32x4>), 1) \ 226 V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int32x4>), 1) \ 227 V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Int32x4>), 1) \ 228 V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Int32x4>), 1) \ 229 V(neg, (UnaryFunc<Int32x4, Neg, Int32x4>), 1) \ 230 V(not, (UnaryFunc<Int32x4, Not, Int32x4>), 1) \ 231 V(splat, (FuncSplat<Int32x4>), 0) 232 233 #define INT32X4_BINARY_FUNCTION_LIST(V) \ 234 V(add, (BinaryFunc<Int32x4, Add, Int32x4>), 2) \ 235 V(and, (BinaryFunc<Int32x4, And, Int32x4>), 2) \ 236 V(equal, (CompareFunc<Int32x4, Equal, Int32x4>), 2) \ 237 V(extractLane, (ExtractLane<Int32x4>), 2) \ 238 V(greaterThan, (CompareFunc<Int32x4, GreaterThan, Int32x4>), 2) \ 239 V(greaterThanOrEqual, (CompareFunc<Int32x4, GreaterThanOrEqual, Int32x4>), 2) \ 240 V(lessThan, (CompareFunc<Int32x4, LessThan, Int32x4>), 2) \ 241 V(lessThanOrEqual, (CompareFunc<Int32x4, LessThanOrEqual, Int32x4>), 2) \ 242 V(load, (Load<Int32x4, 4>), 2) \ 243 V(load3, (Load<Int32x4, 3>), 2) \ 244 V(load2, (Load<Int32x4, 2>), 2) \ 245 V(load1, (Load<Int32x4, 1>), 2) \ 246 V(mul, (BinaryFunc<Int32x4, Mul, Int32x4>), 2) \ 247 V(notEqual, (CompareFunc<Int32x4, NotEqual, Int32x4>), 2) \ 248 V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2) \ 249 V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2) \ 250 V(shiftLeftByScalar, (BinaryScalar<Int32x4, ShiftLeft>), 2) \ 251 V(shiftRightArithmeticByScalar, (BinaryScalar<Int32x4, ShiftRightArithmetic>), 2) \ 252 V(shiftRightLogicalByScalar, (BinaryScalar<Int32x4, ShiftRightLogical>), 2) \ 253 V(xor, (BinaryFunc<Int32x4, Xor, Int32x4>), 2) 254 255 #define INT32X4_TERNARY_FUNCTION_LIST(V) \ 256 V(replaceLane, (ReplaceLane<Int32x4>), 3) \ 257 V(select, (Select<Int32x4, Int32x4>), 3) \ 258 V(selectBits, (SelectBits<Int32x4, Int32x4>), 3) \ 259 V(store, (Store<Int32x4, 4>), 3) \ 260 V(store3, (Store<Int32x4, 3>), 3) \ 261 V(store2, (Store<Int32x4, 2>), 3) \ 262 V(store1, (Store<Int32x4, 1>), 3) 263 264 #define INT32X4_SHUFFLE_FUNCTION_LIST(V) \ 265 V(swizzle, Swizzle<Int32x4>, 5) \ 266 V(shuffle, Shuffle<Int32x4>, 6) 267 268 #define INT32X4_FUNCTION_LIST(V) \ 269 INT32X4_UNARY_FUNCTION_LIST(V) \ 270 INT32X4_BINARY_FUNCTION_LIST(V) \ 271 INT32X4_TERNARY_FUNCTION_LIST(V) \ 272 INT32X4_SHUFFLE_FUNCTION_LIST(V) 273 274 #define CONVERSION_INT32X4_SIMD_OP(_) \ 275 _(fromFloat32x4) \ 276 _(fromFloat32x4Bits) 277 #define FOREACH_INT32X4_SIMD_OP(_) \ 278 CONVERSION_INT32X4_SIMD_OP(_) \ 279 _(selectBits) \ 280 _(shiftLeftByScalar) \ 281 _(shiftRightArithmeticByScalar) \ 282 _(shiftRightLogicalByScalar) 283 #define UNARY_ARITH_FLOAT32X4_SIMD_OP(_) \ 284 _(abs) \ 285 _(sqrt) \ 286 _(reciprocalApproximation) \ 287 _(reciprocalSqrtApproximation) 288 #define BINARY_ARITH_FLOAT32X4_SIMD_OP(_) \ 289 _(div) \ 290 _(max) \ 291 _(min) \ 292 _(maxNum) \ 293 _(minNum) 294 #define FOREACH_FLOAT32X4_SIMD_OP(_) \ 295 UNARY_ARITH_FLOAT32X4_SIMD_OP(_) \ 296 BINARY_ARITH_FLOAT32X4_SIMD_OP(_)\ 297 _(fromInt32x4) \ 298 _(fromInt32x4Bits) 299 #define ARITH_COMMONX4_SIMD_OP(_) \ 300 _(add) \ 301 _(sub) \ 302 _(mul) 303 #define BITWISE_COMMONX4_SIMD_OP(_) \ 304 _(and) \ 305 _(or) \ 306 _(xor) 307 #define COMP_COMMONX4_TO_INT32X4_SIMD_OP(_) \ 308 _(lessThan) \ 309 _(lessThanOrEqual) \ 310 _(equal) \ 311 _(notEqual) \ 312 _(greaterThan) \ 313 _(greaterThanOrEqual) 314 // TODO: remove when all SIMD calls are inlined (bug 1112155) 315 #define ION_COMMONX4_SIMD_OP(_) \ 316 ARITH_COMMONX4_SIMD_OP(_) \ 317 BITWISE_COMMONX4_SIMD_OP(_) \ 318 _(extractLane) \ 319 _(replaceLane) \ 320 _(select) \ 321 _(splat) \ 322 _(not) \ 323 _(neg) \ 324 _(swizzle) \ 325 _(shuffle) \ 326 _(load) \ 327 _(load1) \ 328 _(load2) \ 329 _(load3) \ 330 _(store) \ 331 _(store1) \ 332 _(store2) \ 333 _(store3) \ 334 _(check) 335 #define FOREACH_COMMONX4_SIMD_OP(_) \ 336 ION_COMMONX4_SIMD_OP(_) \ 337 COMP_COMMONX4_TO_INT32X4_SIMD_OP(_) 338 #define FORALL_SIMD_OP(_) \ 339 FOREACH_INT32X4_SIMD_OP(_) \ 340 FOREACH_FLOAT32X4_SIMD_OP(_) \ 341 FOREACH_COMMONX4_SIMD_OP(_) 342 343 namespace js { 344 345 class SIMDObject : public JSObject 346 { 347 public: 348 static const Class class_; 349 static bool toString(JSContext* cx, unsigned int argc, Value* vp); 350 }; 351 352 // These classes implement the concept containing the following constraints: 353 // - requires typename Elem: this is the scalar lane type, stored in each lane 354 // of the SIMD vector. 355 // - requires static const unsigned lanes: this is the number of lanes (length) 356 // of the SIMD vector. 357 // - requires static const SimdTypeDescr::Type type: this is the SimdTypeDescr 358 // enum value corresponding to the SIMD type. 359 // - requires static bool Cast(JSContext*, JS::HandleValue, Elem*): casts a 360 // given Value to the current scalar lane type and saves it in the Elem 361 // out-param. 362 // - requires static Value ToValue(Elem): returns a Value of the right type 363 // containing the given value. 364 // 365 // This concept is used in the templates above to define the functions 366 // associated to a given type and in their implementations, to avoid code 367 // redundancy. 368 369 struct Float32x4 { 370 typedef float Elem; 371 static const unsigned lanes = 4; 372 static const SimdTypeDescr::Type type = SimdTypeDescr::Float32x4; CastFloat32x4373 static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) { 374 double d; 375 if (!ToNumber(cx, v, &d)) 376 return false; 377 *out = float(d); 378 return true; 379 } ToValueFloat32x4380 static Value ToValue(Elem value) { 381 return DoubleValue(JS::CanonicalizeNaN(value)); 382 } 383 }; 384 385 struct Float64x2 { 386 typedef double Elem; 387 static const unsigned lanes = 2; 388 static const SimdTypeDescr::Type type = SimdTypeDescr::Float64x2; CastFloat64x2389 static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) { 390 return ToNumber(cx, v, out); 391 } ToValueFloat64x2392 static Value ToValue(Elem value) { 393 return DoubleValue(JS::CanonicalizeNaN(value)); 394 } 395 }; 396 397 struct Int8x16 { 398 typedef int8_t Elem; 399 static const unsigned lanes = 16; 400 static const SimdTypeDescr::Type type = SimdTypeDescr::Int8x16; CastInt8x16401 static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) { 402 return ToInt8(cx, v, out); 403 } ToValueInt8x16404 static Value ToValue(Elem value) { 405 return Int32Value(value); 406 } 407 }; 408 409 struct Int16x8 { 410 typedef int16_t Elem; 411 static const unsigned lanes = 8; 412 static const SimdTypeDescr::Type type = SimdTypeDescr::Int16x8; CastInt16x8413 static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) { 414 return ToInt16(cx, v, out); 415 } ToValueInt16x8416 static Value ToValue(Elem value) { 417 return Int32Value(value); 418 } 419 }; 420 421 struct Int32x4 { 422 typedef int32_t Elem; 423 static const unsigned lanes = 4; 424 static const SimdTypeDescr::Type type = SimdTypeDescr::Int32x4; CastInt32x4425 static bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) { 426 return ToInt32(cx, v, out); 427 } ToValueInt32x4428 static Value ToValue(Elem value) { 429 return Int32Value(value); 430 } 431 }; 432 433 template<typename V> 434 JSObject* CreateSimd(JSContext* cx, const typename V::Elem* data); 435 436 template<typename V> 437 bool IsVectorObject(HandleValue v); 438 439 template<typename V> 440 bool ToSimdConstant(JSContext* cx, HandleValue v, jit::SimdConstant* out); 441 442 #define DECLARE_SIMD_FLOAT32X4_FUNCTION(Name, Func, Operands) \ 443 extern bool \ 444 simd_float32x4_##Name(JSContext* cx, unsigned argc, Value* vp); 445 FLOAT32X4_FUNCTION_LIST(DECLARE_SIMD_FLOAT32X4_FUNCTION) 446 #undef DECLARE_SIMD_FLOAT32X4_FUNCTION 447 448 #define DECLARE_SIMD_FLOAT64X2_FUNCTION(Name, Func, Operands) \ 449 extern bool \ 450 simd_float64x2_##Name(JSContext* cx, unsigned argc, Value* vp); 451 FLOAT64X2_FUNCTION_LIST(DECLARE_SIMD_FLOAT64X2_FUNCTION) 452 #undef DECLARE_SIMD_FLOAT64X2_FUNCTION 453 454 #define DECLARE_SIMD_INT8X16_FUNCTION(Name, Func, Operands) \ 455 extern bool \ 456 simd_int8x16_##Name(JSContext* cx, unsigned argc, Value* vp); 457 INT8X16_FUNCTION_LIST(DECLARE_SIMD_INT8X16_FUNCTION) 458 #undef DECLARE_SIMD_INT8X16_FUNCTION 459 460 #define DECLARE_SIMD_INT16X8_FUNCTION(Name, Func, Operands) \ 461 extern bool \ 462 simd_int16x8_##Name(JSContext* cx, unsigned argc, Value* vp); 463 INT16X8_FUNCTION_LIST(DECLARE_SIMD_INT16X8_FUNCTION) 464 #undef DECLARE_SIMD_INT16X8_FUNCTION 465 466 #define DECLARE_SIMD_INT32x4_FUNCTION(Name, Func, Operands) \ 467 extern bool \ 468 simd_int32x4_##Name(JSContext* cx, unsigned argc, Value* vp); 469 INT32X4_FUNCTION_LIST(DECLARE_SIMD_INT32x4_FUNCTION) 470 #undef DECLARE_SIMD_INT32x4_FUNCTION 471 472 JSObject* 473 InitSIMDClass(JSContext* cx, HandleObject obj); 474 475 } /* namespace js */ 476 477 #endif /* builtin_SIMD_h */ 478