Source code

Revision control

Other Tools

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:
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
*
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/WasmOpIter.h"
20
21
using namespace js;
22
using namespace js::jit;
23
using namespace js::wasm;
24
25
#ifdef ENABLE_WASM_GC
26
# ifndef ENABLE_WASM_REFTYPES
27
# error "GC types require the reftypes feature"
28
# endif
29
#endif
30
31
#ifdef DEBUG
32
33
# ifdef ENABLE_WASM_REFTYPES
34
# define WASM_REF_OP(code) return code
35
# else
36
# define WASM_REF_OP(code) break
37
# endif
38
# ifdef ENABLE_WASM_GC
39
# define WASM_GC_OP(code) return code
40
# else
41
# define WASM_GC_OP(code) break
42
# endif
43
44
OpKind wasm::Classify(OpBytes op) {
45
switch (Op(op.b0)) {
46
case Op::Block:
47
return OpKind::Block;
48
case Op::Loop:
49
return OpKind::Loop;
50
case Op::Unreachable:
51
return OpKind::Unreachable;
52
case Op::Drop:
53
return OpKind::Drop;
54
case Op::I32Const:
55
return OpKind::I32;
56
case Op::I64Const:
57
return OpKind::I64;
58
case Op::F32Const:
59
return OpKind::F32;
60
case Op::F64Const:
61
return OpKind::F64;
62
case Op::Br:
63
return OpKind::Br;
64
case Op::BrIf:
65
return OpKind::BrIf;
66
case Op::BrTable:
67
return OpKind::BrTable;
68
case Op::Nop:
69
return OpKind::Nop;
70
case Op::I32Clz:
71
case Op::I32Ctz:
72
case Op::I32Popcnt:
73
case Op::I64Clz:
74
case Op::I64Ctz:
75
case Op::I64Popcnt:
76
case Op::F32Abs:
77
case Op::F32Neg:
78
case Op::F32Ceil:
79
case Op::F32Floor:
80
case Op::F32Trunc:
81
case Op::F32Nearest:
82
case Op::F32Sqrt:
83
case Op::F64Abs:
84
case Op::F64Neg:
85
case Op::F64Ceil:
86
case Op::F64Floor:
87
case Op::F64Trunc:
88
case Op::F64Nearest:
89
case Op::F64Sqrt:
90
return OpKind::Unary;
91
case Op::I32Add:
92
case Op::I32Sub:
93
case Op::I32Mul:
94
case Op::I32DivS:
95
case Op::I32DivU:
96
case Op::I32RemS:
97
case Op::I32RemU:
98
case Op::I32And:
99
case Op::I32Or:
100
case Op::I32Xor:
101
case Op::I32Shl:
102
case Op::I32ShrS:
103
case Op::I32ShrU:
104
case Op::I32Rotl:
105
case Op::I32Rotr:
106
case Op::I64Add:
107
case Op::I64Sub:
108
case Op::I64Mul:
109
case Op::I64DivS:
110
case Op::I64DivU:
111
case Op::I64RemS:
112
case Op::I64RemU:
113
case Op::I64And:
114
case Op::I64Or:
115
case Op::I64Xor:
116
case Op::I64Shl:
117
case Op::I64ShrS:
118
case Op::I64ShrU:
119
case Op::I64Rotl:
120
case Op::I64Rotr:
121
case Op::F32Add:
122
case Op::F32Sub:
123
case Op::F32Mul:
124
case Op::F32Div:
125
case Op::F32Min:
126
case Op::F32Max:
127
case Op::F32CopySign:
128
case Op::F64Add:
129
case Op::F64Sub:
130
case Op::F64Mul:
131
case Op::F64Div:
132
case Op::F64Min:
133
case Op::F64Max:
134
case Op::F64CopySign:
135
return OpKind::Binary;
136
case Op::I32Eq:
137
case Op::I32Ne:
138
case Op::I32LtS:
139
case Op::I32LtU:
140
case Op::I32LeS:
141
case Op::I32LeU:
142
case Op::I32GtS:
143
case Op::I32GtU:
144
case Op::I32GeS:
145
case Op::I32GeU:
146
case Op::I64Eq:
147
case Op::I64Ne:
148
case Op::I64LtS:
149
case Op::I64LtU:
150
case Op::I64LeS:
151
case Op::I64LeU:
152
case Op::I64GtS:
153
case Op::I64GtU:
154
case Op::I64GeS:
155
case Op::I64GeU:
156
case Op::F32Eq:
157
case Op::F32Ne:
158
case Op::F32Lt:
159
case Op::F32Le:
160
case Op::F32Gt:
161
case Op::F32Ge:
162
case Op::F64Eq:
163
case Op::F64Ne:
164
case Op::F64Lt:
165
case Op::F64Le:
166
case Op::F64Gt:
167
case Op::F64Ge:
168
return OpKind::Comparison;
169
case Op::I32Eqz:
170
case Op::I32WrapI64:
171
case Op::I32TruncSF32:
172
case Op::I32TruncUF32:
173
case Op::I32ReinterpretF32:
174
case Op::I32TruncSF64:
175
case Op::I32TruncUF64:
176
case Op::I64ExtendSI32:
177
case Op::I64ExtendUI32:
178
case Op::I64TruncSF32:
179
case Op::I64TruncUF32:
180
case Op::I64TruncSF64:
181
case Op::I64TruncUF64:
182
case Op::I64ReinterpretF64:
183
case Op::I64Eqz:
184
case Op::F32ConvertSI32:
185
case Op::F32ConvertUI32:
186
case Op::F32ReinterpretI32:
187
case Op::F32ConvertSI64:
188
case Op::F32ConvertUI64:
189
case Op::F32DemoteF64:
190
case Op::F64ConvertSI32:
191
case Op::F64ConvertUI32:
192
case Op::F64ConvertSI64:
193
case Op::F64ConvertUI64:
194
case Op::F64ReinterpretI64:
195
case Op::F64PromoteF32:
196
case Op::I32Extend8S:
197
case Op::I32Extend16S:
198
case Op::I64Extend8S:
199
case Op::I64Extend16S:
200
case Op::I64Extend32S:
201
return OpKind::Conversion;
202
case Op::I32Load8S:
203
case Op::I32Load8U:
204
case Op::I32Load16S:
205
case Op::I32Load16U:
206
case Op::I64Load8S:
207
case Op::I64Load8U:
208
case Op::I64Load16S:
209
case Op::I64Load16U:
210
case Op::I64Load32S:
211
case Op::I64Load32U:
212
case Op::I32Load:
213
case Op::I64Load:
214
case Op::F32Load:
215
case Op::F64Load:
216
return OpKind::Load;
217
case Op::I32Store8:
218
case Op::I32Store16:
219
case Op::I64Store8:
220
case Op::I64Store16:
221
case Op::I64Store32:
222
case Op::I32Store:
223
case Op::I64Store:
224
case Op::F32Store:
225
case Op::F64Store:
226
return OpKind::Store;
227
case Op::SelectNumeric:
228
case Op::SelectTyped:
229
return OpKind::Select;
230
case Op::GetLocal:
231
return OpKind::GetLocal;
232
case Op::SetLocal:
233
return OpKind::SetLocal;
234
case Op::TeeLocal:
235
return OpKind::TeeLocal;
236
case Op::GetGlobal:
237
return OpKind::GetGlobal;
238
case Op::SetGlobal:
239
return OpKind::SetGlobal;
240
case Op::TableGet:
241
WASM_REF_OP(OpKind::TableGet);
242
case Op::TableSet:
243
WASM_REF_OP(OpKind::TableSet);
244
case Op::Call:
245
return OpKind::Call;
246
case Op::CallIndirect:
247
return OpKind::CallIndirect;
248
case Op::Return:
249
case Op::Limit:
250
// Accept Limit, for use in decoding the end of a function after the body.
251
return OpKind::Return;
252
case Op::If:
253
return OpKind::If;
254
case Op::Else:
255
return OpKind::Else;
256
case Op::End:
257
return OpKind::End;
258
case Op::MemorySize:
259
return OpKind::MemorySize;
260
case Op::MemoryGrow:
261
return OpKind::MemoryGrow;
262
case Op::RefNull:
263
WASM_REF_OP(OpKind::RefNull);
264
case Op::RefIsNull:
265
WASM_REF_OP(OpKind::Conversion);
266
case Op::RefFunc:
267
WASM_REF_OP(OpKind::RefFunc);
268
case Op::RefEq:
269
WASM_GC_OP(OpKind::Comparison);
270
case Op::MiscPrefix: {
271
switch (MiscOp(op.b1)) {
272
case MiscOp::Limit:
273
// Reject Limit for MiscPrefix encoding
274
break;
275
case MiscOp::I32TruncSSatF32:
276
case MiscOp::I32TruncUSatF32:
277
case MiscOp::I32TruncSSatF64:
278
case MiscOp::I32TruncUSatF64:
279
case MiscOp::I64TruncSSatF32:
280
case MiscOp::I64TruncUSatF32:
281
case MiscOp::I64TruncSSatF64:
282
case MiscOp::I64TruncUSatF64:
283
return OpKind::Conversion;
284
case MiscOp::MemCopy:
285
case MiscOp::TableCopy:
286
return OpKind::MemOrTableCopy;
287
case MiscOp::DataDrop:
288
case MiscOp::ElemDrop:
289
return OpKind::DataOrElemDrop;
290
case MiscOp::MemFill:
291
return OpKind::MemFill;
292
case MiscOp::MemInit:
293
case MiscOp::TableInit:
294
return OpKind::MemOrTableInit;
295
case MiscOp::TableFill:
296
WASM_REF_OP(OpKind::TableFill);
297
case MiscOp::TableGrow:
298
WASM_REF_OP(OpKind::TableGrow);
299
case MiscOp::TableSize:
300
WASM_REF_OP(OpKind::TableSize);
301
case MiscOp::StructNew:
302
WASM_GC_OP(OpKind::StructNew);
303
case MiscOp::StructGet:
304
WASM_GC_OP(OpKind::StructGet);
305
case MiscOp::StructSet:
306
WASM_GC_OP(OpKind::StructSet);
307
case MiscOp::StructNarrow:
308
WASM_GC_OP(OpKind::StructNarrow);
309
}
310
break;
311
}
312
case Op::ThreadPrefix: {
313
switch (ThreadOp(op.b1)) {
314
case ThreadOp::Limit:
315
// Reject Limit for ThreadPrefix encoding
316
break;
317
case ThreadOp::Wake:
318
return OpKind::Wake;
319
case ThreadOp::I32Wait:
320
case ThreadOp::I64Wait:
321
return OpKind::Wait;
322
case ThreadOp::Fence:
323
return OpKind::Fence;
324
case ThreadOp::I32AtomicLoad:
325
case ThreadOp::I64AtomicLoad:
326
case ThreadOp::I32AtomicLoad8U:
327
case ThreadOp::I32AtomicLoad16U:
328
case ThreadOp::I64AtomicLoad8U:
329
case ThreadOp::I64AtomicLoad16U:
330
case ThreadOp::I64AtomicLoad32U:
331
return OpKind::AtomicLoad;
332
case ThreadOp::I32AtomicStore:
333
case ThreadOp::I64AtomicStore:
334
case ThreadOp::I32AtomicStore8U:
335
case ThreadOp::I32AtomicStore16U:
336
case ThreadOp::I64AtomicStore8U:
337
case ThreadOp::I64AtomicStore16U:
338
case ThreadOp::I64AtomicStore32U:
339
return OpKind::AtomicStore;
340
case ThreadOp::I32AtomicAdd:
341
case ThreadOp::I64AtomicAdd:
342
case ThreadOp::I32AtomicAdd8U:
343
case ThreadOp::I32AtomicAdd16U:
344
case ThreadOp::I64AtomicAdd8U:
345
case ThreadOp::I64AtomicAdd16U:
346
case ThreadOp::I64AtomicAdd32U:
347
case ThreadOp::I32AtomicSub:
348
case ThreadOp::I64AtomicSub:
349
case ThreadOp::I32AtomicSub8U:
350
case ThreadOp::I32AtomicSub16U:
351
case ThreadOp::I64AtomicSub8U:
352
case ThreadOp::I64AtomicSub16U:
353
case ThreadOp::I64AtomicSub32U:
354
case ThreadOp::I32AtomicAnd:
355
case ThreadOp::I64AtomicAnd:
356
case ThreadOp::I32AtomicAnd8U:
357
case ThreadOp::I32AtomicAnd16U:
358
case ThreadOp::I64AtomicAnd8U:
359
case ThreadOp::I64AtomicAnd16U:
360
case ThreadOp::I64AtomicAnd32U:
361
case ThreadOp::I32AtomicOr:
362
case ThreadOp::I64AtomicOr:
363
case ThreadOp::I32AtomicOr8U:
364
case ThreadOp::I32AtomicOr16U:
365
case ThreadOp::I64AtomicOr8U:
366
case ThreadOp::I64AtomicOr16U:
367
case ThreadOp::I64AtomicOr32U:
368
case ThreadOp::I32AtomicXor:
369
case ThreadOp::I64AtomicXor:
370
case ThreadOp::I32AtomicXor8U:
371
case ThreadOp::I32AtomicXor16U:
372
case ThreadOp::I64AtomicXor8U:
373
case ThreadOp::I64AtomicXor16U:
374
case ThreadOp::I64AtomicXor32U:
375
case ThreadOp::I32AtomicXchg:
376
case ThreadOp::I64AtomicXchg:
377
case ThreadOp::I32AtomicXchg8U:
378
case ThreadOp::I32AtomicXchg16U:
379
case ThreadOp::I64AtomicXchg8U:
380
case ThreadOp::I64AtomicXchg16U:
381
case ThreadOp::I64AtomicXchg32U:
382
return OpKind::AtomicBinOp;
383
case ThreadOp::I32AtomicCmpXchg:
384
case ThreadOp::I64AtomicCmpXchg:
385
case ThreadOp::I32AtomicCmpXchg8U:
386
case ThreadOp::I32AtomicCmpXchg16U:
387
case ThreadOp::I64AtomicCmpXchg8U:
388
case ThreadOp::I64AtomicCmpXchg16U:
389
case ThreadOp::I64AtomicCmpXchg32U:
390
return OpKind::AtomicCompareExchange;
391
default:
392
break;
393
}
394
break;
395
}
396
case Op::MozPrefix: {
397
switch (MozOp(op.b1)) {
398
case MozOp::Limit:
399
// Reject Limit for the MozPrefix encoding
400
break;
401
case MozOp::TeeGlobal:
402
return OpKind::TeeGlobal;
403
case MozOp::I32BitNot:
404
case MozOp::I32Abs:
405
case MozOp::I32Neg:
406
return OpKind::Unary;
407
case MozOp::I32Min:
408
case MozOp::I32Max:
409
case MozOp::F64Mod:
410
case MozOp::F64Pow:
411
case MozOp::F64Atan2:
412
return OpKind::Binary;
413
case MozOp::F64Sin:
414
case MozOp::F64Cos:
415
case MozOp::F64Tan:
416
case MozOp::F64Asin:
417
case MozOp::F64Acos:
418
case MozOp::F64Atan:
419
case MozOp::F64Exp:
420
case MozOp::F64Log:
421
return OpKind::Unary;
422
case MozOp::I32TeeStore8:
423
case MozOp::I32TeeStore16:
424
case MozOp::I64TeeStore8:
425
case MozOp::I64TeeStore16:
426
case MozOp::I64TeeStore32:
427
case MozOp::I32TeeStore:
428
case MozOp::I64TeeStore:
429
case MozOp::F32TeeStore:
430
case MozOp::F64TeeStore:
431
case MozOp::F32TeeStoreF64:
432
case MozOp::F64TeeStoreF32:
433
return OpKind::TeeStore;
434
case MozOp::OldCallDirect:
435
return OpKind::OldCallDirect;
436
case MozOp::OldCallIndirect:
437
return OpKind::OldCallIndirect;
438
}
439
break;
440
}
441
}
442
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("unimplemented opcode");
443
}
444
445
# undef WASM_GC_OP
446
# undef WASM_REF_OP
447
448
#endif