Skip to content

Commit

Permalink
5466: deserialization and execution support for CAST
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanmon committed Apr 18, 2024
1 parent 65770c7 commit c0210f6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ const std::unordered_map<OpCode, std::vector<OperandType>> OPCODE_WIRE_FORMAT =
{ OpCode::AND, three_operand_format },
{ OpCode::OR, three_operand_format },
{ OpCode::XOR, three_operand_format },
// Compute - Type Conversions
{ OpCode::CAST, { OperandType::INDIRECT, OperandType::TAG, OperandType::UINT32, OperandType::UINT32 } },
// Execution Environment - Calldata
{ OpCode::CALLDATACOPY, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } },
// Machine State - Internal Control Flow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ std::vector<Row> Execution::gen_trace(std::vector<Instruction> const& instructio
std::get<uint32_t>(inst.operands.at(4)),
std::get<AvmMemoryTag>(inst.operands.at(1)));
break;
// Compute - Type Conversions
case OpCode::CAST:
trace_builder.op_cast(std::get<uint8_t>(inst.operands.at(0)),
std::get<uint32_t>(inst.operands.at(2)),
std::get<uint32_t>(inst.operands.at(3)),
std::get<AvmMemoryTag>(inst.operands.at(1)));
break;
// Execution Environment - Calldata
case OpCode::CALLDATACOPY:
trace_builder.calldata_copy(std::get<uint8_t>(inst.operands.at(0)),
Expand Down
41 changes: 41 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 @@ -607,6 +607,47 @@ TEST_F(AvmExecutionTests, indMovOpcode)
gen_proof_and_validate(bytecode, std::move(trace), {});
}

// Positive test for SET and CAST opcodes
TEST_F(AvmExecutionTests, setAndCastOpcodes)
{
std::string bytecode_hex = to_hex(OpCode::SET) + // opcode SET
"00" // Indirect flag
"02" // U16
"B813" // val 47123
"00000011" // dst_offset 17
+ to_hex(OpCode::CAST) + // opcode CAST
"00" // Indirect flag
"01" // U8
"00000011" // addr a
"00000012" // addr casted a
+ 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(3));

// SUB
EXPECT_THAT(instructions.at(1),
AllOf(Field(&Instruction::op_code, OpCode::CAST),
Field(&Instruction::operands,
ElementsAre(VariantWith<uint8_t>(0),
VariantWith<AvmMemoryTag>(AvmMemoryTag::U8),
VariantWith<uint32_t>(17),
VariantWith<uint32_t>(18)))));

auto trace = Execution::gen_trace(instructions);

// Find the first row enabling the cast selector
auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_cast == 1; });
EXPECT_EQ(row->avm_main_ic, 19); // 0XB813 --> 0X13 = 19

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

// Negative test detecting an invalid opcode byte.
TEST_F(AvmExecutionTests, invalidOpcode)
{
Expand Down

0 comments on commit c0210f6

Please sign in to comment.