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
3#include "barretenberg/aztec/aztec_constants.hpp"
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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
20 { WireOpCode::ADD_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
22 { WireOpCode::SUB_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
24 { WireOpCode::MUL_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
26 { WireOpCode::DIV_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
28 { WireOpCode::FDIV_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
30 { WireOpCode::EQ_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
32 { WireOpCode::LT_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
34 { WireOpCode::LTE_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
36 { WireOpCode::AND_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
38 { WireOpCode::OR_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
40 { WireOpCode::XOR_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
42 { WireOpCode::NOT_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
44 { WireOpCode::SHL_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
46 { WireOpCode::SHR_16, { 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, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
48 { WireOpCode::CAST_16, { 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
49 // Execution Environment
50 { WireOpCode::GETENVVAR_16, { 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 } },
51 // Execution Environment - Calldata
52 { WireOpCode::CALLDATACOPY, { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
53 { WireOpCode::SUCCESSCOPY, { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
54 { WireOpCode::RETURNDATASIZE, { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
55 { WireOpCode::RETURNDATACOPY, { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
56 // Machine State
57 // Machine State - Internal Control Flow
58 { WireOpCode::JUMP_32, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } },
59 { WireOpCode::JUMPI_32, { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
60 { WireOpCode::INTERNALCALL, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } },
61 { WireOpCode::INTERNALRETURN, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
62 // Machine State - Memory
63 { WireOpCode::SET_8, { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } },
64 { WireOpCode::SET_16, { 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0 } },
65 { WireOpCode::SET_32, { 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 } },
66 { WireOpCode::SET_64, { 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 } },
67 { WireOpCode::SET_128, { 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0 } },
68 { WireOpCode::SET_FF, { 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 } },
69 { WireOpCode::MOV_8, { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
70 { WireOpCode::MOV_16, { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
71 // World State
72 { WireOpCode::SLOAD, { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
73 { WireOpCode::SSTORE, { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
74 { WireOpCode::NOTEHASHEXISTS, { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
75 { WireOpCode::EMITNOTEHASH, { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
76 { WireOpCode::NULLIFIEREXISTS, { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
77 { WireOpCode::EMITNULLIFIER, { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
78 { WireOpCode::L1TOL2MSGEXISTS, { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
79 { WireOpCode::GETCONTRACTINSTANCE, { 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
80 // Accrued Substate
81 { WireOpCode::EMITPUBLICLOG, { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
82 { WireOpCode::SENDL2TOL1MSG, { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
83 // Control Flow - Contract Calls
84 { WireOpCode::CALL, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
85 { WireOpCode::STATICCALL, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
86 { WireOpCode::RETURN, { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
87 { WireOpCode::REVERT_8, { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
88 { WireOpCode::REVERT_16, { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
89 // Misc
90 { WireOpCode::DEBUGLOG, { 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
91 // Gadgets
92 { WireOpCode::POSEIDON2PERM, { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
93 { WireOpCode::SHA256COMPRESSION, { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
94 { WireOpCode::KECCAKF1600, { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
95 { WireOpCode::ECADD, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
96 // Conversions
97 { WireOpCode::TORADIXBE, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
98 };
99 return WireOpCode_DC_SELECTORS;
100}
101
102} // namespace
103
104// Ordered to match WireOpCode enum
106{
107 static const std::unordered_map<WireOpCode, WireInstructionSpec> WIRE_INSTRUCTION_SPEC = {
108 // Compute
110 { .exec_opcode = ExecutionOpCode::ADD,
111 .size_in_bytes = 5,
112 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::ADD_8) } },
114 { .exec_opcode = ExecutionOpCode::ADD,
115 .size_in_bytes = 8,
116 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::ADD_16) } },
118 { .exec_opcode = ExecutionOpCode::SUB,
119 .size_in_bytes = 5,
120 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SUB_8) } },
122 { .exec_opcode = ExecutionOpCode::SUB,
123 .size_in_bytes = 8,
124 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SUB_16) } },
126 { .exec_opcode = ExecutionOpCode::MUL,
127 .size_in_bytes = 5,
128 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::MUL_8) } },
130 { .exec_opcode = ExecutionOpCode::MUL,
131 .size_in_bytes = 8,
132 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::MUL_16) } },
134 { .exec_opcode = ExecutionOpCode::DIV,
135 .size_in_bytes = 5,
136 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::DIV_8) } },
138 { .exec_opcode = ExecutionOpCode::DIV,
139 .size_in_bytes = 8,
140 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::DIV_16) } },
142 { .exec_opcode = ExecutionOpCode::FDIV,
143 .size_in_bytes = 5,
144 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::FDIV_8) } },
146 { .exec_opcode = ExecutionOpCode::FDIV,
147 .size_in_bytes = 8,
148 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::FDIV_16) } },
150 { .exec_opcode = ExecutionOpCode::EQ,
151 .size_in_bytes = 5,
152 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::EQ_8) } },
154 { .exec_opcode = ExecutionOpCode::EQ,
155 .size_in_bytes = 8,
156 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::EQ_16) } },
158 { .exec_opcode = ExecutionOpCode::LT,
159 .size_in_bytes = 5,
160 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::LT_8) } },
162 { .exec_opcode = ExecutionOpCode::LT,
163 .size_in_bytes = 8,
164 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::LT_16) } },
166 { .exec_opcode = ExecutionOpCode::LTE,
167 .size_in_bytes = 5,
168 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::LTE_8) } },
170 { .exec_opcode = ExecutionOpCode::LTE,
171 .size_in_bytes = 8,
172 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::LTE_16) } },
174 { .exec_opcode = ExecutionOpCode::AND,
175 .size_in_bytes = 5,
176 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::AND_8) } },
178 { .exec_opcode = ExecutionOpCode::AND,
179 .size_in_bytes = 8,
180 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::AND_16) } },
182 { .exec_opcode = ExecutionOpCode::OR,
183 .size_in_bytes = 5,
184 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::OR_8) } },
186 { .exec_opcode = ExecutionOpCode::OR,
187 .size_in_bytes = 8,
188 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::OR_16) } },
190 { .exec_opcode = ExecutionOpCode::XOR,
191 .size_in_bytes = 5,
192 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::XOR_8) } },
194 { .exec_opcode = ExecutionOpCode::XOR,
195 .size_in_bytes = 8,
196 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::XOR_16) } },
198 { .exec_opcode = ExecutionOpCode::NOT,
199 .size_in_bytes = 4,
200 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::NOT_8) } },
202 { .exec_opcode = ExecutionOpCode::NOT,
203 .size_in_bytes = 6,
204 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::NOT_16) } },
206 { .exec_opcode = ExecutionOpCode::SHL,
207 .size_in_bytes = 5,
208 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SHL_8) } },
210 { .exec_opcode = ExecutionOpCode::SHL,
211 .size_in_bytes = 8,
212 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SHL_16) } },
214 { .exec_opcode = ExecutionOpCode::SHR,
215 .size_in_bytes = 5,
216 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SHR_8) } },
218 { .exec_opcode = ExecutionOpCode::SHR,
219 .size_in_bytes = 8,
220 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SHR_16) } },
222 {
223 .exec_opcode = ExecutionOpCode::CAST,
224 .size_in_bytes = 5,
225 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::CAST_8),
226 .tag_operand_idx = 3, // op3
227 } },
229 {
230 .exec_opcode = ExecutionOpCode::CAST,
231 .size_in_bytes = 7,
232 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::CAST_16),
233 .tag_operand_idx = 3, // op3
234 } },
235
236 // Execution Environment
238 { .exec_opcode = ExecutionOpCode::GETENVVAR,
239 .size_in_bytes = 5,
240 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::GETENVVAR_16) } },
241 // Execution Environment - Calldata
243 { .exec_opcode = ExecutionOpCode::CALLDATACOPY,
244 .size_in_bytes = 8,
245 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::CALLDATACOPY) } },
247 { .exec_opcode = ExecutionOpCode::SUCCESSCOPY,
248 .size_in_bytes = 4,
249 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SUCCESSCOPY) } },
251 { .exec_opcode = ExecutionOpCode::RETURNDATASIZE,
252 .size_in_bytes = 4,
253 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::RETURNDATASIZE) } },
255 { .exec_opcode = ExecutionOpCode::RETURNDATACOPY,
256 .size_in_bytes = 8,
257 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::RETURNDATACOPY) } },
258
259 // Machine State
260 // Machine State - Internal Control Flow
262 { .exec_opcode = ExecutionOpCode::JUMP,
263 .size_in_bytes = 5,
264 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::JUMP_32) } },
266 { .exec_opcode = ExecutionOpCode::JUMPI,
267 .size_in_bytes = 8,
268 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::JUMPI_32) } },
270 { .exec_opcode = ExecutionOpCode::INTERNALCALL,
271 .size_in_bytes = 5,
272 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::INTERNALCALL) } },
274 { .exec_opcode = ExecutionOpCode::INTERNALRETURN,
275 .size_in_bytes = 1,
276 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::INTERNALRETURN) } },
277 // Machine State - Memory
279 {
280 .exec_opcode = ExecutionOpCode::SET,
281 .size_in_bytes = 5,
282 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_8),
283 .tag_operand_idx = 2, // op2
284 } },
286 {
287 .exec_opcode = ExecutionOpCode::SET,
288 .size_in_bytes = 7,
289 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_16),
290 .tag_operand_idx = 2, // op2
291 } },
293 {
294 .exec_opcode = ExecutionOpCode::SET,
295 .size_in_bytes = 9,
296 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_32),
297 .tag_operand_idx = 2, // op2
298 } },
300 {
301 .exec_opcode = ExecutionOpCode::SET,
302 .size_in_bytes = 13,
303 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_64),
304 .tag_operand_idx = 2, // op2
305 } },
307 {
308 .exec_opcode = ExecutionOpCode::SET,
309 .size_in_bytes = 21,
310 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_128),
311 .tag_operand_idx = 2, // op2
312 } },
314 {
315 .exec_opcode = ExecutionOpCode::SET,
316 .size_in_bytes = 37,
317 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SET_FF),
318 .tag_operand_idx = 2, // op2
319 } },
321 { .exec_opcode = ExecutionOpCode::MOV,
322 .size_in_bytes = 4,
323 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::MOV_8) } },
325 { .exec_opcode = ExecutionOpCode::MOV,
326 .size_in_bytes = 6,
327 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::MOV_16) } },
328
329 // World State
331 { .exec_opcode = ExecutionOpCode::SLOAD,
332 .size_in_bytes = 8,
333 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SLOAD) } },
335 { .exec_opcode = ExecutionOpCode::SSTORE,
336 .size_in_bytes = 6,
337 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SSTORE) } },
339 { .exec_opcode = ExecutionOpCode::NOTEHASHEXISTS,
340 .size_in_bytes = 8,
341 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::NOTEHASHEXISTS) } },
343 { .exec_opcode = ExecutionOpCode::EMITNOTEHASH,
344 .size_in_bytes = 4,
345 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::EMITNOTEHASH) } },
347 { .exec_opcode = ExecutionOpCode::NULLIFIEREXISTS,
348 .size_in_bytes = 6,
349 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::NULLIFIEREXISTS) } },
351 { .exec_opcode = ExecutionOpCode::EMITNULLIFIER,
352 .size_in_bytes = 4,
353 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::EMITNULLIFIER) } },
355 { .exec_opcode = ExecutionOpCode::L1TOL2MSGEXISTS,
356 .size_in_bytes = 8,
357 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::L1TOL2MSGEXISTS) } },
360 .size_in_bytes = 7,
361 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::GETCONTRACTINSTANCE) } },
362
363 // Accrued Substate
365 { .exec_opcode = ExecutionOpCode::EMITPUBLICLOG,
366 .size_in_bytes = 6,
367 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::EMITPUBLICLOG) } },
369 { .exec_opcode = ExecutionOpCode::SENDL2TOL1MSG,
370 .size_in_bytes = 6,
371 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SENDL2TOL1MSG) } },
372
373 // Control Flow - Contract Calls
375 { .exec_opcode = ExecutionOpCode::CALL,
376 .size_in_bytes = 13,
377 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::CALL) } },
379 { .exec_opcode = ExecutionOpCode::STATICCALL,
380 .size_in_bytes = 13,
381 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::STATICCALL) } },
383 { .exec_opcode = ExecutionOpCode::RETURN,
384 .size_in_bytes = 6,
385 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::RETURN) } },
387 { .exec_opcode = ExecutionOpCode::REVERT,
388 .size_in_bytes = 4,
389 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::REVERT_8) } },
391 { .exec_opcode = ExecutionOpCode::REVERT,
392 .size_in_bytes = 6,
393 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::REVERT_16) } },
394
395 // Misc
397 { .exec_opcode = ExecutionOpCode::DEBUGLOG,
398 .size_in_bytes = 12,
399 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::DEBUGLOG) } },
400
401 // Gadgets
403 { .exec_opcode = ExecutionOpCode::POSEIDON2PERM,
404 .size_in_bytes = 6,
405 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::POSEIDON2PERM) } },
407 { .exec_opcode = ExecutionOpCode::SHA256COMPRESSION,
408 .size_in_bytes = 8,
409 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::SHA256COMPRESSION) } },
411 { .exec_opcode = ExecutionOpCode::KECCAKF1600,
412 .size_in_bytes = 6,
413 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::KECCAKF1600) } },
415 { .exec_opcode = ExecutionOpCode::ECADD,
416 .size_in_bytes = 13,
417 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::ECADD) } },
418 // Conversions
420 { .exec_opcode = ExecutionOpCode::TORADIXBE,
421 .size_in_bytes = 13,
422 .op_dc_selectors = get_wire_opcode_dc_selectors().at(WireOpCode::TORADIXBE) } },
423 };
424 return WIRE_INSTRUCTION_SPEC;
425}
426
428
430{
431 inputs.push_back(tag);
432 return *this;
433}
434
436{
437 inputs.insert(inputs.end(), tags.begin(), tags.end());
438 return *this;
439}
440
442{
443 has_output = true;
444 return *this;
445}
446
448{
449 return index < total_registers();
450}
451
453{
454 return index >= inputs.size() && index < total_registers();
455}
456
458{
459 return index < inputs.size() && inputs[index].has_value();
460}
461
466
467// Ordered to match ExecutionOpCode enum
469{
470 static const std::unordered_map<ExecutionOpCode, ExecInstructionSpec> EXEC_INSTRUCTION_SPEC = {
472 { .num_addresses = 3,
473 .gas_cost = { .opcode_gas = AVM_ADD_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
474 .register_info = RegisterInfo()
476 /*b*/ RegisterInfo::ANY_TAG })
477 .add_output(/*c*/) } },
479 { .num_addresses = 3,
480 .gas_cost = { .opcode_gas = AVM_SUB_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_MUL_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_DIV_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_FDIV_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
502 .register_info = RegisterInfo()
503 .add_inputs({ /*a*/ ValueTag::FF,
504 /*b*/ ValueTag::FF })
505 .add_output(/*c*/) } },
507 { .num_addresses = 3,
508 .gas_cost = { .opcode_gas = AVM_EQ_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
509 .register_info = RegisterInfo()
511 /*b*/ RegisterInfo::ANY_TAG })
512 .add_output(/*c*/) } },
514 { .num_addresses = 3,
515 .gas_cost = { .opcode_gas = AVM_LT_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_LTE_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_AND_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
530 .register_info = RegisterInfo()
532 .add_output(/*c*/) } },
534 { .num_addresses = 3,
535 .gas_cost = { .opcode_gas = AVM_OR_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
536 .register_info = RegisterInfo()
538 .add_output(/*c*/) } },
540 { .num_addresses = 3,
541 .gas_cost = { .opcode_gas = AVM_XOR_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
542 .register_info = RegisterInfo()
544 .add_output(/*c*/) } },
546 { .num_addresses = 2,
547 .gas_cost = { .opcode_gas = AVM_NOT_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
548 .register_info = RegisterInfo().add_inputs({ /*a*/ RegisterInfo::ANY_TAG }).add_output(/*b*/) } },
550 { .num_addresses = 3,
551 .gas_cost = { .opcode_gas = AVM_SHL_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
552 .register_info = RegisterInfo()
554 /*b*/ RegisterInfo::ANY_TAG })
555 .add_output(/*c*/) } },
557 { .num_addresses = 3,
558 .gas_cost = { .opcode_gas = AVM_SHR_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
559 .register_info = RegisterInfo()
561 /*b*/ RegisterInfo::ANY_TAG })
562 .add_output(/*c*/) } },
564 { .num_addresses = 2,
565 .gas_cost = { .opcode_gas = AVM_CAST_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
566 .register_info = RegisterInfo().add_input(/*a*/ RegisterInfo::ANY_TAG).add_output(/*c*/) } },
568 { .num_addresses = 1,
569 .gas_cost = { .opcode_gas = AVM_GETENVVAR_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
570 .register_info = RegisterInfo().add_output(/*dst*/) } },
572 { .num_addresses = 3,
573 .gas_cost = { .opcode_gas = AVM_CALLDATACOPY_BASE_L2_GAS,
574 .base_da = 0,
575 .dyn_l2 = AVM_CALLDATACOPY_DYN_L2_GAS,
576 .dyn_da = 0 },
577 .dyn_gas_id = AVM_DYN_GAS_ID_CALLDATACOPY,
578 .register_info =
579 RegisterInfo().add_inputs({ /*cd_copy_size*/ ValueTag::U32, /*cd_offset_read*/ ValueTag::U32 }) } },
581 { .num_addresses = 1,
582 .gas_cost = { .opcode_gas = AVM_SUCCESSCOPY_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
583 .register_info = RegisterInfo().add_output(/*dst*/) } },
585 { .num_addresses = 1,
586 .gas_cost = { .opcode_gas = AVM_RETURNDATASIZE_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
587 .register_info = RegisterInfo().add_output(/*dst*/) } },
589 { .num_addresses = 3,
590 .gas_cost = { .opcode_gas = AVM_RETURNDATACOPY_BASE_L2_GAS,
591 .base_da = 0,
592 .dyn_l2 = AVM_RETURNDATACOPY_DYN_L2_GAS,
593 .dyn_da = 0 },
594 .dyn_gas_id = AVM_DYN_GAS_ID_RETURNDATACOPY,
595 .register_info =
596 RegisterInfo().add_inputs({ /*rd_copy_size*/ ValueTag::U32, /*rd_offset_read*/ ValueTag::U32 }) } },
598 { .num_addresses = 0,
599 .gas_cost = { .opcode_gas = AVM_JUMP_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } },
601 { .num_addresses = 1,
602 .gas_cost = { .opcode_gas = AVM_JUMPI_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
603 .register_info = RegisterInfo().add_input(/*cond*/ ValueTag::U1) } },
605 {
606 .num_addresses = 0,
607 .gas_cost = { .opcode_gas = AVM_INTERNALCALL_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
608 } },
610 { .num_addresses = 0,
611 .gas_cost = { .opcode_gas = AVM_INTERNALRETURN_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } },
613 { .num_addresses = 1,
614 .gas_cost = { .opcode_gas = AVM_SET_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
615 .register_info = RegisterInfo().add_output(/*dst*/) } },
617 { .num_addresses = 2,
618 .gas_cost = { .opcode_gas = AVM_MOV_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
619 .register_info = RegisterInfo().add_input(/*src*/).add_output(/*dst*/) } },
621 { .num_addresses = 3,
622 .gas_cost = { .opcode_gas = AVM_SLOAD_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
623 .register_info = RegisterInfo()
624 .add_inputs({ /*slot*/ ValueTag::FF, /*contract_address*/ ValueTag::FF })
625 .add_output(/*dst*/) } },
627 { .num_addresses = 2,
628 .gas_cost = { .opcode_gas = AVM_SSTORE_BASE_L2_GAS,
629 .base_da = 0,
630 .dyn_l2 = 0,
631 .dyn_da = AVM_SSTORE_DYN_DA_GAS },
632 .dyn_gas_id = AVM_DYN_GAS_ID_SSTORE,
633 .register_info = RegisterInfo().add_inputs({ /*src*/ ValueTag::FF, /*slot*/ ValueTag::FF }) } },
635 { .num_addresses = 3,
636 .gas_cost = { .opcode_gas = AVM_NOTEHASHEXISTS_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
637 .register_info = RegisterInfo()
638 .add_inputs({ /*unique_note_hash*/ ValueTag::FF, /*leaf_index*/ ValueTag::U64 })
639 .add_output(/*exists*/) } },
641 { .num_addresses = 1,
642 .gas_cost = { .opcode_gas = AVM_EMITNOTEHASH_BASE_L2_GAS,
643 .base_da = AVM_EMITNOTEHASH_BASE_DA_GAS,
644 .dyn_l2 = 0,
645 .dyn_da = 0 },
646 .register_info = RegisterInfo().add_input(/*note_hash*/ ValueTag::FF) } },
648 { .num_addresses = 2,
649 .gas_cost = { .opcode_gas = AVM_NULLIFIEREXISTS_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
650 .register_info = RegisterInfo().add_input(/*siloed_nullifier*/ ValueTag::FF).add_output(/*exists*/) } },
652 { .num_addresses = 1,
653 .gas_cost = { .opcode_gas = AVM_EMITNULLIFIER_BASE_L2_GAS,
654 .base_da = AVM_EMITNULLIFIER_BASE_DA_GAS,
655 .dyn_l2 = 0,
656 .dyn_da = 0 },
657 .register_info = RegisterInfo().add_input(/*nullifier*/ ValueTag::FF) } },
659 { .num_addresses = 3,
660 .gas_cost = { .opcode_gas = AVM_L1TOL2MSGEXISTS_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
661 .register_info = RegisterInfo()
662 .add_inputs({ /*msg_hash*/ ValueTag::FF, /*leaf_index*/ ValueTag::U64 })
663 .add_output(/*exists*/) } },
665 { .num_addresses = 2,
666 .gas_cost = { .opcode_gas = AVM_GETCONTRACTINSTANCE_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
667 .register_info = RegisterInfo().add_input(/*contract_address*/ ValueTag::FF) } },
669 { .num_addresses = 2,
670 .gas_cost = { .opcode_gas = AVM_EMITPUBLICLOG_BASE_L2_GAS,
671 .base_da = AVM_EMITPUBLICLOG_BASE_DA_GAS,
672 .dyn_l2 = AVM_EMITPUBLICLOG_DYN_L2_GAS,
673 .dyn_da = AVM_EMITPUBLICLOG_DYN_DA_GAS },
674 .dyn_gas_id = AVM_DYN_GAS_ID_EMITPUBLICLOG,
675 .register_info = RegisterInfo().add_inputs({ ValueTag::U32 }) } },
677 { .num_addresses = 2,
678 .gas_cost = { .opcode_gas = AVM_SENDL2TOL1MSG_BASE_L2_GAS,
679 .base_da = AVM_SENDL2TOL1MSG_BASE_DA_GAS,
680 .dyn_l2 = 0,
681 .dyn_da = 0 },
682 .register_info =
683 RegisterInfo().add_inputs({ /* recipient */ ValueTag::FF, /* content */ ValueTag::FF }) } },
685 { .num_addresses = 5,
686 .gas_cost = { .opcode_gas = AVM_CALL_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
687 .register_info = RegisterInfo().add_inputs({ /*l2_gas*/ ValueTag::U32,
688 /*da_gas*/ ValueTag::U32,
689 /*contract_address*/ ValueTag::FF,
690 /*args_size*/ ValueTag::U32 }) } },
692 { .num_addresses = 5,
693 .gas_cost = { .opcode_gas = AVM_STATICCALL_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
694 .register_info = RegisterInfo().add_inputs({ /*l2_gas*/ ValueTag::U32,
695 /*da_gas*/ ValueTag::U32,
696 /*contract_address*/ ValueTag::FF,
697 /*args_size*/ ValueTag::U32 }) } },
699 { .num_addresses = 2,
700 .gas_cost = { .opcode_gas = AVM_RETURN_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
701 .register_info = RegisterInfo().add_input(/*rd_size*/ ValueTag::U32) } },
703 { .num_addresses = 2,
704 .gas_cost = { .opcode_gas = AVM_REVERT_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
705 .register_info = RegisterInfo().add_input(/*rev_size*/ ValueTag::U32) } },
707 { .num_addresses = 4,
708 .gas_cost = { .opcode_gas = AVM_DEBUGLOG_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
709 // We don't set the right inputs for debuglog because we make it a noop.
710 .register_info = RegisterInfo() } },
712 { .num_addresses = 2,
713 .gas_cost = { .opcode_gas = AVM_POSEIDON2_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } },
715 { .num_addresses = 3,
716 .gas_cost = { .opcode_gas = AVM_SHA256COMPRESSION_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } },
718 { .num_addresses = 2,
719 .gas_cost = { .opcode_gas = AVM_KECCAKF1600_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 } } },
721 { .num_addresses = 5,
722 .gas_cost = { .opcode_gas = AVM_ECADD_BASE_L2_GAS, .base_da = 0, .dyn_l2 = 0, .dyn_da = 0 },
723 .register_info = RegisterInfo().add_inputs({ /*p_x=*/ValueTag::FF,
724 /*p_y=*/ValueTag::FF,
725 /*q_x*/ ValueTag::FF,
726 /*q_y*/ ValueTag::FF }) } },
728 { .num_addresses = 5,
729 .gas_cost = { .opcode_gas = AVM_TORADIXBE_BASE_L2_GAS,
730 .base_da = 0,
731 .dyn_l2 = AVM_TORADIXBE_DYN_L2_GAS,
732 .dyn_da = 0 },
733 .dyn_gas_id = AVM_DYN_GAS_ID_TORADIX,
734 .register_info = RegisterInfo().add_inputs({ /*value*/ ValueTag::FF,
735 /*radix*/ ValueTag::U32,
736 /*num_limbs*/ ValueTag::U32,
737 /*is_output_bit*/ ValueTag::U1 }) } },
738 };
739 return EXEC_INSTRUCTION_SPEC;
740}
741
742} // namespace bb::avm2
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