93 if (size < AluFuzzerInput::size) {
96 input.to_buffer(
data);
97 return AluFuzzerInput::size;
102 auto op_likes_matched_tags = [](
int op_id) ->
bool {
104 case AVM_EXEC_OP_ID_ALU_ADD:
105 case AVM_EXEC_OP_ID_ALU_SUB:
106 case AVM_EXEC_OP_ID_ALU_MUL:
107 case AVM_EXEC_OP_ID_ALU_DIV:
108 case AVM_EXEC_OP_ID_ALU_FDIV:
109 case AVM_EXEC_OP_ID_ALU_EQ:
110 case AVM_EXEC_OP_ID_ALU_LT:
111 case AVM_EXEC_OP_ID_ALU_LTE:
112 case AVM_EXEC_OP_ID_ALU_SHR:
113 case AVM_EXEC_OP_ID_ALU_SHL:
115 case AVM_EXEC_OP_ID_ALU_NOT:
116 case AVM_EXEC_OP_ID_ALU_TRUNCATE:
124 FF value =
FF(dist(rng), dist(rng), dist(rng), dist(rng));
130 auto random_mem_value = [&rng, random_mem_value_from_tag]() ->
MemoryValue {
133 return random_mem_value_from_tag(
tag);
137 AluFuzzerInput input = AluFuzzerInput::from_buffer(
data);
141 input.op_id =
static_cast<uint16_t
>(1 << dist(rng));
145 int choice = dist(rng);
151 input.a = random_mem_value();
156 if (op_likes_matched_tags(input.op_id)) {
157 input.b = random_mem_value_from_tag(input.a.get_tag());
160 input.b = random_mem_value();
166 input.b = random_mem_value();
167 if (op_likes_matched_tags(input.op_id)) {
168 while (input.b.get_tag() == input.a.get_tag()) {
169 input.b = random_mem_value();
181 std::swap(input.a, input.b);
189 input.to_buffer(
data);
191 if (max_size > AluFuzzerInput::size) {
192 return AluFuzzerInput::size;
195 return AluFuzzerInput::size;
202 if (size < AluFuzzerInput::size) {
203 info(
"Input size too small");
207 AluFuzzerInput input = AluFuzzerInput::from_buffer(
data);
225 switch (input.op_id) {
226 case AVM_EXEC_OP_ID_ALU_ADD: {
227 input.c =
alu.add(input.a, input.b);
228 assert(input.c == input.a + input.b);
231 case AVM_EXEC_OP_ID_ALU_SUB: {
232 input.c =
alu.sub(input.a, input.b);
233 assert(input.c == input.a - input.b);
236 case AVM_EXEC_OP_ID_ALU_MUL: {
237 input.c =
alu.mul(input.a, input.b);
238 assert(input.c == input.a * input.b);
241 case AVM_EXEC_OP_ID_ALU_DIV: {
242 input.c =
alu.div(input.a, input.b);
243 assert(input.c == input.a / input.b);
246 case AVM_EXEC_OP_ID_ALU_FDIV: {
247 input.c =
alu.fdiv(input.a, input.b);
248 assert(input.c == input.a / input.b);
251 case AVM_EXEC_OP_ID_ALU_EQ: {
252 input.c =
alu.eq(input.a, input.b);
257 case AVM_EXEC_OP_ID_ALU_LT: {
258 input.c =
alu.lt(input.a, input.b);
263 case AVM_EXEC_OP_ID_ALU_LTE: {
264 input.c =
alu.lte(input.a, input.b);
269 case AVM_EXEC_OP_ID_ALU_NOT: {
272 input.b =
alu.op_not(input.a);
273 assert(input.b == ~input.a);
276 case AVM_EXEC_OP_ID_ALU_SHR: {
277 input.c =
alu.shr(input.a, input.b);
278 assert(input.c == (input.a >> input.b));
281 case AVM_EXEC_OP_ID_ALU_SHL: {
282 input.c =
alu.shl(input.a, input.b);
283 assert(input.c == (input.a << input.b));
286 case AVM_EXEC_OP_ID_ALU_TRUNCATE: {
287 input.c =
alu.truncate(input.a, input.b.get_tag());
299 if (input.op_id == AVM_EXEC_OP_ID_ALU_TRUNCATE) {
302 { Column::execution_register_0_, input.a.as_ff() },
303 { Column::execution_register_1_, input.c.as_ff() },
304 { Column::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(input.b.get_tag()) },
305 { Column::execution_rop_2_,
static_cast<uint8_t
>(input.b.get_tag()) },
306 { Column::execution_sel_exec_dispatch_cast, 1 },
307 { Column::execution_sel_opcode_error, 0 },
312 { Column::execution_mem_tag_reg_0_,
static_cast<uint8_t
>(input.a.get_tag()) },
313 { Column::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(input.b.get_tag()) },
314 { Column::execution_mem_tag_reg_2_,
static_cast<uint8_t
>(input.c.get_tag()) },
315 { Column::execution_register_0_, input.a.as_ff() },
316 { Column::execution_register_1_, input.b.as_ff() },
317 { Column::execution_register_2_, input.c.as_ff() },
318 { Column::execution_sel_exec_dispatch_alu, 1 },
319 { Column::execution_sel_opcode_error, error ? 1 : 0 },
320 { Column::execution_subtrace_operation_id, input.op_id },
341 if (getenv(
"AVM_DEBUG") !=
nullptr) {
342 info(
"Debugging trace:");
347 check_relation<alu_rel>(
trace);
348 check_all_interactions<AluTraceBuilder>(
trace);
350 if (input.op_id == AVM_EXEC_OP_ID_ALU_TRUNCATE) {
351 check_interaction<ExecutionTraceBuilder, bb::avm2::lookup_execution_dispatch_to_cast_settings>(
trace);
353 check_interaction<ExecutionTraceBuilder, bb::avm2::lookup_execution_dispatch_to_alu_settings>(
trace);