Line data Source code
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 "NamespaceImports.h"
12 :
13 : #include "builtin/TypedObjectConstants.h"
14 : #include "jit/IonTypes.h"
15 : #include "js/Conversions.h"
16 :
17 : /*
18 : * JS SIMD functions.
19 : * Spec matching polyfill:
20 : * https://github.com/tc39/ecmascript_simd/blob/master/src/ecmascript_simd.js
21 : */
22 :
23 : // Bool8x16.
24 : #define BOOL8X16_UNARY_FUNCTION_LIST(V) \
25 : V(not, (UnaryFunc<Bool8x16, LogicalNot, Bool8x16>), 1) \
26 : V(check, (UnaryFunc<Bool8x16, Identity, Bool8x16>), 1) \
27 : V(splat, (FuncSplat<Bool8x16>), 1) \
28 : V(allTrue, (AllTrue<Bool8x16>), 1) \
29 : V(anyTrue, (AnyTrue<Bool8x16>), 1)
30 :
31 : #define BOOL8X16_BINARY_FUNCTION_LIST(V) \
32 : V(extractLane, (ExtractLane<Bool8x16>), 2) \
33 : V(and, (BinaryFunc<Bool8x16, And, Bool8x16>), 2) \
34 : V(or, (BinaryFunc<Bool8x16, Or, Bool8x16>), 2) \
35 : V(xor, (BinaryFunc<Bool8x16, Xor, Bool8x16>), 2) \
36 :
37 : #define BOOL8X16_TERNARY_FUNCTION_LIST(V) \
38 : V(replaceLane, (ReplaceLane<Bool8x16>), 3)
39 :
40 : #define BOOL8X16_FUNCTION_LIST(V) \
41 : BOOL8X16_UNARY_FUNCTION_LIST(V) \
42 : BOOL8X16_BINARY_FUNCTION_LIST(V) \
43 : BOOL8X16_TERNARY_FUNCTION_LIST(V)
44 :
45 : // Bool 16x8.
46 : #define BOOL16X8_UNARY_FUNCTION_LIST(V) \
47 : V(not, (UnaryFunc<Bool16x8, LogicalNot, Bool16x8>), 1) \
48 : V(check, (UnaryFunc<Bool16x8, Identity, Bool16x8>), 1) \
49 : V(splat, (FuncSplat<Bool16x8>), 1) \
50 : V(allTrue, (AllTrue<Bool16x8>), 1) \
51 : V(anyTrue, (AnyTrue<Bool16x8>), 1)
52 :
53 : #define BOOL16X8_BINARY_FUNCTION_LIST(V) \
54 : V(extractLane, (ExtractLane<Bool16x8>), 2) \
55 : V(and, (BinaryFunc<Bool16x8, And, Bool16x8>), 2) \
56 : V(or, (BinaryFunc<Bool16x8, Or, Bool16x8>), 2) \
57 : V(xor, (BinaryFunc<Bool16x8, Xor, Bool16x8>), 2) \
58 :
59 : #define BOOL16X8_TERNARY_FUNCTION_LIST(V) \
60 : V(replaceLane, (ReplaceLane<Bool16x8>), 3)
61 :
62 : #define BOOL16X8_FUNCTION_LIST(V) \
63 : BOOL16X8_UNARY_FUNCTION_LIST(V) \
64 : BOOL16X8_BINARY_FUNCTION_LIST(V) \
65 : BOOL16X8_TERNARY_FUNCTION_LIST(V)
66 :
67 : // Bool32x4.
68 : #define BOOL32X4_UNARY_FUNCTION_LIST(V) \
69 : V(not, (UnaryFunc<Bool32x4, LogicalNot, Bool32x4>), 1) \
70 : V(check, (UnaryFunc<Bool32x4, Identity, Bool32x4>), 1) \
71 : V(splat, (FuncSplat<Bool32x4>), 1) \
72 : V(allTrue, (AllTrue<Bool32x4>), 1) \
73 : V(anyTrue, (AnyTrue<Bool32x4>), 1)
74 :
75 : #define BOOL32X4_BINARY_FUNCTION_LIST(V) \
76 : V(extractLane, (ExtractLane<Bool32x4>), 2) \
77 : V(and, (BinaryFunc<Bool32x4, And, Bool32x4>), 2) \
78 : V(or, (BinaryFunc<Bool32x4, Or, Bool32x4>), 2) \
79 : V(xor, (BinaryFunc<Bool32x4, Xor, Bool32x4>), 2) \
80 :
81 : #define BOOL32X4_TERNARY_FUNCTION_LIST(V) \
82 : V(replaceLane, (ReplaceLane<Bool32x4>), 3)
83 :
84 : #define BOOL32X4_FUNCTION_LIST(V) \
85 : BOOL32X4_UNARY_FUNCTION_LIST(V) \
86 : BOOL32X4_BINARY_FUNCTION_LIST(V) \
87 : BOOL32X4_TERNARY_FUNCTION_LIST(V)
88 :
89 : // Bool64x2.
90 : #define BOOL64X2_UNARY_FUNCTION_LIST(V) \
91 : V(not, (UnaryFunc<Bool64x2, LogicalNot, Bool64x2>), 1) \
92 : V(check, (UnaryFunc<Bool64x2, Identity, Bool64x2>), 1) \
93 : V(splat, (FuncSplat<Bool64x2>), 1) \
94 : V(allTrue, (AllTrue<Bool64x2>), 1) \
95 : V(anyTrue, (AnyTrue<Bool64x2>), 1)
96 :
97 : #define BOOL64X2_BINARY_FUNCTION_LIST(V) \
98 : V(extractLane, (ExtractLane<Bool64x2>), 2) \
99 : V(and, (BinaryFunc<Bool64x2, And, Bool64x2>), 2) \
100 : V(or, (BinaryFunc<Bool64x2, Or, Bool64x2>), 2) \
101 : V(xor, (BinaryFunc<Bool64x2, Xor, Bool64x2>), 2) \
102 :
103 : #define BOOL64X2_TERNARY_FUNCTION_LIST(V) \
104 : V(replaceLane, (ReplaceLane<Bool64x2>), 3)
105 :
106 : #define BOOL64X2_FUNCTION_LIST(V) \
107 : BOOL64X2_UNARY_FUNCTION_LIST(V) \
108 : BOOL64X2_BINARY_FUNCTION_LIST(V) \
109 : BOOL64X2_TERNARY_FUNCTION_LIST(V)
110 :
111 : // Float32x4.
112 : #define FLOAT32X4_UNARY_FUNCTION_LIST(V) \
113 : V(abs, (UnaryFunc<Float32x4, Abs, Float32x4>), 1) \
114 : V(check, (UnaryFunc<Float32x4, Identity, Float32x4>), 1) \
115 : V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Float32x4>), 1) \
116 : V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Float32x4>), 1) \
117 : V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Float32x4>), 1) \
118 : V(fromInt32x4, (FuncConvert<Int32x4, Float32x4>), 1) \
119 : V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float32x4>), 1) \
120 : V(fromUint8x16Bits, (FuncConvertBits<Uint8x16, Float32x4>), 1) \
121 : V(fromUint16x8Bits, (FuncConvertBits<Uint16x8, Float32x4>), 1) \
122 : V(fromUint32x4, (FuncConvert<Uint32x4, Float32x4>), 1) \
123 : V(fromUint32x4Bits, (FuncConvertBits<Uint32x4, Float32x4>), 1) \
124 : V(neg, (UnaryFunc<Float32x4, Neg, Float32x4>), 1) \
125 : V(reciprocalApproximation, (UnaryFunc<Float32x4, RecApprox, Float32x4>), 1) \
126 : V(reciprocalSqrtApproximation, (UnaryFunc<Float32x4, RecSqrtApprox, Float32x4>), 1) \
127 : V(splat, (FuncSplat<Float32x4>), 1) \
128 : V(sqrt, (UnaryFunc<Float32x4, Sqrt, Float32x4>), 1)
129 :
130 : #define FLOAT32X4_BINARY_FUNCTION_LIST(V) \
131 : V(add, (BinaryFunc<Float32x4, Add, Float32x4>), 2) \
132 : V(div, (BinaryFunc<Float32x4, Div, Float32x4>), 2) \
133 : V(equal, (CompareFunc<Float32x4, Equal, Bool32x4>), 2) \
134 : V(extractLane, (ExtractLane<Float32x4>), 2) \
135 : V(greaterThan, (CompareFunc<Float32x4, GreaterThan, Bool32x4>), 2) \
136 : V(greaterThanOrEqual, (CompareFunc<Float32x4, GreaterThanOrEqual, Bool32x4>), 2) \
137 : V(lessThan, (CompareFunc<Float32x4, LessThan, Bool32x4>), 2) \
138 : V(lessThanOrEqual, (CompareFunc<Float32x4, LessThanOrEqual, Bool32x4>), 2) \
139 : V(load, (Load<Float32x4, 4>), 2) \
140 : V(load3, (Load<Float32x4, 3>), 2) \
141 : V(load2, (Load<Float32x4, 2>), 2) \
142 : V(load1, (Load<Float32x4, 1>), 2) \
143 : V(max, (BinaryFunc<Float32x4, Maximum, Float32x4>), 2) \
144 : V(maxNum, (BinaryFunc<Float32x4, MaxNum, Float32x4>), 2) \
145 : V(min, (BinaryFunc<Float32x4, Minimum, Float32x4>), 2) \
146 : V(minNum, (BinaryFunc<Float32x4, MinNum, Float32x4>), 2) \
147 : V(mul, (BinaryFunc<Float32x4, Mul, Float32x4>), 2) \
148 : V(notEqual, (CompareFunc<Float32x4, NotEqual, Bool32x4>), 2) \
149 : V(sub, (BinaryFunc<Float32x4, Sub, Float32x4>), 2)
150 :
151 : #define FLOAT32X4_TERNARY_FUNCTION_LIST(V) \
152 : V(replaceLane, (ReplaceLane<Float32x4>), 3) \
153 : V(select, (Select<Float32x4, Bool32x4>), 3) \
154 : V(store, (Store<Float32x4, 4>), 3) \
155 : V(store3, (Store<Float32x4, 3>), 3) \
156 : V(store2, (Store<Float32x4, 2>), 3) \
157 : V(store1, (Store<Float32x4, 1>), 3)
158 :
159 : #define FLOAT32X4_SHUFFLE_FUNCTION_LIST(V) \
160 : V(swizzle, Swizzle<Float32x4>, 5) \
161 : V(shuffle, Shuffle<Float32x4>, 6)
162 :
163 : #define FLOAT32X4_FUNCTION_LIST(V) \
164 : FLOAT32X4_UNARY_FUNCTION_LIST(V) \
165 : FLOAT32X4_BINARY_FUNCTION_LIST(V) \
166 : FLOAT32X4_TERNARY_FUNCTION_LIST(V) \
167 : FLOAT32X4_SHUFFLE_FUNCTION_LIST(V)
168 :
169 : // Float64x2.
170 : #define FLOAT64X2_UNARY_FUNCTION_LIST(V) \
171 : V(abs, (UnaryFunc<Float64x2, Abs, Float64x2>), 1) \
172 : V(check, (UnaryFunc<Float64x2, Identity, Float64x2>), 1) \
173 : V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Float64x2>), 1) \
174 : V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Float64x2>), 1) \
175 : V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Float64x2>), 1) \
176 : V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float64x2>), 1) \
177 : V(fromUint8x16Bits, (FuncConvertBits<Uint8x16, Float64x2>), 1) \
178 : V(fromUint16x8Bits, (FuncConvertBits<Uint16x8, Float64x2>), 1) \
179 : V(fromUint32x4Bits, (FuncConvertBits<Uint32x4, Float64x2>), 1) \
180 : V(neg, (UnaryFunc<Float64x2, Neg, Float64x2>), 1) \
181 : V(reciprocalApproximation, (UnaryFunc<Float64x2, RecApprox, Float64x2>), 1) \
182 : V(reciprocalSqrtApproximation, (UnaryFunc<Float64x2, RecSqrtApprox, Float64x2>), 1) \
183 : V(splat, (FuncSplat<Float64x2>), 1) \
184 : V(sqrt, (UnaryFunc<Float64x2, Sqrt, Float64x2>), 1)
185 :
186 : #define FLOAT64X2_BINARY_FUNCTION_LIST(V) \
187 : V(add, (BinaryFunc<Float64x2, Add, Float64x2>), 2) \
188 : V(div, (BinaryFunc<Float64x2, Div, Float64x2>), 2) \
189 : V(equal, (CompareFunc<Float64x2, Equal, Bool64x2>), 2) \
190 : V(extractLane, (ExtractLane<Float64x2>), 2) \
191 : V(greaterThan, (CompareFunc<Float64x2, GreaterThan, Bool64x2>), 2) \
192 : V(greaterThanOrEqual, (CompareFunc<Float64x2, GreaterThanOrEqual, Bool64x2>), 2) \
193 : V(lessThan, (CompareFunc<Float64x2, LessThan, Bool64x2>), 2) \
194 : V(lessThanOrEqual, (CompareFunc<Float64x2, LessThanOrEqual, Bool64x2>), 2) \
195 : V(load, (Load<Float64x2, 2>), 2) \
196 : V(load1, (Load<Float64x2, 1>), 2) \
197 : V(max, (BinaryFunc<Float64x2, Maximum, Float64x2>), 2) \
198 : V(maxNum, (BinaryFunc<Float64x2, MaxNum, Float64x2>), 2) \
199 : V(min, (BinaryFunc<Float64x2, Minimum, Float64x2>), 2) \
200 : V(minNum, (BinaryFunc<Float64x2, MinNum, Float64x2>), 2) \
201 : V(mul, (BinaryFunc<Float64x2, Mul, Float64x2>), 2) \
202 : V(notEqual, (CompareFunc<Float64x2, NotEqual, Bool64x2>), 2) \
203 : V(sub, (BinaryFunc<Float64x2, Sub, Float64x2>), 2)
204 :
205 : #define FLOAT64X2_TERNARY_FUNCTION_LIST(V) \
206 : V(replaceLane, (ReplaceLane<Float64x2>), 3) \
207 : V(select, (Select<Float64x2, Bool64x2>), 3) \
208 : V(store, (Store<Float64x2, 2>), 3) \
209 : V(store1, (Store<Float64x2, 1>), 3)
210 :
211 : #define FLOAT64X2_SHUFFLE_FUNCTION_LIST(V) \
212 : V(swizzle, Swizzle<Float64x2>, 3) \
213 : V(shuffle, Shuffle<Float64x2>, 4)
214 :
215 : #define FLOAT64X2_FUNCTION_LIST(V) \
216 : FLOAT64X2_UNARY_FUNCTION_LIST(V) \
217 : FLOAT64X2_BINARY_FUNCTION_LIST(V) \
218 : FLOAT64X2_TERNARY_FUNCTION_LIST(V) \
219 : FLOAT64X2_SHUFFLE_FUNCTION_LIST(V)
220 :
221 : // Int8x16.
222 : #define INT8X16_UNARY_FUNCTION_LIST(V) \
223 : V(check, (UnaryFunc<Int8x16, Identity, Int8x16>), 1) \
224 : V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int8x16>), 1) \
225 : V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int8x16>), 1) \
226 : V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Int8x16>), 1) \
227 : V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Int8x16>), 1) \
228 : V(fromUint8x16Bits, (FuncConvertBits<Uint8x16, Int8x16>), 1) \
229 : V(fromUint16x8Bits, (FuncConvertBits<Uint16x8, Int8x16>), 1) \
230 : V(fromUint32x4Bits, (FuncConvertBits<Uint32x4, Int8x16>), 1) \
231 : V(neg, (UnaryFunc<Int8x16, Neg, Int8x16>), 1) \
232 : V(not, (UnaryFunc<Int8x16, Not, Int8x16>), 1) \
233 : V(splat, (FuncSplat<Int8x16>), 1)
234 :
235 : #define INT8X16_BINARY_FUNCTION_LIST(V) \
236 : V(add, (BinaryFunc<Int8x16, Add, Int8x16>), 2) \
237 : V(addSaturate, (BinaryFunc<Int8x16, AddSaturate, Int8x16>), 2) \
238 : V(and, (BinaryFunc<Int8x16, And, Int8x16>), 2) \
239 : V(equal, (CompareFunc<Int8x16, Equal, Bool8x16>), 2) \
240 : V(extractLane, (ExtractLane<Int8x16>), 2) \
241 : V(greaterThan, (CompareFunc<Int8x16, GreaterThan, Bool8x16>), 2) \
242 : V(greaterThanOrEqual, (CompareFunc<Int8x16, GreaterThanOrEqual, Bool8x16>), 2) \
243 : V(lessThan, (CompareFunc<Int8x16, LessThan, Bool8x16>), 2) \
244 : V(lessThanOrEqual, (CompareFunc<Int8x16, LessThanOrEqual, Bool8x16>), 2) \
245 : V(load, (Load<Int8x16, 16>), 2) \
246 : V(mul, (BinaryFunc<Int8x16, Mul, Int8x16>), 2) \
247 : V(notEqual, (CompareFunc<Int8x16, NotEqual, Bool8x16>), 2) \
248 : V(or, (BinaryFunc<Int8x16, Or, Int8x16>), 2) \
249 : V(sub, (BinaryFunc<Int8x16, Sub, Int8x16>), 2) \
250 : V(subSaturate, (BinaryFunc<Int8x16, SubSaturate, Int8x16>), 2) \
251 : V(shiftLeftByScalar, (BinaryScalar<Int8x16, ShiftLeft>), 2) \
252 : V(shiftRightByScalar, (BinaryScalar<Int8x16, ShiftRightArithmetic>), 2) \
253 : V(xor, (BinaryFunc<Int8x16, Xor, Int8x16>), 2)
254 :
255 : #define INT8X16_TERNARY_FUNCTION_LIST(V) \
256 : V(replaceLane, (ReplaceLane<Int8x16>), 3) \
257 : V(select, (Select<Int8x16, Bool8x16>), 3) \
258 : V(store, (Store<Int8x16, 16>), 3)
259 :
260 : #define INT8X16_SHUFFLE_FUNCTION_LIST(V) \
261 : V(swizzle, Swizzle<Int8x16>, 17) \
262 : V(shuffle, Shuffle<Int8x16>, 18)
263 :
264 : #define INT8X16_FUNCTION_LIST(V) \
265 : INT8X16_UNARY_FUNCTION_LIST(V) \
266 : INT8X16_BINARY_FUNCTION_LIST(V) \
267 : INT8X16_TERNARY_FUNCTION_LIST(V) \
268 : INT8X16_SHUFFLE_FUNCTION_LIST(V)
269 :
270 : // Uint8x16.
271 : #define UINT8X16_UNARY_FUNCTION_LIST(V) \
272 : V(check, (UnaryFunc<Uint8x16, Identity, Uint8x16>), 1) \
273 : V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Uint8x16>), 1) \
274 : V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Uint8x16>), 1) \
275 : V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Uint8x16>), 1) \
276 : V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Uint8x16>), 1) \
277 : V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Uint8x16>), 1) \
278 : V(fromUint16x8Bits, (FuncConvertBits<Uint16x8, Uint8x16>), 1) \
279 : V(fromUint32x4Bits, (FuncConvertBits<Uint32x4, Uint8x16>), 1) \
280 : V(neg, (UnaryFunc<Uint8x16, Neg, Uint8x16>), 1) \
281 : V(not, (UnaryFunc<Uint8x16, Not, Uint8x16>), 1) \
282 : V(splat, (FuncSplat<Uint8x16>), 1)
283 :
284 : #define UINT8X16_BINARY_FUNCTION_LIST(V) \
285 : V(add, (BinaryFunc<Uint8x16, Add, Uint8x16>), 2) \
286 : V(addSaturate, (BinaryFunc<Uint8x16, AddSaturate, Uint8x16>), 2) \
287 : V(and, (BinaryFunc<Uint8x16, And, Uint8x16>), 2) \
288 : V(equal, (CompareFunc<Uint8x16, Equal, Bool8x16>), 2) \
289 : V(extractLane, (ExtractLane<Uint8x16>), 2) \
290 : V(greaterThan, (CompareFunc<Uint8x16, GreaterThan, Bool8x16>), 2) \
291 : V(greaterThanOrEqual, (CompareFunc<Uint8x16, GreaterThanOrEqual, Bool8x16>), 2) \
292 : V(lessThan, (CompareFunc<Uint8x16, LessThan, Bool8x16>), 2) \
293 : V(lessThanOrEqual, (CompareFunc<Uint8x16, LessThanOrEqual, Bool8x16>), 2) \
294 : V(load, (Load<Uint8x16, 16>), 2) \
295 : V(mul, (BinaryFunc<Uint8x16, Mul, Uint8x16>), 2) \
296 : V(notEqual, (CompareFunc<Uint8x16, NotEqual, Bool8x16>), 2) \
297 : V(or, (BinaryFunc<Uint8x16, Or, Uint8x16>), 2) \
298 : V(sub, (BinaryFunc<Uint8x16, Sub, Uint8x16>), 2) \
299 : V(subSaturate, (BinaryFunc<Uint8x16, SubSaturate, Uint8x16>), 2) \
300 : V(shiftLeftByScalar, (BinaryScalar<Uint8x16, ShiftLeft>), 2) \
301 : V(shiftRightByScalar, (BinaryScalar<Uint8x16, ShiftRightLogical>), 2) \
302 : V(xor, (BinaryFunc<Uint8x16, Xor, Uint8x16>), 2)
303 :
304 : #define UINT8X16_TERNARY_FUNCTION_LIST(V) \
305 : V(replaceLane, (ReplaceLane<Uint8x16>), 3) \
306 : V(select, (Select<Uint8x16, Bool8x16>), 3) \
307 : V(store, (Store<Uint8x16, 16>), 3)
308 :
309 : #define UINT8X16_SHUFFLE_FUNCTION_LIST(V) \
310 : V(swizzle, Swizzle<Uint8x16>, 17) \
311 : V(shuffle, Shuffle<Uint8x16>, 18)
312 :
313 : #define UINT8X16_FUNCTION_LIST(V) \
314 : UINT8X16_UNARY_FUNCTION_LIST(V) \
315 : UINT8X16_BINARY_FUNCTION_LIST(V) \
316 : UINT8X16_TERNARY_FUNCTION_LIST(V) \
317 : UINT8X16_SHUFFLE_FUNCTION_LIST(V)
318 :
319 : // Int16x8.
320 : #define INT16X8_UNARY_FUNCTION_LIST(V) \
321 : V(check, (UnaryFunc<Int16x8, Identity, Int16x8>), 1) \
322 : V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int16x8>), 1) \
323 : V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int16x8>), 1) \
324 : V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Int16x8>), 1) \
325 : V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Int16x8>), 1) \
326 : V(fromUint8x16Bits, (FuncConvertBits<Uint8x16, Int16x8>), 1) \
327 : V(fromUint16x8Bits, (FuncConvertBits<Uint16x8, Int16x8>), 1) \
328 : V(fromUint32x4Bits, (FuncConvertBits<Uint32x4, Int16x8>), 1) \
329 : V(neg, (UnaryFunc<Int16x8, Neg, Int16x8>), 1) \
330 : V(not, (UnaryFunc<Int16x8, Not, Int16x8>), 1) \
331 : V(splat, (FuncSplat<Int16x8>), 1)
332 :
333 : #define INT16X8_BINARY_FUNCTION_LIST(V) \
334 : V(add, (BinaryFunc<Int16x8, Add, Int16x8>), 2) \
335 : V(addSaturate, (BinaryFunc<Int16x8, AddSaturate, Int16x8>), 2) \
336 : V(and, (BinaryFunc<Int16x8, And, Int16x8>), 2) \
337 : V(equal, (CompareFunc<Int16x8, Equal, Bool16x8>), 2) \
338 : V(extractLane, (ExtractLane<Int16x8>), 2) \
339 : V(greaterThan, (CompareFunc<Int16x8, GreaterThan, Bool16x8>), 2) \
340 : V(greaterThanOrEqual, (CompareFunc<Int16x8, GreaterThanOrEqual, Bool16x8>), 2) \
341 : V(lessThan, (CompareFunc<Int16x8, LessThan, Bool16x8>), 2) \
342 : V(lessThanOrEqual, (CompareFunc<Int16x8, LessThanOrEqual, Bool16x8>), 2) \
343 : V(load, (Load<Int16x8, 8>), 2) \
344 : V(mul, (BinaryFunc<Int16x8, Mul, Int16x8>), 2) \
345 : V(notEqual, (CompareFunc<Int16x8, NotEqual, Bool16x8>), 2) \
346 : V(or, (BinaryFunc<Int16x8, Or, Int16x8>), 2) \
347 : V(sub, (BinaryFunc<Int16x8, Sub, Int16x8>), 2) \
348 : V(subSaturate, (BinaryFunc<Int16x8, SubSaturate, Int16x8>), 2) \
349 : V(shiftLeftByScalar, (BinaryScalar<Int16x8, ShiftLeft>), 2) \
350 : V(shiftRightByScalar, (BinaryScalar<Int16x8, ShiftRightArithmetic>), 2) \
351 : V(xor, (BinaryFunc<Int16x8, Xor, Int16x8>), 2)
352 :
353 : #define INT16X8_TERNARY_FUNCTION_LIST(V) \
354 : V(replaceLane, (ReplaceLane<Int16x8>), 3) \
355 : V(select, (Select<Int16x8, Bool16x8>), 3) \
356 : V(store, (Store<Int16x8, 8>), 3)
357 :
358 : #define INT16X8_SHUFFLE_FUNCTION_LIST(V) \
359 : V(swizzle, Swizzle<Int16x8>, 9) \
360 : V(shuffle, Shuffle<Int16x8>, 10)
361 :
362 : #define INT16X8_FUNCTION_LIST(V) \
363 : INT16X8_UNARY_FUNCTION_LIST(V) \
364 : INT16X8_BINARY_FUNCTION_LIST(V) \
365 : INT16X8_TERNARY_FUNCTION_LIST(V) \
366 : INT16X8_SHUFFLE_FUNCTION_LIST(V)
367 :
368 : // Uint16x8.
369 : #define UINT16X8_UNARY_FUNCTION_LIST(V) \
370 : V(check, (UnaryFunc<Uint16x8, Identity, Uint16x8>), 1) \
371 : V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Uint16x8>), 1) \
372 : V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Uint16x8>), 1) \
373 : V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Uint16x8>), 1) \
374 : V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Uint16x8>), 1) \
375 : V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Uint16x8>), 1) \
376 : V(fromUint8x16Bits, (FuncConvertBits<Uint8x16, Uint16x8>), 1) \
377 : V(fromUint32x4Bits, (FuncConvertBits<Uint32x4, Uint16x8>), 1) \
378 : V(neg, (UnaryFunc<Uint16x8, Neg, Uint16x8>), 1) \
379 : V(not, (UnaryFunc<Uint16x8, Not, Uint16x8>), 1) \
380 : V(splat, (FuncSplat<Uint16x8>), 1)
381 :
382 : #define UINT16X8_BINARY_FUNCTION_LIST(V) \
383 : V(add, (BinaryFunc<Uint16x8, Add, Uint16x8>), 2) \
384 : V(addSaturate, (BinaryFunc<Uint16x8, AddSaturate, Uint16x8>), 2) \
385 : V(and, (BinaryFunc<Uint16x8, And, Uint16x8>), 2) \
386 : V(equal, (CompareFunc<Uint16x8, Equal, Bool16x8>), 2) \
387 : V(extractLane, (ExtractLane<Uint16x8>), 2) \
388 : V(greaterThan, (CompareFunc<Uint16x8, GreaterThan, Bool16x8>), 2) \
389 : V(greaterThanOrEqual, (CompareFunc<Uint16x8, GreaterThanOrEqual, Bool16x8>), 2) \
390 : V(lessThan, (CompareFunc<Uint16x8, LessThan, Bool16x8>), 2) \
391 : V(lessThanOrEqual, (CompareFunc<Uint16x8, LessThanOrEqual, Bool16x8>), 2) \
392 : V(load, (Load<Uint16x8, 8>), 2) \
393 : V(mul, (BinaryFunc<Uint16x8, Mul, Uint16x8>), 2) \
394 : V(notEqual, (CompareFunc<Uint16x8, NotEqual, Bool16x8>), 2) \
395 : V(or, (BinaryFunc<Uint16x8, Or, Uint16x8>), 2) \
396 : V(sub, (BinaryFunc<Uint16x8, Sub, Uint16x8>), 2) \
397 : V(subSaturate, (BinaryFunc<Uint16x8, SubSaturate, Uint16x8>), 2) \
398 : V(shiftLeftByScalar, (BinaryScalar<Uint16x8, ShiftLeft>), 2) \
399 : V(shiftRightByScalar, (BinaryScalar<Uint16x8, ShiftRightLogical>), 2) \
400 : V(xor, (BinaryFunc<Uint16x8, Xor, Uint16x8>), 2)
401 :
402 : #define UINT16X8_TERNARY_FUNCTION_LIST(V) \
403 : V(replaceLane, (ReplaceLane<Uint16x8>), 3) \
404 : V(select, (Select<Uint16x8, Bool16x8>), 3) \
405 : V(store, (Store<Uint16x8, 8>), 3)
406 :
407 : #define UINT16X8_SHUFFLE_FUNCTION_LIST(V) \
408 : V(swizzle, Swizzle<Uint16x8>, 9) \
409 : V(shuffle, Shuffle<Uint16x8>, 10)
410 :
411 : #define UINT16X8_FUNCTION_LIST(V) \
412 : UINT16X8_UNARY_FUNCTION_LIST(V) \
413 : UINT16X8_BINARY_FUNCTION_LIST(V) \
414 : UINT16X8_TERNARY_FUNCTION_LIST(V) \
415 : UINT16X8_SHUFFLE_FUNCTION_LIST(V)
416 :
417 : // Int32x4.
418 : #define INT32X4_UNARY_FUNCTION_LIST(V) \
419 : V(check, (UnaryFunc<Int32x4, Identity, Int32x4>), 1) \
420 : V(fromFloat32x4, (FuncConvert<Float32x4, Int32x4>), 1) \
421 : V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int32x4>), 1) \
422 : V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Int32x4>), 1) \
423 : V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Int32x4>), 1) \
424 : V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Int32x4>), 1) \
425 : V(fromUint8x16Bits, (FuncConvertBits<Uint8x16, Int32x4>), 1) \
426 : V(fromUint16x8Bits, (FuncConvertBits<Uint16x8, Int32x4>), 1) \
427 : V(fromUint32x4Bits, (FuncConvertBits<Uint32x4, Int32x4>), 1) \
428 : V(neg, (UnaryFunc<Int32x4, Neg, Int32x4>), 1) \
429 : V(not, (UnaryFunc<Int32x4, Not, Int32x4>), 1) \
430 : V(splat, (FuncSplat<Int32x4>), 0)
431 :
432 : #define INT32X4_BINARY_FUNCTION_LIST(V) \
433 : V(add, (BinaryFunc<Int32x4, Add, Int32x4>), 2) \
434 : V(and, (BinaryFunc<Int32x4, And, Int32x4>), 2) \
435 : V(equal, (CompareFunc<Int32x4, Equal, Bool32x4>), 2) \
436 : V(extractLane, (ExtractLane<Int32x4>), 2) \
437 : V(greaterThan, (CompareFunc<Int32x4, GreaterThan, Bool32x4>), 2) \
438 : V(greaterThanOrEqual, (CompareFunc<Int32x4, GreaterThanOrEqual, Bool32x4>), 2) \
439 : V(lessThan, (CompareFunc<Int32x4, LessThan, Bool32x4>), 2) \
440 : V(lessThanOrEqual, (CompareFunc<Int32x4, LessThanOrEqual, Bool32x4>), 2) \
441 : V(load, (Load<Int32x4, 4>), 2) \
442 : V(load3, (Load<Int32x4, 3>), 2) \
443 : V(load2, (Load<Int32x4, 2>), 2) \
444 : V(load1, (Load<Int32x4, 1>), 2) \
445 : V(mul, (BinaryFunc<Int32x4, Mul, Int32x4>), 2) \
446 : V(notEqual, (CompareFunc<Int32x4, NotEqual, Bool32x4>), 2) \
447 : V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2) \
448 : V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2) \
449 : V(shiftLeftByScalar, (BinaryScalar<Int32x4, ShiftLeft>), 2) \
450 : V(shiftRightByScalar, (BinaryScalar<Int32x4, ShiftRightArithmetic>), 2) \
451 : V(xor, (BinaryFunc<Int32x4, Xor, Int32x4>), 2)
452 :
453 : #define INT32X4_TERNARY_FUNCTION_LIST(V) \
454 : V(replaceLane, (ReplaceLane<Int32x4>), 3) \
455 : V(select, (Select<Int32x4, Bool32x4>), 3) \
456 : V(store, (Store<Int32x4, 4>), 3) \
457 : V(store3, (Store<Int32x4, 3>), 3) \
458 : V(store2, (Store<Int32x4, 2>), 3) \
459 : V(store1, (Store<Int32x4, 1>), 3)
460 :
461 : #define INT32X4_SHUFFLE_FUNCTION_LIST(V) \
462 : V(swizzle, Swizzle<Int32x4>, 5) \
463 : V(shuffle, Shuffle<Int32x4>, 6)
464 :
465 : #define INT32X4_FUNCTION_LIST(V) \
466 : INT32X4_UNARY_FUNCTION_LIST(V) \
467 : INT32X4_BINARY_FUNCTION_LIST(V) \
468 : INT32X4_TERNARY_FUNCTION_LIST(V) \
469 : INT32X4_SHUFFLE_FUNCTION_LIST(V)
470 :
471 : // Uint32x4.
472 : #define UINT32X4_UNARY_FUNCTION_LIST(V) \
473 : V(check, (UnaryFunc<Uint32x4, Identity, Uint32x4>), 1) \
474 : V(fromFloat32x4, (FuncConvert<Float32x4, Uint32x4>), 1) \
475 : V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Uint32x4>), 1) \
476 : V(fromFloat64x2Bits, (FuncConvertBits<Float64x2, Uint32x4>), 1) \
477 : V(fromInt8x16Bits, (FuncConvertBits<Int8x16, Uint32x4>), 1) \
478 : V(fromInt16x8Bits, (FuncConvertBits<Int16x8, Uint32x4>), 1) \
479 : V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Uint32x4>), 1) \
480 : V(fromUint8x16Bits, (FuncConvertBits<Uint8x16, Uint32x4>), 1) \
481 : V(fromUint16x8Bits, (FuncConvertBits<Uint16x8, Uint32x4>), 1) \
482 : V(neg, (UnaryFunc<Uint32x4, Neg, Uint32x4>), 1) \
483 : V(not, (UnaryFunc<Uint32x4, Not, Uint32x4>), 1) \
484 : V(splat, (FuncSplat<Uint32x4>), 0)
485 :
486 : #define UINT32X4_BINARY_FUNCTION_LIST(V) \
487 : V(add, (BinaryFunc<Uint32x4, Add, Uint32x4>), 2) \
488 : V(and, (BinaryFunc<Uint32x4, And, Uint32x4>), 2) \
489 : V(equal, (CompareFunc<Uint32x4, Equal, Bool32x4>), 2) \
490 : V(extractLane, (ExtractLane<Uint32x4>), 2) \
491 : V(greaterThan, (CompareFunc<Uint32x4, GreaterThan, Bool32x4>), 2) \
492 : V(greaterThanOrEqual, (CompareFunc<Uint32x4, GreaterThanOrEqual, Bool32x4>), 2) \
493 : V(lessThan, (CompareFunc<Uint32x4, LessThan, Bool32x4>), 2) \
494 : V(lessThanOrEqual, (CompareFunc<Uint32x4, LessThanOrEqual, Bool32x4>), 2) \
495 : V(load, (Load<Uint32x4, 4>), 2) \
496 : V(load3, (Load<Uint32x4, 3>), 2) \
497 : V(load2, (Load<Uint32x4, 2>), 2) \
498 : V(load1, (Load<Uint32x4, 1>), 2) \
499 : V(mul, (BinaryFunc<Uint32x4, Mul, Uint32x4>), 2) \
500 : V(notEqual, (CompareFunc<Uint32x4, NotEqual, Bool32x4>), 2) \
501 : V(or, (BinaryFunc<Uint32x4, Or, Uint32x4>), 2) \
502 : V(sub, (BinaryFunc<Uint32x4, Sub, Uint32x4>), 2) \
503 : V(shiftLeftByScalar, (BinaryScalar<Uint32x4, ShiftLeft>), 2) \
504 : V(shiftRightByScalar, (BinaryScalar<Uint32x4, ShiftRightLogical>), 2) \
505 : V(xor, (BinaryFunc<Uint32x4, Xor, Uint32x4>), 2)
506 :
507 : #define UINT32X4_TERNARY_FUNCTION_LIST(V) \
508 : V(replaceLane, (ReplaceLane<Uint32x4>), 3) \
509 : V(select, (Select<Uint32x4, Bool32x4>), 3) \
510 : V(store, (Store<Uint32x4, 4>), 3) \
511 : V(store3, (Store<Uint32x4, 3>), 3) \
512 : V(store2, (Store<Uint32x4, 2>), 3) \
513 : V(store1, (Store<Uint32x4, 1>), 3)
514 :
515 : #define UINT32X4_SHUFFLE_FUNCTION_LIST(V) \
516 : V(swizzle, Swizzle<Uint32x4>, 5) \
517 : V(shuffle, Shuffle<Uint32x4>, 6)
518 :
519 : #define UINT32X4_FUNCTION_LIST(V) \
520 : UINT32X4_UNARY_FUNCTION_LIST(V) \
521 : UINT32X4_BINARY_FUNCTION_LIST(V) \
522 : UINT32X4_TERNARY_FUNCTION_LIST(V) \
523 : UINT32X4_SHUFFLE_FUNCTION_LIST(V)
524 :
525 : /*
526 : * The FOREACH macros below partition all of the SIMD operations into disjoint
527 : * sets.
528 : */
529 :
530 : // Operations available on all SIMD types. Mixed arity.
531 : #define FOREACH_COMMON_SIMD_OP(_) \
532 : _(extractLane) \
533 : _(replaceLane) \
534 : _(check) \
535 : _(splat)
536 :
537 : // Lanewise operations available on numeric SIMD types.
538 : // Include lane-wise select here since it is not arithmetic and defined on
539 : // numeric types too.
540 : #define FOREACH_LANE_SIMD_OP(_) \
541 : _(select) \
542 : _(swizzle) \
543 : _(shuffle)
544 :
545 : // Memory operations available on numeric SIMD types.
546 : #define FOREACH_MEMORY_SIMD_OP(_) \
547 : _(load) \
548 : _(store)
549 :
550 : // Memory operations available on numeric X4 SIMD types.
551 : #define FOREACH_MEMORY_X4_SIMD_OP(_) \
552 : _(load1) \
553 : _(load2) \
554 : _(load3) \
555 : _(store1) \
556 : _(store2) \
557 : _(store3)
558 :
559 : // Unary operations on Bool vectors.
560 : #define FOREACH_BOOL_SIMD_UNOP(_) \
561 : _(allTrue) \
562 : _(anyTrue)
563 :
564 : // Unary bitwise SIMD operators defined on all integer and boolean SIMD types.
565 : #define FOREACH_BITWISE_SIMD_UNOP(_) \
566 : _(not)
567 :
568 : // Binary bitwise SIMD operators defined on all integer and boolean SIMD types.
569 : #define FOREACH_BITWISE_SIMD_BINOP(_) \
570 : _(and) \
571 : _(or) \
572 : _(xor)
573 :
574 : // Bitwise shifts defined on integer SIMD types.
575 : #define FOREACH_SHIFT_SIMD_OP(_) \
576 : _(shiftLeftByScalar) \
577 : _(shiftRightByScalar)
578 :
579 : // Unary arithmetic operators defined on numeric SIMD types.
580 : #define FOREACH_NUMERIC_SIMD_UNOP(_) \
581 : _(neg)
582 :
583 : // Binary arithmetic operators defined on numeric SIMD types.
584 : #define FOREACH_NUMERIC_SIMD_BINOP(_) \
585 : _(add) \
586 : _(sub) \
587 : _(mul)
588 :
589 : // Unary arithmetic operators defined on floating point SIMD types.
590 : #define FOREACH_FLOAT_SIMD_UNOP(_) \
591 : _(abs) \
592 : _(sqrt) \
593 : _(reciprocalApproximation) \
594 : _(reciprocalSqrtApproximation)
595 :
596 : // Binary arithmetic operators defined on floating point SIMD types.
597 : #define FOREACH_FLOAT_SIMD_BINOP(_) \
598 : _(div) \
599 : _(max) \
600 : _(min) \
601 : _(maxNum) \
602 : _(minNum)
603 :
604 : // Binary operations on small integer (< 32 bits) vectors.
605 : #define FOREACH_SMINT_SIMD_BINOP(_) \
606 : _(addSaturate) \
607 : _(subSaturate)
608 :
609 : // Comparison operators defined on numeric SIMD types.
610 : #define FOREACH_COMP_SIMD_OP(_) \
611 : _(lessThan) \
612 : _(lessThanOrEqual) \
613 : _(equal) \
614 : _(notEqual) \
615 : _(greaterThan) \
616 : _(greaterThanOrEqual)
617 :
618 : /*
619 : * All SIMD operations, excluding casts.
620 : */
621 : #define FORALL_SIMD_NONCAST_OP(_) \
622 : FOREACH_COMMON_SIMD_OP(_) \
623 : FOREACH_LANE_SIMD_OP(_) \
624 : FOREACH_MEMORY_SIMD_OP(_) \
625 : FOREACH_MEMORY_X4_SIMD_OP(_) \
626 : FOREACH_BOOL_SIMD_UNOP(_) \
627 : FOREACH_BITWISE_SIMD_UNOP(_) \
628 : FOREACH_BITWISE_SIMD_BINOP(_) \
629 : FOREACH_SHIFT_SIMD_OP(_) \
630 : FOREACH_NUMERIC_SIMD_UNOP(_) \
631 : FOREACH_NUMERIC_SIMD_BINOP(_) \
632 : FOREACH_FLOAT_SIMD_UNOP(_) \
633 : FOREACH_FLOAT_SIMD_BINOP(_) \
634 : FOREACH_SMINT_SIMD_BINOP(_) \
635 : FOREACH_COMP_SIMD_OP(_)
636 :
637 : /*
638 : * All operations on integer SIMD types, excluding casts and
639 : * FOREACH_MEMORY_X4_OP.
640 : */
641 : #define FORALL_INT_SIMD_OP(_) \
642 : FOREACH_COMMON_SIMD_OP(_) \
643 : FOREACH_LANE_SIMD_OP(_) \
644 : FOREACH_MEMORY_SIMD_OP(_) \
645 : FOREACH_BITWISE_SIMD_UNOP(_) \
646 : FOREACH_BITWISE_SIMD_BINOP(_) \
647 : FOREACH_SHIFT_SIMD_OP(_) \
648 : FOREACH_NUMERIC_SIMD_UNOP(_) \
649 : FOREACH_NUMERIC_SIMD_BINOP(_) \
650 : FOREACH_COMP_SIMD_OP(_)
651 :
652 : /*
653 : * All operations on floating point SIMD types, excluding casts and
654 : * FOREACH_MEMORY_X4_OP.
655 : */
656 : #define FORALL_FLOAT_SIMD_OP(_) \
657 : FOREACH_COMMON_SIMD_OP(_) \
658 : FOREACH_LANE_SIMD_OP(_) \
659 : FOREACH_MEMORY_SIMD_OP(_) \
660 : FOREACH_NUMERIC_SIMD_UNOP(_) \
661 : FOREACH_NUMERIC_SIMD_BINOP(_) \
662 : FOREACH_FLOAT_SIMD_UNOP(_) \
663 : FOREACH_FLOAT_SIMD_BINOP(_) \
664 : FOREACH_COMP_SIMD_OP(_)
665 :
666 : /*
667 : * All operations on Bool SIMD types.
668 : *
669 : * These types don't have casts, so no need to specialize.
670 : */
671 : #define FORALL_BOOL_SIMD_OP(_) \
672 : FOREACH_COMMON_SIMD_OP(_) \
673 : FOREACH_BOOL_SIMD_UNOP(_) \
674 : FOREACH_BITWISE_SIMD_UNOP(_) \
675 : FOREACH_BITWISE_SIMD_BINOP(_)
676 :
677 : /*
678 : * The sets of cast operations are listed per type below.
679 : *
680 : * These sets are not disjoint.
681 : */
682 :
683 : #define FOREACH_INT8X16_SIMD_CAST(_) \
684 : _(fromFloat32x4Bits) \
685 : _(fromFloat64x2Bits) \
686 : _(fromInt16x8Bits) \
687 : _(fromInt32x4Bits)
688 :
689 : #define FOREACH_INT16X8_SIMD_CAST(_) \
690 : _(fromFloat32x4Bits) \
691 : _(fromFloat64x2Bits) \
692 : _(fromInt8x16Bits) \
693 : _(fromInt32x4Bits)
694 :
695 : #define FOREACH_INT32X4_SIMD_CAST(_) \
696 : _(fromFloat32x4) \
697 : _(fromFloat32x4Bits) \
698 : _(fromFloat64x2Bits) \
699 : _(fromInt8x16Bits) \
700 : _(fromInt16x8Bits)
701 :
702 : #define FOREACH_FLOAT32X4_SIMD_CAST(_)\
703 : _(fromFloat64x2Bits) \
704 : _(fromInt8x16Bits) \
705 : _(fromInt16x8Bits) \
706 : _(fromInt32x4) \
707 : _(fromInt32x4Bits)
708 :
709 : #define FOREACH_FLOAT64X2_SIMD_CAST(_)\
710 : _(fromFloat32x4Bits) \
711 : _(fromInt8x16Bits) \
712 : _(fromInt16x8Bits) \
713 : _(fromInt32x4Bits)
714 :
715 : // All operations on Int32x4.
716 : #define FORALL_INT32X4_SIMD_OP(_) \
717 : FORALL_INT_SIMD_OP(_) \
718 : FOREACH_MEMORY_X4_SIMD_OP(_) \
719 : FOREACH_INT32X4_SIMD_CAST(_)
720 :
721 : // All operations on Float32X4
722 : #define FORALL_FLOAT32X4_SIMD_OP(_) \
723 : FORALL_FLOAT_SIMD_OP(_) \
724 : FOREACH_MEMORY_X4_SIMD_OP(_) \
725 : FOREACH_FLOAT32X4_SIMD_CAST(_)
726 :
727 : /*
728 : * All SIMD operations assuming only 32x4 types exist.
729 : * This is used in the current asm.js impl.
730 : */
731 : #define FORALL_SIMD_ASMJS_OP(_) \
732 : FORALL_SIMD_NONCAST_OP(_) \
733 : _(fromFloat32x4) \
734 : _(fromFloat32x4Bits) \
735 : _(fromInt8x16Bits) \
736 : _(fromInt16x8Bits) \
737 : _(fromInt32x4) \
738 : _(fromInt32x4Bits) \
739 : _(fromUint8x16Bits) \
740 : _(fromUint16x8Bits) \
741 : _(fromUint32x4) \
742 : _(fromUint32x4Bits)
743 :
744 : // All operations on Int8x16 or Uint8x16 in the asm.js world.
745 : // Note: this does not include conversions and casts to/from Uint8x16 because
746 : // this list is shared between Int8x16 and Uint8x16.
747 : #define FORALL_INT8X16_ASMJS_OP(_) \
748 : FORALL_INT_SIMD_OP(_) \
749 : FOREACH_SMINT_SIMD_BINOP(_) \
750 : _(fromInt16x8Bits) \
751 : _(fromInt32x4Bits) \
752 : _(fromFloat32x4Bits)
753 :
754 : // All operations on Int16x8 or Uint16x8 in the asm.js world.
755 : // Note: this does not include conversions and casts to/from Uint16x8 because
756 : // this list is shared between Int16x8 and Uint16x8.
757 : #define FORALL_INT16X8_ASMJS_OP(_) \
758 : FORALL_INT_SIMD_OP(_) \
759 : FOREACH_SMINT_SIMD_BINOP(_) \
760 : _(fromInt8x16Bits) \
761 : _(fromInt32x4Bits) \
762 : _(fromFloat32x4Bits)
763 :
764 : // All operations on Int32x4 or Uint32x4 in the asm.js world.
765 : // Note: this does not include conversions and casts to/from Uint32x4 because
766 : // this list is shared between Int32x4 and Uint32x4.
767 : #define FORALL_INT32X4_ASMJS_OP(_) \
768 : FORALL_INT_SIMD_OP(_) \
769 : FOREACH_MEMORY_X4_SIMD_OP(_) \
770 : _(fromInt8x16Bits) \
771 : _(fromInt16x8Bits) \
772 : _(fromFloat32x4) \
773 : _(fromFloat32x4Bits)
774 :
775 : // All operations on Float32X4 in the asm.js world.
776 : #define FORALL_FLOAT32X4_ASMJS_OP(_) \
777 : FORALL_FLOAT_SIMD_OP(_) \
778 : FOREACH_MEMORY_X4_SIMD_OP(_) \
779 : _(fromInt8x16Bits) \
780 : _(fromInt16x8Bits) \
781 : _(fromInt32x4Bits) \
782 : _(fromInt32x4) \
783 : _(fromUint32x4)
784 :
785 : namespace js {
786 :
787 : // Complete set of SIMD types.
788 : // It must be kept in sync with the enumeration of values in
789 : // TypedObjectConstants.h; in particular we need to ensure that Count is
790 : // appropriately set with respect to the number of actual types.
791 : enum class SimdType {
792 : Int8x16 = JS_SIMDTYPEREPR_INT8X16,
793 : Int16x8 = JS_SIMDTYPEREPR_INT16X8,
794 : Int32x4 = JS_SIMDTYPEREPR_INT32X4,
795 : Uint8x16 = JS_SIMDTYPEREPR_UINT8X16,
796 : Uint16x8 = JS_SIMDTYPEREPR_UINT16X8,
797 : Uint32x4 = JS_SIMDTYPEREPR_UINT32X4,
798 : Float32x4 = JS_SIMDTYPEREPR_FLOAT32X4,
799 : Float64x2 = JS_SIMDTYPEREPR_FLOAT64X2,
800 : Bool8x16 = JS_SIMDTYPEREPR_BOOL8X16,
801 : Bool16x8 = JS_SIMDTYPEREPR_BOOL16X8,
802 : Bool32x4 = JS_SIMDTYPEREPR_BOOL32X4,
803 : Bool64x2 = JS_SIMDTYPEREPR_BOOL64X2,
804 : Count
805 : };
806 :
807 : // The integer SIMD types have a lot of operations that do the exact same thing
808 : // for signed and unsigned integer types. Sometimes it is simpler to treat
809 : // signed and unsigned integer SIMD types as the same type, using a SimdSign to
810 : // distinguish the few cases where there is a difference.
811 : enum class SimdSign {
812 : // Signedness is not applicable to this type. (i.e., Float or Bool).
813 : NotApplicable,
814 : // Treat as an unsigned integer with a range 0 .. 2^N-1.
815 : Unsigned,
816 : // Treat as a signed integer in two's complement encoding.
817 : Signed,
818 : };
819 :
820 : // Get the signedness of a SIMD type.
821 : inline SimdSign
822 0 : GetSimdSign(SimdType t)
823 : {
824 0 : switch(t) {
825 : case SimdType::Int8x16:
826 : case SimdType::Int16x8:
827 : case SimdType::Int32x4:
828 0 : return SimdSign::Signed;
829 :
830 : case SimdType::Uint8x16:
831 : case SimdType::Uint16x8:
832 : case SimdType::Uint32x4:
833 0 : return SimdSign::Unsigned;
834 :
835 : default:
836 0 : return SimdSign::NotApplicable;
837 : }
838 : }
839 :
840 : inline bool
841 : IsSignedIntSimdType(SimdType type)
842 : {
843 : return GetSimdSign(type) == SimdSign::Signed;
844 : }
845 :
846 : // Get the boolean SIMD type with the same shape as t.
847 : //
848 : // This is the result type of a comparison operation, and it can also be used to
849 : // identify the geometry of a SIMD type.
850 : inline SimdType
851 0 : GetBooleanSimdType(SimdType t)
852 : {
853 0 : switch(t) {
854 : case SimdType::Int8x16:
855 : case SimdType::Uint8x16:
856 : case SimdType::Bool8x16:
857 0 : return SimdType::Bool8x16;
858 :
859 : case SimdType::Int16x8:
860 : case SimdType::Uint16x8:
861 : case SimdType::Bool16x8:
862 0 : return SimdType::Bool16x8;
863 :
864 : case SimdType::Int32x4:
865 : case SimdType::Uint32x4:
866 : case SimdType::Float32x4:
867 : case SimdType::Bool32x4:
868 0 : return SimdType::Bool32x4;
869 :
870 : case SimdType::Float64x2:
871 : case SimdType::Bool64x2:
872 0 : return SimdType::Bool64x2;
873 :
874 : case SimdType::Count:
875 0 : break;
876 : }
877 0 : MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Bad SIMD type");
878 : }
879 :
880 : // Get the number of lanes in a SIMD type.
881 : inline unsigned
882 0 : GetSimdLanes(SimdType t)
883 : {
884 0 : switch(t) {
885 : case SimdType::Int8x16:
886 : case SimdType::Uint8x16:
887 : case SimdType::Bool8x16:
888 0 : return 16;
889 :
890 : case SimdType::Int16x8:
891 : case SimdType::Uint16x8:
892 : case SimdType::Bool16x8:
893 0 : return 8;
894 :
895 : case SimdType::Int32x4:
896 : case SimdType::Uint32x4:
897 : case SimdType::Float32x4:
898 : case SimdType::Bool32x4:
899 0 : return 4;
900 :
901 : case SimdType::Float64x2:
902 : case SimdType::Bool64x2:
903 0 : return 2;
904 :
905 : case SimdType::Count:
906 0 : break;
907 : }
908 0 : MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Bad SIMD type");
909 : }
910 :
911 : // Complete set of SIMD operations.
912 : //
913 : // No SIMD types implement all of these operations.
914 : //
915 : // C++ defines keywords and/or/xor/not, so prepend Fn_ to all named functions to
916 : // avoid clashes.
917 : //
918 : // Note: because of a gcc < v4.8's compiler bug, uint8_t can't be used as the
919 : // storage class here. See bug 1243810. See also
920 : // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64037 .
921 : enum class SimdOperation {
922 : // The constructor call. No Fn_ prefix here.
923 : Constructor,
924 :
925 : // All the operations, except for casts.
926 : #define DEFOP(x) Fn_##x,
927 : FORALL_SIMD_NONCAST_OP(DEFOP)
928 : #undef DEFOP
929 :
930 : // Int <-> Float conversions.
931 : Fn_fromInt32x4,
932 : Fn_fromUint32x4,
933 : Fn_fromFloat32x4,
934 :
935 : // Bitcasts. One for each type with a memory representation.
936 : Fn_fromInt8x16Bits,
937 : Fn_fromInt16x8Bits,
938 : Fn_fromInt32x4Bits,
939 : Fn_fromUint8x16Bits,
940 : Fn_fromUint16x8Bits,
941 : Fn_fromUint32x4Bits,
942 : Fn_fromFloat32x4Bits,
943 : Fn_fromFloat64x2Bits,
944 :
945 : Last = Fn_fromFloat64x2Bits
946 : };
947 :
948 : // These classes implement the concept containing the following constraints:
949 : // - requires typename Elem: this is the scalar lane type, stored in each lane
950 : // of the SIMD vector.
951 : // - requires static const unsigned lanes: this is the number of lanes (length)
952 : // of the SIMD vector.
953 : // - requires static const SimdType type: this is the SimdType enum value
954 : // corresponding to the SIMD type.
955 : // - requires static bool Cast(JSContext*, JS::HandleValue, Elem*): casts a
956 : // given Value to the current scalar lane type and saves it in the Elem
957 : // out-param.
958 : // - requires static Value ToValue(Elem): returns a Value of the right type
959 : // containing the given value.
960 : //
961 : // This concept is used in the templates above to define the functions
962 : // associated to a given type and in their implementations, to avoid code
963 : // redundancy.
964 :
965 : struct Float32x4 {
966 : typedef float Elem;
967 : static const unsigned lanes = 4;
968 : static const SimdType type = SimdType::Float32x4;
969 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
970 : double d;
971 0 : if (!ToNumber(cx, v, &d))
972 0 : return false;
973 0 : *out = float(d);
974 0 : return true;
975 : }
976 0 : static Value ToValue(Elem value) {
977 0 : return DoubleValue(JS::CanonicalizeNaN(value));
978 : }
979 : };
980 :
981 : struct Float64x2 {
982 : typedef double Elem;
983 : static const unsigned lanes = 2;
984 : static const SimdType type = SimdType::Float64x2;
985 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
986 0 : return ToNumber(cx, v, out);
987 : }
988 0 : static Value ToValue(Elem value) {
989 0 : return DoubleValue(JS::CanonicalizeNaN(value));
990 : }
991 : };
992 :
993 : struct Int8x16 {
994 : typedef int8_t Elem;
995 : static const unsigned lanes = 16;
996 : static const SimdType type = SimdType::Int8x16;
997 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
998 0 : return ToInt8(cx, v, out);
999 : }
1000 0 : static Value ToValue(Elem value) {
1001 0 : return NumberValue(value);
1002 : }
1003 : };
1004 :
1005 : struct Int16x8 {
1006 : typedef int16_t Elem;
1007 : static const unsigned lanes = 8;
1008 : static const SimdType type = SimdType::Int16x8;
1009 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
1010 0 : return ToInt16(cx, v, out);
1011 : }
1012 0 : static Value ToValue(Elem value) {
1013 0 : return NumberValue(value);
1014 : }
1015 : };
1016 :
1017 : struct Int32x4 {
1018 : typedef int32_t Elem;
1019 : static const unsigned lanes = 4;
1020 : static const SimdType type = SimdType::Int32x4;
1021 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
1022 0 : return ToInt32(cx, v, out);
1023 : }
1024 0 : static Value ToValue(Elem value) {
1025 0 : return NumberValue(value);
1026 : }
1027 : };
1028 :
1029 : struct Uint8x16 {
1030 : typedef uint8_t Elem;
1031 : static const unsigned lanes = 16;
1032 : static const SimdType type = SimdType::Uint8x16;
1033 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
1034 0 : return ToUint8(cx, v, out);
1035 : }
1036 0 : static Value ToValue(Elem value) {
1037 0 : return NumberValue(value);
1038 : }
1039 : };
1040 :
1041 : struct Uint16x8 {
1042 : typedef uint16_t Elem;
1043 : static const unsigned lanes = 8;
1044 : static const SimdType type = SimdType::Uint16x8;
1045 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
1046 0 : return ToUint16(cx, v, out);
1047 : }
1048 0 : static Value ToValue(Elem value) {
1049 0 : return NumberValue(value);
1050 : }
1051 : };
1052 :
1053 : struct Uint32x4 {
1054 : typedef uint32_t Elem;
1055 : static const unsigned lanes = 4;
1056 : static const SimdType type = SimdType::Uint32x4;
1057 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
1058 0 : return ToUint32(cx, v, out);
1059 : }
1060 0 : static Value ToValue(Elem value) {
1061 0 : return NumberValue(value);
1062 : }
1063 : };
1064 :
1065 : struct Bool8x16 {
1066 : typedef int8_t Elem;
1067 : static const unsigned lanes = 16;
1068 : static const SimdType type = SimdType::Bool8x16;
1069 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
1070 0 : *out = ToBoolean(v) ? -1 : 0;
1071 0 : return true;
1072 : }
1073 0 : static Value ToValue(Elem value) {
1074 0 : return BooleanValue(value);
1075 : }
1076 : };
1077 :
1078 : struct Bool16x8 {
1079 : typedef int16_t Elem;
1080 : static const unsigned lanes = 8;
1081 : static const SimdType type = SimdType::Bool16x8;
1082 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
1083 0 : *out = ToBoolean(v) ? -1 : 0;
1084 0 : return true;
1085 : }
1086 0 : static Value ToValue(Elem value) {
1087 0 : return BooleanValue(value);
1088 : }
1089 : };
1090 :
1091 : struct Bool32x4 {
1092 : typedef int32_t Elem;
1093 : static const unsigned lanes = 4;
1094 : static const SimdType type = SimdType::Bool32x4;
1095 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
1096 0 : *out = ToBoolean(v) ? -1 : 0;
1097 0 : return true;
1098 : }
1099 0 : static Value ToValue(Elem value) {
1100 0 : return BooleanValue(value);
1101 : }
1102 : };
1103 :
1104 : struct Bool64x2 {
1105 : typedef int64_t Elem;
1106 : static const unsigned lanes = 2;
1107 : static const SimdType type = SimdType::Bool64x2;
1108 0 : static MOZ_MUST_USE bool Cast(JSContext* cx, JS::HandleValue v, Elem* out) {
1109 0 : *out = ToBoolean(v) ? -1 : 0;
1110 0 : return true;
1111 : }
1112 0 : static Value ToValue(Elem value) {
1113 0 : return BooleanValue(value);
1114 : }
1115 : };
1116 :
1117 : // Get the well known name of the SIMD.* object corresponding to type.
1118 : PropertyName* SimdTypeToName(const JSAtomState& atoms, SimdType type);
1119 :
1120 : // Check if name is the well known name of a SIMD type.
1121 : // Returns true and sets *type iff name is known.
1122 : bool IsSimdTypeName(const JSAtomState& atoms, const PropertyName* name, SimdType* type);
1123 :
1124 : const char* SimdTypeToString(SimdType type);
1125 :
1126 : template<typename V>
1127 : JSObject* CreateSimd(JSContext* cx, const typename V::Elem* data);
1128 :
1129 : template<typename V>
1130 : bool IsVectorObject(HandleValue v);
1131 :
1132 : template<typename V>
1133 : MOZ_MUST_USE bool ToSimdConstant(JSContext* cx, HandleValue v, jit::SimdConstant* out);
1134 :
1135 : JSObject*
1136 : InitSimdClass(JSContext* cx, HandleObject obj);
1137 :
1138 : namespace jit {
1139 :
1140 : extern const JSJitInfo JitInfo_SimdInt32x4_extractLane;
1141 : extern const JSJitInfo JitInfo_SimdFloat32x4_extractLane;
1142 :
1143 : } // namespace jit
1144 :
1145 : #define DECLARE_SIMD_FLOAT32X4_FUNCTION(Name, Func, Operands) \
1146 : extern MOZ_MUST_USE bool \
1147 : simd_float32x4_##Name(JSContext* cx, unsigned argc, Value* vp);
1148 : FLOAT32X4_FUNCTION_LIST(DECLARE_SIMD_FLOAT32X4_FUNCTION)
1149 : #undef DECLARE_SIMD_FLOAT32X4_FUNCTION
1150 :
1151 : #define DECLARE_SIMD_FLOAT64X2_FUNCTION(Name, Func, Operands) \
1152 : extern MOZ_MUST_USE bool \
1153 : simd_float64x2_##Name(JSContext* cx, unsigned argc, Value* vp);
1154 : FLOAT64X2_FUNCTION_LIST(DECLARE_SIMD_FLOAT64X2_FUNCTION)
1155 : #undef DECLARE_SIMD_FLOAT64X2_FUNCTION
1156 :
1157 : #define DECLARE_SIMD_INT8X16_FUNCTION(Name, Func, Operands) \
1158 : extern MOZ_MUST_USE bool \
1159 : simd_int8x16_##Name(JSContext* cx, unsigned argc, Value* vp);
1160 : INT8X16_FUNCTION_LIST(DECLARE_SIMD_INT8X16_FUNCTION)
1161 : #undef DECLARE_SIMD_INT8X16_FUNCTION
1162 :
1163 : #define DECLARE_SIMD_INT16X8_FUNCTION(Name, Func, Operands) \
1164 : extern MOZ_MUST_USE bool \
1165 : simd_int16x8_##Name(JSContext* cx, unsigned argc, Value* vp);
1166 : INT16X8_FUNCTION_LIST(DECLARE_SIMD_INT16X8_FUNCTION)
1167 : #undef DECLARE_SIMD_INT16X8_FUNCTION
1168 :
1169 : #define DECLARE_SIMD_INT32X4_FUNCTION(Name, Func, Operands) \
1170 : extern MOZ_MUST_USE bool \
1171 : simd_int32x4_##Name(JSContext* cx, unsigned argc, Value* vp);
1172 : INT32X4_FUNCTION_LIST(DECLARE_SIMD_INT32X4_FUNCTION)
1173 : #undef DECLARE_SIMD_INT32X4_FUNCTION
1174 :
1175 : #define DECLARE_SIMD_UINT8X16_FUNCTION(Name, Func, Operands) \
1176 : extern MOZ_MUST_USE bool \
1177 : simd_uint8x16_##Name(JSContext* cx, unsigned argc, Value* vp);
1178 : UINT8X16_FUNCTION_LIST(DECLARE_SIMD_UINT8X16_FUNCTION)
1179 : #undef DECLARE_SIMD_UINT8X16_FUNCTION
1180 :
1181 : #define DECLARE_SIMD_UINT16X8_FUNCTION(Name, Func, Operands) \
1182 : extern MOZ_MUST_USE bool \
1183 : simd_uint16x8_##Name(JSContext* cx, unsigned argc, Value* vp);
1184 : UINT16X8_FUNCTION_LIST(DECLARE_SIMD_UINT16X8_FUNCTION)
1185 : #undef DECLARE_SIMD_UINT16X8_FUNCTION
1186 :
1187 : #define DECLARE_SIMD_UINT32X4_FUNCTION(Name, Func, Operands) \
1188 : extern MOZ_MUST_USE bool \
1189 : simd_uint32x4_##Name(JSContext* cx, unsigned argc, Value* vp);
1190 : UINT32X4_FUNCTION_LIST(DECLARE_SIMD_UINT32X4_FUNCTION)
1191 : #undef DECLARE_SIMD_UINT32X4_FUNCTION
1192 :
1193 : #define DECLARE_SIMD_BOOL8X16_FUNCTION(Name, Func, Operands) \
1194 : extern MOZ_MUST_USE bool \
1195 : simd_bool8x16_##Name(JSContext* cx, unsigned argc, Value* vp);
1196 : BOOL8X16_FUNCTION_LIST(DECLARE_SIMD_BOOL8X16_FUNCTION)
1197 : #undef DECLARE_SIMD_BOOL8X16_FUNCTION
1198 :
1199 : #define DECLARE_SIMD_BOOL16X8_FUNCTION(Name, Func, Operands) \
1200 : extern MOZ_MUST_USE bool \
1201 : simd_bool16x8_##Name(JSContext* cx, unsigned argc, Value* vp);
1202 : BOOL16X8_FUNCTION_LIST(DECLARE_SIMD_BOOL16X8_FUNCTION)
1203 : #undef DECLARE_SIMD_BOOL16X8_FUNCTION
1204 :
1205 : #define DECLARE_SIMD_BOOL32X4_FUNCTION(Name, Func, Operands) \
1206 : extern MOZ_MUST_USE bool \
1207 : simd_bool32x4_##Name(JSContext* cx, unsigned argc, Value* vp);
1208 : BOOL32X4_FUNCTION_LIST(DECLARE_SIMD_BOOL32X4_FUNCTION)
1209 : #undef DECLARE_SIMD_BOOL32X4_FUNCTION
1210 :
1211 : #define DECLARE_SIMD_BOOL64X2_FUNCTION(Name, Func, Operands) \
1212 : extern MOZ_MUST_USE bool \
1213 : simd_bool64x2_##Name(JSContext* cx, unsigned argc, Value* vp);
1214 : BOOL64X2_FUNCTION_LIST(DECLARE_SIMD_BOOL64X2_FUNCTION)
1215 : #undef DECLARE_SIMD_BOOL64X2_FUNCTION
1216 :
1217 : } /* namespace js */
1218 :
1219 : #endif /* builtin_SIMD_h */
|