Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / js / src / wasm / WasmOpIter.cpp
blobd60a87dc12c0fb85d4919ea26c0ff968dbd4214d
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
4 * Copyright 2015 Mozilla Foundation
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 #include "wasm/WasmOpIter.h"
21 #include "jit/AtomicOp.h"
23 using namespace js;
24 using namespace js::jit;
25 using namespace js::wasm;
27 #ifdef ENABLE_WASM_GC
28 # ifndef ENABLE_WASM_GC
29 # error "GC types require the function-references feature"
30 # endif
31 #endif
33 #ifdef DEBUG
35 # ifdef ENABLE_WASM_GC
36 # define WASM_FUNCTION_REFERENCES_OP(code) return code
37 # else
38 # define WASM_FUNCTION_REFERENCES_OP(code) break
39 # endif
40 # ifdef ENABLE_WASM_GC
41 # define WASM_GC_OP(code) return code
42 # else
43 # define WASM_GC_OP(code) break
44 # endif
45 # ifdef ENABLE_WASM_SIMD
46 # define WASM_SIMD_OP(code) return code
47 # else
48 # define WASM_SIMD_OP(code) break
49 # endif
51 OpKind wasm::Classify(OpBytes op) {
52 switch (Op(op.b0)) {
53 case Op::Block:
54 return OpKind::Block;
55 case Op::Loop:
56 return OpKind::Loop;
57 case Op::Unreachable:
58 return OpKind::Unreachable;
59 case Op::Drop:
60 return OpKind::Drop;
61 case Op::I32Const:
62 return OpKind::I32;
63 case Op::I64Const:
64 return OpKind::I64;
65 case Op::F32Const:
66 return OpKind::F32;
67 case Op::F64Const:
68 return OpKind::F64;
69 case Op::Br:
70 return OpKind::Br;
71 case Op::BrIf:
72 return OpKind::BrIf;
73 case Op::BrTable:
74 return OpKind::BrTable;
75 case Op::Nop:
76 return OpKind::Nop;
77 case Op::I32Clz:
78 case Op::I32Ctz:
79 case Op::I32Popcnt:
80 case Op::I64Clz:
81 case Op::I64Ctz:
82 case Op::I64Popcnt:
83 case Op::F32Abs:
84 case Op::F32Neg:
85 case Op::F32Ceil:
86 case Op::F32Floor:
87 case Op::F32Trunc:
88 case Op::F32Nearest:
89 case Op::F32Sqrt:
90 case Op::F64Abs:
91 case Op::F64Neg:
92 case Op::F64Ceil:
93 case Op::F64Floor:
94 case Op::F64Trunc:
95 case Op::F64Nearest:
96 case Op::F64Sqrt:
97 return OpKind::Unary;
98 case Op::I32Add:
99 case Op::I32Sub:
100 case Op::I32Mul:
101 case Op::I32DivS:
102 case Op::I32DivU:
103 case Op::I32RemS:
104 case Op::I32RemU:
105 case Op::I32And:
106 case Op::I32Or:
107 case Op::I32Xor:
108 case Op::I32Shl:
109 case Op::I32ShrS:
110 case Op::I32ShrU:
111 case Op::I32Rotl:
112 case Op::I32Rotr:
113 case Op::I64Add:
114 case Op::I64Sub:
115 case Op::I64Mul:
116 case Op::I64DivS:
117 case Op::I64DivU:
118 case Op::I64RemS:
119 case Op::I64RemU:
120 case Op::I64And:
121 case Op::I64Or:
122 case Op::I64Xor:
123 case Op::I64Shl:
124 case Op::I64ShrS:
125 case Op::I64ShrU:
126 case Op::I64Rotl:
127 case Op::I64Rotr:
128 case Op::F32Add:
129 case Op::F32Sub:
130 case Op::F32Mul:
131 case Op::F32Div:
132 case Op::F32Min:
133 case Op::F32Max:
134 case Op::F32CopySign:
135 case Op::F64Add:
136 case Op::F64Sub:
137 case Op::F64Mul:
138 case Op::F64Div:
139 case Op::F64Min:
140 case Op::F64Max:
141 case Op::F64CopySign:
142 return OpKind::Binary;
143 case Op::I32Eq:
144 case Op::I32Ne:
145 case Op::I32LtS:
146 case Op::I32LtU:
147 case Op::I32LeS:
148 case Op::I32LeU:
149 case Op::I32GtS:
150 case Op::I32GtU:
151 case Op::I32GeS:
152 case Op::I32GeU:
153 case Op::I64Eq:
154 case Op::I64Ne:
155 case Op::I64LtS:
156 case Op::I64LtU:
157 case Op::I64LeS:
158 case Op::I64LeU:
159 case Op::I64GtS:
160 case Op::I64GtU:
161 case Op::I64GeS:
162 case Op::I64GeU:
163 case Op::F32Eq:
164 case Op::F32Ne:
165 case Op::F32Lt:
166 case Op::F32Le:
167 case Op::F32Gt:
168 case Op::F32Ge:
169 case Op::F64Eq:
170 case Op::F64Ne:
171 case Op::F64Lt:
172 case Op::F64Le:
173 case Op::F64Gt:
174 case Op::F64Ge:
175 return OpKind::Comparison;
176 case Op::I32Eqz:
177 case Op::I32WrapI64:
178 case Op::I32TruncF32S:
179 case Op::I32TruncF32U:
180 case Op::I32ReinterpretF32:
181 case Op::I32TruncF64S:
182 case Op::I32TruncF64U:
183 case Op::I64ExtendI32S:
184 case Op::I64ExtendI32U:
185 case Op::I64TruncF32S:
186 case Op::I64TruncF32U:
187 case Op::I64TruncF64S:
188 case Op::I64TruncF64U:
189 case Op::I64ReinterpretF64:
190 case Op::I64Eqz:
191 case Op::F32ConvertI32S:
192 case Op::F32ConvertI32U:
193 case Op::F32ReinterpretI32:
194 case Op::F32ConvertI64S:
195 case Op::F32ConvertI64U:
196 case Op::F32DemoteF64:
197 case Op::F64ConvertI32S:
198 case Op::F64ConvertI32U:
199 case Op::F64ConvertI64S:
200 case Op::F64ConvertI64U:
201 case Op::F64ReinterpretI64:
202 case Op::F64PromoteF32:
203 case Op::I32Extend8S:
204 case Op::I32Extend16S:
205 case Op::I64Extend8S:
206 case Op::I64Extend16S:
207 case Op::I64Extend32S:
208 return OpKind::Conversion;
209 case Op::I32Load8S:
210 case Op::I32Load8U:
211 case Op::I32Load16S:
212 case Op::I32Load16U:
213 case Op::I64Load8S:
214 case Op::I64Load8U:
215 case Op::I64Load16S:
216 case Op::I64Load16U:
217 case Op::I64Load32S:
218 case Op::I64Load32U:
219 case Op::I32Load:
220 case Op::I64Load:
221 case Op::F32Load:
222 case Op::F64Load:
223 return OpKind::Load;
224 case Op::I32Store8:
225 case Op::I32Store16:
226 case Op::I64Store8:
227 case Op::I64Store16:
228 case Op::I64Store32:
229 case Op::I32Store:
230 case Op::I64Store:
231 case Op::F32Store:
232 case Op::F64Store:
233 return OpKind::Store;
234 case Op::SelectNumeric:
235 case Op::SelectTyped:
236 return OpKind::Select;
237 case Op::LocalGet:
238 return OpKind::GetLocal;
239 case Op::LocalSet:
240 return OpKind::SetLocal;
241 case Op::LocalTee:
242 return OpKind::TeeLocal;
243 case Op::GlobalGet:
244 return OpKind::GetGlobal;
245 case Op::GlobalSet:
246 return OpKind::SetGlobal;
247 case Op::TableGet:
248 return OpKind::TableGet;
249 case Op::TableSet:
250 return OpKind::TableSet;
251 case Op::Call:
252 return OpKind::Call;
253 case Op::ReturnCall:
254 return OpKind::ReturnCall;
255 case Op::CallIndirect:
256 return OpKind::CallIndirect;
257 case Op::ReturnCallIndirect:
258 return OpKind::ReturnCallIndirect;
259 case Op::CallRef:
260 WASM_FUNCTION_REFERENCES_OP(OpKind::CallRef);
261 case Op::ReturnCallRef:
262 WASM_FUNCTION_REFERENCES_OP(OpKind::ReturnCallRef);
263 case Op::Return:
264 case Op::Limit:
265 // Accept Limit, for use in decoding the end of a function after the body.
266 return OpKind::Return;
267 case Op::If:
268 return OpKind::If;
269 case Op::Else:
270 return OpKind::Else;
271 case Op::End:
272 return OpKind::End;
273 case Op::Catch:
274 return OpKind::Catch;
275 case Op::CatchAll:
276 return OpKind::CatchAll;
277 case Op::Delegate:
278 return OpKind::Delegate;
279 case Op::Throw:
280 return OpKind::Throw;
281 case Op::Rethrow:
282 return OpKind::Rethrow;
283 case Op::Try:
284 return OpKind::Try;
285 case Op::ThrowRef:
286 return OpKind::ThrowRef;
287 case Op::TryTable:
288 return OpKind::TryTable;
289 case Op::MemorySize:
290 return OpKind::MemorySize;
291 case Op::MemoryGrow:
292 return OpKind::MemoryGrow;
293 case Op::RefNull:
294 return OpKind::RefNull;
295 case Op::RefIsNull:
296 return OpKind::Conversion;
297 case Op::RefFunc:
298 return OpKind::RefFunc;
299 case Op::RefAsNonNull:
300 WASM_FUNCTION_REFERENCES_OP(OpKind::RefAsNonNull);
301 case Op::BrOnNull:
302 WASM_FUNCTION_REFERENCES_OP(OpKind::BrOnNull);
303 case Op::BrOnNonNull:
304 WASM_FUNCTION_REFERENCES_OP(OpKind::BrOnNonNull);
305 case Op::RefEq:
306 WASM_GC_OP(OpKind::Comparison);
307 case Op::GcPrefix: {
308 switch (GcOp(op.b1)) {
309 case GcOp::Limit:
310 // Reject Limit for GcPrefix encoding
311 break;
312 case GcOp::StructNew:
313 WASM_GC_OP(OpKind::StructNew);
314 case GcOp::StructNewDefault:
315 WASM_GC_OP(OpKind::StructNewDefault);
316 case GcOp::StructGet:
317 case GcOp::StructGetS:
318 case GcOp::StructGetU:
319 WASM_GC_OP(OpKind::StructGet);
320 case GcOp::StructSet:
321 WASM_GC_OP(OpKind::StructSet);
322 case GcOp::ArrayNew:
323 WASM_GC_OP(OpKind::ArrayNew);
324 case GcOp::ArrayNewFixed:
325 WASM_GC_OP(OpKind::ArrayNewFixed);
326 case GcOp::ArrayNewDefault:
327 WASM_GC_OP(OpKind::ArrayNewDefault);
328 case GcOp::ArrayNewData:
329 WASM_GC_OP(OpKind::ArrayNewData);
330 case GcOp::ArrayNewElem:
331 WASM_GC_OP(OpKind::ArrayNewElem);
332 case GcOp::ArrayInitData:
333 WASM_GC_OP(OpKind::ArrayInitData);
334 case GcOp::ArrayInitElem:
335 WASM_GC_OP(OpKind::ArrayInitElem);
336 case GcOp::ArrayGet:
337 case GcOp::ArrayGetS:
338 case GcOp::ArrayGetU:
339 WASM_GC_OP(OpKind::ArrayGet);
340 case GcOp::ArraySet:
341 WASM_GC_OP(OpKind::ArraySet);
342 case GcOp::ArrayLen:
343 WASM_GC_OP(OpKind::ArrayLen);
344 case GcOp::ArrayCopy:
345 WASM_GC_OP(OpKind::ArrayCopy);
346 case GcOp::ArrayFill:
347 WASM_GC_OP(OpKind::ArrayFill);
348 case GcOp::RefI31:
349 case GcOp::I31GetS:
350 case GcOp::I31GetU:
351 WASM_GC_OP(OpKind::Conversion);
352 case GcOp::RefTest:
353 case GcOp::RefTestNull:
354 WASM_GC_OP(OpKind::RefTest);
355 case GcOp::RefCast:
356 case GcOp::RefCastNull:
357 WASM_GC_OP(OpKind::RefCast);
358 case GcOp::BrOnCast:
359 case GcOp::BrOnCastFail:
360 WASM_GC_OP(OpKind::BrOnCast);
361 case GcOp::AnyConvertExtern:
362 WASM_GC_OP(OpKind::RefConversion);
363 case GcOp::ExternConvertAny:
364 WASM_GC_OP(OpKind::RefConversion);
366 break;
368 case Op::SimdPrefix: {
369 switch (SimdOp(op.b1)) {
370 case SimdOp::MozPMADDUBSW:
371 case SimdOp::Limit:
372 // Reject Limit and reserved codes for SimdPrefix encoding
373 break;
374 case SimdOp::I8x16ExtractLaneS:
375 case SimdOp::I8x16ExtractLaneU:
376 case SimdOp::I16x8ExtractLaneS:
377 case SimdOp::I16x8ExtractLaneU:
378 case SimdOp::I32x4ExtractLane:
379 case SimdOp::I64x2ExtractLane:
380 case SimdOp::F32x4ExtractLane:
381 case SimdOp::F64x2ExtractLane:
382 WASM_SIMD_OP(OpKind::ExtractLane);
383 case SimdOp::I8x16Splat:
384 case SimdOp::I16x8Splat:
385 case SimdOp::I32x4Splat:
386 case SimdOp::I64x2Splat:
387 case SimdOp::F32x4Splat:
388 case SimdOp::F64x2Splat:
389 case SimdOp::V128AnyTrue:
390 case SimdOp::I8x16AllTrue:
391 case SimdOp::I16x8AllTrue:
392 case SimdOp::I32x4AllTrue:
393 case SimdOp::I64x2AllTrue:
394 case SimdOp::I8x16Bitmask:
395 case SimdOp::I16x8Bitmask:
396 case SimdOp::I32x4Bitmask:
397 case SimdOp::I64x2Bitmask:
398 WASM_SIMD_OP(OpKind::Conversion);
399 case SimdOp::I8x16ReplaceLane:
400 case SimdOp::I16x8ReplaceLane:
401 case SimdOp::I32x4ReplaceLane:
402 case SimdOp::I64x2ReplaceLane:
403 case SimdOp::F32x4ReplaceLane:
404 case SimdOp::F64x2ReplaceLane:
405 WASM_SIMD_OP(OpKind::ReplaceLane);
406 case SimdOp::I8x16Eq:
407 case SimdOp::I8x16Ne:
408 case SimdOp::I8x16LtS:
409 case SimdOp::I8x16LtU:
410 case SimdOp::I8x16GtS:
411 case SimdOp::I8x16GtU:
412 case SimdOp::I8x16LeS:
413 case SimdOp::I8x16LeU:
414 case SimdOp::I8x16GeS:
415 case SimdOp::I8x16GeU:
416 case SimdOp::I16x8Eq:
417 case SimdOp::I16x8Ne:
418 case SimdOp::I16x8LtS:
419 case SimdOp::I16x8LtU:
420 case SimdOp::I16x8GtS:
421 case SimdOp::I16x8GtU:
422 case SimdOp::I16x8LeS:
423 case SimdOp::I16x8LeU:
424 case SimdOp::I16x8GeS:
425 case SimdOp::I16x8GeU:
426 case SimdOp::I32x4Eq:
427 case SimdOp::I32x4Ne:
428 case SimdOp::I32x4LtS:
429 case SimdOp::I32x4LtU:
430 case SimdOp::I32x4GtS:
431 case SimdOp::I32x4GtU:
432 case SimdOp::I32x4LeS:
433 case SimdOp::I32x4LeU:
434 case SimdOp::I32x4GeS:
435 case SimdOp::I32x4GeU:
436 case SimdOp::I64x2Eq:
437 case SimdOp::I64x2Ne:
438 case SimdOp::I64x2LtS:
439 case SimdOp::I64x2GtS:
440 case SimdOp::I64x2LeS:
441 case SimdOp::I64x2GeS:
442 case SimdOp::F32x4Eq:
443 case SimdOp::F32x4Ne:
444 case SimdOp::F32x4Lt:
445 case SimdOp::F32x4Gt:
446 case SimdOp::F32x4Le:
447 case SimdOp::F32x4Ge:
448 case SimdOp::F64x2Eq:
449 case SimdOp::F64x2Ne:
450 case SimdOp::F64x2Lt:
451 case SimdOp::F64x2Gt:
452 case SimdOp::F64x2Le:
453 case SimdOp::F64x2Ge:
454 case SimdOp::V128And:
455 case SimdOp::V128Or:
456 case SimdOp::V128Xor:
457 case SimdOp::V128AndNot:
458 case SimdOp::I8x16AvgrU:
459 case SimdOp::I16x8AvgrU:
460 case SimdOp::I8x16Add:
461 case SimdOp::I8x16AddSatS:
462 case SimdOp::I8x16AddSatU:
463 case SimdOp::I8x16Sub:
464 case SimdOp::I8x16SubSatS:
465 case SimdOp::I8x16SubSatU:
466 case SimdOp::I8x16MinS:
467 case SimdOp::I8x16MaxS:
468 case SimdOp::I8x16MinU:
469 case SimdOp::I8x16MaxU:
470 case SimdOp::I16x8Add:
471 case SimdOp::I16x8AddSatS:
472 case SimdOp::I16x8AddSatU:
473 case SimdOp::I16x8Sub:
474 case SimdOp::I16x8SubSatS:
475 case SimdOp::I16x8SubSatU:
476 case SimdOp::I16x8Mul:
477 case SimdOp::I16x8MinS:
478 case SimdOp::I16x8MaxS:
479 case SimdOp::I16x8MinU:
480 case SimdOp::I16x8MaxU:
481 case SimdOp::I32x4Add:
482 case SimdOp::I32x4Sub:
483 case SimdOp::I32x4Mul:
484 case SimdOp::I32x4MinS:
485 case SimdOp::I32x4MaxS:
486 case SimdOp::I32x4MinU:
487 case SimdOp::I32x4MaxU:
488 case SimdOp::I64x2Add:
489 case SimdOp::I64x2Sub:
490 case SimdOp::I64x2Mul:
491 case SimdOp::F32x4Add:
492 case SimdOp::F32x4Sub:
493 case SimdOp::F32x4Mul:
494 case SimdOp::F32x4Div:
495 case SimdOp::F32x4Min:
496 case SimdOp::F32x4Max:
497 case SimdOp::F64x2Add:
498 case SimdOp::F64x2Sub:
499 case SimdOp::F64x2Mul:
500 case SimdOp::F64x2Div:
501 case SimdOp::F64x2Min:
502 case SimdOp::F64x2Max:
503 case SimdOp::I8x16NarrowI16x8S:
504 case SimdOp::I8x16NarrowI16x8U:
505 case SimdOp::I16x8NarrowI32x4S:
506 case SimdOp::I16x8NarrowI32x4U:
507 case SimdOp::I8x16Swizzle:
508 case SimdOp::F32x4PMin:
509 case SimdOp::F32x4PMax:
510 case SimdOp::F64x2PMin:
511 case SimdOp::F64x2PMax:
512 case SimdOp::I32x4DotI16x8S:
513 case SimdOp::I16x8ExtmulLowI8x16S:
514 case SimdOp::I16x8ExtmulHighI8x16S:
515 case SimdOp::I16x8ExtmulLowI8x16U:
516 case SimdOp::I16x8ExtmulHighI8x16U:
517 case SimdOp::I32x4ExtmulLowI16x8S:
518 case SimdOp::I32x4ExtmulHighI16x8S:
519 case SimdOp::I32x4ExtmulLowI16x8U:
520 case SimdOp::I32x4ExtmulHighI16x8U:
521 case SimdOp::I64x2ExtmulLowI32x4S:
522 case SimdOp::I64x2ExtmulHighI32x4S:
523 case SimdOp::I64x2ExtmulLowI32x4U:
524 case SimdOp::I64x2ExtmulHighI32x4U:
525 case SimdOp::I16x8Q15MulrSatS:
526 case SimdOp::F32x4RelaxedMin:
527 case SimdOp::F32x4RelaxedMax:
528 case SimdOp::F64x2RelaxedMin:
529 case SimdOp::F64x2RelaxedMax:
530 case SimdOp::I8x16RelaxedSwizzle:
531 case SimdOp::I16x8RelaxedQ15MulrS:
532 case SimdOp::I16x8DotI8x16I7x16S:
533 WASM_SIMD_OP(OpKind::Binary);
534 case SimdOp::I8x16Neg:
535 case SimdOp::I16x8Neg:
536 case SimdOp::I16x8ExtendLowI8x16S:
537 case SimdOp::I16x8ExtendHighI8x16S:
538 case SimdOp::I16x8ExtendLowI8x16U:
539 case SimdOp::I16x8ExtendHighI8x16U:
540 case SimdOp::I32x4Neg:
541 case SimdOp::I32x4ExtendLowI16x8S:
542 case SimdOp::I32x4ExtendHighI16x8S:
543 case SimdOp::I32x4ExtendLowI16x8U:
544 case SimdOp::I32x4ExtendHighI16x8U:
545 case SimdOp::I32x4TruncSatF32x4S:
546 case SimdOp::I32x4TruncSatF32x4U:
547 case SimdOp::I64x2Neg:
548 case SimdOp::I64x2ExtendLowI32x4S:
549 case SimdOp::I64x2ExtendHighI32x4S:
550 case SimdOp::I64x2ExtendLowI32x4U:
551 case SimdOp::I64x2ExtendHighI32x4U:
552 case SimdOp::F32x4Abs:
553 case SimdOp::F32x4Neg:
554 case SimdOp::F32x4Sqrt:
555 case SimdOp::F32x4ConvertI32x4S:
556 case SimdOp::F32x4ConvertI32x4U:
557 case SimdOp::F64x2Abs:
558 case SimdOp::F64x2Neg:
559 case SimdOp::F64x2Sqrt:
560 case SimdOp::V128Not:
561 case SimdOp::I8x16Popcnt:
562 case SimdOp::I8x16Abs:
563 case SimdOp::I16x8Abs:
564 case SimdOp::I32x4Abs:
565 case SimdOp::I64x2Abs:
566 case SimdOp::F32x4Ceil:
567 case SimdOp::F32x4Floor:
568 case SimdOp::F32x4Trunc:
569 case SimdOp::F32x4Nearest:
570 case SimdOp::F64x2Ceil:
571 case SimdOp::F64x2Floor:
572 case SimdOp::F64x2Trunc:
573 case SimdOp::F64x2Nearest:
574 case SimdOp::F32x4DemoteF64x2Zero:
575 case SimdOp::F64x2PromoteLowF32x4:
576 case SimdOp::F64x2ConvertLowI32x4S:
577 case SimdOp::F64x2ConvertLowI32x4U:
578 case SimdOp::I32x4TruncSatF64x2SZero:
579 case SimdOp::I32x4TruncSatF64x2UZero:
580 case SimdOp::I16x8ExtaddPairwiseI8x16S:
581 case SimdOp::I16x8ExtaddPairwiseI8x16U:
582 case SimdOp::I32x4ExtaddPairwiseI16x8S:
583 case SimdOp::I32x4ExtaddPairwiseI16x8U:
584 case SimdOp::I32x4RelaxedTruncF32x4S:
585 case SimdOp::I32x4RelaxedTruncF32x4U:
586 case SimdOp::I32x4RelaxedTruncF64x2SZero:
587 case SimdOp::I32x4RelaxedTruncF64x2UZero:
588 WASM_SIMD_OP(OpKind::Unary);
589 case SimdOp::I8x16Shl:
590 case SimdOp::I8x16ShrS:
591 case SimdOp::I8x16ShrU:
592 case SimdOp::I16x8Shl:
593 case SimdOp::I16x8ShrS:
594 case SimdOp::I16x8ShrU:
595 case SimdOp::I32x4Shl:
596 case SimdOp::I32x4ShrS:
597 case SimdOp::I32x4ShrU:
598 case SimdOp::I64x2Shl:
599 case SimdOp::I64x2ShrS:
600 case SimdOp::I64x2ShrU:
601 WASM_SIMD_OP(OpKind::VectorShift);
602 case SimdOp::V128Bitselect:
603 WASM_SIMD_OP(OpKind::Ternary);
604 case SimdOp::I8x16Shuffle:
605 WASM_SIMD_OP(OpKind::VectorShuffle);
606 case SimdOp::V128Const:
607 WASM_SIMD_OP(OpKind::V128);
608 case SimdOp::V128Load:
609 case SimdOp::V128Load8Splat:
610 case SimdOp::V128Load16Splat:
611 case SimdOp::V128Load32Splat:
612 case SimdOp::V128Load64Splat:
613 case SimdOp::V128Load8x8S:
614 case SimdOp::V128Load8x8U:
615 case SimdOp::V128Load16x4S:
616 case SimdOp::V128Load16x4U:
617 case SimdOp::V128Load32x2S:
618 case SimdOp::V128Load32x2U:
619 case SimdOp::V128Load32Zero:
620 case SimdOp::V128Load64Zero:
621 WASM_SIMD_OP(OpKind::Load);
622 case SimdOp::V128Store:
623 WASM_SIMD_OP(OpKind::Store);
624 case SimdOp::V128Load8Lane:
625 case SimdOp::V128Load16Lane:
626 case SimdOp::V128Load32Lane:
627 case SimdOp::V128Load64Lane:
628 WASM_SIMD_OP(OpKind::LoadLane);
629 case SimdOp::V128Store8Lane:
630 case SimdOp::V128Store16Lane:
631 case SimdOp::V128Store32Lane:
632 case SimdOp::V128Store64Lane:
633 WASM_SIMD_OP(OpKind::StoreLane);
634 case SimdOp::F32x4RelaxedMadd:
635 case SimdOp::F32x4RelaxedNmadd:
636 case SimdOp::F64x2RelaxedMadd:
637 case SimdOp::F64x2RelaxedNmadd:
638 case SimdOp::I8x16RelaxedLaneSelect:
639 case SimdOp::I16x8RelaxedLaneSelect:
640 case SimdOp::I32x4RelaxedLaneSelect:
641 case SimdOp::I64x2RelaxedLaneSelect:
642 case SimdOp::I32x4DotI8x16I7x16AddS:
643 WASM_SIMD_OP(OpKind::Ternary);
645 break;
647 case Op::MiscPrefix: {
648 switch (MiscOp(op.b1)) {
649 case MiscOp::Limit:
650 // Reject Limit for MiscPrefix encoding
651 break;
652 case MiscOp::I32TruncSatF32S:
653 case MiscOp::I32TruncSatF32U:
654 case MiscOp::I32TruncSatF64S:
655 case MiscOp::I32TruncSatF64U:
656 case MiscOp::I64TruncSatF32S:
657 case MiscOp::I64TruncSatF32U:
658 case MiscOp::I64TruncSatF64S:
659 case MiscOp::I64TruncSatF64U:
660 return OpKind::Conversion;
661 case MiscOp::MemoryCopy:
662 case MiscOp::TableCopy:
663 return OpKind::MemOrTableCopy;
664 case MiscOp::DataDrop:
665 case MiscOp::ElemDrop:
666 return OpKind::DataOrElemDrop;
667 case MiscOp::MemoryFill:
668 return OpKind::MemFill;
669 case MiscOp::MemoryInit:
670 case MiscOp::TableInit:
671 return OpKind::MemOrTableInit;
672 case MiscOp::TableFill:
673 return OpKind::TableFill;
674 case MiscOp::MemoryDiscard:
675 return OpKind::MemDiscard;
676 case MiscOp::TableGrow:
677 return OpKind::TableGrow;
678 case MiscOp::TableSize:
679 return OpKind::TableSize;
681 break;
683 case Op::ThreadPrefix: {
684 switch (ThreadOp(op.b1)) {
685 case ThreadOp::Limit:
686 // Reject Limit for ThreadPrefix encoding
687 break;
688 case ThreadOp::Wake:
689 return OpKind::Wake;
690 case ThreadOp::I32Wait:
691 case ThreadOp::I64Wait:
692 return OpKind::Wait;
693 case ThreadOp::Fence:
694 return OpKind::Fence;
695 case ThreadOp::I32AtomicLoad:
696 case ThreadOp::I64AtomicLoad:
697 case ThreadOp::I32AtomicLoad8U:
698 case ThreadOp::I32AtomicLoad16U:
699 case ThreadOp::I64AtomicLoad8U:
700 case ThreadOp::I64AtomicLoad16U:
701 case ThreadOp::I64AtomicLoad32U:
702 return OpKind::AtomicLoad;
703 case ThreadOp::I32AtomicStore:
704 case ThreadOp::I64AtomicStore:
705 case ThreadOp::I32AtomicStore8U:
706 case ThreadOp::I32AtomicStore16U:
707 case ThreadOp::I64AtomicStore8U:
708 case ThreadOp::I64AtomicStore16U:
709 case ThreadOp::I64AtomicStore32U:
710 return OpKind::AtomicStore;
711 case ThreadOp::I32AtomicAdd:
712 case ThreadOp::I64AtomicAdd:
713 case ThreadOp::I32AtomicAdd8U:
714 case ThreadOp::I32AtomicAdd16U:
715 case ThreadOp::I64AtomicAdd8U:
716 case ThreadOp::I64AtomicAdd16U:
717 case ThreadOp::I64AtomicAdd32U:
718 case ThreadOp::I32AtomicSub:
719 case ThreadOp::I64AtomicSub:
720 case ThreadOp::I32AtomicSub8U:
721 case ThreadOp::I32AtomicSub16U:
722 case ThreadOp::I64AtomicSub8U:
723 case ThreadOp::I64AtomicSub16U:
724 case ThreadOp::I64AtomicSub32U:
725 case ThreadOp::I32AtomicAnd:
726 case ThreadOp::I64AtomicAnd:
727 case ThreadOp::I32AtomicAnd8U:
728 case ThreadOp::I32AtomicAnd16U:
729 case ThreadOp::I64AtomicAnd8U:
730 case ThreadOp::I64AtomicAnd16U:
731 case ThreadOp::I64AtomicAnd32U:
732 case ThreadOp::I32AtomicOr:
733 case ThreadOp::I64AtomicOr:
734 case ThreadOp::I32AtomicOr8U:
735 case ThreadOp::I32AtomicOr16U:
736 case ThreadOp::I64AtomicOr8U:
737 case ThreadOp::I64AtomicOr16U:
738 case ThreadOp::I64AtomicOr32U:
739 case ThreadOp::I32AtomicXor:
740 case ThreadOp::I64AtomicXor:
741 case ThreadOp::I32AtomicXor8U:
742 case ThreadOp::I32AtomicXor16U:
743 case ThreadOp::I64AtomicXor8U:
744 case ThreadOp::I64AtomicXor16U:
745 case ThreadOp::I64AtomicXor32U:
746 case ThreadOp::I32AtomicXchg:
747 case ThreadOp::I64AtomicXchg:
748 case ThreadOp::I32AtomicXchg8U:
749 case ThreadOp::I32AtomicXchg16U:
750 case ThreadOp::I64AtomicXchg8U:
751 case ThreadOp::I64AtomicXchg16U:
752 case ThreadOp::I64AtomicXchg32U:
753 return OpKind::AtomicBinOp;
754 case ThreadOp::I32AtomicCmpXchg:
755 case ThreadOp::I64AtomicCmpXchg:
756 case ThreadOp::I32AtomicCmpXchg8U:
757 case ThreadOp::I32AtomicCmpXchg16U:
758 case ThreadOp::I64AtomicCmpXchg8U:
759 case ThreadOp::I64AtomicCmpXchg16U:
760 case ThreadOp::I64AtomicCmpXchg32U:
761 return OpKind::AtomicCompareExchange;
762 default:
763 break;
765 break;
767 case Op::MozPrefix: {
768 switch (MozOp(op.b1)) {
769 case MozOp::Limit:
770 // Reject Limit for the MozPrefix encoding
771 break;
772 case MozOp::TeeGlobal:
773 return OpKind::TeeGlobal;
774 case MozOp::I32BitNot:
775 case MozOp::I32Abs:
776 case MozOp::I32Neg:
777 return OpKind::Unary;
778 case MozOp::I32Min:
779 case MozOp::I32Max:
780 case MozOp::F64Mod:
781 case MozOp::F64Pow:
782 case MozOp::F64Atan2:
783 return OpKind::Binary;
784 case MozOp::F64SinNative:
785 case MozOp::F64SinFdlibm:
786 case MozOp::F64CosNative:
787 case MozOp::F64CosFdlibm:
788 case MozOp::F64TanNative:
789 case MozOp::F64TanFdlibm:
790 case MozOp::F64Asin:
791 case MozOp::F64Acos:
792 case MozOp::F64Atan:
793 case MozOp::F64Exp:
794 case MozOp::F64Log:
795 return OpKind::Unary;
796 case MozOp::I32TeeStore8:
797 case MozOp::I32TeeStore16:
798 case MozOp::I64TeeStore8:
799 case MozOp::I64TeeStore16:
800 case MozOp::I64TeeStore32:
801 case MozOp::I32TeeStore:
802 case MozOp::I64TeeStore:
803 case MozOp::F32TeeStore:
804 case MozOp::F64TeeStore:
805 case MozOp::F32TeeStoreF64:
806 case MozOp::F64TeeStoreF32:
807 return OpKind::TeeStore;
808 case MozOp::OldCallDirect:
809 return OpKind::OldCallDirect;
810 case MozOp::OldCallIndirect:
811 return OpKind::OldCallIndirect;
812 case MozOp::CallBuiltinModuleFunc:
813 return OpKind::CallBuiltinModuleFunc;
815 break;
817 case Op::FirstPrefix:
818 break;
820 MOZ_CRASH("unimplemented opcode");
823 # undef WASM_GC_OP
824 # undef WASM_REF_OP
826 #endif // DEBUG
828 bool UnsetLocalsState::init(const ValTypeVector& locals, size_t numParams) {
829 MOZ_ASSERT(setLocalsStack_.empty());
831 // Find the first and total count of non-defaultable locals.
832 size_t firstNonDefaultable = UINT32_MAX;
833 size_t countNonDefaultable = 0;
834 for (size_t i = numParams; i < locals.length(); i++) {
835 if (!locals[i].isDefaultable()) {
836 firstNonDefaultable = std::min(i, firstNonDefaultable);
837 countNonDefaultable++;
840 firstNonDefaultLocal_ = firstNonDefaultable;
841 if (countNonDefaultable == 0) {
842 // No locals to track, saving CPU cycles.
843 MOZ_ASSERT(firstNonDefaultable == UINT32_MAX);
844 return true;
847 // setLocalsStack_ cannot be deeper than amount of non-defaultable locals.
848 if (!setLocalsStack_.reserve(countNonDefaultable)) {
849 return false;
852 // Allocate a bitmap for locals starting at the first non-defaultable local.
853 size_t bitmapSize =
854 ((locals.length() - firstNonDefaultable) + (WordBits - 1)) / WordBits;
855 if (!unsetLocals_.resize(bitmapSize)) {
856 return false;
858 memset(unsetLocals_.begin(), 0, bitmapSize * WordSize);
859 for (size_t i = firstNonDefaultable; i < locals.length(); i++) {
860 if (!locals[i].isDefaultable()) {
861 size_t localUnsetIndex = i - firstNonDefaultable;
862 unsetLocals_[localUnsetIndex / WordBits] |=
863 1 << (localUnsetIndex % WordBits);
866 return true;