1#!/usr/bin/env python3
2#
3# Copyright 2018 WebAssembly Community Group participants
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import sys
18
19instructions = [
20    ("unreachable",    "makeUnreachable()"),
21    ("nop",            "makeNop()"),
22    ("block",          "makeBlock(s)"),
23    ("loop",           "makeLoop(s)"),
24    ("if",             "makeIf(s)"),
25    ("then",           "makeThenOrElse(s)"),
26    ("else",           "makeThenOrElse(s)"),
27    ("br",             "makeBreak(s)"),
28    ("br_if",          "makeBreak(s)"),
29    ("br_table",       "makeBreakTable(s)"),
30    ("return",         "makeReturn(s)"),
31    ("call",           "makeCall(s, /*isReturn=*/false)"),
32    ("call_indirect",  "makeCallIndirect(s, /*isReturn=*/false)"),
33    ("return_call",    "makeCall(s, /*isReturn=*/true)"),
34    ("return_call_indirect", "makeCallIndirect(s, /*isReturn=*/true)"),
35    ("drop",           "makeDrop(s)"),
36    ("select",         "makeSelect(s)"),
37    ("local.get",      "makeLocalGet(s)"),
38    ("local.set",      "makeLocalSet(s)"),
39    ("local.tee",      "makeLocalTee(s)"),
40    ("global.get",     "makeGlobalGet(s)"),
41    ("global.set",     "makeGlobalSet(s)"),
42    ("memory.init",    "makeMemoryInit(s)"),
43    ("data.drop",      "makeDataDrop(s)"),
44    ("memory.copy",    "makeMemoryCopy(s)"),
45    ("memory.fill",    "makeMemoryFill(s)"),
46    ("i32.load",       "makeLoad(s, Type::i32, /*isAtomic=*/false)"),
47    ("i64.load",       "makeLoad(s, Type::i64, /*isAtomic=*/false)"),
48    ("f32.load",       "makeLoad(s, Type::f32, /*isAtomic=*/false)"),
49    ("f64.load",       "makeLoad(s, Type::f64, /*isAtomic=*/false)"),
50    ("i32.load8_s",    "makeLoad(s, Type::i32, /*isAtomic=*/false)"),
51    ("i32.load8_u",    "makeLoad(s, Type::i32, /*isAtomic=*/false)"),
52    ("i32.load16_s",   "makeLoad(s, Type::i32, /*isAtomic=*/false)"),
53    ("i32.load16_u",   "makeLoad(s, Type::i32, /*isAtomic=*/false)"),
54    ("i64.load8_s",    "makeLoad(s, Type::i64, /*isAtomic=*/false)"),
55    ("i64.load8_u",    "makeLoad(s, Type::i64, /*isAtomic=*/false)"),
56    ("i64.load16_s",   "makeLoad(s, Type::i64, /*isAtomic=*/false)"),
57    ("i64.load16_u",   "makeLoad(s, Type::i64, /*isAtomic=*/false)"),
58    ("i64.load32_s",   "makeLoad(s, Type::i64, /*isAtomic=*/false)"),
59    ("i64.load32_u",   "makeLoad(s, Type::i64, /*isAtomic=*/false)"),
60    ("i32.store",      "makeStore(s, Type::i32, /*isAtomic=*/false)"),
61    ("i64.store",      "makeStore(s, Type::i64, /*isAtomic=*/false)"),
62    ("f32.store",      "makeStore(s, Type::f32, /*isAtomic=*/false)"),
63    ("f64.store",      "makeStore(s, Type::f64, /*isAtomic=*/false)"),
64    ("i32.store8",     "makeStore(s, Type::i32, /*isAtomic=*/false)"),
65    ("i32.store16",    "makeStore(s, Type::i32, /*isAtomic=*/false)"),
66    ("i64.store8",     "makeStore(s, Type::i64, /*isAtomic=*/false)"),
67    ("i64.store16",    "makeStore(s, Type::i64, /*isAtomic=*/false)"),
68    ("i64.store32",    "makeStore(s, Type::i64, /*isAtomic=*/false)"),
69    ("memory.size",    "makeMemorySize(s)"),
70    ("memory.grow",    "makeMemoryGrow(s)"),
71    ("i32.const",      "makeConst(s, Type::i32)"),
72    ("i64.const",      "makeConst(s, Type::i64)"),
73    ("f32.const",      "makeConst(s, Type::f32)"),
74    ("f64.const",      "makeConst(s, Type::f64)"),
75    ("i32.eqz",        "makeUnary(s, UnaryOp::EqZInt32)"),
76    ("i32.eq",         "makeBinary(s, BinaryOp::EqInt32)"),
77    ("i32.ne",         "makeBinary(s, BinaryOp::NeInt32)"),
78    ("i32.lt_s",       "makeBinary(s, BinaryOp::LtSInt32)"),
79    ("i32.lt_u",       "makeBinary(s, BinaryOp::LtUInt32)"),
80    ("i32.gt_s",       "makeBinary(s, BinaryOp::GtSInt32)"),
81    ("i32.gt_u",       "makeBinary(s, BinaryOp::GtUInt32)"),
82    ("i32.le_s",       "makeBinary(s, BinaryOp::LeSInt32)"),
83    ("i32.le_u",       "makeBinary(s, BinaryOp::LeUInt32)"),
84    ("i32.ge_s",       "makeBinary(s, BinaryOp::GeSInt32)"),
85    ("i32.ge_u",       "makeBinary(s, BinaryOp::GeUInt32)"),
86    ("i64.eqz",        "makeUnary(s, UnaryOp::EqZInt64)"),
87    ("i64.eq",         "makeBinary(s, BinaryOp::EqInt64)"),
88    ("i64.ne",         "makeBinary(s, BinaryOp::NeInt64)"),
89    ("i64.lt_s",       "makeBinary(s, BinaryOp::LtSInt64)"),
90    ("i64.lt_u",       "makeBinary(s, BinaryOp::LtUInt64)"),
91    ("i64.gt_s",       "makeBinary(s, BinaryOp::GtSInt64)"),
92    ("i64.gt_u",       "makeBinary(s, BinaryOp::GtUInt64)"),
93    ("i64.le_s",       "makeBinary(s, BinaryOp::LeSInt64)"),
94    ("i64.le_u",       "makeBinary(s, BinaryOp::LeUInt64)"),
95    ("i64.ge_s",       "makeBinary(s, BinaryOp::GeSInt64)"),
96    ("i64.ge_u",       "makeBinary(s, BinaryOp::GeUInt64)"),
97    ("f32.eq",         "makeBinary(s, BinaryOp::EqFloat32)"),
98    ("f32.ne",         "makeBinary(s, BinaryOp::NeFloat32)"),
99    ("f32.lt",         "makeBinary(s, BinaryOp::LtFloat32)"),
100    ("f32.gt",         "makeBinary(s, BinaryOp::GtFloat32)"),
101    ("f32.le",         "makeBinary(s, BinaryOp::LeFloat32)"),
102    ("f32.ge",         "makeBinary(s, BinaryOp::GeFloat32)"),
103    ("f64.eq",         "makeBinary(s, BinaryOp::EqFloat64)"),
104    ("f64.ne",         "makeBinary(s, BinaryOp::NeFloat64)"),
105    ("f64.lt",         "makeBinary(s, BinaryOp::LtFloat64)"),
106    ("f64.gt",         "makeBinary(s, BinaryOp::GtFloat64)"),
107    ("f64.le",         "makeBinary(s, BinaryOp::LeFloat64)"),
108    ("f64.ge",         "makeBinary(s, BinaryOp::GeFloat64)"),
109    ("i32.clz",        "makeUnary(s, UnaryOp::ClzInt32)"),
110    ("i32.ctz",        "makeUnary(s, UnaryOp::CtzInt32)"),
111    ("i32.popcnt",     "makeUnary(s, UnaryOp::PopcntInt32)"),
112    ("i32.add",        "makeBinary(s, BinaryOp::AddInt32)"),
113    ("i32.sub",        "makeBinary(s, BinaryOp::SubInt32)"),
114    ("i32.mul",        "makeBinary(s, BinaryOp::MulInt32)"),
115    ("i32.div_s",      "makeBinary(s, BinaryOp::DivSInt32)"),
116    ("i32.div_u",      "makeBinary(s, BinaryOp::DivUInt32)"),
117    ("i32.rem_s",      "makeBinary(s, BinaryOp::RemSInt32)"),
118    ("i32.rem_u",      "makeBinary(s, BinaryOp::RemUInt32)"),
119    ("i32.and",        "makeBinary(s, BinaryOp::AndInt32)"),
120    ("i32.or",         "makeBinary(s, BinaryOp::OrInt32)"),
121    ("i32.xor",        "makeBinary(s, BinaryOp::XorInt32)"),
122    ("i32.shl",        "makeBinary(s, BinaryOp::ShlInt32)"),
123    ("i32.shr_s",      "makeBinary(s, BinaryOp::ShrSInt32)"),
124    ("i32.shr_u",      "makeBinary(s, BinaryOp::ShrUInt32)"),
125    ("i32.rotl",       "makeBinary(s, BinaryOp::RotLInt32)"),
126    ("i32.rotr",       "makeBinary(s, BinaryOp::RotRInt32)"),
127    ("i64.clz",        "makeUnary(s, UnaryOp::ClzInt64)"),
128    ("i64.ctz",        "makeUnary(s, UnaryOp::CtzInt64)"),
129    ("i64.popcnt",     "makeUnary(s, UnaryOp::PopcntInt64)"),
130    ("i64.add",        "makeBinary(s, BinaryOp::AddInt64)"),
131    ("i64.sub",        "makeBinary(s, BinaryOp::SubInt64)"),
132    ("i64.mul",        "makeBinary(s, BinaryOp::MulInt64)"),
133    ("i64.div_s",      "makeBinary(s, BinaryOp::DivSInt64)"),
134    ("i64.div_u",      "makeBinary(s, BinaryOp::DivUInt64)"),
135    ("i64.rem_s",      "makeBinary(s, BinaryOp::RemSInt64)"),
136    ("i64.rem_u",      "makeBinary(s, BinaryOp::RemUInt64)"),
137    ("i64.and",        "makeBinary(s, BinaryOp::AndInt64)"),
138    ("i64.or",         "makeBinary(s, BinaryOp::OrInt64)"),
139    ("i64.xor",        "makeBinary(s, BinaryOp::XorInt64)"),
140    ("i64.shl",        "makeBinary(s, BinaryOp::ShlInt64)"),
141    ("i64.shr_s",      "makeBinary(s, BinaryOp::ShrSInt64)"),
142    ("i64.shr_u",      "makeBinary(s, BinaryOp::ShrUInt64)"),
143    ("i64.rotl",       "makeBinary(s, BinaryOp::RotLInt64)"),
144    ("i64.rotr",       "makeBinary(s, BinaryOp::RotRInt64)"),
145    ("f32.abs",        "makeUnary(s, UnaryOp::AbsFloat32)"),
146    ("f32.neg",        "makeUnary(s, UnaryOp::NegFloat32)"),
147    ("f32.ceil",       "makeUnary(s, UnaryOp::CeilFloat32)"),
148    ("f32.floor",      "makeUnary(s, UnaryOp::FloorFloat32)"),
149    ("f32.trunc",      "makeUnary(s, UnaryOp::TruncFloat32)"),
150    ("f32.nearest",    "makeUnary(s, UnaryOp::NearestFloat32)"),
151    ("f32.sqrt",       "makeUnary(s, UnaryOp::SqrtFloat32)"),
152    ("f32.add",        "makeBinary(s, BinaryOp::AddFloat32)"),
153    ("f32.sub",        "makeBinary(s, BinaryOp::SubFloat32)"),
154    ("f32.mul",        "makeBinary(s, BinaryOp::MulFloat32)"),
155    ("f32.div",        "makeBinary(s, BinaryOp::DivFloat32)"),
156    ("f32.min",        "makeBinary(s, BinaryOp::MinFloat32)"),
157    ("f32.max",        "makeBinary(s, BinaryOp::MaxFloat32)"),
158    ("f32.copysign",   "makeBinary(s, BinaryOp::CopySignFloat32)"),
159    ("f64.abs",        "makeUnary(s, UnaryOp::AbsFloat64)"),
160    ("f64.neg",        "makeUnary(s, UnaryOp::NegFloat64)"),
161    ("f64.ceil",       "makeUnary(s, UnaryOp::CeilFloat64)"),
162    ("f64.floor",      "makeUnary(s, UnaryOp::FloorFloat64)"),
163    ("f64.trunc",      "makeUnary(s, UnaryOp::TruncFloat64)"),
164    ("f64.nearest",    "makeUnary(s, UnaryOp::NearestFloat64)"),
165    ("f64.sqrt",       "makeUnary(s, UnaryOp::SqrtFloat64)"),
166    ("f64.add",        "makeBinary(s, BinaryOp::AddFloat64)"),
167    ("f64.sub",        "makeBinary(s, BinaryOp::SubFloat64)"),
168    ("f64.mul",        "makeBinary(s, BinaryOp::MulFloat64)"),
169    ("f64.div",        "makeBinary(s, BinaryOp::DivFloat64)"),
170    ("f64.min",        "makeBinary(s, BinaryOp::MinFloat64)"),
171    ("f64.max",        "makeBinary(s, BinaryOp::MaxFloat64)"),
172    ("f64.copysign",   "makeBinary(s, BinaryOp::CopySignFloat64)"),
173    ("i32.wrap_i64",   "makeUnary(s, UnaryOp::WrapInt64)"),
174    ("i32.trunc_f32_s",     "makeUnary(s, UnaryOp::TruncSFloat32ToInt32)"),
175    ("i32.trunc_f32_u",     "makeUnary(s, UnaryOp::TruncUFloat32ToInt32)"),
176    ("i32.trunc_f64_s",     "makeUnary(s, UnaryOp::TruncSFloat64ToInt32)"),
177    ("i32.trunc_f64_u",     "makeUnary(s, UnaryOp::TruncUFloat64ToInt32)"),
178    ("i64.extend_i32_s",    "makeUnary(s, UnaryOp::ExtendSInt32)"),
179    ("i64.extend_i32_u",    "makeUnary(s, UnaryOp::ExtendUInt32)"),
180    ("i64.trunc_f32_s",     "makeUnary(s, UnaryOp::TruncSFloat32ToInt64)"),
181    ("i64.trunc_f32_u",     "makeUnary(s, UnaryOp::TruncUFloat32ToInt64)"),
182    ("i64.trunc_f64_s",     "makeUnary(s, UnaryOp::TruncSFloat64ToInt64)"),
183    ("i64.trunc_f64_u",     "makeUnary(s, UnaryOp::TruncUFloat64ToInt64)"),
184    ("f32.convert_i32_s",   "makeUnary(s, UnaryOp::ConvertSInt32ToFloat32)"),
185    ("f32.convert_i32_u",   "makeUnary(s, UnaryOp::ConvertUInt32ToFloat32)"),
186    ("f32.convert_i64_s",   "makeUnary(s, UnaryOp::ConvertSInt64ToFloat32)"),
187    ("f32.convert_i64_u",   "makeUnary(s, UnaryOp::ConvertUInt64ToFloat32)"),
188    ("f32.demote_f64",      "makeUnary(s, UnaryOp::DemoteFloat64)"),
189    ("f64.convert_i32_s",   "makeUnary(s, UnaryOp::ConvertSInt32ToFloat64)"),
190    ("f64.convert_i32_u",   "makeUnary(s, UnaryOp::ConvertUInt32ToFloat64)"),
191    ("f64.convert_i64_s",   "makeUnary(s, UnaryOp::ConvertSInt64ToFloat64)"),
192    ("f64.convert_i64_u",   "makeUnary(s, UnaryOp::ConvertUInt64ToFloat64)"),
193    ("f64.promote_f32",     "makeUnary(s, UnaryOp::PromoteFloat32)"),
194    ("i32.reinterpret_f32", "makeUnary(s, UnaryOp::ReinterpretFloat32)"),
195    ("i64.reinterpret_f64", "makeUnary(s, UnaryOp::ReinterpretFloat64)"),
196    ("f32.reinterpret_i32", "makeUnary(s, UnaryOp::ReinterpretInt32)"),
197    ("f64.reinterpret_i64", "makeUnary(s, UnaryOp::ReinterpretInt64)"),
198    ("i32.extend8_s",       "makeUnary(s, UnaryOp::ExtendS8Int32)"),
199    ("i32.extend16_s",      "makeUnary(s, UnaryOp::ExtendS16Int32)"),
200    ("i64.extend8_s",       "makeUnary(s, UnaryOp::ExtendS8Int64)"),
201    ("i64.extend16_s",      "makeUnary(s, UnaryOp::ExtendS16Int64)"),
202    ("i64.extend32_s",      "makeUnary(s, UnaryOp::ExtendS32Int64)"),
203    # atomic instructions
204    ("atomic.notify",           "makeAtomicNotify(s)"),
205    ("i32.atomic.wait",         "makeAtomicWait(s, Type::i32)"),
206    ("i64.atomic.wait",         "makeAtomicWait(s, Type::i64)"),
207    ("atomic.fence",            "makeAtomicFence(s)"),
208    ("i32.atomic.load8_u",      "makeLoad(s, Type::i32, /*isAtomic=*/true)"),
209    ("i32.atomic.load16_u",     "makeLoad(s, Type::i32, /*isAtomic=*/true)"),
210    ("i32.atomic.load",         "makeLoad(s, Type::i32, /*isAtomic=*/true)"),
211    ("i64.atomic.load8_u",      "makeLoad(s, Type::i64, /*isAtomic=*/true)"),
212    ("i64.atomic.load16_u",     "makeLoad(s, Type::i64, /*isAtomic=*/true)"),
213    ("i64.atomic.load32_u",     "makeLoad(s, Type::i64, /*isAtomic=*/true)"),
214    ("i64.atomic.load",         "makeLoad(s, Type::i64, /*isAtomic=*/true)"),
215    ("i32.atomic.store8",       "makeStore(s, Type::i32, /*isAtomic=*/true)"),
216    ("i32.atomic.store16",      "makeStore(s, Type::i32, /*isAtomic=*/true)"),
217    ("i32.atomic.store",        "makeStore(s, Type::i32, /*isAtomic=*/true)"),
218    ("i64.atomic.store8",       "makeStore(s, Type::i64, /*isAtomic=*/true)"),
219    ("i64.atomic.store16",      "makeStore(s, Type::i64, /*isAtomic=*/true)"),
220    ("i64.atomic.store32",      "makeStore(s, Type::i64, /*isAtomic=*/true)"),
221    ("i64.atomic.store",        "makeStore(s, Type::i64, /*isAtomic=*/true)"),
222    ("i32.atomic.rmw8.add_u",   "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
223    ("i32.atomic.rmw16.add_u",  "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
224    ("i32.atomic.rmw.add",      "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
225    ("i64.atomic.rmw8.add_u",   "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
226    ("i64.atomic.rmw16.add_u",  "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
227    ("i64.atomic.rmw32.add_u",  "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
228    ("i64.atomic.rmw.add",      "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
229    ("i32.atomic.rmw8.sub_u",   "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
230    ("i32.atomic.rmw16.sub_u",  "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
231    ("i32.atomic.rmw.sub",      "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
232    ("i64.atomic.rmw8.sub_u",   "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
233    ("i64.atomic.rmw16.sub_u",  "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
234    ("i64.atomic.rmw32.sub_u",  "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
235    ("i64.atomic.rmw.sub",      "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
236    ("i32.atomic.rmw8.and_u",   "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
237    ("i32.atomic.rmw16.and_u",  "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
238    ("i32.atomic.rmw.and",      "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
239    ("i64.atomic.rmw8.and_u",   "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
240    ("i64.atomic.rmw16.and_u",  "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
241    ("i64.atomic.rmw32.and_u",  "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
242    ("i64.atomic.rmw.and",      "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
243    ("i32.atomic.rmw8.or_u",    "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
244    ("i32.atomic.rmw16.or_u",   "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
245    ("i32.atomic.rmw.or",       "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
246    ("i64.atomic.rmw8.or_u",    "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
247    ("i64.atomic.rmw16.or_u",   "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
248    ("i64.atomic.rmw32.or_u",   "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
249    ("i64.atomic.rmw.or",       "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
250    ("i32.atomic.rmw8.xor_u",   "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
251    ("i32.atomic.rmw16.xor_u",  "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
252    ("i32.atomic.rmw.xor",      "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
253    ("i64.atomic.rmw8.xor_u",   "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
254    ("i64.atomic.rmw16.xor_u",  "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
255    ("i64.atomic.rmw32.xor_u",  "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
256    ("i64.atomic.rmw.xor",      "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
257    ("i32.atomic.rmw8.xchg_u",  "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
258    ("i32.atomic.rmw16.xchg_u", "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
259    ("i32.atomic.rmw.xchg",     "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
260    ("i64.atomic.rmw8.xchg_u",  "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
261    ("i64.atomic.rmw16.xchg_u", "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
262    ("i64.atomic.rmw32.xchg_u", "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
263    ("i64.atomic.rmw.xchg",     "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
264    ("i32.atomic.rmw8.cmpxchg_u",  "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
265    ("i32.atomic.rmw16.cmpxchg_u", "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
266    ("i32.atomic.rmw.cmpxchg",     "makeAtomicRMWOrCmpxchg(s, Type::i32)"),
267    ("i64.atomic.rmw8.cmpxchg_u",  "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
268    ("i64.atomic.rmw16.cmpxchg_u", "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
269    ("i64.atomic.rmw32.cmpxchg_u", "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
270    ("i64.atomic.rmw.cmpxchg",     "makeAtomicRMWOrCmpxchg(s, Type::i64)"),
271    # nontrapping float-to-int instructions
272    ("i32.trunc_sat_f32_s", "makeUnary(s, UnaryOp::TruncSatSFloat32ToInt32)"),
273    ("i32.trunc_sat_f32_u", "makeUnary(s, UnaryOp::TruncSatUFloat32ToInt32)"),
274    ("i32.trunc_sat_f64_s", "makeUnary(s, UnaryOp::TruncSatSFloat64ToInt32)"),
275    ("i32.trunc_sat_f64_u", "makeUnary(s, UnaryOp::TruncSatUFloat64ToInt32)"),
276    ("i64.trunc_sat_f32_s", "makeUnary(s, UnaryOp::TruncSatSFloat32ToInt64)"),
277    ("i64.trunc_sat_f32_u", "makeUnary(s, UnaryOp::TruncSatUFloat32ToInt64)"),
278    ("i64.trunc_sat_f64_s", "makeUnary(s, UnaryOp::TruncSatSFloat64ToInt64)"),
279    ("i64.trunc_sat_f64_u", "makeUnary(s, UnaryOp::TruncSatUFloat64ToInt64)"),
280    # SIMD ops
281    ("v128.load",            "makeLoad(s, Type::v128, /*isAtomic=*/false)"),
282    ("v128.store",           "makeStore(s, Type::v128, /*isAtomic=*/false)"),
283    ("v128.const",           "makeConst(s, Type::v128)"),
284    ("v8x16.shuffle",        "makeSIMDShuffle(s)"),
285    ("i8x16.splat",          "makeUnary(s, UnaryOp::SplatVecI8x16)"),
286    ("i8x16.extract_lane_s", "makeSIMDExtract(s, SIMDExtractOp::ExtractLaneSVecI8x16, 16)"),
287    ("i8x16.extract_lane_u", "makeSIMDExtract(s, SIMDExtractOp::ExtractLaneUVecI8x16, 16)"),
288    ("i8x16.replace_lane",   "makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI8x16, 16)"),
289    ("i16x8.splat",          "makeUnary(s, UnaryOp::SplatVecI16x8)"),
290    ("i16x8.extract_lane_s", "makeSIMDExtract(s, SIMDExtractOp::ExtractLaneSVecI16x8, 8)"),
291    ("i16x8.extract_lane_u", "makeSIMDExtract(s, SIMDExtractOp::ExtractLaneUVecI16x8, 8)"),
292    ("i16x8.replace_lane",   "makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI16x8, 8)"),
293    ("i32x4.splat",          "makeUnary(s, UnaryOp::SplatVecI32x4)"),
294    ("i32x4.extract_lane",   "makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI32x4, 4)"),
295    ("i32x4.replace_lane",   "makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI32x4, 4)"),
296    ("i64x2.splat",          "makeUnary(s, UnaryOp::SplatVecI64x2)"),
297    ("i64x2.extract_lane",   "makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI64x2, 2)"),
298    ("i64x2.replace_lane",   "makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI64x2, 2)"),
299    ("f32x4.splat",          "makeUnary(s, UnaryOp::SplatVecF32x4)"),
300    ("f32x4.extract_lane",   "makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecF32x4, 4)"),
301    ("f32x4.replace_lane",   "makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecF32x4, 4)"),
302    ("f64x2.splat",          "makeUnary(s, UnaryOp::SplatVecF64x2)"),
303    ("f64x2.extract_lane",   "makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecF64x2, 2)"),
304    ("f64x2.replace_lane",   "makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecF64x2, 2)"),
305    ("i8x16.eq",             "makeBinary(s, BinaryOp::EqVecI8x16)"),
306    ("i8x16.ne",             "makeBinary(s, BinaryOp::NeVecI8x16)"),
307    ("i8x16.lt_s",           "makeBinary(s, BinaryOp::LtSVecI8x16)"),
308    ("i8x16.lt_u",           "makeBinary(s, BinaryOp::LtUVecI8x16)"),
309    ("i8x16.gt_s",           "makeBinary(s, BinaryOp::GtSVecI8x16)"),
310    ("i8x16.gt_u",           "makeBinary(s, BinaryOp::GtUVecI8x16)"),
311    ("i8x16.le_s",           "makeBinary(s, BinaryOp::LeSVecI8x16)"),
312    ("i8x16.le_u",           "makeBinary(s, BinaryOp::LeUVecI8x16)"),
313    ("i8x16.ge_s",           "makeBinary(s, BinaryOp::GeSVecI8x16)"),
314    ("i8x16.ge_u",           "makeBinary(s, BinaryOp::GeUVecI8x16)"),
315    ("i16x8.eq",             "makeBinary(s, BinaryOp::EqVecI16x8)"),
316    ("i16x8.ne",             "makeBinary(s, BinaryOp::NeVecI16x8)"),
317    ("i16x8.lt_s",           "makeBinary(s, BinaryOp::LtSVecI16x8)"),
318    ("i16x8.lt_u",           "makeBinary(s, BinaryOp::LtUVecI16x8)"),
319    ("i16x8.gt_s",           "makeBinary(s, BinaryOp::GtSVecI16x8)"),
320    ("i16x8.gt_u",           "makeBinary(s, BinaryOp::GtUVecI16x8)"),
321    ("i16x8.le_s",           "makeBinary(s, BinaryOp::LeSVecI16x8)"),
322    ("i16x8.le_u",           "makeBinary(s, BinaryOp::LeUVecI16x8)"),
323    ("i16x8.ge_s",           "makeBinary(s, BinaryOp::GeSVecI16x8)"),
324    ("i16x8.ge_u",           "makeBinary(s, BinaryOp::GeUVecI16x8)"),
325    ("i32x4.eq",             "makeBinary(s, BinaryOp::EqVecI32x4)"),
326    ("i32x4.ne",             "makeBinary(s, BinaryOp::NeVecI32x4)"),
327    ("i32x4.lt_s",           "makeBinary(s, BinaryOp::LtSVecI32x4)"),
328    ("i32x4.lt_u",           "makeBinary(s, BinaryOp::LtUVecI32x4)"),
329    ("i32x4.gt_s",           "makeBinary(s, BinaryOp::GtSVecI32x4)"),
330    ("i32x4.gt_u",           "makeBinary(s, BinaryOp::GtUVecI32x4)"),
331    ("i32x4.le_s",           "makeBinary(s, BinaryOp::LeSVecI32x4)"),
332    ("i32x4.le_u",           "makeBinary(s, BinaryOp::LeUVecI32x4)"),
333    ("i32x4.ge_s",           "makeBinary(s, BinaryOp::GeSVecI32x4)"),
334    ("i32x4.ge_u",           "makeBinary(s, BinaryOp::GeUVecI32x4)"),
335    ("f32x4.eq",             "makeBinary(s, BinaryOp::EqVecF32x4)"),
336    ("f32x4.ne",             "makeBinary(s, BinaryOp::NeVecF32x4)"),
337    ("f32x4.lt",             "makeBinary(s, BinaryOp::LtVecF32x4)"),
338    ("f32x4.gt",             "makeBinary(s, BinaryOp::GtVecF32x4)"),
339    ("f32x4.le",             "makeBinary(s, BinaryOp::LeVecF32x4)"),
340    ("f32x4.ge",             "makeBinary(s, BinaryOp::GeVecF32x4)"),
341    ("f64x2.eq",             "makeBinary(s, BinaryOp::EqVecF64x2)"),
342    ("f64x2.ne",             "makeBinary(s, BinaryOp::NeVecF64x2)"),
343    ("f64x2.lt",             "makeBinary(s, BinaryOp::LtVecF64x2)"),
344    ("f64x2.gt",             "makeBinary(s, BinaryOp::GtVecF64x2)"),
345    ("f64x2.le",             "makeBinary(s, BinaryOp::LeVecF64x2)"),
346    ("f64x2.ge",             "makeBinary(s, BinaryOp::GeVecF64x2)"),
347    ("v128.not",             "makeUnary(s, UnaryOp::NotVec128)"),
348    ("v128.and",             "makeBinary(s, BinaryOp::AndVec128)"),
349    ("v128.or",              "makeBinary(s, BinaryOp::OrVec128)"),
350    ("v128.xor",             "makeBinary(s, BinaryOp::XorVec128)"),
351    ("v128.andnot",          "makeBinary(s, BinaryOp::AndNotVec128)"),
352    ("v128.bitselect",       "makeSIMDTernary(s, SIMDTernaryOp::Bitselect)"),
353    ("i8x16.abs",            "makeUnary(s, UnaryOp::AbsVecI8x16)"),
354    ("i8x16.neg",            "makeUnary(s, UnaryOp::NegVecI8x16)"),
355    ("i8x16.any_true",       "makeUnary(s, UnaryOp::AnyTrueVecI8x16)"),
356    ("i8x16.all_true",       "makeUnary(s, UnaryOp::AllTrueVecI8x16)"),
357    ("i8x16.bitmask",        "makeUnary(s, UnaryOp::BitmaskVecI8x16)"),
358    ("i8x16.shl",            "makeSIMDShift(s, SIMDShiftOp::ShlVecI8x16)"),
359    ("i8x16.shr_s",          "makeSIMDShift(s, SIMDShiftOp::ShrSVecI8x16)"),
360    ("i8x16.shr_u",          "makeSIMDShift(s, SIMDShiftOp::ShrUVecI8x16)"),
361    ("i8x16.add",            "makeBinary(s, BinaryOp::AddVecI8x16)"),
362    ("i8x16.add_saturate_s", "makeBinary(s, BinaryOp::AddSatSVecI8x16)"),
363    ("i8x16.add_saturate_u", "makeBinary(s, BinaryOp::AddSatUVecI8x16)"),
364    ("i8x16.sub",            "makeBinary(s, BinaryOp::SubVecI8x16)"),
365    ("i8x16.sub_saturate_s", "makeBinary(s, BinaryOp::SubSatSVecI8x16)"),
366    ("i8x16.sub_saturate_u", "makeBinary(s, BinaryOp::SubSatUVecI8x16)"),
367    ("i8x16.mul",            "makeBinary(s, BinaryOp::MulVecI8x16)"),
368    ("i8x16.min_s",          "makeBinary(s, BinaryOp::MinSVecI8x16)"),
369    ("i8x16.min_u",          "makeBinary(s, BinaryOp::MinUVecI8x16)"),
370    ("i8x16.max_s",          "makeBinary(s, BinaryOp::MaxSVecI8x16)"),
371    ("i8x16.max_u",          "makeBinary(s, BinaryOp::MaxUVecI8x16)"),
372    ("i8x16.avgr_u",         "makeBinary(s, BinaryOp::AvgrUVecI8x16)"),
373    ("i16x8.abs",            "makeUnary(s, UnaryOp::AbsVecI16x8)"),
374    ("i16x8.neg",            "makeUnary(s, UnaryOp::NegVecI16x8)"),
375    ("i16x8.any_true",       "makeUnary(s, UnaryOp::AnyTrueVecI16x8)"),
376    ("i16x8.all_true",       "makeUnary(s, UnaryOp::AllTrueVecI16x8)"),
377    ("i16x8.bitmask",        "makeUnary(s, UnaryOp::BitmaskVecI16x8)"),
378    ("i16x8.shl",            "makeSIMDShift(s, SIMDShiftOp::ShlVecI16x8)"),
379    ("i16x8.shr_s",          "makeSIMDShift(s, SIMDShiftOp::ShrSVecI16x8)"),
380    ("i16x8.shr_u",          "makeSIMDShift(s, SIMDShiftOp::ShrUVecI16x8)"),
381    ("i16x8.add",            "makeBinary(s, BinaryOp::AddVecI16x8)"),
382    ("i16x8.add_saturate_s", "makeBinary(s, BinaryOp::AddSatSVecI16x8)"),
383    ("i16x8.add_saturate_u", "makeBinary(s, BinaryOp::AddSatUVecI16x8)"),
384    ("i16x8.sub",            "makeBinary(s, BinaryOp::SubVecI16x8)"),
385    ("i16x8.sub_saturate_s", "makeBinary(s, BinaryOp::SubSatSVecI16x8)"),
386    ("i16x8.sub_saturate_u", "makeBinary(s, BinaryOp::SubSatUVecI16x8)"),
387    ("i16x8.mul",            "makeBinary(s, BinaryOp::MulVecI16x8)"),
388    ("i16x8.min_s",          "makeBinary(s, BinaryOp::MinSVecI16x8)"),
389    ("i16x8.min_u",          "makeBinary(s, BinaryOp::MinUVecI16x8)"),
390    ("i16x8.max_s",          "makeBinary(s, BinaryOp::MaxSVecI16x8)"),
391    ("i16x8.max_u",          "makeBinary(s, BinaryOp::MaxUVecI16x8)"),
392    ("i16x8.avgr_u",         "makeBinary(s, BinaryOp::AvgrUVecI16x8)"),
393    ("i32x4.abs",            "makeUnary(s, UnaryOp::AbsVecI32x4)"),
394    ("i32x4.neg",            "makeUnary(s, UnaryOp::NegVecI32x4)"),
395    ("i32x4.any_true",       "makeUnary(s, UnaryOp::AnyTrueVecI32x4)"),
396    ("i32x4.all_true",       "makeUnary(s, UnaryOp::AllTrueVecI32x4)"),
397    ("i32x4.bitmask",        "makeUnary(s, UnaryOp::BitmaskVecI32x4)"),
398    ("i32x4.shl",            "makeSIMDShift(s, SIMDShiftOp::ShlVecI32x4)"),
399    ("i32x4.shr_s",          "makeSIMDShift(s, SIMDShiftOp::ShrSVecI32x4)"),
400    ("i32x4.shr_u",          "makeSIMDShift(s, SIMDShiftOp::ShrUVecI32x4)"),
401    ("i32x4.add",            "makeBinary(s, BinaryOp::AddVecI32x4)"),
402    ("i32x4.sub",            "makeBinary(s, BinaryOp::SubVecI32x4)"),
403    ("i32x4.mul",            "makeBinary(s, BinaryOp::MulVecI32x4)"),
404    ("i32x4.min_s",          "makeBinary(s, BinaryOp::MinSVecI32x4)"),
405    ("i32x4.min_u",          "makeBinary(s, BinaryOp::MinUVecI32x4)"),
406    ("i32x4.max_s",          "makeBinary(s, BinaryOp::MaxSVecI32x4)"),
407    ("i32x4.max_u",          "makeBinary(s, BinaryOp::MaxUVecI32x4)"),
408    ("i32x4.dot_i16x8_s",    "makeBinary(s, BinaryOp::DotSVecI16x8ToVecI32x4)"),
409    ("i64x2.neg",            "makeUnary(s, UnaryOp::NegVecI64x2)"),
410    ("i64x2.any_true",       "makeUnary(s, UnaryOp::AnyTrueVecI64x2)"),
411    ("i64x2.all_true",       "makeUnary(s, UnaryOp::AllTrueVecI64x2)"),
412    ("i64x2.shl",            "makeSIMDShift(s, SIMDShiftOp::ShlVecI64x2)"),
413    ("i64x2.shr_s",          "makeSIMDShift(s, SIMDShiftOp::ShrSVecI64x2)"),
414    ("i64x2.shr_u",          "makeSIMDShift(s, SIMDShiftOp::ShrUVecI64x2)"),
415    ("i64x2.add",            "makeBinary(s, BinaryOp::AddVecI64x2)"),
416    ("i64x2.sub",            "makeBinary(s, BinaryOp::SubVecI64x2)"),
417    ("i64x2.mul",            "makeBinary(s, BinaryOp::MulVecI64x2)"),
418    ("f32x4.abs",            "makeUnary(s, UnaryOp::AbsVecF32x4)"),
419    ("f32x4.neg",            "makeUnary(s, UnaryOp::NegVecF32x4)"),
420    ("f32x4.sqrt",           "makeUnary(s, UnaryOp::SqrtVecF32x4)"),
421    ("f32x4.qfma",           "makeSIMDTernary(s, SIMDTernaryOp::QFMAF32x4)"),
422    ("f32x4.qfms",           "makeSIMDTernary(s, SIMDTernaryOp::QFMSF32x4)"),
423    ("f32x4.add",            "makeBinary(s, BinaryOp::AddVecF32x4)"),
424    ("f32x4.sub",            "makeBinary(s, BinaryOp::SubVecF32x4)"),
425    ("f32x4.mul",            "makeBinary(s, BinaryOp::MulVecF32x4)"),
426    ("f32x4.div",            "makeBinary(s, BinaryOp::DivVecF32x4)"),
427    ("f32x4.min",            "makeBinary(s, BinaryOp::MinVecF32x4)"),
428    ("f32x4.max",            "makeBinary(s, BinaryOp::MaxVecF32x4)"),
429    ("f32x4.pmin",           "makeBinary(s, BinaryOp::PMinVecF32x4)"),
430    ("f32x4.pmax",           "makeBinary(s, BinaryOp::PMaxVecF32x4)"),
431    ("f32x4.ceil",           "makeUnary(s, UnaryOp::CeilVecF32x4)"),
432    ("f32x4.floor",          "makeUnary(s, UnaryOp::FloorVecF32x4)"),
433    ("f32x4.trunc",          "makeUnary(s, UnaryOp::TruncVecF32x4)"),
434    ("f32x4.nearest",        "makeUnary(s, UnaryOp::NearestVecF32x4)"),
435    ("f64x2.abs",            "makeUnary(s, UnaryOp::AbsVecF64x2)"),
436    ("f64x2.neg",            "makeUnary(s, UnaryOp::NegVecF64x2)"),
437    ("f64x2.sqrt",           "makeUnary(s, UnaryOp::SqrtVecF64x2)"),
438    ("f64x2.qfma",           "makeSIMDTernary(s, SIMDTernaryOp::QFMAF64x2)"),
439    ("f64x2.qfms",           "makeSIMDTernary(s, SIMDTernaryOp::QFMSF64x2)"),
440    ("f64x2.add",            "makeBinary(s, BinaryOp::AddVecF64x2)"),
441    ("f64x2.sub",            "makeBinary(s, BinaryOp::SubVecF64x2)"),
442    ("f64x2.mul",            "makeBinary(s, BinaryOp::MulVecF64x2)"),
443    ("f64x2.div",            "makeBinary(s, BinaryOp::DivVecF64x2)"),
444    ("f64x2.min",            "makeBinary(s, BinaryOp::MinVecF64x2)"),
445    ("f64x2.max",            "makeBinary(s, BinaryOp::MaxVecF64x2)"),
446    ("f64x2.pmin",           "makeBinary(s, BinaryOp::PMinVecF64x2)"),
447    ("f64x2.pmax",           "makeBinary(s, BinaryOp::PMaxVecF64x2)"),
448    ("f64x2.ceil",           "makeUnary(s, UnaryOp::CeilVecF64x2)"),
449    ("f64x2.floor",          "makeUnary(s, UnaryOp::FloorVecF64x2)"),
450    ("f64x2.trunc",          "makeUnary(s, UnaryOp::TruncVecF64x2)"),
451    ("f64x2.nearest",        "makeUnary(s, UnaryOp::NearestVecF64x2)"),
452    ("i32x4.trunc_sat_f32x4_s",  "makeUnary(s, UnaryOp::TruncSatSVecF32x4ToVecI32x4)"),
453    ("i32x4.trunc_sat_f32x4_u",  "makeUnary(s, UnaryOp::TruncSatUVecF32x4ToVecI32x4)"),
454    ("i64x2.trunc_sat_f64x2_s",  "makeUnary(s, UnaryOp::TruncSatSVecF64x2ToVecI64x2)"),
455    ("i64x2.trunc_sat_f64x2_u",  "makeUnary(s, UnaryOp::TruncSatUVecF64x2ToVecI64x2)"),
456    ("f32x4.convert_i32x4_s",    "makeUnary(s, UnaryOp::ConvertSVecI32x4ToVecF32x4)"),
457    ("f32x4.convert_i32x4_u",    "makeUnary(s, UnaryOp::ConvertUVecI32x4ToVecF32x4)"),
458    ("f64x2.convert_i64x2_s",    "makeUnary(s, UnaryOp::ConvertSVecI64x2ToVecF64x2)"),
459    ("f64x2.convert_i64x2_u",    "makeUnary(s, UnaryOp::ConvertUVecI64x2ToVecF64x2)"),
460    ("v8x16.load_splat",         "makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec8x16)"),
461    ("v16x8.load_splat",         "makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec16x8)"),
462    ("v32x4.load_splat",         "makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec32x4)"),
463    ("v64x2.load_splat",         "makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec64x2)"),
464    ("i16x8.load8x8_s",          "makeSIMDLoad(s, SIMDLoadOp::LoadExtSVec8x8ToVecI16x8)"),
465    ("i16x8.load8x8_u",          "makeSIMDLoad(s, SIMDLoadOp::LoadExtUVec8x8ToVecI16x8)"),
466    ("i32x4.load16x4_s",         "makeSIMDLoad(s, SIMDLoadOp::LoadExtSVec16x4ToVecI32x4)"),
467    ("i32x4.load16x4_u",         "makeSIMDLoad(s, SIMDLoadOp::LoadExtUVec16x4ToVecI32x4)"),
468    ("i64x2.load32x2_s",         "makeSIMDLoad(s, SIMDLoadOp::LoadExtSVec32x2ToVecI64x2)"),
469    ("i64x2.load32x2_u",         "makeSIMDLoad(s, SIMDLoadOp::LoadExtUVec32x2ToVecI64x2)"),
470    ("v128.load32_zero",         "makeSIMDLoad(s, SIMDLoadOp::Load32Zero)"),
471    ("v128.load64_zero",         "makeSIMDLoad(s, SIMDLoadOp::Load64Zero)"),
472    ("i8x16.narrow_i16x8_s",     "makeBinary(s, BinaryOp::NarrowSVecI16x8ToVecI8x16)"),
473    ("i8x16.narrow_i16x8_u",     "makeBinary(s, BinaryOp::NarrowUVecI16x8ToVecI8x16)"),
474    ("i16x8.narrow_i32x4_s",     "makeBinary(s, BinaryOp::NarrowSVecI32x4ToVecI16x8)"),
475    ("i16x8.narrow_i32x4_u",     "makeBinary(s, BinaryOp::NarrowUVecI32x4ToVecI16x8)"),
476    ("i16x8.widen_low_i8x16_s",  "makeUnary(s, UnaryOp::WidenLowSVecI8x16ToVecI16x8)"),
477    ("i16x8.widen_high_i8x16_s", "makeUnary(s, UnaryOp::WidenHighSVecI8x16ToVecI16x8)"),
478    ("i16x8.widen_low_i8x16_u",  "makeUnary(s, UnaryOp::WidenLowUVecI8x16ToVecI16x8)"),
479    ("i16x8.widen_high_i8x16_u", "makeUnary(s, UnaryOp::WidenHighUVecI8x16ToVecI16x8)"),
480    ("i32x4.widen_low_i16x8_s",  "makeUnary(s, UnaryOp::WidenLowSVecI16x8ToVecI32x4)"),
481    ("i32x4.widen_high_i16x8_s", "makeUnary(s, UnaryOp::WidenHighSVecI16x8ToVecI32x4)"),
482    ("i32x4.widen_low_i16x8_u",  "makeUnary(s, UnaryOp::WidenLowUVecI16x8ToVecI32x4)"),
483    ("i32x4.widen_high_i16x8_u", "makeUnary(s, UnaryOp::WidenHighUVecI16x8ToVecI32x4)"),
484    ("v8x16.swizzle",            "makeBinary(s, BinaryOp::SwizzleVec8x16)"),
485    # reference types instructions
486    # TODO Add table instructions
487    ("ref.null",             "makeRefNull(s)"),
488    ("ref.is_null",          "makeRefIsNull(s)"),
489    ("ref.func",             "makeRefFunc(s)"),
490    # exception handling instructions
491    ("try",                  "makeTry(s)"),
492    ("throw",                "makeThrow(s)"),
493    ("rethrow",              "makeRethrow(s)"),
494    ("br_on_exn",            "makeBrOnExn(s)"),
495    # Multivalue pseudoinstructions
496    ("tuple.make",           "makeTupleMake(s)"),
497    ("tuple.extract",        "makeTupleExtract(s)"),
498    ("pop",                  "makePop(s)"),
499    # GC
500    ("ref.eq",               "makeRefEq(s)"),
501    ("i31.new",              "makeI31New(s)"),
502    ("i31.get_s",            "makeI31Get(s, true)"),
503    ("i31.get_u",            "makeI31Get(s, false)"),
504    ("ref.test",             "makeRefTest(s)"),
505    ("ref.cast",             "makeRefCast(s)"),
506    ("br_on_cast",           "makeBrOnCast(s)"),
507    ("rtt.canon",            "makeRttCanon(s)"),
508    ("rtt.sub",              "makeRttSub(s)"),
509    ("struct.new_with_rtt",  "makeStructNew(s, false)"),
510    ("struct.new_default_with_rtt", "makeStructNew(s, true)"),
511    ("struct.get",           "makeStructGet(s)"),
512    ("struct.get_s",         "makeStructGet(s, true)"),
513    ("struct.get_u",         "makeStructGet(s, false)"),
514    ("struct.set",           "makeStructSet(s)"),
515    ("array.new_with_rtt",   "makeArrayNew(s, false)"),
516    ("array.new_default_with_rtt", "makeArrayNew(s, true)"),
517    ("array.get",           "makeArrayGet(s)"),
518    ("array.get_s",         "makeArrayGet(s, true)"),
519    ("array.get_u",         "makeArrayGet(s, false)"),
520    ("array.set",           "makeArraySet(s)"),
521    ("array.len",           "makeArrayLen(s)")
522]
523
524
525class CodePrinter:
526    indents = 0
527
528    def __enter__(self):
529        CodePrinter.indents += 1
530
531    def __exit__(self, *args):
532        CodePrinter.indents -= 1
533
534    def indent(self):
535        # call in a 'with' statement
536        return self
537
538    def print_line(self, line):
539        print("  " * CodePrinter.indents + line)
540
541
542class Node:
543    def __init__(self, expr=None, children=None, inst=None):
544        # the expression to return if this is the string has ended
545        self.expr = expr
546        # map unique strings to children nodes
547        self.children = children if children else {}
548        # full instruction leading to this node
549        self.inst = inst
550
551    def _common_prefix(a, b):
552        """Return the common prefix of two strings."""
553        prefix = []
554        while a and b and a[0] == b[0]:
555            prefix.append(a[0])
556            a = a[1:]
557            b = b[1:]
558        return "".join(prefix)
559
560    def do_insert(self, full_inst, inst, expr):
561        if not inst:
562            assert self.expr is None, "Repeated instruction " + full_inst
563            self.expr = expr
564            self.inst = full_inst
565            return
566        # find key with shared prefix
567        prefix, key = "", None
568        for k in self.children:
569            prefix = Node._common_prefix(inst, k)
570            if prefix:
571                key = k
572                break
573        if key is None:
574            # unique prefix, insert and stop
575            self.children[inst] = Node(expr, inst=full_inst)
576            return
577        key_remainder = key[len(prefix):]
578        if key_remainder:
579            # split key and move everything after the prefix to a new node
580            child = self.children.pop(key)
581            self.children[prefix] = Node(children={key_remainder: child})
582            # update key for recursive insert
583            key = prefix
584        # chop off prefix and recurse
585        self.children[key].do_insert(full_inst, inst[len(key):], expr)
586
587    def insert(self, inst, expr):
588        self.do_insert(inst, inst, expr)
589
590
591def instruction_parser():
592    """Build a trie out of all the instructions, then emit it as C++ code."""
593    trie = Node()
594    inst_length = 0
595    for inst, expr in instructions:
596        inst_length = max(inst_length, len(inst))
597        trie.insert(inst, expr)
598
599    printer = CodePrinter()
600
601    printer.print_line("char op[{}] = {{'\\0'}};".format(inst_length + 1))
602    printer.print_line("strncpy(op, s[0]->c_str(), {});".format(inst_length))
603
604    def print_leaf(expr, inst):
605        printer.print_line("if (strcmp(op, \"{inst}\") == 0) {{ return {expr}; }}"
606                           .format(inst=inst, expr=expr))
607        printer.print_line("goto parse_error;")
608
609    def emit(node, idx=0):
610        assert node.children
611        printer.print_line("switch (op[{}]) {{".format(idx))
612        with printer.indent():
613            if node.expr:
614                printer.print_line("case '\\0':")
615                with printer.indent():
616                    print_leaf(node.expr, node.inst)
617            children = sorted(node.children.items(), key=lambda pair: pair[0])
618            for prefix, child in children:
619                if child.children:
620                    printer.print_line("case '{}': {{".format(prefix[0]))
621                    with printer.indent():
622                        emit(child, idx + len(prefix))
623                    printer.print_line("}")
624                else:
625                    assert child.expr
626                    printer.print_line("case '{}':".format(prefix[0]))
627                    with printer.indent():
628                        print_leaf(child.expr, child.inst)
629            printer.print_line("default: goto parse_error;")
630        printer.print_line("}")
631
632    emit(trie)
633    printer.print_line("parse_error:")
634    with printer.indent():
635        printer.print_line("throw ParseException(std::string(op), s.line, s.col);")
636
637
638def print_header():
639    print("// DO NOT EDIT! This file generated by scripts/gen-s-parser.py\n")
640    print("// clang-format off\n")
641
642
643def print_footer():
644    print("\n// clang-format on")
645
646
647def generate_with_guard(generator, guard):
648    print("#ifdef {}".format(guard))
649    print("#undef {}".format(guard))
650    generator()
651    print("#endif // {}".format(guard))
652
653
654def main():
655    if sys.version_info.major != 3:
656        import datetime
657        print("It's " + str(datetime.datetime.now().year) + "! Use Python 3!")
658        sys.exit(1)
659    print_header()
660    generate_with_guard(instruction_parser, "INSTRUCTION_PARSER")
661    print_footer()
662
663
664if __name__ == "__main__":
665    main()
666