Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
instruction_spec.cpp
Go to the documentation of this file.
2
5
6#include <array>
7
8namespace bb::avm2 {
9
10namespace {
11
12// This structure is code-generated (but manually set) by the test:
13// DecompositionSelectors.CodeGen (op_decomposition.test.cpp)
14// Ordered to match WireOpCode enum
16{
18 // Compute
19 { WireOpCode::ADD_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
20 { WireOpCode::ADD_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
21 { WireOpCode::SUB_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
22 { WireOpCode::SUB_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
23 { WireOpCode::MUL_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
24 { WireOpCode::MUL_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
25 { WireOpCode::DIV_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
26 { WireOpCode::DIV_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
27 { WireOpCode::FDIV_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
28 { WireOpCode::FDIV_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
29 { WireOpCode::EQ_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
30 { WireOpCode::EQ_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
31 { WireOpCode::LT_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
32 { WireOpCode::LT_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
33 { WireOpCode::LTE_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
34 { WireOpCode::LTE_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
35 { WireOpCode::AND_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
36 { WireOpCode::AND_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
37 { WireOpCode::OR_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
38 { WireOpCode::OR_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
39 { WireOpCode::XOR_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
40 { WireOpCode::XOR_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
41 { WireOpCode::NOT_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
42 { WireOpCode::NOT_16, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
43 { WireOpCode::SHL_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
44 { WireOpCode::SHL_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
45 { WireOpCode::SHR_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
46 { WireOpCode::SHR_16, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
47 { WireOpCode::CAST_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
48 { WireOpCode::CAST_16, { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
49
50 // Execution Environment
51 { WireOpCode::GETENVVAR_16, { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 } },
52 // Execution Environment - Calldata
53 { WireOpCode::CALLDATACOPY, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
54 { WireOpCode::SUCCESSCOPY, { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
55 { WireOpCode::RETURNDATASIZE, { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
56 { WireOpCode::RETURNDATACOPY, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
57
58 // Machine State
59 // Machine State - Internal Control Flow
60 { WireOpCode::JUMP_32, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } },
61 { WireOpCode::JUMPI_32, { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
62 { WireOpCode::INTERNALCALL, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } },
63 { WireOpCode::INTERNALRETURN, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
64 // Machine State - Memory
65 { WireOpCode::SET_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
66 { WireOpCode::SET_16, { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0 } },
67 { WireOpCode::SET_32, { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 } },
68 { WireOpCode::SET_64, { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 } },
69 { WireOpCode::SET_128, { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0 } },
70 { WireOpCode::SET_FF, { 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 } },
71 { WireOpCode::MOV_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
72 { WireOpCode::MOV_16, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
73
74 // World State
75 { WireOpCode::SLOAD, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
76 { WireOpCode::SSTORE, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
77 { WireOpCode::NOTEHASHEXISTS, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
78 { WireOpCode::EMITNOTEHASH, { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
79 { WireOpCode::NULLIFIEREXISTS, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
80 { WireOpCode::EMITNULLIFIER, { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
81 { WireOpCode::L1TOL2MSGEXISTS, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
82 { WireOpCode::GETCONTRACTINSTANCE, { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
83
84 // Accrued Substate
85 { WireOpCode::EMITUNENCRYPTEDLOG, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
86 { WireOpCode::SENDL2TOL1MSG, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
87
88 // Control Flow - Contract Calls
89 { WireOpCode::CALL, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
90 { WireOpCode::STATICCALL, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
91 { WireOpCode::RETURN, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
92 { WireOpCode::REVERT_8, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
93 { WireOpCode::REVERT_16, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
94
95 // Misc
96 { WireOpCode::DEBUGLOG, { 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
97
98 // Gadgets
99 { WireOpCode::POSEIDON2PERM, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
100 { WireOpCode::SHA256COMPRESSION, { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
101 { WireOpCode::KECCAKF1600, { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
102 { WireOpCode::ECADD, { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
103 // Conversions
104 { WireOpCode::TORADIXBE, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
105 };
106 return WireOpCode_DC_SELECTORS;
107}
108
109} // namespace
110
111// Ordered to match WireOpCode enum
113{
114 static const std::unordered_map<WireOpCode, WireInstructionSpec> WIRE_INSTRUCTION_SPEC = {
115 // Compute
117 { .exec_opcode = ExecutionOpCode::ADD,
118 .size_in_bytes = 5,
119 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::ADD_8) } },
121 { .exec_opcode = ExecutionOpCode::ADD,
122 .size_in_bytes = 8,
123 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::ADD_16) } },
125 { .exec_opcode = ExecutionOpCode::SUB,
126 .size_in_bytes = 5,
127 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SUB_8) } },
129 { .exec_opcode = ExecutionOpCode::SUB,
130 .size_in_bytes = 8,
131 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SUB_16) } },
133 { .exec_opcode = ExecutionOpCode::MUL,
134 .size_in_bytes = 5,
135 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::MUL_8) } },
137 { .exec_opcode = ExecutionOpCode::MUL,
138 .size_in_bytes = 8,
139 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::MUL_16) } },
141 { .exec_opcode = ExecutionOpCode::DIV,
142 .size_in_bytes = 5,
143 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::DIV_8) } },
145 { .exec_opcode = ExecutionOpCode::DIV,
146 .size_in_bytes = 8,
147 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::DIV_16) } },
149 { .exec_opcode = ExecutionOpCode::FDIV,
150 .size_in_bytes = 5,
151 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::FDIV_8) } },
153 { .exec_opcode = ExecutionOpCode::FDIV,
154 .size_in_bytes = 8,
155 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::FDIV_16) } },
157 { .exec_opcode = ExecutionOpCode::EQ,
158 .size_in_bytes = 5,
159 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::EQ_8) } },
161 { .exec_opcode = ExecutionOpCode::EQ,
162 .size_in_bytes = 8,
163 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::EQ_16) } },
165 { .exec_opcode = ExecutionOpCode::LT,
166 .size_in_bytes = 5,
167 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::LT_8) } },
169 { .exec_opcode = ExecutionOpCode::LT,
170 .size_in_bytes = 8,
171 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::LT_16) } },
173 { .exec_opcode = ExecutionOpCode::LTE,
174 .size_in_bytes = 5,
175 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::LTE_8) } },
177 { .exec_opcode = ExecutionOpCode::LTE,
178 .size_in_bytes = 8,
179 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::LTE_16) } },
181 { .exec_opcode = ExecutionOpCode::AND,
182 .size_in_bytes = 5,
183 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::AND_8) } },
185 { .exec_opcode = ExecutionOpCode::AND,
186 .size_in_bytes = 8,
187 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::AND_16) } },
189 { .exec_opcode = ExecutionOpCode::OR,
190 .size_in_bytes = 5,
191 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::OR_8) } },
193 { .exec_opcode = ExecutionOpCode::OR,
194 .size_in_bytes = 8,
195 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::OR_16) } },
197 { .exec_opcode = ExecutionOpCode::XOR,
198 .size_in_bytes = 5,
199 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::XOR_8) } },
201 { .exec_opcode = ExecutionOpCode::XOR,
202 .size_in_bytes = 8,
203 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::XOR_16) } },
205 { .exec_opcode = ExecutionOpCode::NOT,
206 .size_in_bytes = 4,
207 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::NOT_8) } },
209 { .exec_opcode = ExecutionOpCode::NOT,
210 .size_in_bytes = 6,
211 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::NOT_16) } },
213 { .exec_opcode = ExecutionOpCode::SHL,
214 .size_in_bytes = 5,
215 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SHL_8) } },
217 { .exec_opcode = ExecutionOpCode::SHL,
218 .size_in_bytes = 8,
219 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SHL_16) } },
221 { .exec_opcode = ExecutionOpCode::SHR,
222 .size_in_bytes = 5,
223 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SHR_8) } },
225 { .exec_opcode = ExecutionOpCode::SHR,
226 .size_in_bytes = 8,
227 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SHR_16) } },
229 {
230 .exec_opcode = ExecutionOpCode::CAST,
231 .size_in_bytes = 5,
232 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::CAST_8),
233 .tag_operand_idx = 3, // op3
234 } },
236 {
237 .exec_opcode = ExecutionOpCode::CAST,
238 .size_in_bytes = 7,
239 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::CAST_16),
240 .tag_operand_idx = 3, // op3
241 } },
242
243 // Execution Environment
245 { .exec_opcode = ExecutionOpCode::GETENVVAR,
246 .size_in_bytes = 5,
247 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::GETENVVAR_16) } },
248 // Execution Environment - Calldata
250 { .exec_opcode = ExecutionOpCode::CALLDATACOPY,
251 .size_in_bytes = 8,
252 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::CALLDATACOPY) } },
254 { .exec_opcode = ExecutionOpCode::SUCCESSCOPY,
255 .size_in_bytes = 4,
256 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SUCCESSCOPY) } },
258 { .exec_opcode = ExecutionOpCode::RETURNDATASIZE,
259 .size_in_bytes = 4,
260 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::RETURNDATASIZE) } },
262 { .exec_opcode = ExecutionOpCode::RETURNDATACOPY,
263 .size_in_bytes = 8,
264 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::RETURNDATACOPY) } },
265
266 // Machine State
267 // Machine State - Internal Control Flow
269 { .exec_opcode = ExecutionOpCode::JUMP,
270 .size_in_bytes = 5,
271 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::JUMP_32) } },
273 { .exec_opcode = ExecutionOpCode::JUMPI,
274 .size_in_bytes = 8,
275 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::JUMPI_32) } },
277 { .exec_opcode = ExecutionOpCode::INTERNALCALL,
278 .size_in_bytes = 5,
279 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::INTERNALCALL) } },
281 { .exec_opcode = ExecutionOpCode::INTERNALRETURN,
282 .size_in_bytes = 1,
283 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::INTERNALRETURN) } },
284 // Machine State - Memory
286 {
287 .exec_opcode = ExecutionOpCode::SET,
288 .size_in_bytes = 5,
289 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_8),
290 .tag_operand_idx = 2, // op2
291 } },
293 {
294 .exec_opcode = ExecutionOpCode::SET,
295 .size_in_bytes = 7,
296 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_16),
297 .tag_operand_idx = 2, // op2
298 } },
300 {
301 .exec_opcode = ExecutionOpCode::SET,
302 .size_in_bytes = 9,
303 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_32),
304 .tag_operand_idx = 2, // op2
305 } },
307 {
308 .exec_opcode = ExecutionOpCode::SET,
309 .size_in_bytes = 13,
310 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_64),
311 .tag_operand_idx = 2, // op2
312 } },
314 {
315 .exec_opcode = ExecutionOpCode::SET,
316 .size_in_bytes = 21,
317 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_128),
318 .tag_operand_idx = 2, // op2
319 } },
321 {
322 .exec_opcode = ExecutionOpCode::SET,
323 .size_in_bytes = 37,
324 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_FF),
325 .tag_operand_idx = 2, // op2
326 } },
328 { .exec_opcode = ExecutionOpCode::MOV,
329 .size_in_bytes = 4,
330 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::MOV_8) } },
332 { .exec_opcode = ExecutionOpCode::MOV,
333 .size_in_bytes = 6,
334 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::MOV_16) } },
335
336 // World State
338 { .exec_opcode = ExecutionOpCode::SLOAD,
339 .size_in_bytes = 6,
340 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SLOAD) } },
342 { .exec_opcode = ExecutionOpCode::SSTORE,
343 .size_in_bytes = 6,
344 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SSTORE) } },
346 { .exec_opcode = ExecutionOpCode::NOTEHASHEXISTS,
347 .size_in_bytes = 8,
348 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::NOTEHASHEXISTS) } },
350 { .exec_opcode = ExecutionOpCode::EMITNOTEHASH,
351 .size_in_bytes = 4,
352 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::EMITNOTEHASH) } },
354 { .exec_opcode = ExecutionOpCode::NULLIFIEREXISTS,
355 .size_in_bytes = 8,
356 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::NULLIFIEREXISTS) } },
358 { .exec_opcode = ExecutionOpCode::EMITNULLIFIER,
359 .size_in_bytes = 4,
360 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::EMITNULLIFIER) } },
362 { .exec_opcode = ExecutionOpCode::L1TOL2MSGEXISTS,
363 .size_in_bytes = 8,
364 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::L1TOL2MSGEXISTS) } },
367 .size_in_bytes = 7,
368 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::GETCONTRACTINSTANCE) } },
369
370 // Accrued Substate
373 .size_in_bytes = 6,
374 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::EMITUNENCRYPTEDLOG) } },
376 { .exec_opcode = ExecutionOpCode::SENDL2TOL1MSG,
377 .size_in_bytes = 6,
378 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SENDL2TOL1MSG) } },
379
380 // Control Flow - Contract Calls
382 { .exec_opcode = ExecutionOpCode::CALL,
383 .size_in_bytes = 13,
384 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::CALL) } },
386 { .exec_opcode = ExecutionOpCode::STATICCALL,
387 .size_in_bytes = 13,
388 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::STATICCALL) } },
390 { .exec_opcode = ExecutionOpCode::RETURN,
391 .size_in_bytes = 6,
392 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::RETURN) } },
394 { .exec_opcode = ExecutionOpCode::REVERT,
395 .size_in_bytes = 4,
396 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::REVERT_8) } },
398 { .exec_opcode = ExecutionOpCode::REVERT,
399 .size_in_bytes = 6,
400 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::REVERT_16) } },
401
402 // Misc
404 { .exec_opcode = ExecutionOpCode::DEBUGLOG,
405 .size_in_bytes = 12,
406 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::DEBUGLOG) } },
407
408 // Gadgets
410 { .exec_opcode = ExecutionOpCode::POSEIDON2PERM,
411 .size_in_bytes = 6,
412 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::POSEIDON2PERM) } },
414 { .exec_opcode = ExecutionOpCode::SHA256COMPRESSION,
415 .size_in_bytes = 8,
416 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SHA256COMPRESSION) } },
418 { .exec_opcode = ExecutionOpCode::KECCAKF1600,
419 .size_in_bytes = 6,
420 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::KECCAKF1600) } },
422 { .exec_opcode = ExecutionOpCode::ECADD,
423 .size_in_bytes = 17,
424 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::ECADD) } },
425 // Conversions
427 { .exec_opcode = ExecutionOpCode::TORADIXBE,
428 .size_in_bytes = 13,
429 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::TORADIXBE) } },
430 };
431 return WIRE_INSTRUCTION_SPEC;
432}
433
435
437{
438 inputs.push_back(tag);
439 return *this;
440}
441
443{
444 inputs.insert(inputs.end(), tags.begin(), tags.end());
445 return *this;
446}
447
449{
450 has_output = true;
451 return *this;
452}
453
455{
456 return index < total_registers();
457}
458
460{
461 return index >= inputs.size() && index < total_registers();
462}
463
465{
466 return index < inputs.size() && inputs.at(index).has_value();
467}
468
473
474// Ordered to match ExecutionOpCode enum
476{
477 static const std::unordered_map<ExecutionOpCode, ExecInstructionSpec> EXEC_INSTRUCTION_SPEC = {
479 { .num_addresses = 3,
480 .gas_cost = { .opcode_gas = AVM_ADD_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
481 .register_info = RegisterInfo()
483 /*b*/ RegisterInfo::ANY_TAG })
484 .add_output(/*c*/) } },
486 { .num_addresses = 3,
487 .gas_cost = { .opcode_gas = AVM_SUB_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
488 .register_info = RegisterInfo()
490 /*b*/ RegisterInfo::ANY_TAG })
491 .add_output(/*c*/) } },
493 { .num_addresses = 3,
494 .gas_cost = { .opcode_gas = AVM_MUL_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
495 .register_info = RegisterInfo()
497 /*b*/ RegisterInfo::ANY_TAG })
498 .add_output(/*c*/) } },
500 { .num_addresses = 3,
501 .gas_cost = { .opcode_gas = AVM_DIV_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
502 .register_info = RegisterInfo()
504 /*b*/ RegisterInfo::ANY_TAG })
505 .add_output(/*c*/) } },
507 { .num_addresses = 3,
508 .gas_cost = { .opcode_gas = AVM_FDIV_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
509 .register_info = RegisterInfo()
510 .add_inputs({ /*a*/ ValueTag::FF,
511 /*b*/ ValueTag::FF })
512 .add_output(/*c*/) } },
514 { .num_addresses = 3,
515 .gas_cost = { .opcode_gas = AVM_EQ_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
516 .register_info = RegisterInfo()
518 /*b*/ RegisterInfo::ANY_TAG })
519 .add_output(/*c*/) } },
521 { .num_addresses = 3,
522 .gas_cost = { .opcode_gas = AVM_LT_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
523 .register_info = RegisterInfo()
525 /*b*/ RegisterInfo::ANY_TAG })
526 .add_output(/*c*/) } },
528 { .num_addresses = 3,
529 .gas_cost = { .opcode_gas = AVM_LTE_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
530 .register_info = RegisterInfo()
532 /*b*/ RegisterInfo::ANY_TAG })
533 .add_output(/*c*/) } },
535 { .num_addresses = 3,
536 .gas_cost = { .opcode_gas = AVM_AND_BASE_L2_GAS,
537 .base_da = 0,
538 .dyn_l2 = AVM_BITWISE_DYN_L2_GAS,
539 .dyn_da = 0 },
540 .dyn_gas_id = AVM_DYN_GAS_ID_BITWISE,
541 .register_info = RegisterInfo()
543 .add_output(/*c*/) } },
545 { .num_addresses = 3,
546 .gas_cost = { .opcode_gas = AVM_OR_BASE_L2_GAS,
547 .base_da = 0,
548 .dyn_l2 = AVM_BITWISE_DYN_L2_GAS,
549 .dyn_da = 0 },
550 .dyn_gas_id = AVM_DYN_GAS_ID_BITWISE,
551 .register_info = RegisterInfo()
553 .add_output(/*c*/) } },
555 { .num_addresses = 3,
556 .gas_cost = { .opcode_gas = AVM_XOR_BASE_L2_GAS,
557 .base_da = 0,
558 .dyn_l2 = AVM_BITWISE_DYN_L2_GAS,
559 .dyn_da = 0 },
560 .dyn_gas_id = AVM_DYN_GAS_ID_BITWISE,
561 .register_info = RegisterInfo()
563 .add_output(/*c*/) } },
565 { .num_addresses = 2,
566 .gas_cost = { .opcode_gas = AVM_NOT_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
567 .register_info = RegisterInfo().add_inputs({ /*a*/ RegisterInfo::ANY_TAG }).add_output(/*b*/) } },
569 { .num_addresses = 3,
570 .gas_cost = { .opcode_gas = AVM_SHL_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
571 .register_info = RegisterInfo()
573 /*b*/ RegisterInfo::ANY_TAG })
574 .add_output(/*c*/) } },
576 { .num_addresses = 3,
577 .gas_cost = { .opcode_gas = AVM_SHR_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
578 .register_info = RegisterInfo()
580 /*b*/ RegisterInfo::ANY_TAG })
581 .add_output(/*c*/) } },
583 { .num_addresses = 2,
584 .gas_cost = { .opcode_gas = AVM_CAST_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
585 .register_info = RegisterInfo().add_input(/*a*/ RegisterInfo::ANY_TAG).add_output(/*c*/) } },
587 { .num_addresses = 1,
588 .gas_cost = { .opcode_gas = AVM_GETENVVAR_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
589 .register_info = RegisterInfo().add_output(/*dst*/) } },
591 { .num_addresses = 3,
592 .gas_cost = { .opcode_gas = AVM_CALLDATACOPY_BASE_L2_GAS,
593 .base_da = 0,
595 .dyn_da = 0 },
596 .dyn_gas_id = AVM_DYN_GAS_ID_CALLDATACOPY,
597 .register_info =
598 RegisterInfo().add_inputs({ /*cd_copy_size*/ ValueTag::U32, /*cd_offset_read*/ ValueTag::U32 }) } },
600 { .num_addresses = 1,
601 .gas_cost = { .opcode_gas = AVM_SUCCESSCOPY_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
602 .register_info = RegisterInfo().add_output(/*dst*/) } },
604 { .num_addresses = 1,
605 .gas_cost = { .opcode_gas = AVM_RETURNDATASIZE_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
606 .register_info = RegisterInfo().add_output(/*dst*/) } },
608 { .num_addresses = 3,
609 .gas_cost = { .opcode_gas = AVM_RETURNDATACOPY_BASE_L2_GAS,
610 .base_da = 0,
612 .dyn_da = 0 },
613 .dyn_gas_id = AVM_DYN_GAS_ID_RETURNDATACOPY,
614 .register_info =
615 RegisterInfo().add_inputs({ /*rd_copy_size*/ ValueTag::U32, /*rd_offset_read*/ ValueTag::U32 }) } },
617 { .num_addresses = 0,
618 .gas_cost = { .opcode_gas = AVM_JUMP_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } },
620 { .num_addresses = 1,
621 .gas_cost = { .opcode_gas = AVM_JUMPI_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
622 .register_info = RegisterInfo().add_input(/*cond*/ ValueTag::U1) } },
624 {
625 .num_addresses = 0,
626 .gas_cost = { .opcode_gas = AVM_INTERNALCALL_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
627 } },
629 { .num_addresses = 0,
630 .gas_cost = { .opcode_gas = AVM_INTERNALRETURN_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } },
632 { .num_addresses = 1,
633 .gas_cost = { .opcode_gas = AVM_SET_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
634 .register_info = RegisterInfo().add_output(/*dst*/) } },
636 { .num_addresses = 2,
637 .gas_cost = { .opcode_gas = AVM_MOV_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
638 .register_info = RegisterInfo().add_input(/*src*/).add_output(/*dst*/) } },
640 { .num_addresses = 2,
641 .gas_cost = { .opcode_gas = AVM_SLOAD_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
642 .register_info = RegisterInfo().add_input(/*slot*/ ValueTag::FF).add_output(/*dst*/) } },
644 { .num_addresses = 2,
645 .gas_cost = { .opcode_gas = AVM_SSTORE_BASE_L2_GAS,
646 .base_da = 0,
647 .dyn_l2 = 0,
648 .dyn_da = AVM_SSTORE_DYN_DA_GAS },
649 .dyn_gas_id = AVM_DYN_GAS_ID_SSTORE,
650 .register_info = RegisterInfo().add_inputs({ /*src*/ ValueTag::FF, /*slot*/ ValueTag::FF }) } },
652 { .num_addresses = 3,
653 .gas_cost = { .opcode_gas = AVM_NOTEHASHEXISTS_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
654 .register_info = RegisterInfo()
655 .add_inputs({ /*unique_note_hash*/ ValueTag::FF, /*leaf_index*/ ValueTag::U64 })
656 .add_output(/*exists*/) } },
658 { .num_addresses = 1,
659 .gas_cost = { .opcode_gas = AVM_EMITNOTEHASH_BASE_L2_GAS,
661 .dyn_l2 = 0,
662 .dyn_da = 0 },
663 .register_info = RegisterInfo().add_input(/*note_hash*/ ValueTag::FF) } },
665 { .num_addresses = 3,
666 .gas_cost = { .opcode_gas = AVM_NULLIFIEREXISTS_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
667 .register_info = RegisterInfo()
668 .add_inputs({ /*nullifier*/ ValueTag::FF,
669 /*address*/ ValueTag::FF })
670 .add_output(/*exists*/) } },
672 { .num_addresses = 1,
673 .gas_cost = { .opcode_gas = AVM_EMITNULLIFIER_BASE_L2_GAS,
675 .dyn_l2 = 0,
676 .dyn_da = 0 },
677 .register_info = RegisterInfo().add_input(/*nullifier*/ ValueTag::FF) } },
679 { .num_addresses = 3,
680 .gas_cost = { .opcode_gas = AVM_L1TOL2MSGEXISTS_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
681 .register_info = RegisterInfo()
682 .add_inputs({ /*msg_hash*/ ValueTag::FF, /*leaf_index*/ ValueTag::U64 })
683 .add_output(/*exists*/) } },
685 { .num_addresses = 2,
686 .gas_cost = { .opcode_gas = AVM_GETCONTRACTINSTANCE_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
687 .register_info = RegisterInfo().add_input(/*contract_address*/ ValueTag::FF) } },
689 { .num_addresses = 2,
690 .gas_cost = { .opcode_gas = AVM_EMITUNENCRYPTEDLOG_BASE_L2_GAS,
695 .register_info = RegisterInfo().add_inputs({ ValueTag::U32 }) } },
697 { .num_addresses = 2,
698 .gas_cost = { .opcode_gas = AVM_SENDL2TOL1MSG_BASE_L2_GAS,
700 .dyn_l2 = 0,
701 .dyn_da = 0 },
702 .register_info =
703 RegisterInfo().add_inputs({ /* recipient */ ValueTag::FF, /* content */ ValueTag::FF }) } },
705 { .num_addresses = 5,
706 .gas_cost = { .opcode_gas = AVM_CALL_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
707 .register_info = RegisterInfo().add_inputs({ /*l2_gas*/ ValueTag::U32,
708 /*da_gas*/ ValueTag::U32,
709 /*contract_address*/ ValueTag::FF,
710 /*cd_size*/ ValueTag::U32 }) } },
712 { .num_addresses = 5,
713 .gas_cost = { .opcode_gas = AVM_STATICCALL_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
714 .register_info = RegisterInfo().add_inputs({ /*l2_gas*/ ValueTag::U32,
715 /*da_gas*/ ValueTag::U32,
716 /*contract_address*/ ValueTag::FF,
717 /*cd_size*/ ValueTag::U32 }) } },
719 { .num_addresses = 2,
720 .gas_cost = { .opcode_gas = AVM_RETURN_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
721 .register_info = RegisterInfo().add_input(/*rd_size*/ ValueTag::U32) } },
723 { .num_addresses = 2,
724 .gas_cost = { .opcode_gas = AVM_REVERT_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
725 .register_info = RegisterInfo().add_input(/*rev_size*/ ValueTag::U32) } },
727 { .num_addresses = 4,
728 .gas_cost = { .opcode_gas = AVM_DEBUGLOG_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
729 // We don't set the right inputs for debuglog because we make it a noop.
730 .register_info = RegisterInfo() } },
732 { .num_addresses = 2,
733 .gas_cost = { .opcode_gas = AVM_POSEIDON2_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } },
735 { .num_addresses = 3,
736 .gas_cost = { .opcode_gas = AVM_SHA256COMPRESSION_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } },
738 { .num_addresses = 2,
739 .gas_cost = { .opcode_gas = AVM_KECCAKF1600_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } },
741 { .num_addresses = 7,
742 .gas_cost = { .opcode_gas = AVM_ECADD_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
743 .register_info = RegisterInfo().add_inputs({ /*p_x=*/ValueTag::FF,
744 /*p_y=*/ValueTag::FF,
745 /*p_inf*/ ValueTag::U1,
746 /*q_x*/ ValueTag::FF,
747 /*q_y*/ ValueTag::FF,
748 /*q_inf*/ ValueTag::U1 }) } },
750 { .num_addresses = 5,
751 .gas_cost = { .opcode_gas = AVM_TORADIXBE_BASE_L2_GAS,
752 .base_da = 0,
753 .dyn_l2 = AVM_TORADIXBE_DYN_L2_GAS,
754 .dyn_da = 0 },
755 .dyn_gas_id = AVM_DYN_GAS_ID_TORADIX,
756 .register_info = RegisterInfo().add_inputs({ /*value*/ ValueTag::FF,
757 /*radix*/ ValueTag::U32,
758 /*num_limbs*/ ValueTag::U32,
759 /*is_output_bit*/ ValueTag::U1 }) } },
760 };
761 return EXEC_INSTRUCTION_SPEC;
762}
763
764} // namespace bb::avm2
#define AVM_JUMPI_BASE_L2_GAS
#define AVM_DYN_GAS_ID_RETURNDATACOPY
#define AVM_SHL_BASE_L2_GAS
#define AVM_RETURN_BASE_L2_GAS
#define AVM_MUL_BASE_L2_GAS
#define AVM_CAST_BASE_L2_GAS
#define AVM_POSEIDON2_BASE_L2_GAS
#define AVM_CALLDATACOPY_DYN_L2_GAS
#define AVM_TORADIXBE_DYN_L2_GAS
#define AVM_SUCCESSCOPY_BASE_L2_GAS
#define AVM_NOT_BASE_L2_GAS
#define AVM_GETENVVAR_BASE_L2_GAS
#define AVM_OR_BASE_L2_GAS
#define AVM_SLOAD_BASE_L2_GAS
#define AVM_DYN_GAS_ID_SSTORE
#define AVM_EMITUNENCRYPTEDLOG_DYN_DA_GAS
#define AVM_EMITUNENCRYPTEDLOG_BASE_DA_GAS
#define AVM_ADD_BASE_L2_GAS
#define AVM_STATICCALL_BASE_L2_GAS
#define AVM_BITWISE_DYN_L2_GAS
#define AVM_RETURNDATACOPY_DYN_L2_GAS
#define AVM_DYN_GAS_ID_TORADIX
#define AVM_INTERNALRETURN_BASE_L2_GAS
#define AVM_REVERT_BASE_L2_GAS
#define AVM_EMITUNENCRYPTEDLOG_BASE_L2_GAS
#define AVM_EMITNULLIFIER_BASE_DA_GAS
#define AVM_SENDL2TOL1MSG_BASE_L2_GAS
#define AVM_EMITNOTEHASH_BASE_L2_GAS
#define AVM_RETURNDATASIZE_BASE_L2_GAS
#define AVM_JUMP_BASE_L2_GAS
#define AVM_INTERNALCALL_BASE_L2_GAS
#define AVM_NOTEHASHEXISTS_BASE_L2_GAS
#define AVM_NULLIFIEREXISTS_BASE_L2_GAS
#define AVM_XOR_BASE_L2_GAS
#define AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS
#define AVM_AND_BASE_L2_GAS
#define AVM_DEBUGLOG_BASE_L2_GAS
#define AVM_EMITNULLIFIER_BASE_L2_GAS
#define AVM_DYN_GAS_ID_CALLDATACOPY
#define AVM_SET_BASE_L2_GAS
#define AVM_EQ_BASE_L2_GAS
#define AVM_DIV_BASE_L2_GAS
#define AVM_SENDL2TOL1MSG_BASE_DA_GAS
#define AVM_EMITNOTEHASH_BASE_DA_GAS
#define AVM_KECCAKF1600_BASE_L2_GAS
#define AVM_LT_BASE_L2_GAS
#define AVM_SSTORE_BASE_L2_GAS
#define AVM_DYN_GAS_ID_EMITUNENCRYPTEDLOG
#define AVM_DYN_GAS_ID_BITWISE
#define AVM_SUB_BASE_L2_GAS
#define AVM_CALLDATACOPY_BASE_L2_GAS
#define AVM_TORADIXBE_BASE_L2_GAS
#define AVM_FDIV_BASE_L2_GAS
#define AVM_CALL_BASE_L2_GAS
#define AVM_L1TOL2MSGEXISTS_BASE_L2_GAS
#define AVM_ECADD_BASE_L2_GAS
#define AVM_SSTORE_DYN_DA_GAS
#define AVM_SHA256COMPRESSION_BASE_L2_GAS
#define AVM_RETURNDATACOPY_BASE_L2_GAS
#define AVM_SHR_BASE_L2_GAS
#define AVM_LTE_BASE_L2_GAS
#define AVM_MOV_BASE_L2_GAS
#define AVM_GETCONTRACTINSTANCE_BASE_L2_GAS
RegisterInfo & add_inputs(const std::vector< std::optional< ValueTag > > &tags)
std::optional< ValueTag > expected_tag(size_t index) const
RegisterInfo & add_input(std::optional< ValueTag > tag=std::nullopt)
std::vector< std::optional< ValueTag > > inputs
const std::unordered_map< WireOpCode, WireInstructionSpec > & get_wire_instruction_spec()
const std::unordered_map< ExecutionOpCode, ExecInstructionSpec > & get_exec_instruction_spec()
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13