Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
pure_addressing.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cstdint>
5#include <vector>
6
15
16namespace bb::avm2::simulation {
17
19{
20 BB_BENCH_NAME("PureAddressing::resolve");
21
22 ExecutionOpCode exec_opcode = instruction_info_db.get(instruction.opcode).exec_opcode;
23 const ExecInstructionSpec& spec = instruction_info_db.get(exec_opcode);
24
25 assert(spec.num_addresses <= instruction.operands.size());
26
28 std::vector<Operand> resolved_operands = instruction.operands;
29
30 for (size_t i = 0; i < spec.num_addresses; ++i) {
31 Operand& operand = resolved_operands[i];
32 const ValueTag tag = operand.get_tag();
33
34 // We assume from serialization that the operand is <= the bits of a memory address.
35 // We assert this here as it is a precondition.
37 // Normalize possibly smaller sizes to MemoryAddress.
38 if (tag != MemoryAddressTag) {
39 operand = Operand::from(static_cast<MemoryAddress>(operand.to<MemoryAddress>()));
40 }
41
42 // Handle relative addressing
43 if (is_operand_relative(instruction.indirect, i)) {
44 if (!base_address) {
45 MemoryValue maybe_base_address = memory.get(0);
46 if (!memory.is_valid_address(maybe_base_address)) {
48 format("Addressing error: Base address (mem[0]) is not a valid address (has tag ",
49 std::to_string(maybe_base_address.get_tag()),
50 ")"));
51 }
52 base_address = maybe_base_address.as<MemoryAddress>();
53 }
54 const uint64_t rel_offset = operand.as<MemoryAddress>();
55 const uint64_t offset = rel_offset + *base_address;
57 throw AddressingException(format("Addressing error: Relative address out of range. Base address ",
58 *base_address,
59 ", relative offset ",
60 rel_offset));
61 }
62 operand = Operand::from(static_cast<MemoryAddress>(offset));
63 }
64
65 // Handle indirection
66 if (is_operand_indirect(instruction.indirect, i)) {
67 const MemoryValue& indirect_value = memory.get(operand.as<MemoryAddress>());
68 if (!memory.is_valid_address(indirect_value)) {
70 format("Addressing error: Address after indirection is not a valid address (address ",
71 operand.to_string(),
72 ") has tag ",
73 std::to_string(indirect_value.get_tag()),
74 ")"));
75 }
76 operand = indirect_value;
77 }
78 }
79
80 return resolved_operands;
81}
82
83} // namespace bb::avm2::simulation
#define AVM_HIGHEST_MEM_ADDRESS
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:219
static TaggedValue from(T value)
ValueTag get_tag() const
std::string to_string() const
virtual const ExecInstructionSpec & get(ExecutionOpCode opcode) const =0
const InstructionInfoDBInterface & instruction_info_db
std::vector< Operand > resolve(const Instruction &instruction, MemoryInterface &memory) override
std::string format(Args... args)
Definition log.hpp:22
ssize_t offset
Definition engine.cpp:36
Instruction instruction
bool is_operand_relative(uint16_t indirect_flag, size_t operand_index)
Definition addressing.hpp:8
bool is_operand_indirect(uint16_t indirect_flag, size_t operand_index)
uint8_t get_tag_bits(ValueTag tag)
uint32_t MemoryAddress
constexpr auto MemoryAddressTag
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)