Skip to content

Commit

Permalink
5557: deserialization and execution layer for CMOV
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanmon committed Apr 9, 2024
1 parent 80dbf2d commit 2bc02f6
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const std::unordered_map<OpCode, std::vector<OperandType>> OPCODE_WIRE_FORMAT =
// Machine State - Memory
// OpCode::SET is handled differently
{ OpCode::MOV, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } },
{ OpCode::CMOV,
{ OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } },
// Control Flow - Contract Calls
{ OpCode::RETURN, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } },
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,13 @@ std::vector<Row> Execution::gen_trace(std::vector<Instruction> const& instructio
std::get<uint32_t>(inst.operands.at(1)),
std::get<uint32_t>(inst.operands.at(2)));
break;
case OpCode::CMOV:
trace_builder.op_cmov(std::get<uint8_t>(inst.operands.at(0)),
std::get<uint32_t>(inst.operands.at(1)),
std::get<uint32_t>(inst.operands.at(2)),
std::get<uint32_t>(inst.operands.at(3)),
std::get<uint32_t>(inst.operands.at(4)));
break;
// Control Flow - Contract Calls
case OpCode::RETURN:
trace_builder.return_op(std::get<uint8_t>(inst.operands.at(0)),
Expand Down
56 changes: 56 additions & 0 deletions barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,62 @@ TEST_F(AvmExecutionTests, movOpcode)
gen_proof_and_validate(bytecode, std::move(trace), {});
}

// Positive test with CMOV.
TEST_F(AvmExecutionTests, cmovOpcode)
{
std::string bytecode_hex = to_hex(OpCode::SET) + // opcode SET
"00" // Indirect flag
"01" // U8
"03" // val 3
"00000010" // a_offset 16
+ to_hex(OpCode::SET) + // opcode SET
"00" // Indirect flag
"02" // U16
"0004" // val 4
"00000011" // b_offset 17
+ to_hex(OpCode::SET) + // opcode SET
"00" // Indirect flag
"03" // U32
"00000005" // val 5
"00000020" // cond_offset 32
+ to_hex(OpCode::CMOV) + // opcode CMOV
"00" // Indirect flag
"00000010" // a_offset 16
"00000011" // b_offset 17
"00000020" // cond_offset 32
"00000012" // dst_offset 18
+ to_hex(OpCode::RETURN) + // opcode RETURN
"00" // Indirect flag
"00000000" // ret offset 0
"00000000"; // ret size 0

auto bytecode = hex_to_bytes(bytecode_hex);
auto instructions = Deserialization::parse(bytecode);

ASSERT_THAT(instructions, SizeIs(5));

// CMOV
EXPECT_THAT(instructions.at(3),
AllOf(Field(&Instruction::op_code, OpCode::CMOV),
Field(&Instruction::operands,
ElementsAre(VariantWith<uint8_t>(0),
VariantWith<uint32_t>(16),
VariantWith<uint32_t>(17),
VariantWith<uint32_t>(32),
VariantWith<uint32_t>(18)))));

auto trace = Execution::gen_trace(instructions);

// Find the first row enabling the CMOV selector
auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_cmov == 1; });
EXPECT_EQ(row->avm_main_ia, 3);
EXPECT_EQ(row->avm_main_ib, 4);
EXPECT_EQ(row->avm_main_ic, 3);
EXPECT_EQ(row->avm_main_id, 5);

gen_proof_and_validate(bytecode, std::move(trace), {});
}

// Positive test with indirect MOV.
TEST_F(AvmExecutionTests, indMovOpcode)
{
Expand Down

0 comments on commit 2bc02f6

Please sign in to comment.