Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
program_block.cpp
Go to the documentation of this file.
11
13{
14 if (resolved_address.pointer_address.has_value()) {
15 if (resolved_address.via_relative) {
16 // Indirect relative: Write the pointer in a relative manner
18 .operand(static_cast<uint16_t>(resolved_address.operand_address))
19 .relative()
21 .operand(resolved_address.absolute_address)
22 .build();
23 instructions.push_back(set_pointer_instruction);
24 } else {
25 // Indirect: Write the pointer directly
27 .operand(static_cast<uint16_t>(resolved_address.pointer_address.value()))
29 .operand(resolved_address.absolute_address)
30 .build();
31 instructions.push_back(set_pointer_instruction);
32 }
33
35 }
36}
37
40{
41 for (const auto& param : params) {
42 auto tag =
43 std::visit(overloaded{ [](const VariableRef& var) -> std::optional<MemoryTag> { return var.tag.value; },
44 [](const AddressRef&) -> std::optional<MemoryTag> { return std::nullopt; } },
45 param);
46 if (tag.has_value()) {
47 memory_manager.set_memory_address(tag.value(), result_address.absolute_address);
48 return;
49 }
50 }
51}
52
54{
55#ifdef DISABLE_ADD_8_INSTRUCTION
56 return;
57#endif
61 if (!a.has_value() || !b.has_value() || !result.has_value()) {
62 return;
63 }
64 preprocess_memory_addresses(a.value().first);
65 preprocess_memory_addresses(b.value().first);
66 preprocess_memory_addresses(result.value().first);
67
69 .operand(a.value().second)
70 .operand(b.value().second)
71 .operand(result.value().second)
72 .build();
73 instructions.push_back(add_8_instruction);
74 record_result_tag_from_param_tags({ instruction.a_address, instruction.b_address }, result.value().first);
75}
76
78{
79#ifdef DISABLE_SUB_8_INSTRUCTION
80 return;
81#endif
85 if (!a.has_value() || !b.has_value() || !result.has_value()) {
86 return;
87 }
88 preprocess_memory_addresses(a.value().first);
89 preprocess_memory_addresses(b.value().first);
90 preprocess_memory_addresses(result.value().first);
92 .operand(a.value().second)
93 .operand(b.value().second)
94 .operand(result.value().second)
95 .build();
96 instructions.push_back(sub_8_instruction);
97 record_result_tag_from_param_tags({ instruction.a_address, instruction.b_address }, result.value().first);
98}
99
101{
102#ifdef DISABLE_MUL_8_INSTRUCTION
103 return;
104#endif
108 if (!a.has_value() || !b.has_value() || !result.has_value()) {
109 return;
110 }
111 preprocess_memory_addresses(a.value().first);
112 preprocess_memory_addresses(b.value().first);
113 preprocess_memory_addresses(result.value().first);
115 .operand(a.value().second)
116 .operand(b.value().second)
117 .operand(result.value().second)
118 .build();
119 instructions.push_back(mul_8_instruction);
120 record_result_tag_from_param_tags({ instruction.a_address, instruction.b_address }, result.value().first);
121}
122
124{
125#ifdef DISABLE_DIV_8_INSTRUCTION
126 return;
127#endif
131 if (!a.has_value() || !b.has_value() || !result.has_value()) {
132 return;
133 }
134 preprocess_memory_addresses(a.value().first);
135 preprocess_memory_addresses(b.value().first);
136 preprocess_memory_addresses(result.value().first);
138 .operand(a.value().second)
139 .operand(b.value().second)
140 .operand(result.value().second)
141 .build();
142 instructions.push_back(div_8_instruction);
143 record_result_tag_from_param_tags({ instruction.a_address, instruction.b_address }, result.value().first);
144}
145
147{
148#ifdef DISABLE_EQ_8_INSTRUCTION
149 return;
150#endif
154 if (!a.has_value() || !b.has_value() || !result.has_value()) {
155 return;
156 }
157 preprocess_memory_addresses(a.value().first);
158 preprocess_memory_addresses(b.value().first);
159 preprocess_memory_addresses(result.value().first);
161 .operand(a.value().second)
162 .operand(b.value().second)
163 .operand(result.value().second)
164 .build();
165 instructions.push_back(eq_8_instruction);
166 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result.value().first.absolute_address);
167}
168
170{
171#ifdef DISABLE_LT_8_INSTRUCTION
172 return;
173#endif
177 if (!a.has_value() || !b.has_value() || !result.has_value()) {
178 return;
179 }
180 preprocess_memory_addresses(a.value().first);
181 preprocess_memory_addresses(b.value().first);
182 preprocess_memory_addresses(result.value().first);
184 .operand(a.value().second)
185 .operand(b.value().second)
186 .operand(result.value().second)
187 .build();
188 instructions.push_back(lt_8_instruction);
189 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result.value().first.absolute_address);
190}
191
193{
194#ifdef DISABLE_LTE_8_INSTRUCTION
195 return;
196#endif
200 if (!a.has_value() || !b.has_value() || !result.has_value()) {
201 return;
202 }
203 preprocess_memory_addresses(a.value().first);
204 preprocess_memory_addresses(b.value().first);
205 preprocess_memory_addresses(result.value().first);
207 .operand(a.value().second)
208 .operand(b.value().second)
209 .operand(result.value().second)
210 .build();
211 instructions.push_back(lte_8_instruction);
212 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result.value().first.absolute_address);
213}
214
216{
217#ifdef DISABLE_AND_8_INSTRUCTION
218 return;
219#endif
223 if (!a.has_value() || !b.has_value() || !result.has_value()) {
224 return;
225 }
226
227 preprocess_memory_addresses(a.value().first);
228 preprocess_memory_addresses(b.value().first);
229 preprocess_memory_addresses(result.value().first);
231 .operand(a.value().second)
232 .operand(b.value().second)
233 .operand(result.value().second)
234 .build();
235 instructions.push_back(and_8_instruction);
236 record_result_tag_from_param_tags({ instruction.a_address, instruction.b_address }, result.value().first);
237}
238
240{
241#ifdef DISABLE_OR_8_INSTRUCTION
242 return;
243#endif
247 if (!a.has_value() || !b.has_value() || !result.has_value()) {
248 return;
249 }
250
251 preprocess_memory_addresses(a.value().first);
252 preprocess_memory_addresses(b.value().first);
253 preprocess_memory_addresses(result.value().first);
255 .operand(a.value().second)
256 .operand(b.value().second)
257 .operand(result.value().second)
258 .build();
259 instructions.push_back(or_8_instruction);
260 record_result_tag_from_param_tags({ instruction.a_address, instruction.b_address }, result.value().first);
261}
262
264{
265#ifdef DISABLE_XOR_8_INSTRUCTION
266 return;
267#endif
271 if (!a.has_value() || !b.has_value() || !result.has_value()) {
272 return;
273 }
274
275 preprocess_memory_addresses(a.value().first);
276 preprocess_memory_addresses(b.value().first);
277 preprocess_memory_addresses(result.value().first);
279 .operand(a.value().second)
280 .operand(b.value().second)
281 .operand(result.value().second)
282 .build();
283 instructions.push_back(xor_8_instruction);
284 record_result_tag_from_param_tags({ instruction.a_address, instruction.b_address }, result.value().first);
285}
286
288{
289#ifdef DISABLE_SHL_8_INSTRUCTION
290 return;
291#endif
295 if (!a.has_value() || !b.has_value() || !result.has_value()) {
296 return;
297 }
298
299 preprocess_memory_addresses(a.value().first);
300 preprocess_memory_addresses(b.value().first);
301 preprocess_memory_addresses(result.value().first);
303 .operand(a.value().second)
304 .operand(b.value().second)
305 .operand(result.value().second)
306 .build();
307 instructions.push_back(shl_8_instruction);
308 record_result_tag_from_param_tags({ instruction.a_address, instruction.b_address }, result.value().first);
309}
310
312{
313#ifdef DISABLE_SHR_8_INSTRUCTION
314 return;
315#endif
319 if (!a.has_value() || !b.has_value() || !result.has_value()) {
320 return;
321 }
322
323 preprocess_memory_addresses(a.value().first);
324 preprocess_memory_addresses(b.value().first);
325 preprocess_memory_addresses(result.value().first);
327 .operand(a.value().second)
328 .operand(b.value().second)
329 .operand(result.value().second)
330 .build();
331 instructions.push_back(shr_8_instruction);
332 record_result_tag_from_param_tags({ instruction.a_address, instruction.b_address }, result.value().first);
333}
334
336{
337#ifdef DISABLE_SET_8_INSTRUCTION
338 return;
339#endif
340 auto effective_address_operand = memory_manager.get_resolved_address_and_operand_8(instruction.result_address);
341 if (!effective_address_operand.has_value()) {
342 return;
343 }
344 preprocess_memory_addresses(effective_address_operand.value().first);
346 .operand(effective_address_operand.value().second)
347 .operand(instruction.value_tag.value)
348 .operand(instruction.value)
349 .build());
351 effective_address_operand.value().first.absolute_address);
352}
353
355{
356#ifdef DISABLE_SET_16_INSTRUCTION
357 return;
358#endif
359 auto effective_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
360 if (!effective_address_operand.has_value()) {
361 return;
362 }
363 preprocess_memory_addresses(effective_address_operand.value().first);
365 .operand(effective_address_operand.value().second)
366 .operand(instruction.value_tag.value)
367 .operand(instruction.value)
368 .build());
370 effective_address_operand.value().first.absolute_address);
371}
372
374{
375#ifdef DISABLE_SET_32_INSTRUCTION
376 return;
377#endif
378 auto effective_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
379 if (!effective_address_operand.has_value()) {
380 return;
381 }
382 preprocess_memory_addresses(effective_address_operand.value().first);
384 .operand(effective_address_operand.value().second)
385 .operand(instruction.value_tag.value)
386 .operand(instruction.value)
387 .build());
389 effective_address_operand.value().first.absolute_address);
390}
391
393{
394#ifdef DISABLE_SET_64_INSTRUCTION
395 return;
396#endif
397 auto effective_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
398 if (!effective_address_operand.has_value()) {
399 return;
400 }
401 preprocess_memory_addresses(effective_address_operand.value().first);
403 .operand(effective_address_operand.value().second)
404 .operand(instruction.value_tag.value)
405 .operand(instruction.value)
406 .build());
408 effective_address_operand.value().first.absolute_address);
409}
410
412{
413#ifdef DISABLE_SET_128_INSTRUCTION
414 return;
415#endif
416 auto effective_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
417 if (!effective_address_operand.has_value()) {
418 return;
419 }
421 (static_cast<uint128_t>(instruction.value_high) << 64) | static_cast<uint128_t>(instruction.value_low);
422 preprocess_memory_addresses(effective_address_operand.value().first);
424 .operand(effective_address_operand.value().second)
425 .operand(instruction.value_tag.value)
426 .operand(value)
427 .build());
429 effective_address_operand.value().first.absolute_address);
430}
431
433{
434#ifdef DISABLE_SET_FF_INSTRUCTION
435 return;
436#endif
437 auto effective_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
438 if (!effective_address_operand.has_value()) {
439 return;
440 }
441 preprocess_memory_addresses(effective_address_operand.value().first);
443 .operand(effective_address_operand.value().second)
444 .operand(instruction.value_tag.value)
445 .operand(instruction.value)
446 .build());
448 effective_address_operand.value().first.absolute_address);
449}
450
452{
453#ifdef DISABLE_MOV_8_INSTRUCTION
454 return;
455#endif
456 auto src_address_operand = memory_manager.get_resolved_address_and_operand_8(instruction.src_address);
457 auto result_address_operand = memory_manager.get_resolved_address_and_operand_8(instruction.result_address);
458 if (!src_address_operand.has_value() || !result_address_operand.has_value()) {
459 return;
460 }
461 preprocess_memory_addresses(src_address_operand.value().first);
462 preprocess_memory_addresses(result_address_operand.value().first);
464 .operand(src_address_operand.value().second)
465 .operand(result_address_operand.value().second)
466 .build();
467 instructions.push_back(mov_8_instruction);
468 record_result_tag_from_param_tags({ instruction.src_address }, result_address_operand.value().first);
469}
470
472{
473#ifdef DISABLE_MOV_16_INSTRUCTION
474 return;
475#endif
476 auto src_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.src_address);
477 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
478 if (!src_address_operand.has_value() || !result_address_operand.has_value()) {
479 return;
480 }
481
482 preprocess_memory_addresses(src_address_operand.value().first);
483 preprocess_memory_addresses(result_address_operand.value().first);
485 .operand(src_address_operand.value().second)
486 .operand(result_address_operand.value().second)
487 .build();
488 instructions.push_back(mov_16_instruction);
489 record_result_tag_from_param_tags({ instruction.src_address }, result_address_operand.value().first);
490}
491
493{
494#ifdef DISABLE_FDIV_8_INSTRUCTION
495 return;
496#endif
497 auto a_address_operand = memory_manager.get_resolved_address_and_operand_8(instruction.a_address);
498 auto b_address_operand = memory_manager.get_resolved_address_and_operand_8(instruction.b_address);
499 auto result_address_operand = memory_manager.get_resolved_address_and_operand_8(instruction.result_address);
500 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
501 return;
502 }
503
504 preprocess_memory_addresses(a_address_operand.value().first);
505 preprocess_memory_addresses(b_address_operand.value().first);
506 preprocess_memory_addresses(result_address_operand.value().first);
508 .operand(a_address_operand.value().second)
509 .operand(b_address_operand.value().second)
510 .operand(result_address_operand.value().second)
511 .build();
512 instructions.push_back(fdiv_8_instruction);
514 result_address_operand.value().first);
515}
516
518{
519#ifdef DISABLE_NOT_8_INSTRUCTION
520 return;
521#endif
522 auto a_address_operand = memory_manager.get_resolved_address_and_operand_8(instruction.a_address);
523 auto result_address_operand = memory_manager.get_resolved_address_and_operand_8(instruction.result_address);
524 if (!a_address_operand.has_value() || !result_address_operand.has_value()) {
525 return;
526 }
527
528 preprocess_memory_addresses(a_address_operand.value().first);
529 preprocess_memory_addresses(result_address_operand.value().first);
531 .operand(a_address_operand.value().second)
532 .operand(result_address_operand.value().second)
533 .build();
534 instructions.push_back(not_8_instruction);
535 record_result_tag_from_param_tags({ instruction.a_address }, result_address_operand.value().first);
536}
537
539{
540#ifdef DISABLE_ADD_16_INSTRUCTION
541 return;
542#endif
543 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
544 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
545 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
546 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
547 return;
548 }
549
550 preprocess_memory_addresses(a_address_operand.value().first);
551 preprocess_memory_addresses(b_address_operand.value().first);
552 preprocess_memory_addresses(result_address_operand.value().first);
554 .operand(a_address_operand.value().second)
555 .operand(b_address_operand.value().second)
556 .operand(result_address_operand.value().second)
557 .build();
558 instructions.push_back(add_16_instruction);
560 result_address_operand.value().first);
561}
562
564{
565#ifdef DISABLE_SUB_16_INSTRUCTION
566 return;
567#endif
568 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
569 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
570 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
571 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
572 return;
573 }
574
575 preprocess_memory_addresses(a_address_operand.value().first);
576 preprocess_memory_addresses(b_address_operand.value().first);
577 preprocess_memory_addresses(result_address_operand.value().first);
579 .operand(a_address_operand.value().second)
580 .operand(b_address_operand.value().second)
581 .operand(result_address_operand.value().second)
582 .build();
583 instructions.push_back(sub_16_instruction);
585 result_address_operand.value().first);
586}
587
589{
590#ifdef DISABLE_MUL_16_INSTRUCTION
591 return;
592#endif
593 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
594 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
595 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
596 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
597 return;
598 }
599
600 preprocess_memory_addresses(a_address_operand.value().first);
601 preprocess_memory_addresses(b_address_operand.value().first);
602 preprocess_memory_addresses(result_address_operand.value().first);
604 .operand(a_address_operand.value().second)
605 .operand(b_address_operand.value().second)
606 .operand(result_address_operand.value().second)
607 .build();
608 instructions.push_back(mul_16_instruction);
610 result_address_operand.value().first);
611}
612
614{
615#ifdef DISABLE_DIV_16_INSTRUCTION
616 return;
617#endif
618 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
619 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
620 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
621 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
622 return;
623 }
624
625 preprocess_memory_addresses(a_address_operand.value().first);
626 preprocess_memory_addresses(b_address_operand.value().first);
627 preprocess_memory_addresses(result_address_operand.value().first);
629 .operand(a_address_operand.value().second)
630 .operand(b_address_operand.value().second)
631 .operand(result_address_operand.value().second)
632 .build();
633 instructions.push_back(div_16_instruction);
635 result_address_operand.value().first);
636}
637
639{
640#ifdef DISABLE_FDIV_16_INSTRUCTION
641 return;
642#endif
643 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
644 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
645 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
646 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
647 return;
648 }
649
650 preprocess_memory_addresses(a_address_operand.value().first);
651 preprocess_memory_addresses(b_address_operand.value().first);
652 preprocess_memory_addresses(result_address_operand.value().first);
654 .operand(a_address_operand.value().second)
655 .operand(b_address_operand.value().second)
656 .operand(result_address_operand.value().second)
657 .build();
658 instructions.push_back(fdiv_16_instruction);
660 result_address_operand.value().first);
661}
662
664{
665#ifdef DISABLE_EQ_16_INSTRUCTION
666 return;
667#endif
668 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
669 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
670 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
671 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
672 return;
673 }
674
675 preprocess_memory_addresses(a_address_operand.value().first);
676 preprocess_memory_addresses(b_address_operand.value().first);
677 preprocess_memory_addresses(result_address_operand.value().first);
679 .operand(a_address_operand.value().second)
680 .operand(b_address_operand.value().second)
681 .operand(result_address_operand.value().second)
682 .build();
683 instructions.push_back(eq_16_instruction);
684 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result_address_operand.value().first.absolute_address);
685}
686
688{
689#ifdef DISABLE_LT_16_INSTRUCTION
690 return;
691#endif
692 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
693 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
694 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
695 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
696 return;
697 }
698
699 preprocess_memory_addresses(a_address_operand.value().first);
700 preprocess_memory_addresses(b_address_operand.value().first);
701 preprocess_memory_addresses(result_address_operand.value().first);
703 .operand(a_address_operand.value().second)
704 .operand(b_address_operand.value().second)
705 .operand(result_address_operand.value().second)
706 .build();
707 instructions.push_back(lt_16_instruction);
708 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result_address_operand.value().first.absolute_address);
709}
710
712{
713#ifdef DISABLE_LTE_16_INSTRUCTION
714 return;
715#endif
716 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
717 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
718 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
719 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
720 return;
721 }
722
723 preprocess_memory_addresses(a_address_operand.value().first);
724 preprocess_memory_addresses(b_address_operand.value().first);
725 preprocess_memory_addresses(result_address_operand.value().first);
727 .operand(a_address_operand.value().second)
728 .operand(b_address_operand.value().second)
729 .operand(result_address_operand.value().second)
730 .build();
731 instructions.push_back(lte_16_instruction);
732 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result_address_operand.value().first.absolute_address);
733}
734
736{
737#ifdef DISABLE_AND_16_INSTRUCTION
738 return;
739#endif
740 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
741 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
742 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
743 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
744 return;
745 }
746
747 preprocess_memory_addresses(a_address_operand.value().first);
748 preprocess_memory_addresses(b_address_operand.value().first);
749 preprocess_memory_addresses(result_address_operand.value().first);
751 .operand(a_address_operand.value().second)
752 .operand(b_address_operand.value().second)
753 .operand(result_address_operand.value().second)
754 .build();
755 instructions.push_back(and_16_instruction);
757 result_address_operand.value().first);
758}
759
761{
762#ifdef DISABLE_OR_16_INSTRUCTION
763 return;
764#endif
765 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
766 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
767 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
768 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
769 return;
770 }
771
772 preprocess_memory_addresses(a_address_operand.value().first);
773 preprocess_memory_addresses(b_address_operand.value().first);
774 preprocess_memory_addresses(result_address_operand.value().first);
776 .operand(a_address_operand.value().second)
777 .operand(b_address_operand.value().second)
778 .operand(result_address_operand.value().second)
779 .build();
780 instructions.push_back(or_16_instruction);
782 result_address_operand.value().first);
783}
784
786{
787#ifdef DISABLE_XOR_16_INSTRUCTION
788 return;
789#endif
790 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
791 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
792 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
793 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
794 return;
795 }
796
797 preprocess_memory_addresses(a_address_operand.value().first);
798 preprocess_memory_addresses(b_address_operand.value().first);
799 preprocess_memory_addresses(result_address_operand.value().first);
801 .operand(a_address_operand.value().second)
802 .operand(b_address_operand.value().second)
803 .operand(result_address_operand.value().second)
804 .build();
805 instructions.push_back(xor_16_instruction);
807 result_address_operand.value().first);
808}
809
811{
812#ifdef DISABLE_NOT_16_INSTRUCTION
813 return;
814#endif
815 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
816 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
817 if (!a_address_operand.has_value() || !result_address_operand.has_value()) {
818 return;
819 }
820
821 preprocess_memory_addresses(a_address_operand.value().first);
822 preprocess_memory_addresses(result_address_operand.value().first);
824 .operand(a_address_operand.value().second)
825 .operand(result_address_operand.value().second)
826 .build();
827 instructions.push_back(not_16_instruction);
828 record_result_tag_from_param_tags({ instruction.a_address }, result_address_operand.value().first);
829}
830
832{
833#ifdef DISABLE_SHL_16_INSTRUCTION
834 return;
835#endif
836 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
837 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
838 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
839 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
840 return;
841 }
842 preprocess_memory_addresses(a_address_operand.value().first);
843 preprocess_memory_addresses(b_address_operand.value().first);
844 preprocess_memory_addresses(result_address_operand.value().first);
845
847 .operand(a_address_operand.value().second)
848 .operand(b_address_operand.value().second)
849 .operand(result_address_operand.value().second)
850 .build();
851 instructions.push_back(shl_16_instruction);
853 result_address_operand.value().first);
854}
855
857{
858#ifdef DISABLE_SHR_16_INSTRUCTION
859 return;
860#endif
861 auto a_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.a_address);
862 auto b_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.b_address);
863 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
864 if (!a_address_operand.has_value() || !b_address_operand.has_value() || !result_address_operand.has_value()) {
865 return;
866 }
867
868 preprocess_memory_addresses(a_address_operand.value().first);
869 preprocess_memory_addresses(b_address_operand.value().first);
870 preprocess_memory_addresses(result_address_operand.value().first);
872 .operand(a_address_operand.value().second)
873 .operand(b_address_operand.value().second)
874 .operand(result_address_operand.value().second)
875 .build();
876 instructions.push_back(shr_16_instruction);
878 result_address_operand.value().first);
879}
880
882{
883#ifdef DISABLE_CAST_8_INSTRUCTION
884 return;
885#endif
886 auto src_address_operand = memory_manager.get_resolved_address_and_operand_8(instruction.src_address);
887 auto result_address_operand = memory_manager.get_resolved_address_and_operand_8(instruction.result_address);
888 if (!src_address_operand.has_value() || !result_address_operand.has_value()) {
889 return;
890 }
891
892 preprocess_memory_addresses(src_address_operand.value().first);
893 preprocess_memory_addresses(result_address_operand.value().first);
895 .operand(src_address_operand.value().second)
896 .operand(result_address_operand.value().second)
897 .operand(instruction.target_tag.value)
898 .build();
899 instructions.push_back(cast_8_instruction);
901 result_address_operand.value().first.absolute_address);
902}
903
905{
906#ifdef DISABLE_CAST_16_INSTRUCTION
907 return;
908#endif
909 auto src_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.src_address);
910 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
911 if (!src_address_operand.has_value() || !result_address_operand.has_value()) {
912 return;
913 }
914
915 preprocess_memory_addresses(src_address_operand.value().first);
916 preprocess_memory_addresses(result_address_operand.value().first);
918 .operand(src_address_operand.value().second)
919 .operand(result_address_operand.value().second)
920 .operand(instruction.target_tag.value)
921 .build();
922 instructions.push_back(cast_16_instruction);
924 result_address_operand.value().first.absolute_address);
925}
926
928{
929#ifdef DISABLE_SSTORE_INSTRUCTION
930 return;
931#endif
932 auto src_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.src_address);
933 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
934 if (!src_address_operand.has_value() || !result_address_operand.has_value()) {
935 return;
936 }
937 preprocess_memory_addresses(src_address_operand.value().first);
938 preprocess_memory_addresses(result_address_operand.value().first);
939 auto set_slot_instruction = SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF,
940 .result_address = instruction.result_address,
941 .value = instruction.slot };
942 this->process_set_ff_instruction(set_slot_instruction);
944 .operand(src_address_operand.value().second)
945 .operand(result_address_operand.value().second)
946 .build();
947 instructions.push_back(sstore_instruction);
949}
950
952{
953#ifdef DISABLE_SLOAD_INSTRUCTION
954 return;
955#endif
956 auto slot_addr = memory_manager.get_slot(instruction.slot_index);
957 if (!slot_addr.has_value()) {
958 return;
959 }
960
961 auto set_slot_instruction = SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF,
962 .result_address = instruction.slot_address,
963 .value = *slot_addr };
964 this->process_set_ff_instruction(set_slot_instruction);
965 auto slot_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.slot_address);
966 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
967 auto contract_address_operand =
969 if (!slot_address_operand.has_value() || !result_address_operand.has_value() ||
970 !contract_address_operand.has_value()) {
971 return;
972 }
973 preprocess_memory_addresses(slot_address_operand.value().first);
974 preprocess_memory_addresses(result_address_operand.value().first);
975 preprocess_memory_addresses(contract_address_operand.value().first);
976
978 .operand(slot_address_operand.value().second)
979 .operand(contract_address_operand.value().second)
980 .operand(result_address_operand.value().second)
981 .build();
982 instructions.push_back(sload_instruction);
983 memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, result_address_operand.value().first.absolute_address);
984}
985
987{
988#ifdef DISABLE_GETENVVAR_INSTRUCTION
989 return;
990#endif
991 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
992 if (!result_address_operand.has_value()) {
993 return;
994 }
995 preprocess_memory_addresses(result_address_operand.value().first);
997 .operand(result_address_operand.value().second)
998 .operand(instruction.type)
999 .build();
1000 instructions.push_back(getenvvar_instruction);
1001 // special case for timestamp, it returns a 64-bit value
1002 if (instruction.type == 6) {
1004 result_address_operand.value().first.absolute_address);
1005 } else {
1007 result_address_operand.value().first.absolute_address);
1008 }
1009}
1010
1012{
1013#ifdef DISABLE_EMITNULLIFIER_INSTRUCTION
1014 return;
1015#endif
1016 auto nullifier_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.nullifier_address);
1017 if (!nullifier_address_operand.has_value()) {
1018 return;
1019 }
1020 preprocess_memory_addresses(nullifier_address_operand.value().first);
1022 .operand(nullifier_address_operand.value().second)
1023 .build();
1024 instructions.push_back(emitnulifier_instruction);
1025}
1026
1028{
1029#ifdef DISABLE_NULLIFIEREXISTS_INSTRUCTION
1030 return;
1031#endif
1032 auto siloed_nullifier_operand =
1034 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
1035 if (!siloed_nullifier_operand.has_value() || !result_address_operand.has_value()) {
1036 return;
1037 }
1038
1039 preprocess_memory_addresses(siloed_nullifier_operand.value().first);
1040 preprocess_memory_addresses(result_address_operand.value().first);
1041
1043 .operand(siloed_nullifier_operand.value().second)
1044 .operand(result_address_operand.value().second)
1045 .build();
1046 instructions.push_back(nullifierexists_instruction);
1047 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result_address_operand.value().first.absolute_address);
1048}
1049
1051{
1052#ifdef DISABLE_EMITNOTEHASH_INSTRUCTION
1053 return;
1054#endif
1055 auto set_note_hash_instruction = SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF,
1056 .result_address = instruction.note_hash_address,
1057 .value = instruction.note_hash };
1058 this->process_set_ff_instruction(set_note_hash_instruction);
1059
1060 // EMITNOTEHASH expects UINT16 operand
1061 auto note_hash_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.note_hash_address);
1062 if (!note_hash_address_operand.has_value()) {
1063 return;
1064 }
1065 preprocess_memory_addresses(note_hash_address_operand.value().first);
1066
1068 .operand(note_hash_address_operand.value().second)
1069 .build();
1070 instructions.push_back(emitnotehash_instruction);
1071}
1072
1074{
1075#ifdef DISABLE_NOTEHASHEXISTS_INSTRUCTION
1076 return;
1077#endif
1078 auto notehash_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.notehash_address);
1079 auto leaf_index_address_operand =
1081 auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
1082 if (!notehash_address_operand.has_value() || !leaf_index_address_operand.has_value() ||
1083 !result_address_operand.has_value()) {
1084 return;
1085 }
1086 preprocess_memory_addresses(notehash_address_operand.value().first);
1087 preprocess_memory_addresses(leaf_index_address_operand.value().first);
1088 preprocess_memory_addresses(result_address_operand.value().first);
1089
1091 .operand(notehash_address_operand.value().second)
1092 .operand(leaf_index_address_operand.value().second)
1093 .operand(result_address_operand.value().second)
1094 .build();
1095 instructions.push_back(notehashexists_instruction);
1096 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result_address_operand.value().first.absolute_address);
1097}
1098
1100{
1101#ifdef DISABLE_CALLDATACOPY_INSTRUCTION
1102 return;
1103#endif
1104 auto copy_size_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.copy_size_address);
1105 auto cd_offset_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.cd_offset_address);
1106 auto dst_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.dst_address);
1107 if (!copy_size_address_operand.has_value() || !cd_offset_address_operand.has_value() ||
1108 !dst_address_operand.has_value()) {
1109 return;
1110 }
1111
1112 preprocess_memory_addresses(copy_size_address_operand.value().first);
1113 preprocess_memory_addresses(cd_offset_address_operand.value().first);
1114 preprocess_memory_addresses(dst_address_operand.value().first);
1116 .operand(copy_size_address_operand.value().second)
1117 .operand(cd_offset_address_operand.value().second)
1118 .operand(dst_address_operand.value().second)
1119 .build();
1120 instructions.push_back(calldatacopy_instruction);
1121}
1122
1124{
1125#ifdef DISABLE_SENDL2TOL1MSG_INSTRUCTION
1126 return;
1127#endif
1128 auto recipient_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.recipient_address);
1129 auto content_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.content_address);
1130 if (!recipient_address_operand.has_value() || !content_address_operand.has_value()) {
1131 return;
1132 }
1133 preprocess_memory_addresses(recipient_address_operand.value().first);
1134 preprocess_memory_addresses(content_address_operand.value().first);
1136 .operand(recipient_address_operand.value().second)
1137 .operand(content_address_operand.value().second)
1138 .build();
1139 instructions.push_back(sendl2tol1msg_instruction);
1140}
1141
1143{
1144#ifdef DISABLE_EMITUNENCRYPTEDLOG_INSTRUCTION
1145 return;
1146#endif
1147 auto log_size_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.log_size_address);
1148 auto log_values_address_operand =
1150 if (!log_size_address_operand.has_value() || !log_values_address_operand.has_value()) {
1151 return;
1152 }
1153 preprocess_memory_addresses(log_size_address_operand.value().first);
1154 preprocess_memory_addresses(log_values_address_operand.value().first);
1155 auto emitunencryptedlog_instruction =
1157 .operand(log_size_address_operand.value().second)
1158 .operand(log_values_address_operand.value().second)
1159 .build();
1160 instructions.push_back(emitunencryptedlog_instruction);
1161}
1162
1164{
1165#ifdef DISABLE_CALL_INSTRUCTION
1166 return;
1167#endif
1174 if (!l2_gas.has_value() || !da_gas.has_value() || !contract_address_address.has_value() ||
1175 !calldata_size_address.has_value() || !calldata_address.has_value()) {
1176 return;
1177 }
1178 preprocess_memory_addresses(l2_gas.value().first);
1179 preprocess_memory_addresses(da_gas.value().first);
1183
1185 .result_address = instruction.calldata_size_address,
1186 .value = static_cast<uint32_t>(instruction.calldata_size) });
1187
1188 auto call_instruction_builder = instruction.is_static_call
1191 auto call_instruction = call_instruction_builder.operand(l2_gas.value().second)
1192 .operand(da_gas.value().second)
1193 .operand(contract_address_address.value().second)
1194 .operand(calldata_size_address.value().second)
1195 .operand(calldata_address.value().second)
1196 .build();
1197 instructions.push_back(call_instruction);
1198}
1199
1201{
1202#ifdef DISABLE_RETURNDATASIZE_INSTRUCTION
1203 return;
1204#endif
1205 auto dst_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.dst_address);
1206 if (!dst_address_operand.has_value()) {
1207 return;
1208 }
1209 preprocess_memory_addresses(dst_address_operand.value().first);
1211 .operand(dst_address_operand.value().second)
1212 .build();
1213 instructions.push_back(returndatasize_instruction);
1214 memory_manager.set_memory_address(bb::avm2::MemoryTag::U32, dst_address_operand.value().first.absolute_address);
1215}
1216
1218{
1219#ifdef DISABLE_RETURNDATACOPY_INSTRUCTION
1220 return;
1221#endif
1222 auto copy_size_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.copy_size_address);
1223 auto rd_offset_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.rd_offset_address);
1224 auto dst_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.dst_address);
1225 if (!copy_size_address_operand.has_value() || !rd_offset_address_operand.has_value() ||
1226 !dst_address_operand.has_value()) {
1227 return;
1228 }
1229 preprocess_memory_addresses(copy_size_address_operand.value().first);
1230 preprocess_memory_addresses(rd_offset_address_operand.value().first);
1231 preprocess_memory_addresses(dst_address_operand.value().first);
1232
1234 .operand(copy_size_address_operand.value().second)
1235 .operand(rd_offset_address_operand.value().second)
1236 .operand(dst_address_operand.value().second)
1237 .build();
1238 instructions.push_back(returndatacopy_instruction);
1239}
1240
1242{
1243#ifdef DISABLE_GETCONTRACTINSTANCE_INSTRUCTION
1244 return;
1245#endif
1248
1250 if (!contract_address_address.has_value() || !dst_address.has_value()) {
1251 return;
1252 }
1255
1256 auto get_contract_instance_instruction =
1258 .operand(contract_address_address.value().second)
1259 .operand(dst_address.value().second)
1260 .operand(instruction.member_enum)
1261 .build();
1262 instructions.push_back(get_contract_instance_instruction);
1264 memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, dst_address.value().first.absolute_address + 1);
1265}
1266
1268{
1269#ifdef DISABLE_SUCCESSCOPY_INSTRUCTION
1270 return;
1271#endif
1272 auto dst_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.dst_address);
1273 if (!dst_address_operand.has_value()) {
1274 return;
1275 }
1276 preprocess_memory_addresses(dst_address_operand.value().first);
1278 .operand(dst_address_operand.value().second)
1279 .build();
1280 instructions.push_back(successcopy_instruction);
1281 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, dst_address_operand.value().first.absolute_address);
1282}
1283
1285{
1286#ifdef DISABLE_ECADD_INSTRUCTION
1287 return;
1288#endif
1296
1297 if (!p1_x.has_value() || !p1_y.has_value() || !p1_inf.has_value() || !p2_x.has_value() || !p2_y.has_value() ||
1298 !p2_inf.has_value() || !result.has_value()) {
1299 return;
1300 }
1301
1302 preprocess_memory_addresses(p1_x.value().first);
1303 preprocess_memory_addresses(p1_y.value().first);
1304 preprocess_memory_addresses(p1_inf.value().first);
1305 preprocess_memory_addresses(p2_x.value().first);
1306 preprocess_memory_addresses(p2_y.value().first);
1307 preprocess_memory_addresses(p2_inf.value().first);
1308 preprocess_memory_addresses(result.value().first);
1309
1311 .operand(p1_x.value().second)
1312 .operand(p1_y.value().second)
1313 .operand(p1_inf.value().second)
1314 .operand(p2_x.value().second)
1315 .operand(p2_y.value().second)
1316 .operand(p2_inf.value().second)
1317 .operand(result.value().second)
1318 .build();
1319 instructions.push_back(ecadd_instruction);
1320
1321 // ECADD writes 3 consecutive memory locations: result_x (FF), result_y (FF), result_is_inf (U1)
1322 memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, result.value().first.absolute_address);
1323 memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, result.value().first.absolute_address + 1);
1324 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result.value().first.absolute_address + 2);
1325}
1326
1328{
1329#ifdef DISABLE_POSEIDON2PERM_INSTRUCTION
1330 return;
1331#endif
1334
1335 if (!src.has_value() || !dst.has_value()) {
1336 return;
1337 }
1338
1339 preprocess_memory_addresses(src.value().first);
1340 preprocess_memory_addresses(dst.value().first);
1341
1343 .operand(src.value().second)
1344 .operand(dst.value().second)
1345 .build();
1346 instructions.push_back(poseidon2perm_instruction);
1347
1348 // Poseidon2 permutation writes 4 consecutive FF values to dst
1349 for (uint32_t i = 0; i < 4; i++) {
1350 memory_manager.set_memory_address(bb::avm2::MemoryTag::FF, dst.value().first.absolute_address + i);
1351 }
1352}
1353
1355{
1356#ifdef DISABLE_KECCAKF1600_INSTRUCTION
1357 return;
1358#endif
1361
1362 if (!src.has_value() || !dst.has_value()) {
1363 return;
1364 }
1365
1366 preprocess_memory_addresses(src.value().first);
1367 preprocess_memory_addresses(dst.value().first);
1368
1370 .operand(dst.value().second)
1371 .operand(src.value().second)
1372 .build();
1373 instructions.push_back(keccakf1600_instruction);
1374
1375 // Keccak-f[1600] permutation writes 25 consecutive U64 values to dst
1376 for (uint32_t i = 0; i < 25; i++) {
1377 memory_manager.set_memory_address(bb::avm2::MemoryTag::U64, dst.value().first.absolute_address + i);
1378 }
1379}
1380
1382{
1383#ifdef DISABLE_SHA256COMPRESSION_INSTRUCTION
1384 return;
1385#endif
1389
1390 if (!state.has_value() || !input.has_value() || !dst.has_value()) {
1391 return;
1392 }
1393
1394 preprocess_memory_addresses(state.value().first);
1395 preprocess_memory_addresses(input.value().first);
1396 preprocess_memory_addresses(dst.value().first);
1397
1399 .operand(dst.value().second)
1400 .operand(state.value().second)
1401 .operand(input.value().second)
1402 .build();
1403 instructions.push_back(sha256compression_instruction);
1404
1405 // SHA256 compression writes 8 consecutive U32 values to dst
1406 for (uint32_t i = 0; i < 8; i++) {
1407 memory_manager.set_memory_address(bb::avm2::MemoryTag::U32, dst.value().first.absolute_address + i);
1408 }
1409}
1410
1412{
1413 auto msg_hash_operand = memory_manager.get_resolved_address_and_operand_16(instruction.msg_hash_address);
1414 auto leaf_index_operand = memory_manager.get_resolved_address_and_operand_16(instruction.leaf_index_address);
1415 auto result_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
1416
1417 if (!msg_hash_operand.has_value() || !leaf_index_operand.has_value() || !result_operand.has_value()) {
1418 return;
1419 }
1420
1421 preprocess_memory_addresses(msg_hash_operand.value().first);
1422 preprocess_memory_addresses(leaf_index_operand.value().first);
1423 preprocess_memory_addresses(result_operand.value().first);
1424
1426 .operand(msg_hash_operand.value().second)
1427 .operand(leaf_index_operand.value().second)
1428 .operand(result_operand.value().second)
1429 .build();
1430 instructions.push_back(l1tol2msgexists_instruction);
1431 memory_manager.set_memory_address(bb::avm2::MemoryTag::U1, result_operand.value().first.absolute_address);
1432}
1433
1435{
1436 auto value_operand = memory_manager.get_resolved_address_and_operand_16(instruction.value_address);
1437 auto radix_operand = memory_manager.get_resolved_address_and_operand_16(instruction.radix_address);
1438 auto num_limbs_operand = memory_manager.get_resolved_address_and_operand_16(instruction.num_limbs_address);
1439 auto output_bits_operand = memory_manager.get_resolved_address_and_operand_16(instruction.output_bits_address);
1440 auto dst_operand = memory_manager.get_resolved_address_and_operand_16(instruction.dst_address);
1441
1442 if (!value_operand.has_value() || !radix_operand.has_value() || !num_limbs_operand.has_value() ||
1443 !output_bits_operand.has_value() || !dst_operand.has_value()) {
1444 return;
1445 }
1446
1447 preprocess_memory_addresses(value_operand.value().first);
1448 preprocess_memory_addresses(radix_operand.value().first);
1449 preprocess_memory_addresses(num_limbs_operand.value().first);
1450 preprocess_memory_addresses(output_bits_operand.value().first);
1451 preprocess_memory_addresses(dst_operand.value().first);
1452
1454 .operand(value_operand.value().second)
1455 .operand(radix_operand.value().second)
1456 .operand(num_limbs_operand.value().second)
1457 .operand(output_bits_operand.value().second)
1458 .operand(dst_operand.value().second)
1459 .build();
1460 instructions.push_back(toradixbe_instruction);
1461
1462 // Use is_output_bits to determine the output memory tag
1463 auto output_tag = instruction.is_output_bits ? bb::avm2::MemoryTag::U1 : bb::avm2::MemoryTag::U8;
1464 memory_manager.set_memory_address(output_tag, dst_operand.value().first.absolute_address);
1465}
1466
1468{
1469 auto level_operand = memory_manager.get_resolved_address_and_operand_16(instruction.level_offset);
1470 auto message_operand = memory_manager.get_resolved_address_and_operand_16(instruction.message_offset);
1471 auto fields_operand = memory_manager.get_resolved_address_and_operand_16(instruction.fields_offset);
1472 auto fields_size_operand = memory_manager.get_resolved_address_and_operand_16(instruction.fields_size_offset);
1473 auto message_size = instruction.message_size;
1474
1475 if (!level_operand.has_value() || !message_operand.has_value() || !fields_operand.has_value() ||
1476 !fields_size_operand.has_value()) {
1477 return;
1478 }
1479
1480 preprocess_memory_addresses(level_operand.value().first);
1481 preprocess_memory_addresses(message_operand.value().first);
1482 preprocess_memory_addresses(fields_operand.value().first);
1483 preprocess_memory_addresses(fields_size_operand.value().first);
1484
1486 .operand(level_operand.value().second)
1487 .operand(message_operand.value().second)
1488 .operand(fields_operand.value().second)
1489 .operand(fields_size_operand.value().second)
1491 .build();
1492 instructions.push_back(debuglog_instruction);
1493}
1494
1498{
1500 // if the block is called by INTERNALCALL, just insert INTERNALRETURN
1501 if (caller != nullptr) {
1502 auto internalreturn_instruction =
1504 instructions.push_back(internalreturn_instruction);
1505 return;
1506 }
1507
1509 if (!return_addr.has_value()) {
1510 return_addr = std::optional<uint32_t>(0);
1511 }
1512
1513 // TODO(defkit): return_size_offset should be const and defined by fuzzer
1514
1515 uint16_t return_size_offset = 5U;
1516 // Ensure operands are created as U16 to match wire format (UINT16)
1518 .operand(return_size_offset)
1520 .operand(static_cast<uint16_t>(return_size))
1521 .build();
1522 instructions.push_back(set_size_instruction);
1523 // RETURN expects UINT16 operands, ensure we cast to uint16_t explicitly
1525 .operand(static_cast<uint16_t>(return_size_offset))
1526 .operand(return_addr.value())
1527 .build();
1528 instructions.push_back(return_instruction);
1529}
1530
1531void ProgramBlock::finalize_with_revert(uint8_t revert_size,
1532 MemoryTagWrapper revert_value_tag,
1533 uint16_t revert_value_offset_index)
1534{
1536
1537 auto revert_addr = memory_manager.get_memory_offset_16(revert_value_tag.value, revert_value_offset_index);
1538 if (!revert_addr.has_value()) {
1539 revert_addr = std::optional<uint32_t>(0);
1540 }
1541
1542 // Once we do more of the randomness in Instruction selection, revert_size_offset we shouldnt need to hardcode
1543 uint16_t revert_size_offset = 5U;
1544 // Ensure operands are created as U16 to match wire format (UINT16)
1546 .operand(revert_size_offset)
1548 .operand(static_cast<uint16_t>(revert_size))
1549 .build();
1550 instructions.push_back(set_size_instruction);
1551 // REVERT_16 expects UINT16 operands, ensure we cast to uint16_t explicitly
1553 .operand(static_cast<uint16_t>(revert_size_offset))
1554 .operand(revert_addr.value())
1555 .build();
1556 instructions.push_back(revert_instruction);
1557}
1558
1559void ProgramBlock::finalize_with_jump(ProgramBlock* target_block, bool copy_memory_manager)
1560{
1562 successors.push_back(target_block);
1563 target_block->predecessors.push_back(this);
1564 target_block->caller = this->caller;
1565 if (copy_memory_manager) {
1566 target_block->memory_manager = memory_manager;
1567 }
1568}
1569
1571 ProgramBlock* target_else_block,
1572 uint16_t condition_offset,
1573 bool copy_memory_manager)
1574{
1576 successors.push_back(target_then_block);
1577 successors.push_back(target_else_block);
1579 target_then_block->predecessors.push_back(this);
1580 target_else_block->predecessors.push_back(this);
1581 target_then_block->caller = this->caller;
1582 target_else_block->caller = this->caller;
1583 if (copy_memory_manager) {
1584 target_then_block->memory_manager = memory_manager;
1585 target_else_block->memory_manager = memory_manager;
1586 }
1587}
1588
1590{
1591 auto internalcall_instruction =
1593 instructions.push_back(internalcall_instruction);
1595 this->successors.push_back(target_block);
1596 target_block->predecessors.push_back(this);
1597 target_block->caller = this->caller;
1598}
1599
1601{
1602 for (auto [instruction_index, target_block] : internal_call_instruction_indicies_to_patch) {
1603 auto internalcall_instruction = instructions.at(instruction_index);
1604 if (target_block->offset == -1) {
1605 throw std::runtime_error("Target block offset is not set, should not happen");
1606 }
1607 auto internalcall_instruction_builder =
1609 .operand(static_cast<uint32_t>(target_block->offset));
1610 instructions.at(instruction_index) = internalcall_instruction_builder.build();
1611 }
1613}
1614
1616{
1618 if (!condition_addr.has_value()) {
1619 return std::nullopt;
1620 }
1621 return condition_addr;
1622}
1623
1632
1637
1639{
1640 memory_manager.set_base_offset(instruction_block.base_offset);
1643 .result_address = AddressRef{ .address = 0, .mode = AddressingMode::Direct },
1644 .value = instruction_block.base_offset });
1645 for (const auto& instr : instruction_block.instructions) {
1646 process_instruction(instr);
1647 }
1648}
1649
1651{
1652 std::visit(
1653 overloaded{
1654 [this](ADD_8_Instruction instruction) { return this->process_add_8_instruction(instruction); },
1655 [this](SUB_8_Instruction instruction) { return this->process_sub_8_instruction(instruction); },
1656 [this](MUL_8_Instruction instruction) { return this->process_mul_8_instruction(instruction); },
1657 [this](DIV_8_Instruction instruction) { return this->process_div_8_instruction(instruction); },
1658 [this](EQ_8_Instruction instruction) { return this->process_eq_8_instruction(instruction); },
1659 [this](LT_8_Instruction instruction) { return this->process_lt_8_instruction(instruction); },
1660 [this](LTE_8_Instruction instruction) { return this->process_lte_8_instruction(instruction); },
1661 [this](AND_8_Instruction instruction) { return this->process_and_8_instruction(instruction); },
1662 [this](OR_8_Instruction instruction) { return this->process_or_8_instruction(instruction); },
1663 [this](XOR_8_Instruction instruction) { return this->process_xor_8_instruction(instruction); },
1664 [this](SHL_8_Instruction instruction) { return this->process_shl_8_instruction(instruction); },
1665 [this](SHR_8_Instruction instruction) { return this->process_shr_8_instruction(instruction); },
1666 [this](SET_8_Instruction instruction) { return this->process_set_8_instruction(instruction); },
1667 [this](SET_16_Instruction instruction) { return this->process_set_16_instruction(instruction); },
1668 [this](SET_32_Instruction instruction) { return this->process_set_32_instruction(instruction); },
1669 [this](SET_64_Instruction instruction) { return this->process_set_64_instruction(instruction); },
1670 [this](SET_128_Instruction instruction) { return this->process_set_128_instruction(instruction); },
1671 [this](SET_FF_Instruction instruction) { return this->process_set_ff_instruction(instruction); },
1672 [this](MOV_8_Instruction instruction) { return this->process_mov_8_instruction(instruction); },
1673 [this](MOV_16_Instruction instruction) { return this->process_mov_16_instruction(instruction); },
1674 [this](FDIV_8_Instruction instruction) { return this->process_fdiv_8_instruction(instruction); },
1675 [this](NOT_8_Instruction instruction) { return this->process_not_8_instruction(instruction); },
1676 [this](ADD_16_Instruction instruction) { return this->process_add_16_instruction(instruction); },
1677 [this](SUB_16_Instruction instruction) { return this->process_sub_16_instruction(instruction); },
1678 [this](MUL_16_Instruction instruction) { return this->process_mul_16_instruction(instruction); },
1679 [this](DIV_16_Instruction instruction) { return this->process_div_16_instruction(instruction); },
1680 [this](FDIV_16_Instruction instruction) { return this->process_fdiv_16_instruction(instruction); },
1681 [this](EQ_16_Instruction instruction) { return this->process_eq_16_instruction(instruction); },
1682 [this](LT_16_Instruction instruction) { return this->process_lt_16_instruction(instruction); },
1683 [this](LTE_16_Instruction instruction) { return this->process_lte_16_instruction(instruction); },
1684 [this](AND_16_Instruction instruction) { return this->process_and_16_instruction(instruction); },
1685 [this](OR_16_Instruction instruction) { return this->process_or_16_instruction(instruction); },
1686 [this](XOR_16_Instruction instruction) { return this->process_xor_16_instruction(instruction); },
1687 [this](NOT_16_Instruction instruction) { return this->process_not_16_instruction(instruction); },
1688 [this](SHL_16_Instruction instruction) { return this->process_shl_16_instruction(instruction); },
1689 [this](SHR_16_Instruction instruction) { return this->process_shr_16_instruction(instruction); },
1690 [this](CAST_8_Instruction instruction) { return this->process_cast_8_instruction(instruction); },
1691 [this](CAST_16_Instruction instruction) { return this->process_cast_16_instruction(instruction); },
1692 [this](SSTORE_Instruction instruction) { return this->process_sstore_instruction(instruction); },
1693 [this](SLOAD_Instruction instruction) { return this->process_sload_instruction(instruction); },
1694 [this](GETENVVAR_Instruction instruction) { return this->process_getenvvar_instruction(instruction); },
1696 return this->process_emitnulifier_instruction(instruction);
1697 },
1699 return this->process_nullifierexists_instruction(instruction);
1700 },
1702 return this->process_emitnotehash_instruction(instruction);
1703 },
1705 return this->process_notehashexists_instruction(instruction);
1706 },
1708 return this->process_calldatacopy_instruction(instruction);
1709 },
1711 return this->process_sendl2tol1msg_instruction(instruction);
1712 },
1714 return this->process_emitunencryptedlog_instruction(instruction);
1715 },
1716 [this](CALL_Instruction instruction) { return this->process_call_instruction(instruction); },
1718 return this->process_returndatasize_instruction(instruction);
1719 },
1721 return this->process_returndatacopy_instruction(instruction);
1722 },
1724 return this->process_getcontractinstance_instruction(instruction);
1725 },
1726 [this](SUCCESSCOPY_Instruction instruction) { return this->process_successcopy_instruction(instruction); },
1727 [this](ECADD_Instruction instruction) { return this->process_ecadd_instruction(instruction); },
1729 return this->process_poseidon2perm_instruction(instruction);
1730 },
1731 [this](KECCAKF1600_Instruction instruction) { return this->process_keccakf1600_instruction(instruction); },
1733 return this->process_sha256compression_instruction(instruction);
1734 },
1736 return this->process_l1tol2msgexists_instruction(instruction);
1737 },
1738 [this](TORADIXBE_Instruction instruction) { return this->process_toradixbe_instruction(instruction); },
1739 [this](DEBUGLOG_Instruction instruction) { return this->process_debuglog_instruction(instruction); },
1740 [](auto) { throw std::runtime_error("Unknown instruction"); },
1741 },
1742 instruction);
1743}
1744
1745std::vector<bb::avm2::simulation::Instruction> ProgramBlock::get_instructions()
1746{
1747 return instructions;
1748}
::FuzzInstruction FuzzInstruction
std::optional< uint16_t > get_memory_offset_16(bb::avm2::MemoryTag tag, uint32_t address_index)
std::optional< std::pair< ResolvedAddress, bb::avm2::testing::OperandBuilder > > get_resolved_address_and_operand_8(ParamRef address)
std::optional< bb::avm2::FF > get_slot(uint16_t slot_offset_index)
bool is_memory_address_set(uint16_t address)
void set_memory_address(bb::avm2::MemoryTag tag, uint32_t address)
void append_slot(bb::avm2::FF slot)
void set_base_offset(uint32_t base_offset)
std::optional< std::pair< ResolvedAddress, bb::avm2::testing::OperandBuilder > > get_resolved_address_and_operand_16(ParamRef address)
void process_shr_16_instruction(SHR_16_Instruction instruction)
void process_set_8_instruction(SET_8_Instruction instruction)
void process_poseidon2perm_instruction(POSEIDON2PERM_Instruction instruction)
std::vector< ProgramBlock * > predecessors
void process_sload_instruction(SLOAD_Instruction instruction)
void finalize_with_return(uint8_t return_size, MemoryTagWrapper return_value_tag, uint16_t return_value_offset_index)
finalize the program block with a return instruction Tries to find memory address with the given retu...
std::vector< bb::avm2::simulation::Instruction > get_instructions()
void preprocess_memory_addresses(ResolvedAddress resolved_address)
preprocess the memory addresses Sets M[0] = base_offset for Relative/IndirectRelative modes Sets M[po...
void insert_internal_call(ProgramBlock *target_block)
insert INTERNALCALL instruction with 0 offset
bool is_memory_address_set(uint16_t address)
void process_emitnotehash_instruction(EMITNOTEHASH_Instruction instruction)
void process_xor_16_instruction(XOR_16_Instruction instruction)
ProgramBlock * caller
the block that called this block by INTERNALCALL This field is copied to predecessors on every CFG in...
void process_or_16_instruction(OR_16_Instruction instruction)
void patch_internal_calls()
in insert_internal_call we insert INTERNALCALL instruction with 0 offset, because we don't know the r...
void finalize_with_jump(ProgramBlock *target_block, bool copy_memory_manager=true)
finalize the block with a jump Sets the terminator type to JUMP, adds the target block to the success...
void process_debuglog_instruction(DEBUGLOG_Instruction instruction)
void process_returndatacopy_instruction(RETURNDATACOPY_Instruction instruction)
uint16_t condition_offset_index
the offset index of the condition variable (for JUMP_IF)
void process_lte_16_instruction(LTE_16_Instruction instruction)
void process_eq_8_instruction(EQ_8_Instruction instruction)
void process_keccakf1600_instruction(KECCAKF1600_Instruction instruction)
void process_fdiv_8_instruction(FDIV_8_Instruction instruction)
void process_nullifierexists_instruction(NULLIFIEREXISTS_Instruction instruction)
void process_not_8_instruction(NOT_8_Instruction instruction)
void process_add_8_instruction(ADD_8_Instruction instruction)
void finalize_with_revert(uint8_t revert_size, MemoryTagWrapper revert_value_tag, uint16_t revert_value_offset_index)
finalize the program block with a revert instruction Similar to finalize_with_return but uses REVERT ...
void process_and_16_instruction(AND_16_Instruction instruction)
MemoryManager memory_manager
void process_sub_8_instruction(SUB_8_Instruction instruction)
void process_shl_8_instruction(SHL_8_Instruction instruction)
void process_notehashexists_instruction(NOTEHASHEXISTS_Instruction instruction)
void process_div_16_instruction(DIV_16_Instruction instruction)
void process_instruction(FuzzInstruction instruction)
process the instruction
void process_toradixbe_instruction(TORADIXBE_Instruction instruction)
void process_emitnulifier_instruction(EMITNULLIFIER_Instruction instruction)
void process_fdiv_16_instruction(FDIV_16_Instruction instruction)
void process_shl_16_instruction(SHL_16_Instruction instruction)
void process_mul_16_instruction(MUL_16_Instruction instruction)
void process_set_ff_instruction(SET_FF_Instruction instruction)
void process_sstore_instruction(SSTORE_Instruction instruction)
std::map< size_t, ProgramBlock * > internal_call_instruction_indicies_to_patch
void process_ecadd_instruction(ECADD_Instruction instruction)
void record_result_tag_from_param_tags(std::initializer_list< ParamRef > params, ResolvedAddress result_address)
void process_div_8_instruction(DIV_8_Instruction instruction)
void process_and_8_instruction(AND_8_Instruction instruction)
void process_lt_16_instruction(LT_16_Instruction instruction)
std::vector< ProgramBlock * > successors
void process_write_terminating_condition_value()
void process_sub_16_instruction(SUB_16_Instruction instruction)
void process_or_8_instruction(OR_8_Instruction instruction)
void process_cast_8_instruction(CAST_8_Instruction instruction)
void process_call_instruction(CALL_Instruction instruction)
void process_cast_16_instruction(CAST_16_Instruction instruction)
void process_not_16_instruction(NOT_16_Instruction instruction)
void process_set_64_instruction(SET_64_Instruction instruction)
void process_calldatacopy_instruction(CALLDATACOPY_Instruction instruction)
void process_successcopy_instruction(SUCCESSCOPY_Instruction instruction)
void process_l1tol2msgexists_instruction(L1TOL2MSGEXISTS_Instruction instruction)
void process_sendl2tol1msg_instruction(SENDL2TOL1MSG_Instruction instruction)
void process_mov_8_instruction(MOV_8_Instruction instruction)
std::optional< uint16_t > get_terminating_condition_value()
void process_emitunencryptedlog_instruction(EMITUNENCRYPTEDLOG_Instruction instruction)
void process_returndatasize_instruction(RETURNDATASIZE_Instruction instruction)
void process_sha256compression_instruction(SHA256COMPRESSION_Instruction instruction)
void process_instruction_block(InstructionBlock &instruction_block)
process the instruction block
void process_mul_8_instruction(MUL_8_Instruction instruction)
void process_set_16_instruction(SET_16_Instruction instruction)
void process_add_16_instruction(ADD_16_Instruction instruction)
void process_xor_8_instruction(XOR_8_Instruction instruction)
void process_eq_16_instruction(EQ_16_Instruction instruction)
void process_lte_8_instruction(LTE_8_Instruction instruction)
void process_getcontractinstance_instruction(GETCONTRACTINSTANCE_Instruction instruction)
void finalize_with_jump_if(ProgramBlock *target_then_block, ProgramBlock *target_else_block, uint16_t condition_offset, bool copy_memory_manager=true)
finalize the block with a jump if Sets the terminator type to JUMP_IF, adds the target blocks to the ...
void process_set_32_instruction(SET_32_Instruction instruction)
void process_getenvvar_instruction(GETENVVAR_Instruction instruction)
TerminatorType terminator_type
void process_lt_8_instruction(LT_8_Instruction instruction)
std::vector< bb::avm2::simulation::Instruction > instructions
void process_shr_8_instruction(SHR_8_Instruction instruction)
void process_mov_16_instruction(MOV_16_Instruction instruction)
void process_set_128_instruction(SET_128_Instruction instruction)
simulation::Instruction build() const
InstructionBuilder & operand(OperandBuilder operand)
FF a
FF b
overloaded(Ts...) -> overloaded< Ts... >
uint64_t da_gas
uint64_t l2_gas
Instruction instruction
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
unsigned __int128 uint128_t
Definition serialize.hpp:44
mem[result_offset] = mem[a_address] + mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] + mem[b_address]
mem[result_offset] = mem[a_address] & mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] & mem[b_address]
uint32_t address
CAST_16: cast mem[src_offset_index] to target_tag and store at dst_offset.
CAST_8: cast mem[src_offset_index] to target_tag and store at dst_offset.
mem[result_offset] = mem[a_address] / mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] / mem[b_address]
EMITNOTEHASH: M[note_hash_offset] = note_hash; emit note hash to the note hash tree.
EMITNULIFIER: inserts new nullifier to the nullifier tree.
mem[result_offset] = mem[a_address] == mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] == mem[b_address]
GETENVVAR: M[result_offset] = getenvvar(type)
KECCAKF1600: Perform Keccak-f[1600] permutation on 25 U64 values M[dst_address:dst_address+25] = kecc...
L1TOL2MSGEXISTS: Check if a L1 to L2 message exists M[result_address] = L1TOL2MSGEXISTS(M[msg_hash_ad...
mem[result_offset] = mem[a_address] < mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] < mem[b_address]
mem[result_offset] = mem[a_address] <= mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] <= mem[b_address]
MOV_16 instruction: mem[dst_offset] = mem[src_offset].
MOV_8 instruction: mem[dst_offset] = mem[src_offset].
mem[result_offset] = mem[a_address] * mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] * mem[b_address]
Wrapper for MemoryTag to allow for msgpack packing and unpacking.
NULLIFIEREXISTS: checks if a siloed nullifier exists in the nullifier tree M[result_address] = NULLIF...
mem[result_offset] = mem[a_address] | mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] | mem[b_address]
POSEIDON2PERM: Perform Poseidon2 permutation on 4 FF values M[dst_address:dst_address+4] = poseidon2_...
Output of resolving an address in the memory manager In order to resolve a given absolute address wit...
uint32_t operand_address
uint32_t absolute_address
std::optional< uint32_t > pointer_address
SET_128 instruction.
SET_16 instruction.
MemoryTagWrapper value_tag
SET_32 instruction.
MemoryTagWrapper value_tag
SET_64 instruction.
SET_8 instruction.
SET_FF instruction.
MemoryTagWrapper value_tag
SHA256COMPRESSION: Perform SHA256 compression M[dst_address:dst_address+8] = sha256_compression(M[sta...
mem[result_offset] = mem[a_address] << mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] << mem[b_address]
mem[result_offset] = mem[a_address] >> mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] >> mem[b_address]
SLOAD: M[slot_offset] = slot; M[result_offset] = S[M[slotOffset]].
SSTORE: M[slot_offset_index] = slot; S[M[slotOffset]] = M[srcOffset].
mem[result_offset] = mem[a_address] - mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] - mem[b_address]
TORADIXBE: Convert a field element to a vector of limbs in big-endian radix representation M[dst_addr...
mem[result_offset] = mem[a_address] ^ mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] ^ mem[b_address]
std::vector< FuzzInstruction > instructions