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