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 : *
4 : * Copyright 2015 Mozilla Foundation
5 : *
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
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
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.
17 : */
18 :
19 : #include "wasm/WasmBinaryIterator.h"
20 :
21 : using namespace js;
22 : using namespace js::jit;
23 : using namespace js::wasm;
24 :
25 : #ifdef DEBUG
26 : OpKind
27 0 : wasm::Classify(OpBytes op)
28 : {
29 0 : switch (Op(op.b0)) {
30 : case Op::Block:
31 0 : return OpKind::Block;
32 : case Op::Loop:
33 0 : return OpKind::Loop;
34 : case Op::Unreachable:
35 0 : return OpKind::Unreachable;
36 : case Op::Drop:
37 0 : return OpKind::Drop;
38 : case Op::I32Const:
39 0 : return OpKind::I32;
40 : case Op::I64Const:
41 0 : return OpKind::I64;
42 : case Op::F32Const:
43 0 : return OpKind::F32;
44 : case Op::F64Const:
45 0 : return OpKind::F64;
46 : case Op::Br:
47 0 : return OpKind::Br;
48 : case Op::BrIf:
49 0 : return OpKind::BrIf;
50 : case Op::BrTable:
51 0 : return OpKind::BrTable;
52 : case Op::Nop:
53 0 : return OpKind::Nop;
54 : case Op::I32Clz:
55 : case Op::I32Ctz:
56 : case Op::I32Popcnt:
57 : case Op::I64Clz:
58 : case Op::I64Ctz:
59 : case Op::I64Popcnt:
60 : case Op::F32Abs:
61 : case Op::F32Neg:
62 : case Op::F32Ceil:
63 : case Op::F32Floor:
64 : case Op::F32Trunc:
65 : case Op::F32Nearest:
66 : case Op::F32Sqrt:
67 : case Op::F64Abs:
68 : case Op::F64Neg:
69 : case Op::F64Ceil:
70 : case Op::F64Floor:
71 : case Op::F64Trunc:
72 : case Op::F64Nearest:
73 : case Op::F64Sqrt:
74 0 : return OpKind::Unary;
75 : case Op::I32Add:
76 : case Op::I32Sub:
77 : case Op::I32Mul:
78 : case Op::I32DivS:
79 : case Op::I32DivU:
80 : case Op::I32RemS:
81 : case Op::I32RemU:
82 : case Op::I32And:
83 : case Op::I32Or:
84 : case Op::I32Xor:
85 : case Op::I32Shl:
86 : case Op::I32ShrS:
87 : case Op::I32ShrU:
88 : case Op::I32Rotl:
89 : case Op::I32Rotr:
90 : case Op::I64Add:
91 : case Op::I64Sub:
92 : case Op::I64Mul:
93 : case Op::I64DivS:
94 : case Op::I64DivU:
95 : case Op::I64RemS:
96 : case Op::I64RemU:
97 : case Op::I64And:
98 : case Op::I64Or:
99 : case Op::I64Xor:
100 : case Op::I64Shl:
101 : case Op::I64ShrS:
102 : case Op::I64ShrU:
103 : case Op::I64Rotl:
104 : case Op::I64Rotr:
105 : case Op::F32Add:
106 : case Op::F32Sub:
107 : case Op::F32Mul:
108 : case Op::F32Div:
109 : case Op::F32Min:
110 : case Op::F32Max:
111 : case Op::F32CopySign:
112 : case Op::F64Add:
113 : case Op::F64Sub:
114 : case Op::F64Mul:
115 : case Op::F64Div:
116 : case Op::F64Min:
117 : case Op::F64Max:
118 : case Op::F64CopySign:
119 0 : return OpKind::Binary;
120 : case Op::I32Eq:
121 : case Op::I32Ne:
122 : case Op::I32LtS:
123 : case Op::I32LtU:
124 : case Op::I32LeS:
125 : case Op::I32LeU:
126 : case Op::I32GtS:
127 : case Op::I32GtU:
128 : case Op::I32GeS:
129 : case Op::I32GeU:
130 : case Op::I64Eq:
131 : case Op::I64Ne:
132 : case Op::I64LtS:
133 : case Op::I64LtU:
134 : case Op::I64LeS:
135 : case Op::I64LeU:
136 : case Op::I64GtS:
137 : case Op::I64GtU:
138 : case Op::I64GeS:
139 : case Op::I64GeU:
140 : case Op::F32Eq:
141 : case Op::F32Ne:
142 : case Op::F32Lt:
143 : case Op::F32Le:
144 : case Op::F32Gt:
145 : case Op::F32Ge:
146 : case Op::F64Eq:
147 : case Op::F64Ne:
148 : case Op::F64Lt:
149 : case Op::F64Le:
150 : case Op::F64Gt:
151 : case Op::F64Ge:
152 0 : return OpKind::Comparison;
153 : case Op::I32Eqz:
154 : case Op::I32WrapI64:
155 : case Op::I32TruncSF32:
156 : case Op::I32TruncUF32:
157 : case Op::I32ReinterpretF32:
158 : case Op::I32TruncSF64:
159 : case Op::I32TruncUF64:
160 : case Op::I64ExtendSI32:
161 : case Op::I64ExtendUI32:
162 : case Op::I64TruncSF32:
163 : case Op::I64TruncUF32:
164 : case Op::I64TruncSF64:
165 : case Op::I64TruncUF64:
166 : case Op::I64ReinterpretF64:
167 : case Op::I64Eqz:
168 : case Op::F32ConvertSI32:
169 : case Op::F32ConvertUI32:
170 : case Op::F32ReinterpretI32:
171 : case Op::F32ConvertSI64:
172 : case Op::F32ConvertUI64:
173 : case Op::F32DemoteF64:
174 : case Op::F64ConvertSI32:
175 : case Op::F64ConvertUI32:
176 : case Op::F64ConvertSI64:
177 : case Op::F64ConvertUI64:
178 : case Op::F64ReinterpretI64:
179 : case Op::F64PromoteF32:
180 0 : return OpKind::Conversion;
181 : case Op::I32Load8S:
182 : case Op::I32Load8U:
183 : case Op::I32Load16S:
184 : case Op::I32Load16U:
185 : case Op::I64Load8S:
186 : case Op::I64Load8U:
187 : case Op::I64Load16S:
188 : case Op::I64Load16U:
189 : case Op::I64Load32S:
190 : case Op::I64Load32U:
191 : case Op::I32Load:
192 : case Op::I64Load:
193 : case Op::F32Load:
194 : case Op::F64Load:
195 0 : return OpKind::Load;
196 : case Op::I32Store8:
197 : case Op::I32Store16:
198 : case Op::I64Store8:
199 : case Op::I64Store16:
200 : case Op::I64Store32:
201 : case Op::I32Store:
202 : case Op::I64Store:
203 : case Op::F32Store:
204 : case Op::F64Store:
205 0 : return OpKind::Store;
206 : case Op::Select:
207 0 : return OpKind::Select;
208 : case Op::GetLocal:
209 0 : return OpKind::GetLocal;
210 : case Op::SetLocal:
211 0 : return OpKind::SetLocal;
212 : case Op::TeeLocal:
213 0 : return OpKind::TeeLocal;
214 : case Op::GetGlobal:
215 0 : return OpKind::GetGlobal;
216 : case Op::SetGlobal:
217 0 : return OpKind::SetGlobal;
218 : case Op::Call:
219 0 : return OpKind::Call;
220 : case Op::CallIndirect:
221 0 : return OpKind::CallIndirect;
222 : case Op::Return:
223 : case Op::Limit:
224 : // Accept Limit, for use in decoding the end of a function after the body.
225 0 : return OpKind::Return;
226 : case Op::If:
227 0 : return OpKind::If;
228 : case Op::Else:
229 0 : return OpKind::Else;
230 : case Op::End:
231 0 : return OpKind::End;
232 : case Op::CurrentMemory:
233 0 : return OpKind::CurrentMemory;
234 : case Op::GrowMemory:
235 0 : return OpKind::GrowMemory;
236 : case Op::AtomicPrefix:
237 0 : break;
238 : case Op::MozPrefix: {
239 0 : switch (MozOp(op.b1)) {
240 : case MozOp::Limit:
241 : // Reject Limit for the MozPrefix encoding
242 0 : break;
243 : case MozOp::TeeGlobal:
244 0 : return OpKind::TeeGlobal;
245 : case MozOp::I8x16Const:
246 0 : return OpKind::I8x16;
247 : case MozOp::I16x8Const:
248 0 : return OpKind::I16x8;
249 : case MozOp::I32x4Const:
250 0 : return OpKind::I32x4;
251 : case MozOp::B8x16Const:
252 0 : return OpKind::B8x16;
253 : case MozOp::B16x8Const:
254 0 : return OpKind::B16x8;
255 : case MozOp::B32x4Const:
256 0 : return OpKind::B32x4;
257 : case MozOp::F32x4Const:
258 0 : return OpKind::F32x4;
259 : case MozOp::I32BitNot:
260 : case MozOp::I32Abs:
261 : case MozOp::I32Neg:
262 : case MozOp::I8x16neg:
263 : case MozOp::I8x16not:
264 : case MozOp::I16x8neg:
265 : case MozOp::I16x8not:
266 : case MozOp::I32x4neg:
267 : case MozOp::I32x4not:
268 : case MozOp::F32x4neg:
269 : case MozOp::F32x4sqrt:
270 : case MozOp::F32x4abs:
271 : case MozOp::F32x4reciprocalApproximation:
272 : case MozOp::F32x4reciprocalSqrtApproximation:
273 : case MozOp::B8x16not:
274 : case MozOp::B16x8not:
275 : case MozOp::B32x4not:
276 0 : return OpKind::Unary;
277 : case MozOp::I32Min:
278 : case MozOp::I32Max:
279 : case MozOp::F64Mod:
280 : case MozOp::F64Pow:
281 : case MozOp::F64Atan2:
282 : case MozOp::I8x16add:
283 : case MozOp::I8x16sub:
284 : case MozOp::I8x16mul:
285 : case MozOp::I8x16addSaturate:
286 : case MozOp::I8x16subSaturate:
287 : case MozOp::I8x16addSaturateU:
288 : case MozOp::I8x16subSaturateU:
289 : case MozOp::I8x16and:
290 : case MozOp::I8x16or:
291 : case MozOp::I8x16xor:
292 : case MozOp::I16x8add:
293 : case MozOp::I16x8sub:
294 : case MozOp::I16x8mul:
295 : case MozOp::I16x8addSaturate:
296 : case MozOp::I16x8subSaturate:
297 : case MozOp::I16x8addSaturateU:
298 : case MozOp::I16x8subSaturateU:
299 : case MozOp::I16x8and:
300 : case MozOp::I16x8or:
301 : case MozOp::I16x8xor:
302 : case MozOp::I32x4add:
303 : case MozOp::I32x4sub:
304 : case MozOp::I32x4mul:
305 : case MozOp::I32x4and:
306 : case MozOp::I32x4or:
307 : case MozOp::I32x4xor:
308 : case MozOp::F32x4add:
309 : case MozOp::F32x4sub:
310 : case MozOp::F32x4mul:
311 : case MozOp::F32x4div:
312 : case MozOp::F32x4min:
313 : case MozOp::F32x4max:
314 : case MozOp::F32x4minNum:
315 : case MozOp::F32x4maxNum:
316 : case MozOp::B8x16and:
317 : case MozOp::B8x16or:
318 : case MozOp::B8x16xor:
319 : case MozOp::B16x8and:
320 : case MozOp::B16x8or:
321 : case MozOp::B16x8xor:
322 : case MozOp::B32x4and:
323 : case MozOp::B32x4or:
324 : case MozOp::B32x4xor:
325 0 : return OpKind::Binary;
326 : case MozOp::F64Sin:
327 : case MozOp::F64Cos:
328 : case MozOp::F64Tan:
329 : case MozOp::F64Asin:
330 : case MozOp::F64Acos:
331 : case MozOp::F64Atan:
332 : case MozOp::F64Exp:
333 : case MozOp::F64Log:
334 0 : return OpKind::Unary;
335 : case MozOp::I32TeeStore8:
336 : case MozOp::I32TeeStore16:
337 : case MozOp::I64TeeStore8:
338 : case MozOp::I64TeeStore16:
339 : case MozOp::I64TeeStore32:
340 : case MozOp::I32TeeStore:
341 : case MozOp::I64TeeStore:
342 : case MozOp::F32TeeStore:
343 : case MozOp::F64TeeStore:
344 : case MozOp::F32TeeStoreF64:
345 : case MozOp::F64TeeStoreF32:
346 0 : return OpKind::TeeStore;
347 : case MozOp::I32x4fromFloat32x4:
348 : case MozOp::I32x4fromFloat32x4U:
349 : case MozOp::F32x4fromInt32x4:
350 : case MozOp::F32x4fromUint32x4:
351 : case MozOp::I32x4fromFloat32x4Bits:
352 : case MozOp::I32x4fromInt8x16Bits:
353 : case MozOp::I32x4fromInt16x8Bits:
354 : case MozOp::I16x8fromInt8x16Bits:
355 : case MozOp::I16x8fromInt32x4Bits:
356 : case MozOp::I16x8fromFloat32x4Bits:
357 : case MozOp::I8x16fromInt16x8Bits:
358 : case MozOp::I8x16fromInt32x4Bits:
359 : case MozOp::I8x16fromFloat32x4Bits:
360 : case MozOp::F32x4fromInt8x16Bits:
361 : case MozOp::F32x4fromInt16x8Bits:
362 : case MozOp::F32x4fromInt32x4Bits:
363 0 : return OpKind::Conversion;
364 : case MozOp::I8x16load:
365 : case MozOp::I16x8load:
366 : case MozOp::I32x4load:
367 : case MozOp::I32x4load1:
368 : case MozOp::I32x4load2:
369 : case MozOp::I32x4load3:
370 : case MozOp::F32x4load:
371 : case MozOp::F32x4load1:
372 : case MozOp::F32x4load2:
373 : case MozOp::F32x4load3:
374 0 : return OpKind::Load;
375 : case MozOp::I8x16store:
376 : case MozOp::I16x8store:
377 : case MozOp::I32x4store:
378 : case MozOp::I32x4store1:
379 : case MozOp::I32x4store2:
380 : case MozOp::I32x4store3:
381 : case MozOp::F32x4store:
382 : case MozOp::F32x4store1:
383 : case MozOp::F32x4store2:
384 : case MozOp::F32x4store3:
385 0 : return OpKind::TeeStore;
386 : case MozOp::OldCallIndirect:
387 0 : return OpKind::OldCallIndirect;
388 : case MozOp::I32AtomicsLoad:
389 0 : return OpKind::AtomicLoad;
390 : case MozOp::I32AtomicsStore:
391 0 : return OpKind::AtomicStore;
392 : case MozOp::I32AtomicsBinOp:
393 0 : return OpKind::AtomicBinOp;
394 : case MozOp::I32AtomicsCompareExchange:
395 0 : return OpKind::AtomicCompareExchange;
396 : case MozOp::I32AtomicsExchange:
397 0 : return OpKind::AtomicExchange;
398 : case MozOp::I8x16extractLane:
399 : case MozOp::I8x16extractLaneU:
400 : case MozOp::I16x8extractLane:
401 : case MozOp::I16x8extractLaneU:
402 : case MozOp::I32x4extractLane:
403 : case MozOp::F32x4extractLane:
404 : case MozOp::B8x16extractLane:
405 : case MozOp::B16x8extractLane:
406 : case MozOp::B32x4extractLane:
407 0 : return OpKind::ExtractLane;
408 : case MozOp::I8x16replaceLane:
409 : case MozOp::I16x8replaceLane:
410 : case MozOp::I32x4replaceLane:
411 : case MozOp::F32x4replaceLane:
412 : case MozOp::B8x16replaceLane:
413 : case MozOp::B16x8replaceLane:
414 : case MozOp::B32x4replaceLane:
415 0 : return OpKind::ReplaceLane;
416 : case MozOp::I8x16swizzle:
417 : case MozOp::I16x8swizzle:
418 : case MozOp::I32x4swizzle:
419 : case MozOp::F32x4swizzle:
420 0 : return OpKind::Swizzle;
421 : case MozOp::I8x16shuffle:
422 : case MozOp::I16x8shuffle:
423 : case MozOp::I32x4shuffle:
424 : case MozOp::F32x4shuffle:
425 0 : return OpKind::Shuffle;
426 : case MozOp::I16x8check:
427 : case MozOp::I16x8splat:
428 : case MozOp::I32x4check:
429 : case MozOp::I32x4splat:
430 : case MozOp::I8x16check:
431 : case MozOp::I8x16splat:
432 : case MozOp::F32x4check:
433 : case MozOp::F32x4splat:
434 : case MozOp::B16x8check:
435 : case MozOp::B16x8splat:
436 : case MozOp::B32x4check:
437 : case MozOp::B32x4splat:
438 : case MozOp::B8x16check:
439 : case MozOp::B8x16splat:
440 0 : return OpKind::Splat;
441 : case MozOp::I8x16select:
442 : case MozOp::I16x8select:
443 : case MozOp::I32x4select:
444 : case MozOp::F32x4select:
445 0 : return OpKind::SimdSelect;
446 : case MozOp::I8x16Constructor:
447 : case MozOp::I16x8Constructor:
448 : case MozOp::I32x4Constructor:
449 : case MozOp::F32x4Constructor:
450 : case MozOp::B8x16Constructor:
451 : case MozOp::B16x8Constructor:
452 : case MozOp::B32x4Constructor:
453 0 : return OpKind::SimdCtor;
454 : case MozOp::B8x16allTrue:
455 : case MozOp::B8x16anyTrue:
456 : case MozOp::B16x8allTrue:
457 : case MozOp::B16x8anyTrue:
458 : case MozOp::B32x4allTrue:
459 : case MozOp::B32x4anyTrue:
460 0 : return OpKind::SimdBooleanReduction;
461 : case MozOp::I8x16shiftLeftByScalar:
462 : case MozOp::I8x16shiftRightByScalar:
463 : case MozOp::I8x16shiftRightByScalarU:
464 : case MozOp::I16x8shiftLeftByScalar:
465 : case MozOp::I16x8shiftRightByScalar:
466 : case MozOp::I16x8shiftRightByScalarU:
467 : case MozOp::I32x4shiftLeftByScalar:
468 : case MozOp::I32x4shiftRightByScalar:
469 : case MozOp::I32x4shiftRightByScalarU:
470 0 : return OpKind::SimdShiftByScalar;
471 : case MozOp::I8x16equal:
472 : case MozOp::I8x16notEqual:
473 : case MozOp::I8x16greaterThan:
474 : case MozOp::I8x16greaterThanOrEqual:
475 : case MozOp::I8x16lessThan:
476 : case MozOp::I8x16lessThanOrEqual:
477 : case MozOp::I8x16greaterThanU:
478 : case MozOp::I8x16greaterThanOrEqualU:
479 : case MozOp::I8x16lessThanU:
480 : case MozOp::I8x16lessThanOrEqualU:
481 : case MozOp::I16x8equal:
482 : case MozOp::I16x8notEqual:
483 : case MozOp::I16x8greaterThan:
484 : case MozOp::I16x8greaterThanOrEqual:
485 : case MozOp::I16x8lessThan:
486 : case MozOp::I16x8lessThanOrEqual:
487 : case MozOp::I16x8greaterThanU:
488 : case MozOp::I16x8greaterThanOrEqualU:
489 : case MozOp::I16x8lessThanU:
490 : case MozOp::I16x8lessThanOrEqualU:
491 : case MozOp::I32x4equal:
492 : case MozOp::I32x4notEqual:
493 : case MozOp::I32x4greaterThan:
494 : case MozOp::I32x4greaterThanOrEqual:
495 : case MozOp::I32x4lessThan:
496 : case MozOp::I32x4lessThanOrEqual:
497 : case MozOp::I32x4greaterThanU:
498 : case MozOp::I32x4greaterThanOrEqualU:
499 : case MozOp::I32x4lessThanU:
500 : case MozOp::I32x4lessThanOrEqualU:
501 : case MozOp::F32x4equal:
502 : case MozOp::F32x4notEqual:
503 : case MozOp::F32x4greaterThan:
504 : case MozOp::F32x4greaterThanOrEqual:
505 : case MozOp::F32x4lessThan:
506 : case MozOp::F32x4lessThanOrEqual:
507 0 : return OpKind::SimdComparison;
508 : }
509 0 : break;
510 : }
511 : }
512 0 : MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("unimplemented opcode");
513 : }
514 : #endif
|