From 7e401cd537ed9a7d0c32dffda33930011b392cb0 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Tue, 9 Apr 2024 16:06:02 +0000 Subject: [PATCH] 5557: deserialization and execution layer for CMOV --- .../vm/avm_trace/avm_deserialization.cpp | 2 + .../vm/avm_trace/avm_execution.cpp | 7 +++ .../vm/tests/avm_execution.test.cpp | 56 +++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp index 03d4091ddef..2590e5e298a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp @@ -44,6 +44,8 @@ const std::unordered_map> 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 } }, }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp index 753ce9eca13..1e018d647d6 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -232,6 +232,13 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(1)), std::get(inst.operands.at(2))); break; + case OpCode::CMOV: + trace_builder.op_cmov(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4))); + break; // Control Flow - Contract Calls case OpCode::RETURN: trace_builder.return_op(std::get(inst.operands.at(0)), diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp index 0feab83b36e..f505eb16ce5 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp @@ -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(0), + VariantWith(16), + VariantWith(17), + VariantWith(32), + VariantWith(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) {