Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
addressing.test.cpp
Go to the documentation of this file.
2
3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
5
16
17namespace bb::avm2::simulation {
18namespace {
19
20using ::bb::avm2::testing::InstructionBuilder;
21using enum ::bb::avm2::WireOpCode;
22using ::testing::ElementsAre;
23using ::testing::ReturnRef;
24using ::testing::StrictMock;
25
26template <typename T> auto from = ::bb::avm2::simulation::Operand::from<T>;
27
28TEST(AvmSimulationAddressingTest, AllDirectAndNonRelative)
29{
30 InstructionInfoDB instruction_info_db;
31 NoopEventEmitter<AddressingEvent> event_emitter;
32
33 // No calls to gt.
34 StrictMock<MockGreaterThan> gt;
35
36 Addressing addressing(instruction_info_db, gt, event_emitter);
37
38 {
39 const auto instr = InstructionBuilder(SET_8)
40 // dstOffset
41 .operand<uint8_t>(1)
42 // tag
43 .operand(MemoryTag::FF)
44 // value
45 .operand<uint8_t>(1)
46 .build();
47
48 // No calls to get the base address.
49 StrictMock<MockMemory> memory;
50
51 const auto operands = addressing.resolve(instr, memory);
52 EXPECT_THAT(operands,
53 ElementsAre(
54 // dstOffset has been resolved and is now a MemoryAddress.
55 from<MemoryAddress>(1),
56 // tag is unchanged.
57 instr.operands.at(1),
58 // value is unchanged.
59 instr.operands.at(2)));
60 }
61 {
62 const auto instr = InstructionBuilder(ADD_16)
63 // aOffset
64 .operand<uint16_t>(1)
65 // bOffset
66 .operand<uint16_t>(2)
67 // dstOffset
68 .operand<uint16_t>(3)
69 .build();
70
71 // No calls to get the base address.
72 StrictMock<MockMemory> memory;
73
74 const auto operands = addressing.resolve(instr, memory);
75 EXPECT_THAT(operands, ElementsAre(from<MemoryAddress>(1), from<MemoryAddress>(2), from<MemoryAddress>(3)));
76 }
77}
78
79TEST(AvmSimulationAddressingTest, RelativeAddressing)
80{
81 InstructionInfoDB instruction_info_db;
82 NoopEventEmitter<AddressingEvent> event_emitter;
83 StrictMock<MockGreaterThan> gt;
84 Addressing addressing(instruction_info_db, gt, event_emitter);
85
86 // For relative addressing, we need a base address other than 0
87 // Base pointer at address 100
88 MemoryValue base_addr = MemoryValue::from<uint32_t>(100);
89
90 // Set up the ADD_8 instruction with relative addressing
91 const auto instr = InstructionBuilder(ADD_8)
92 // aOffset
93 .operand<uint8_t>(10)
94 .relative()
95 // bOffset
96 .operand<uint8_t>(20)
97 // dstOffset
98 .operand<uint8_t>(30)
99 .relative()
100 .build();
101
102 StrictMock<MockMemory> memory;
103 EXPECT_CALL(memory, get(0)).WillOnce(ReturnRef(base_addr));
104 EXPECT_CALL(gt, gt(110, AVM_HIGHEST_MEM_ADDRESS));
105 EXPECT_CALL(gt, gt(130, AVM_HIGHEST_MEM_ADDRESS));
106
107 const auto operands = addressing.resolve(instr, memory);
108
109 EXPECT_THAT(operands,
110 ElementsAre(
111 // aOffset resolved as base + 10 = 110
112 from<MemoryAddress>(110),
113 // bOffset stays the same
114 from<MemoryAddress>(20),
115 // dstOffset resolved as base + 30 = 130
116 from<MemoryAddress>(130)));
117}
118
119TEST(AvmSimulationAddressingTest, IndirectAddressing)
120{
121 InstructionInfoDB instruction_info_db;
122 NoopEventEmitter<AddressingEvent> event_emitter;
123 // No calls to gt gadget.
124 StrictMock<MockGreaterThan> gt;
125 Addressing addressing(instruction_info_db, gt, event_emitter);
126
127 // Set up the ADD_8 instruction with indirect addressing
128 const auto instr = InstructionBuilder(ADD_8)
129 // aOffset - address 5 contains the actual address
130 .operand<uint8_t>(5)
131 .indirect()
132 // bOffset
133 .operand<uint8_t>(10)
134 // dstOffset - address 15 contains the actual address
135 .operand<uint8_t>(15)
136 .indirect()
137 .build();
138
139 StrictMock<MockMemory> memory;
140 MemoryValue addr_5_value = MemoryValue::from<uint32_t>(50);
141 EXPECT_CALL(memory, get(5)).WillOnce(ReturnRef(addr_5_value));
142 MemoryValue addr_15_value = MemoryValue::from<uint32_t>(60);
143 EXPECT_CALL(memory, get(15)).WillOnce(ReturnRef(addr_15_value));
144
145 const auto operands = addressing.resolve(instr, memory);
146
147 // Expect indirect offsets to be resolved by looking up their values in memory
148 EXPECT_THAT(operands,
149 ElementsAre(
150 // aOffset resolved indirectly: memory[5] = 50
151 from<MemoryAddress>(50),
152 // bOffset stays the same
153 from<MemoryAddress>(10),
154 // dstOffset resolved indirectly: memory[15] = 60
155 from<MemoryAddress>(60)));
156}
157
158TEST(AvmSimulationAddressingTest, IndirectAndRelativeAddressing)
159{
160 InstructionInfoDB instruction_info_db;
161 NoopEventEmitter<AddressingEvent> event_emitter;
162 StrictMock<MockGreaterThan> gt;
163 Addressing addressing(instruction_info_db, gt, event_emitter);
164
165 // Base address is 100
166 MemoryValue base_addr = MemoryValue::from<uint32_t>(100);
167
168 // Set up the ADD_8 instruction with both indirect and relative addressing
169 const auto instr = InstructionBuilder(ADD_8)
170 // aOffset (indirect and relative): address base+5 contains value
171 .operand<uint8_t>(5)
172 .indirect()
173 .relative()
174 // bOffset (indirect only): address 10 contains value
175 .operand<uint8_t>(10)
176 .indirect()
177 // dstOffset (relative only)
178 .operand<uint8_t>(15)
179 .relative()
180 .build();
181
182 StrictMock<MockMemory> memory;
183 EXPECT_CALL(memory, get(0)).WillOnce(ReturnRef(base_addr)); // Base address (100)
184 // Address 105 (base+5) contains value 200
185 MemoryValue addr_105_value = MemoryValue::from<uint32_t>(200);
186 EXPECT_CALL(memory, get(105)).WillOnce(ReturnRef(addr_105_value));
187 // Address 10 contains value 60
188 MemoryValue addr_10_value = MemoryValue::from<uint32_t>(60);
189 EXPECT_CALL(memory, get(10)).WillOnce(ReturnRef(addr_10_value));
190 EXPECT_CALL(gt, gt(105, AVM_HIGHEST_MEM_ADDRESS));
191 EXPECT_CALL(gt, gt(115, AVM_HIGHEST_MEM_ADDRESS));
192
193 const auto operands = addressing.resolve(instr, memory);
194
195 // Expect combined indirect and relative addressing
196 EXPECT_THAT(operands,
197 ElementsAre(
198 // aOffset: relative (base+5=105) and indirect (memory[105]=200)
199 from<MemoryAddress>(200),
200 // bOffset: indirect only (memory[10]=60)
201 from<MemoryAddress>(60),
202 // dstOffset: relative only (base+15=115)
203 from<MemoryAddress>(115)));
204}
205
206} // namespace
207} // namespace bb::avm2::simulation
#define AVM_HIGHEST_MEM_ADDRESS
EventEmitter< DataCopyEvent > event_emitter
GreaterThan gt
InstructionInfoDB instruction_info_db
TEST(EmitUnencryptedLogTest, Basic)
TaggedValue MemoryValue
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
MemoryStore memory