diff --git a/avm-transpiler/src/instructions.rs b/avm-transpiler/src/instructions.rs index 0fc44228f440..0e25dedc3f38 100644 --- a/avm-transpiler/src/instructions.rs +++ b/avm-transpiler/src/instructions.rs @@ -80,7 +80,7 @@ impl Debug for AvmInstruction { impl Default for AvmInstruction { fn default() -> Self { AvmInstruction { - opcode: AvmOpcode::ADD, + opcode: AvmOpcode::ADD_8, // TODO(4266): default to Some(0), since all instructions have indirect flag except jumps indirect: None, tag: None, diff --git a/avm-transpiler/src/opcodes.rs b/avm-transpiler/src/opcodes.rs index 94a52cf5d265..f06cece6b7d2 100644 --- a/avm-transpiler/src/opcodes.rs +++ b/avm-transpiler/src/opcodes.rs @@ -4,20 +4,33 @@ #[derive(PartialEq, Copy, Clone, Debug, Eq, Hash)] pub enum AvmOpcode { // Compute - ADD, - SUB, - MUL, - DIV, - FDIV, - EQ, - LT, - LTE, - AND, - OR, - XOR, + ADD_8, + ADD_16, + SUB_8, + SUB_16, + MUL_8, + MUL_16, + DIV_8, + DIV_16, + FDIV_8, + FDIV_16, + EQ_8, + EQ_16, + LT_8, + LT_16, + LTE_8, + LTE_16, + AND_8, + AND_16, + OR_8, + OR_16, + XOR_8, + XOR_16, NOT, - SHL, - SHR, + SHL_8, + SHL_16, + SHR_8, + SHR_16, CAST, // Execution environment ADDRESS, @@ -89,22 +102,35 @@ impl AvmOpcode { match self { // Compute // Compute - Arithmetic - AvmOpcode::ADD => "ADD", - AvmOpcode::SUB => "SUB", - AvmOpcode::MUL => "MUL", - AvmOpcode::DIV => "DIV", - AvmOpcode::FDIV => "FDIV", + AvmOpcode::ADD_8 => "ADD_8", + AvmOpcode::ADD_16 => "ADD_16", + AvmOpcode::SUB_8 => "SUB_8", + AvmOpcode::SUB_16 => "SUB_16", + AvmOpcode::MUL_8 => "MUL_8", + AvmOpcode::MUL_16 => "MUL_16", + AvmOpcode::DIV_8 => "DIV_8", + AvmOpcode::DIV_16 => "DIV_16", + AvmOpcode::FDIV_8 => "FDIV_8", + AvmOpcode::FDIV_16 => "FDIV_16", // Compute - Comparators - AvmOpcode::EQ => "EQ", - AvmOpcode::LT => "LT", - AvmOpcode::LTE => "LTE", + AvmOpcode::EQ_8 => "EQ_8", + AvmOpcode::EQ_16 => "EQ_16", + AvmOpcode::LT_8 => "LT_8", + AvmOpcode::LT_16 => "LT_16", + AvmOpcode::LTE_8 => "LTE_8", + AvmOpcode::LTE_16 => "LTE_16", // Compute - Bitwise - AvmOpcode::AND => "AND", - AvmOpcode::OR => "OR", - AvmOpcode::XOR => "XOR", + AvmOpcode::AND_8 => "AND_8", + AvmOpcode::AND_16 => "AND_16", + AvmOpcode::OR_8 => "OR_8", + AvmOpcode::OR_16 => "OR_16", + AvmOpcode::XOR_8 => "XOR_8", + AvmOpcode::XOR_16 => "XOR_16", AvmOpcode::NOT => "NOT", - AvmOpcode::SHL => "SHL", - AvmOpcode::SHR => "SHR", + AvmOpcode::SHL_8 => "SHL_8", + AvmOpcode::SHL_16 => "SHL_16", + AvmOpcode::SHR_8 => "SHR_8", + AvmOpcode::SHR_16 => "SHR_16", // Compute - Type Conversions AvmOpcode::CAST => "CAST", diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index 25a64479120b..eb24c6b380cb 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -30,24 +30,65 @@ pub fn brillig_to_avm( for brillig_instr in brillig_bytecode { match brillig_instr { BrilligOpcode::BinaryFieldOp { destination, op, lhs, rhs } => { + let bits_needed = + [lhs.0, rhs.0, destination.0].iter().map(bits_needed_for).max().unwrap(); + + assert!( + bits_needed == 8 || bits_needed == 16, + "BinaryFieldOp only support 8 or 16 bit encodings, got: {}", + bits_needed + ); + let avm_opcode = match op { - BinaryFieldOp::Add => AvmOpcode::ADD, - BinaryFieldOp::Sub => AvmOpcode::SUB, - BinaryFieldOp::Mul => AvmOpcode::MUL, - BinaryFieldOp::Div => AvmOpcode::FDIV, - BinaryFieldOp::IntegerDiv => AvmOpcode::DIV, - BinaryFieldOp::Equals => AvmOpcode::EQ, - BinaryFieldOp::LessThan => AvmOpcode::LT, - BinaryFieldOp::LessThanEquals => AvmOpcode::LTE, + BinaryFieldOp::Add => match bits_needed { + 8 => AvmOpcode::ADD_8, + 16 => AvmOpcode::ADD_16, + _ => unreachable!(), + }, + BinaryFieldOp::Sub => match bits_needed { + 8 => AvmOpcode::SUB_8, + 16 => AvmOpcode::SUB_16, + _ => unreachable!(), + }, + BinaryFieldOp::Mul => match bits_needed { + 8 => AvmOpcode::MUL_8, + 16 => AvmOpcode::MUL_16, + _ => unreachable!(), + }, + BinaryFieldOp::Div => match bits_needed { + 8 => AvmOpcode::FDIV_8, + 16 => AvmOpcode::FDIV_16, + _ => unreachable!(), + }, + BinaryFieldOp::IntegerDiv => match bits_needed { + 8 => AvmOpcode::DIV_8, + 16 => AvmOpcode::DIV_16, + _ => unreachable!(), + }, + BinaryFieldOp::Equals => match bits_needed { + 8 => AvmOpcode::EQ_8, + 16 => AvmOpcode::EQ_16, + _ => unreachable!(), + }, + BinaryFieldOp::LessThan => match bits_needed { + 8 => AvmOpcode::LT_8, + 16 => AvmOpcode::LT_16, + _ => unreachable!(), + }, + BinaryFieldOp::LessThanEquals => match bits_needed { + 8 => AvmOpcode::LTE_8, + 16 => AvmOpcode::LTE_16, + _ => unreachable!(), + }, }; avm_instrs.push(AvmInstruction { opcode: avm_opcode, indirect: Some(ALL_DIRECT), - tag: if avm_opcode == AvmOpcode::FDIV { None } else { Some(AvmTypeTag::FIELD) }, + tag: Some(AvmTypeTag::FIELD), operands: vec![ - AvmOperand::U32 { value: lhs.to_usize() as u32 }, - AvmOperand::U32 { value: rhs.to_usize() as u32 }, - AvmOperand::U32 { value: destination.to_usize() as u32 }, + make_operand(bits_needed, &lhs.0), + make_operand(bits_needed, &rhs.0), + make_operand(bits_needed, &destination.0), ], }); } @@ -57,28 +98,84 @@ pub fn brillig_to_avm( "BinaryIntOp bit size should be integral: {:?}", brillig_instr ); + let bits_needed = + [lhs.0, rhs.0, destination.0].iter().map(bits_needed_for).max().unwrap(); + assert!( + bits_needed == 8 || bits_needed == 16, + "BinaryIntOp only support 8 or 16 bit encodings, got: {}", + bits_needed + ); + let avm_opcode = match op { - BinaryIntOp::Add => AvmOpcode::ADD, - BinaryIntOp::Sub => AvmOpcode::SUB, - BinaryIntOp::Mul => AvmOpcode::MUL, - BinaryIntOp::Div => AvmOpcode::DIV, - BinaryIntOp::Equals => AvmOpcode::EQ, - BinaryIntOp::LessThan => AvmOpcode::LT, - BinaryIntOp::LessThanEquals => AvmOpcode::LTE, - BinaryIntOp::And => AvmOpcode::AND, - BinaryIntOp::Or => AvmOpcode::OR, - BinaryIntOp::Xor => AvmOpcode::XOR, - BinaryIntOp::Shl => AvmOpcode::SHL, - BinaryIntOp::Shr => AvmOpcode::SHR, + BinaryIntOp::Add => match bits_needed { + 8 => AvmOpcode::ADD_8, + 16 => AvmOpcode::ADD_16, + _ => unreachable!(), + }, + BinaryIntOp::Sub => match bits_needed { + 8 => AvmOpcode::SUB_8, + 16 => AvmOpcode::SUB_16, + _ => unreachable!(), + }, + BinaryIntOp::Mul => match bits_needed { + 8 => AvmOpcode::MUL_8, + 16 => AvmOpcode::MUL_16, + _ => unreachable!(), + }, + BinaryIntOp::Div => match bits_needed { + 8 => AvmOpcode::DIV_8, + 16 => AvmOpcode::DIV_16, + _ => unreachable!(), + }, + BinaryIntOp::And => match bits_needed { + 8 => AvmOpcode::AND_8, + 16 => AvmOpcode::AND_16, + _ => unreachable!(), + }, + BinaryIntOp::Or => match bits_needed { + 8 => AvmOpcode::OR_8, + 16 => AvmOpcode::OR_16, + _ => unreachable!(), + }, + BinaryIntOp::Xor => match bits_needed { + 8 => AvmOpcode::XOR_8, + 16 => AvmOpcode::XOR_16, + _ => unreachable!(), + }, + BinaryIntOp::Shl => match bits_needed { + 8 => AvmOpcode::SHL_8, + 16 => AvmOpcode::SHL_16, + _ => unreachable!(), + }, + BinaryIntOp::Shr => match bits_needed { + 8 => AvmOpcode::SHR_8, + 16 => AvmOpcode::SHR_16, + _ => unreachable!(), + }, + BinaryIntOp::Equals => match bits_needed { + 8 => AvmOpcode::EQ_8, + 16 => AvmOpcode::EQ_16, + _ => unreachable!(), + }, + BinaryIntOp::LessThan => match bits_needed { + 8 => AvmOpcode::LT_8, + 16 => AvmOpcode::LT_16, + _ => unreachable!(), + }, + BinaryIntOp::LessThanEquals => match bits_needed { + 8 => AvmOpcode::LTE_8, + 16 => AvmOpcode::LTE_16, + _ => unreachable!(), + }, }; avm_instrs.push(AvmInstruction { opcode: avm_opcode, indirect: Some(ALL_DIRECT), tag: Some(tag_from_bit_size(BitSize::Integer(*bit_size))), operands: vec![ - AvmOperand::U32 { value: lhs.to_usize() as u32 }, - AvmOperand::U32 { value: rhs.to_usize() as u32 }, - AvmOperand::U32 { value: destination.to_usize() as u32 }, + make_operand(bits_needed, &lhs.0), + make_operand(bits_needed, &rhs.0), + make_operand(bits_needed, &destination.0), ], }); } @@ -214,9 +311,9 @@ pub fn brillig_to_avm( // We are adding a MOV instruction that moves a value to itself. // This should therefore not affect the program's execution. avm_instrs.push(AvmInstruction { - opcode: AvmOpcode::MOV_8, + opcode: AvmOpcode::MOV_16, indirect: Some(ALL_DIRECT), - operands: vec![AvmOperand::U32 { value: 0x18ca }, AvmOperand::U32 { value: 0x18ca }], + operands: vec![AvmOperand::U16 { value: 0x18ca }, AvmOperand::U16 { value: 0x18ca }], ..Default::default() }); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp index a3be8b380289..ea2042526479 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp @@ -8,12 +8,10 @@ #include namespace tests_avm { - using namespace bb; using namespace bb::avm_trace; namespace { - void common_validate_arithmetic_op(Row const& main_row, Row const& alu_row, FF const& a, @@ -493,7 +491,7 @@ TEST_F(AvmArithmeticTestsFF, fDivision) trace_builder.op_calldata_copy(0, 0, 1, 0); // Memory layout: [15,315,0,0,0,0,....] - trace_builder.op_fdiv(0, 1, 0, 2); // [15,315,21,0,0,0....] + trace_builder.op_fdiv(0, 1, 0, 2, AvmMemoryTag::FF); // [15,315,21,0,0,0....] trace_builder.op_return(0, 0, 3); auto trace = trace_builder.finalize(); @@ -521,7 +519,7 @@ TEST_F(AvmArithmeticTestsFF, fDivisionNumeratorZero) trace_builder.op_calldata_copy(0, 0, 1, 0); // Memory layout: [15,0,0,0,0,0,....] - trace_builder.op_fdiv(0, 1, 0, 0); // [0,0,0,0,0,0....] + trace_builder.op_fdiv(0, 1, 0, 0, AvmMemoryTag::FF); // [0,0,0,0,0,0....] trace_builder.op_return(0, 0, 3); auto trace = trace_builder.finalize(); @@ -550,7 +548,7 @@ TEST_F(AvmArithmeticTestsFF, fDivisionByZeroError) trace_builder.op_calldata_copy(0, 0, 1, 0); // Memory layout: [15,0,0,0,0,0,....] - trace_builder.op_fdiv(0, 0, 1, 2); // [15,0,0,0,0,0....] + trace_builder.op_fdiv(0, 0, 1, 2, AvmMemoryTag::FF); // [15,0,0,0,0,0....] trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); @@ -573,7 +571,7 @@ TEST_F(AvmArithmeticTestsFF, fDivisionByZeroError) TEST_F(AvmArithmeticTestsFF, fDivisionZeroByZeroError) { // Memory layout: [0,0,0,0,0,0,....] - trace_builder.op_fdiv(0, 0, 1, 2); // [0,0,0,0,0,0....] + trace_builder.op_fdiv(0, 0, 1, 2, AvmMemoryTag::FF); // [0,0,0,0,0,0....] trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); @@ -604,15 +602,16 @@ TEST_F(AvmArithmeticTestsFF, mixedOperationsWithError) trace_builder.op_calldata_copy(0, 0, 1, 0); // Memory layout: [0,0,45,23,12,0,0,0,....] - trace_builder.op_add(0, 2, 3, 4, AvmMemoryTag::FF); // [0,0,45,23,68,0,0,0,....] - trace_builder.op_add(0, 4, 5, 5, AvmMemoryTag::FF); // [0,0,45,23,68,68,0,0,....] - trace_builder.op_add(0, 5, 5, 5, AvmMemoryTag::FF); // [0,0,45,23,68,136,0,0,....] - trace_builder.op_add(0, 5, 6, 7, AvmMemoryTag::FF); // [0,0,45,23,68,136,0,136,0....] - trace_builder.op_sub(0, 7, 6, 8, AvmMemoryTag::FF); // [0,0,45,23,68,136,0,136,136,0....] - trace_builder.op_mul(0, 8, 8, 8, AvmMemoryTag::FF); // [0,0,45,23,68,136,0,136,136^2,0....] - trace_builder.op_fdiv(0, 3, 5, 1); // [0,23*136^(-1),45,23,68,136,0,136,136^2,0....] - trace_builder.op_fdiv(0, 1, 1, 9); // [0,23*136^(-1),45,23,68,136,0,136,136^2,1,0....] - trace_builder.op_fdiv(0, 9, 0, 4); // [0,23*136^(-1),45,23,1/0,136,0,136,136^2,1,0....] Error: division by 0 + trace_builder.op_add(0, 2, 3, 4, AvmMemoryTag::FF); // [0,0,45,23,68,0,0,0,....] + trace_builder.op_add(0, 4, 5, 5, AvmMemoryTag::FF); // [0,0,45,23,68,68,0,0,....] + trace_builder.op_add(0, 5, 5, 5, AvmMemoryTag::FF); // [0,0,45,23,68,136,0,0,....] + trace_builder.op_add(0, 5, 6, 7, AvmMemoryTag::FF); // [0,0,45,23,68,136,0,136,0....] + trace_builder.op_sub(0, 7, 6, 8, AvmMemoryTag::FF); // [0,0,45,23,68,136,0,136,136,0....] + trace_builder.op_mul(0, 8, 8, 8, AvmMemoryTag::FF); // [0,0,45,23,68,136,0,136,136^2,0....] + trace_builder.op_fdiv(0, 3, 5, 1, AvmMemoryTag::FF); // [0,23*136^(-1),45,23,68,136,0,136,136^2,0....] + trace_builder.op_fdiv(0, 1, 1, 9, AvmMemoryTag::FF); // [0,23*136^(-1),45,23,68,136,0,136,136^2,1,0....] + trace_builder.op_fdiv( + 0, 9, 0, 4, AvmMemoryTag::FF); // [0,23*136^(-1),45,23,1/0,136,0,136,136^2,1,0....] Error: division by 0 trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); @@ -1527,7 +1526,6 @@ TEST_F(AvmArithmeticTestsU128, nonEquality) // Test on basic incorrect addition over finite field type. TEST_F(AvmArithmeticNegativeTestsFF, addition) { - auto trace = gen_mutated_trace_add(FF(37), FF(4), FF(40), AvmMemoryTag::FF); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_ADD_SUB_1"); } @@ -1535,7 +1533,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, addition) // Test on basic incorrect subtraction over finite field type. TEST_F(AvmArithmeticNegativeTestsFF, subtraction) { - auto trace = gen_mutated_trace_sub(FF(17), FF(8), FF(-9), AvmMemoryTag::FF); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_ADD_SUB_1"); } @@ -1543,7 +1540,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, subtraction) // Test on basic incorrect multiplication over finite field type. TEST_F(AvmArithmeticNegativeTestsFF, multiplication) { - auto trace = gen_mutated_trace_mul(FF(9), FF(100), FF(9000000), AvmMemoryTag::FF); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_MULTIPLICATION_FF"); } @@ -1551,13 +1547,12 @@ TEST_F(AvmArithmeticNegativeTestsFF, multiplication) // Test on basic incorrect division over finite field type. TEST_F(AvmArithmeticNegativeTestsFF, fDivision) { - std::vector const calldata = { 15, 315 }; gen_trace_builder(calldata); trace_builder.op_calldata_copy(0, 0, 2, 0); // Memory layout: [15,315,0,0,0,0,....] - trace_builder.op_fdiv(0, 1, 0, 2); // [15,315,21,0,0,0....] + trace_builder.op_fdiv(0, 1, 0, 2, AvmMemoryTag::FF); // [15,315,21,0,0,0....] trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); @@ -1571,13 +1566,12 @@ TEST_F(AvmArithmeticNegativeTestsFF, fDivision) // in the trace. TEST_F(AvmArithmeticNegativeTestsFF, fDivisionNoZeroButError) { - std::vector const calldata = { 15, 315 }; gen_trace_builder(calldata); trace_builder.op_calldata_copy(0, 0, 2, 0); // Memory layout: [15,315,0,0,0,0,....] - trace_builder.op_fdiv(0, 1, 0, 2); // [15,315,21,0,0,0....] + trace_builder.op_fdiv(0, 1, 0, 2, AvmMemoryTag::FF); // [15,315,21,0,0,0....] trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); @@ -1600,13 +1594,12 @@ TEST_F(AvmArithmeticNegativeTestsFF, fDivisionNoZeroButError) // Test with finite field division by zero occurs and no error is raised (remove error flag) TEST_F(AvmArithmeticNegativeTestsFF, fDivisionByZeroNoError) { - std::vector const calldata = { 15 }; gen_trace_builder(calldata); trace_builder.op_calldata_copy(0, 0, 1, 0); // Memory layout: [15,0,0,0,0,0,....] - trace_builder.op_fdiv(0, 0, 1, 2); // [15,0,0,0,0,0....] + trace_builder.op_fdiv(0, 0, 1, 2, AvmMemoryTag::FF); // [15,0,0,0,0,0....] trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); @@ -1622,9 +1615,8 @@ TEST_F(AvmArithmeticNegativeTestsFF, fDivisionByZeroNoError) // Test with finite field division of zero by zero occurs and no error is raised (remove error flag) TEST_F(AvmArithmeticNegativeTestsFF, fDivisionZeroByZeroNoError) { - // Memory layout: [0,0,0,0,0,0,....] - trace_builder.op_fdiv(0, 0, 1, 2); // [0,0,0,0,0,0....] + trace_builder.op_fdiv(0, 0, 1, 2, AvmMemoryTag::FF); // [0,0,0,0,0,0....] trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); @@ -1640,12 +1632,11 @@ TEST_F(AvmArithmeticNegativeTestsFF, fDivisionZeroByZeroNoError) // Test with finite field division using a wrong read instruction tag TEST_F(AvmArithmeticNegativeTestsFF, fDivisionWrongRInTag) { - std::vector const calldata = { 18, 6 }; gen_trace_builder(calldata); trace_builder.op_calldata_copy(0, 0, 1, 0); // Memory layout: [18,6,0,0,0,0,....] - trace_builder.op_fdiv(0, 0, 1, 2); // [18,6,3,0,0,0....] + trace_builder.op_fdiv(0, 0, 1, 2, AvmMemoryTag::FF); // [18,6,3,0,0,0....] trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); @@ -1661,12 +1652,11 @@ TEST_F(AvmArithmeticNegativeTestsFF, fDivisionWrongRInTag) // Test with finite field division using a wrong write instruction tag TEST_F(AvmArithmeticNegativeTestsFF, fDivisionWrongWInTag) { - std::vector const calldata = { 18, 6 }; gen_trace_builder(calldata); trace_builder.op_calldata_copy(0, 0, 1, 0); // Memory layout: [18,6,0,0,0,0,....] - trace_builder.op_fdiv(0, 0, 1, 2); // [18,6,3,0,0,0....] + trace_builder.op_fdiv(0, 0, 1, 2, AvmMemoryTag::FF); // [18,6,3,0,0,0....] trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); @@ -1683,7 +1673,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, fDivisionWrongWInTag) // the addition, subtraction, multiplication. TEST_F(AvmArithmeticNegativeTestsFF, operationWithErrorFlag1) { - std::vector const calldata = { 37, 4, 11 }; gen_trace_builder(calldata); trace_builder.op_calldata_copy(0, 0, 3, 0); @@ -1705,7 +1694,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, operationWithErrorFlag1) TEST_F(AvmArithmeticNegativeTestsFF, operationWithErrorFlag2) { - std::vector const calldata = { 8, 4, 17 }; gen_trace_builder(calldata); trace_builder.op_calldata_copy(0, 0, 3, 0); @@ -1726,7 +1714,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, operationWithErrorFlag2) TEST_F(AvmArithmeticNegativeTestsFF, operationWithErrorFlag3) { - std::vector const calldata = { 5, 0, 20 }; gen_trace_builder(calldata); trace_builder.op_calldata_copy(0, 0, 3, 0); @@ -1748,7 +1735,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, operationWithErrorFlag3) // Tests a situation for field elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsFF, invalidEquality) { - std::vector trace = gen_mutated_trace_eq(FF::modulus_minus_two, FF(0), FF(1), FF(0), AvmMemoryTag::FF); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); } @@ -1756,7 +1742,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, invalidEquality) // Tests a situation for field elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsFF, invalidInequality) { - std::vector trace = gen_mutated_trace_eq(FF::modulus_minus_two, FF::modulus_minus_two, FF(0), FF(0), AvmMemoryTag::FF); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); @@ -1765,7 +1750,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, invalidInequality) // Tests a situation for field elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsFF, nonBooleanEq) { - std::vector trace = gen_mutated_trace_eq(FF::modulus_minus_two, FF::modulus_minus_two, FF(10), FF(0), AvmMemoryTag::FF); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_RES_IS_BOOL"); @@ -1774,7 +1758,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, nonBooleanEq) // Tests a situation for field elements where the tag for c is not U8. TEST_F(AvmArithmeticNegativeTestsFF, eqOutputWrongTag) { - FF elem = FF::modulus - FF(15); std::vector const calldata = { elem, elem }; gen_trace_builder(calldata); @@ -1794,7 +1777,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, eqOutputWrongTag) // Tests a situation for field elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsFF, invalidInverseDifference) { - // The a, b and c registers contain the correct information, only the inversion of differences is wrong. std::vector trace = gen_mutated_trace_eq(FF::modulus_minus_two, FF(0), FF(0), FF(5).invert(), AvmMemoryTag::FF); @@ -1808,7 +1790,6 @@ TEST_F(AvmArithmeticNegativeTestsFF, invalidInverseDifference) // Test on basic incorrect addition over U8. TEST_F(AvmArithmeticNegativeTestsU8, addition) { - auto trace = gen_mutated_trace_add(FF(234), FF(22), FF(1), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_ADD_SUB_2"); } @@ -1816,7 +1797,6 @@ TEST_F(AvmArithmeticNegativeTestsU8, addition) // Test on basic incorrect subtraction over U8. TEST_F(AvmArithmeticNegativeTestsU8, subtraction) { - auto trace = gen_mutated_trace_sub(FF(100), FF(104), FF(253), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_ADD_SUB_2"); } @@ -1824,7 +1804,6 @@ TEST_F(AvmArithmeticNegativeTestsU8, subtraction) // Test on basic incorrect multiplication over U8. TEST_F(AvmArithmeticNegativeTestsU8, multiplication) { - auto trace = gen_mutated_trace_mul(FF(9), FF(100), FF(55), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_MUL_COMMON_2"); } @@ -1832,7 +1811,6 @@ TEST_F(AvmArithmeticNegativeTestsU8, multiplication) // Tests a situation for U8 elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU8, invalidEquality) { - std::vector trace = gen_mutated_trace_eq(FF(10), FF(255), FF(1), FF(0), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); } @@ -1840,7 +1818,6 @@ TEST_F(AvmArithmeticNegativeTestsU8, invalidEquality) // Tests a situation for U8 elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsU8, invalidInequality) { - std::vector trace = gen_mutated_trace_eq(FF(128), FF(128), FF(0), FF(0), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); } @@ -1848,7 +1825,6 @@ TEST_F(AvmArithmeticNegativeTestsU8, invalidInequality) // Tests a situation for U8 elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsU8, nonBooleanEq) { - std::vector trace = gen_mutated_trace_eq(FF(128), FF(128), FF(200), FF(0), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_RES_IS_BOOL"); } @@ -1856,7 +1832,6 @@ TEST_F(AvmArithmeticNegativeTestsU8, nonBooleanEq) // Tests a situation for U8 elements where the tag for c is not U8. TEST_F(AvmArithmeticNegativeTestsU8, eqOutputWrongTag) { - auto trace = gen_trace_eq(2, 3, 23, 24, 25, AvmMemoryTag::U8); // Find the first row enabling the eq selector @@ -1870,7 +1845,6 @@ TEST_F(AvmArithmeticNegativeTestsU8, eqOutputWrongTag) // Tests a situation for U8 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU8, invalidInverseDifference) { - // The a, b and c registers contain the correct information, only the inversion of differences is wrong. std::vector trace = gen_mutated_trace_eq(FF(130), FF(0), FF(0), FF(1000).invert(), AvmMemoryTag::U8); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); @@ -1883,7 +1857,6 @@ TEST_F(AvmArithmeticNegativeTestsU8, invalidInverseDifference) // Test on basic incorrect addition over U16. TEST_F(AvmArithmeticNegativeTestsU16, addition) { - auto trace = gen_mutated_trace_add(FF(8234), FF(7428), FF(653), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_ADD_SUB_2"); } @@ -1891,7 +1864,6 @@ TEST_F(AvmArithmeticNegativeTestsU16, addition) // Test on basic incorrect subtraction over U16. TEST_F(AvmArithmeticNegativeTestsU16, subtraction) { - auto trace = gen_mutated_trace_sub(FF(100), FF(932), FF(25373), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_ADD_SUB_2"); } @@ -1899,7 +1871,6 @@ TEST_F(AvmArithmeticNegativeTestsU16, subtraction) // Test on basic incorrect multiplication over U16. TEST_F(AvmArithmeticNegativeTestsU16, multiplication) { - auto trace = gen_mutated_trace_mul(FF(8096), FF(1024), FF(1), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_MUL_COMMON_2"); } @@ -1907,7 +1878,6 @@ TEST_F(AvmArithmeticNegativeTestsU16, multiplication) // Tests a situation for U16 elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU16, invalidEquality) { - std::vector trace = gen_mutated_trace_eq(FF(10), FF(255), FF(1), FF(0), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); } @@ -1915,7 +1885,6 @@ TEST_F(AvmArithmeticNegativeTestsU16, invalidEquality) // Tests a situation for U16 elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsU16, invalidInequality) { - std::vector trace = gen_mutated_trace_eq(FF(128), FF(128), FF(0), FF(0), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); } @@ -1923,7 +1892,6 @@ TEST_F(AvmArithmeticNegativeTestsU16, invalidInequality) // Tests a situation for U16 elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsU16, nonBooleanEq) { - std::vector trace = gen_mutated_trace_eq(FF(128), FF(128), FF(200), FF(0), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_RES_IS_BOOL"); } @@ -1931,7 +1899,6 @@ TEST_F(AvmArithmeticNegativeTestsU16, nonBooleanEq) // Tests a situation for U16 elements where the tag for c is not U8. TEST_F(AvmArithmeticNegativeTestsU16, eqOutputWrongTag) { - auto trace = gen_trace_eq(1515, 1515, 23, 24, 25, AvmMemoryTag::U16); // Find the first row enabling the eq selector @@ -1945,7 +1912,6 @@ TEST_F(AvmArithmeticNegativeTestsU16, eqOutputWrongTag) // Tests a situation for U16 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU16, invalidInverseDifference) { - // The a, b and c registers contain the correct information, only the inversion of differences is wrong. std::vector trace = gen_mutated_trace_eq(FF(130), FF(0), FF(0), FF(1000).invert(), AvmMemoryTag::U16); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); @@ -1957,7 +1923,6 @@ TEST_F(AvmArithmeticNegativeTestsU16, invalidInverseDifference) // Test on basic incorrect addition over U32. TEST_F(AvmArithmeticNegativeTestsU32, addition) { - auto trace = gen_mutated_trace_add(FF(1972382341), FF(1111133221), FF(1222222222), AvmMemoryTag::U32); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_ADD_SUB_2"); } @@ -1965,7 +1930,6 @@ TEST_F(AvmArithmeticNegativeTestsU32, addition) // Test on basic incorrect subtraction over U32. TEST_F(AvmArithmeticNegativeTestsU32, subtraction) { - auto trace = gen_mutated_trace_sub(FF(3999888777LLU), FF(UINT32_MAX), FF(2537332433LLU), AvmMemoryTag::U32); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_ADD_SUB_2"); } @@ -1973,7 +1937,6 @@ TEST_F(AvmArithmeticNegativeTestsU32, subtraction) // Test on basic incorrect multiplication over U32. TEST_F(AvmArithmeticNegativeTestsU32, multiplication) { - auto trace = gen_mutated_trace_mul(FF(UINT32_MAX), FF(UINT32_MAX), FF(0), AvmMemoryTag::U32); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_MUL_COMMON_2"); } @@ -1981,7 +1944,6 @@ TEST_F(AvmArithmeticNegativeTestsU32, multiplication) // Tests a situation for U32 elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU32, invalidEquality) { - std::vector trace = gen_mutated_trace_eq(FF(UINT32_MAX - 10), FF(UINT32_MAX), FF(1), FF(0), AvmMemoryTag::U32); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); } @@ -1989,7 +1951,6 @@ TEST_F(AvmArithmeticNegativeTestsU32, invalidEquality) // Tests a situation for U32 elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsU32, invalidInequality) { - std::vector trace = gen_mutated_trace_eq(FF(73934721LLU), FF(73934721LLU), FF(0), FF(0), AvmMemoryTag::U32); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); } @@ -1997,7 +1958,6 @@ TEST_F(AvmArithmeticNegativeTestsU32, invalidInequality) // Tests a situation for U32 elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsU32, nonBooleanEq) { - std::vector trace = gen_mutated_trace_eq(FF(623138LLU), FF(623138LLU), FF(8728342LLU), FF(0), AvmMemoryTag::U32); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_RES_IS_BOOL"); @@ -2006,7 +1966,6 @@ TEST_F(AvmArithmeticNegativeTestsU32, nonBooleanEq) // Tests a situation for U32 elements where the tag for c is not U8. TEST_F(AvmArithmeticNegativeTestsU32, eqOutputWrongTag) { - auto trace = gen_trace_eq(15, 15, 23, 24, 25, AvmMemoryTag::U32); // Find the first row enabling the eq selector @@ -2020,7 +1979,6 @@ TEST_F(AvmArithmeticNegativeTestsU32, eqOutputWrongTag) // Tests a situation for U32 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU32, invalidInverseDifference) { - // The a, b and c registers contain the correct information, only the inversion of differences is wrong. std::vector trace = gen_mutated_trace_eq(FF(74329231LLU), FF(74329231LLU), FF(0), FF(7432701LLU).invert(), AvmMemoryTag::U32); @@ -2034,7 +1992,6 @@ TEST_F(AvmArithmeticNegativeTestsU32, invalidInverseDifference) // Test on basic incorrect addition over U64. TEST_F(AvmArithmeticNegativeTestsU64, addition) { - auto trace = gen_mutated_trace_add( FF(3324236423198282341LLU), FF(999999991111133221LLU), FF(1222222222236LLU), AvmMemoryTag::U64); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_ADD_SUB_2"); @@ -2043,7 +2000,6 @@ TEST_F(AvmArithmeticNegativeTestsU64, addition) // Test on basic incorrect subtraction over U64. TEST_F(AvmArithmeticNegativeTestsU64, subtraction) { - auto trace = gen_mutated_trace_sub(FF(399988877723434LLU), FF(UINT64_MAX), FF(25373324332342LLU), AvmMemoryTag::U64); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_ADD_SUB_2"); @@ -2052,7 +2008,6 @@ TEST_F(AvmArithmeticNegativeTestsU64, subtraction) // Test on basic incorrect multiplication over U64. TEST_F(AvmArithmeticNegativeTestsU64, multiplication) { - auto trace = gen_mutated_trace_mul(FF(399988877723434LLU), FF(9998887772343LLU), FF(9283674827534LLU), AvmMemoryTag::U64); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_MUL_COMMON_2"); @@ -2061,7 +2016,6 @@ TEST_F(AvmArithmeticNegativeTestsU64, multiplication) // Tests a situation for U64 elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU64, invalidEquality) { - std::vector trace = gen_mutated_trace_eq(FF(3999888777231234LLU), FF(3999882177231234LLU), FF(1), FF(0), AvmMemoryTag::U64); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); @@ -2070,7 +2024,6 @@ TEST_F(AvmArithmeticNegativeTestsU64, invalidEquality) // Tests a situation for U64 elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsU64, invalidInequality) { - std::vector trace = gen_mutated_trace_eq(FF(9998887772343LLU), FF(73934721LLU), FF(0), FF(0), AvmMemoryTag::U64); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_EQ"); @@ -2079,7 +2032,6 @@ TEST_F(AvmArithmeticNegativeTestsU64, invalidInequality) // Tests a situation for U64 elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsU64, nonBooleanEq) { - std::vector trace = gen_mutated_trace_eq(FF(9998887772343LLU), FF(9998887772343LLU), FF(2), FF(0), AvmMemoryTag::U64); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_RES_IS_BOOL"); @@ -2088,7 +2040,6 @@ TEST_F(AvmArithmeticNegativeTestsU64, nonBooleanEq) // Tests a situation for U64 elements where the tag for c is not U8. TEST_F(AvmArithmeticNegativeTestsU64, eqOutputWrongTag) { - auto trace = gen_trace_eq(198732, 15, 23, 24, 25, AvmMemoryTag::U64); // Find the first row enabling the eq selector @@ -2102,7 +2053,6 @@ TEST_F(AvmArithmeticNegativeTestsU64, eqOutputWrongTag) // Tests a situation for U64 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU64, invalidInverseDifference) { - // The a, b and c registers contain the correct information, only the inversion of differences is wrong. std::vector trace = gen_mutated_trace_eq( FF(9998887772343LLU), FF(9998887772343LLU), FF(0), FF(0x373428).invert(), AvmMemoryTag::U64); @@ -2116,7 +2066,6 @@ TEST_F(AvmArithmeticNegativeTestsU64, invalidInverseDifference) // Test on basic incorrect addition over U128. TEST_F(AvmArithmeticNegativeTestsU128, addition) { - uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; uint128_t const b = (uint128_t{ 0x3333222233331111LLU } << 64) + uint128_t{ 0x5555111155553333LLU }; uint128_t const c = (uint128_t{ 0x8888444466665555LLU } << 64) + uint128_t{ 0xDDDDAAAAFFFFEEEFLLU }; @@ -2131,7 +2080,6 @@ TEST_F(AvmArithmeticNegativeTestsU128, addition) // Test on basic incorrect subtraction over U128. TEST_F(AvmArithmeticNegativeTestsU128, subtraction) { - uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; uint128_t const b = (uint128_t{ 0x7333222233331111LLU } << 64) + uint128_t{ 0x5555111155553333LLU }; uint128_t const c = (uint128_t{ 0x8888444466665555LLU } << 64) + uint128_t{ 0xDDDDALLU }; @@ -2146,7 +2094,6 @@ TEST_F(AvmArithmeticNegativeTestsU128, subtraction) // Test on basic incorrect multiplication over U128. TEST_F(AvmArithmeticNegativeTestsU128, multiplication) { - uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; uint128_t const b = (uint128_t{ 0x7333222233331111LLU } << 64) + uint128_t{ 0x5555111155553333LLU }; uint128_t const c = (uint128_t{ 0x8888444466665555LLU } << 64) + uint128_t{ 0xDDDDALLU }; @@ -2162,7 +2109,6 @@ TEST_F(AvmArithmeticNegativeTestsU128, multiplication) // another alu operation. TEST_F(AvmArithmeticNegativeTestsU128, multiplicationSecondRowNoOp) { - trace_builder.op_set(0, 3, 0, AvmMemoryTag::U128); trace_builder.op_set(0, 4, 1, AvmMemoryTag::U128); @@ -2193,7 +2139,6 @@ TEST_F(AvmArithmeticNegativeTestsU128, multiplicationSecondRowNoOp) // Tests a situation for U128 elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU128, invalidEquality) { - uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; FF const ff_a = FF{ uint256_t::from_uint128(a) }; uint128_t const b = (uint128_t{ 0x5555222313334444LLU } << 64) + uint128_t{ 0x88889998AAABBBBLLU }; @@ -2206,7 +2151,6 @@ TEST_F(AvmArithmeticNegativeTestsU128, invalidEquality) // Tests a situation for U128 elements where a == b but c == 0; TEST_F(AvmArithmeticNegativeTestsU128, invalidInequality) { - uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; FF const ff_a = FF{ uint256_t::from_uint128(a) }; @@ -2217,7 +2161,6 @@ TEST_F(AvmArithmeticNegativeTestsU128, invalidInequality) // Tests a situation for U128 elements where c is non-boolean, i,e, c!= {0,1}; TEST_F(AvmArithmeticNegativeTestsU128, nonBooleanEq) { - uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; FF const ff_a = FF{ uint256_t::from_uint128(a) }; std::vector trace = gen_mutated_trace_eq(ff_a, ff_a, FF::modulus - FF(1), FF(0), AvmMemoryTag::U128); @@ -2227,7 +2170,6 @@ TEST_F(AvmArithmeticNegativeTestsU128, nonBooleanEq) // Tests a situation for U128 elements where the tag for c is not U8. TEST_F(AvmArithmeticNegativeTestsU128, eqOutputWrongTag) { - auto trace = gen_trace_eq(1587, 1587, 23, 24, 25, AvmMemoryTag::U128); // Find the first row enabling the eq selector @@ -2241,7 +2183,6 @@ TEST_F(AvmArithmeticNegativeTestsU128, eqOutputWrongTag) // Tests a situation for U128 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU128, invalidInverseDifference) { - uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; FF const ff_a = FF{ uint256_t::from_uint128(a) }; // The a, b and c registers contain the correct information, only the inversion of differences is wrong. diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp index f983abe2e162..00b53ce7d93a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp @@ -68,12 +68,12 @@ class AvmExecutionTests : public ::testing::Test { // Parsing, trace generation and proving is verified. TEST_F(AvmExecutionTests, basicAddReturn) { - std::string bytecode_hex = to_hex(OpCode::ADD) + // opcode ADD + std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD "00" // Indirect flag "01" // U8 - "00000007" // addr a 7 - "00000009" // addr b 9 - "00000001" // addr c 1 + "0007" // addr a 7 + "0009" // addr b 9 + "0001" // addr c 1 + to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag "00000000" // ret offset 0 @@ -87,13 +87,13 @@ TEST_F(AvmExecutionTests, basicAddReturn) // ADD EXPECT_THAT(instructions.at(0), - AllOf(Field(&Instruction::op_code, OpCode::ADD), + AllOf(Field(&Instruction::op_code, OpCode::ADD_16), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(AvmMemoryTag::U8), - VariantWith(7), - VariantWith(9), - VariantWith(1))))); + VariantWith(7), + VariantWith(9), + VariantWith(1))))); // RETURN EXPECT_THAT(instructions.at(1), @@ -118,12 +118,12 @@ TEST_F(AvmExecutionTests, setAndSubOpcodes) "02" // U16 "9103" // val 37123 "0033" // dst_offset 51 - + to_hex(OpCode::SUB) + // opcode SUB + + to_hex(OpCode::SUB_8) + // opcode SUB "00" // Indirect flag "02" // U16 - "000000AA" // addr a - "00000033" // addr b - "00000001" // addr c 1 + "AA" // addr a + "33" // addr b + "01" // addr c 1 + to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag "00000000" // ret offset 0 @@ -154,13 +154,13 @@ TEST_F(AvmExecutionTests, setAndSubOpcodes) // SUB EXPECT_THAT(instructions.at(2), - AllOf(Field(&Instruction::op_code, OpCode::SUB), + AllOf(Field(&Instruction::op_code, OpCode::SUB_8), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(AvmMemoryTag::U16), - VariantWith(170), - VariantWith(51), - VariantWith(1))))); + VariantWith(170), + VariantWith(51), + VariantWith(1))))); auto trace = gen_trace_from_instr(instructions); @@ -189,12 +189,12 @@ TEST_F(AvmExecutionTests, powerWithMulOpcodes) "01" // val "01"; // dst_offset 1 - std::string const mul_hex = to_hex(OpCode::MUL) + // opcode MUL - "00" // Indirect flag - "04" // U64 - "00000000" // addr a - "00000001" // addr b - "00000001"; // addr c 1 + std::string const mul_hex = to_hex(OpCode::MUL_8) + // opcode MUL + "00" // Indirect flag + "04" // U64 + "00" // addr a + "01" // addr b + "01"; // addr c 1 std::string const ret_hex = to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag @@ -214,23 +214,23 @@ TEST_F(AvmExecutionTests, powerWithMulOpcodes) // MUL first pos EXPECT_THAT(instructions.at(2), - AllOf(Field(&Instruction::op_code, OpCode::MUL), + AllOf(Field(&Instruction::op_code, OpCode::MUL_8), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(AvmMemoryTag::U64), - VariantWith(0), - VariantWith(1), - VariantWith(1))))); + VariantWith(0), + VariantWith(1), + VariantWith(1))))); // MUL last pos EXPECT_THAT(instructions.at(13), - AllOf(Field(&Instruction::op_code, OpCode::MUL), + AllOf(Field(&Instruction::op_code, OpCode::MUL_8), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(AvmMemoryTag::U64), - VariantWith(0), - VariantWith(1), - VariantWith(1))))); + VariantWith(0), + VariantWith(1), + VariantWith(1))))); // RETURN EXPECT_THAT(instructions.at(14), @@ -266,12 +266,12 @@ TEST_F(AvmExecutionTests, simpleInternalCall) "0004" // dst_offset 4 + to_hex(OpCode::INTERNALCALL) + // opcode INTERNALCALL "00000004" // jmp_dest - + to_hex(OpCode::ADD) + // opcode ADD + + to_hex(OpCode::ADD_16) + // opcode ADD "00" // Indirect flag "03" // U32 - "00000004" // addr a 4 - "00000007" // addr b 7 - "00000009" // addr c9 + "0004" // addr a 4 + "0007" // addr b 7 + "0009" // addr c9 + to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag "00000000" // ret offset 0 @@ -342,22 +342,21 @@ TEST_F(AvmExecutionTests, nestedInternalCalls) + "000000" + val + "00" + dst_offset; }; - const std::string tag_address_arguments = "00" // Indirect Flag - "01" // U8 - "00000002" // addr a 2 - "00000003" // addr b 3 - "00000002"; // addr c 2 + const std::string tag_address_arguments = "00" // Indirect Flag + "01" // U8 + "02" // addr a 2 + "03" // addr b 3 + "02"; // addr c 2 const std::string return_instruction_hex = to_hex(OpCode::RETURN) // opcode RETURN + "00" // Indirect flag "00000000" // ret offset 0 "00000000"; // ret size 0 - const std::string bytecode_f1 = to_hex(OpCode::ADD) + tag_address_arguments + to_hex(OpCode::INTERNALRETURN); - const std::string bytecode_f2 = to_hex(OpCode::MUL) + tag_address_arguments + to_hex(OpCode::INTERNALRETURN); + const std::string bytecode_f1 = to_hex(OpCode::ADD_8) + tag_address_arguments + to_hex(OpCode::INTERNALRETURN); + const std::string bytecode_f2 = to_hex(OpCode::MUL_8) + tag_address_arguments + to_hex(OpCode::INTERNALRETURN); const std::string bytecode_g = internalCallInstructionHex("06") + setInstructionHex("11", "03") + internalCallInstructionHex("04") + to_hex(OpCode::INTERNALRETURN); - std::string bytecode_hex = setInstructionHex("04", "02") + setInstructionHex("07", "03") + internalCallInstructionHex("08") + return_instruction_hex + bytecode_f2 + bytecode_f1 + bytecode_g; @@ -368,11 +367,10 @@ TEST_F(AvmExecutionTests, nestedInternalCalls) ASSERT_THAT(instructions, SizeIs(12)); // Expected sequence of opcodes - std::vector const opcode_sequence{ - OpCode::SET_32, OpCode::SET_32, OpCode::INTERNALCALL, OpCode::RETURN, - OpCode::MUL, OpCode::INTERNALRETURN, OpCode::ADD, OpCode::INTERNALRETURN, - OpCode::INTERNALCALL, OpCode::SET_32, OpCode::INTERNALCALL, OpCode::INTERNALRETURN - }; + std::vector const opcode_sequence{ OpCode::SET_32, OpCode::SET_32, OpCode::INTERNALCALL, + OpCode::RETURN, OpCode::MUL_8, OpCode::INTERNALRETURN, + OpCode::ADD_8, OpCode::INTERNALRETURN, OpCode::INTERNALCALL, + OpCode::SET_32, OpCode::INTERNALCALL, OpCode::INTERNALRETURN }; for (size_t i = 0; i < 12; i++) { EXPECT_EQ(instructions.at(i).op_code, opcode_sequence.at(i)); @@ -420,17 +418,18 @@ TEST_F(AvmExecutionTests, jumpAndCalldatacopy) "0000000A" // dst_offset // M[10] = 13, M[11] = 156 + to_hex(OpCode::JUMP_16) + // opcode JUMP "0005" // jmp_dest (FDIV located at 3) - + to_hex(OpCode::SUB) + // opcode SUB + + to_hex(OpCode::SUB_8) + // opcode SUB "00" // Indirect flag "06" // FF - "0000000B" // addr 11 - "0000000A" // addr 10 - "00000001" // addr c 1 (If executed would be 156 - 13 = 143) - + to_hex(OpCode::FDIV) + // opcode FDIV + "0B" // addr 11 + "0A" // addr 10 + "01" // addr c 1 (If executed would be 156 - 13 = 143) + + to_hex(OpCode::FDIV_8) + // opcode FDIV "00" // Indirect flag - "0000000B" // addr 11 - "0000000A" // addr 10 - "00000001" // addr c 1 (156 / 13 = 12) + "06" // tag + "0B" // addr 11 + "0A" // addr 10 + "01" // addr c 1 (156 / 13 = 12) + to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag "00000000" // ret offset 0 @@ -517,18 +516,18 @@ TEST_F(AvmExecutionTests, jumpiAndCalldatacopy) "00" // Indirect flag "0006" // jmp_dest (MUL located at 6) "000A" // cond_offset 10 - + to_hex(OpCode::ADD) + // opcode ADD + + to_hex(OpCode::ADD_16) + // opcode ADD "00" // Indirect flag "02" // U16 - "00000065" // addr 101 - "00000065" // addr 101 - "00000065" // output addr 101 - + to_hex(OpCode::MUL) + // opcode MUL + "0065" // addr 101 + "0065" // addr 101 + "0065" // output addr 101 + + to_hex(OpCode::MUL_8) + // opcode MUL "00" // Indirect flag "02" // U16 - "00000065" // addr 101 - "00000065" // addr 101 - "00000066" // output of MUL addr 102 + "65" // addr 101 + "65" // addr 101 + "66" // output of MUL addr 102 + to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag "00000000" // ret offset 0 @@ -1693,12 +1692,12 @@ TEST_F(AvmExecutionTests, l2GasLeft) // Positive test for DAGASLEFT opcode TEST_F(AvmExecutionTests, daGasLeft) { - std::string bytecode_hex = to_hex(OpCode::ADD) + // opcode ADD + std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD "00" // Indirect flag "03" // U32 - "00000007" // addr a 7 - "00000009" // addr b 9 - "00000001" // addr c 1 + "0007" // addr a 7 + "0009" // addr b 9 + "0001" // addr c 1 + to_hex(OpCode::DAGASLEFT) + // opcode DAGASLEFT "00" // Indirect flag "00000027" // dst_offset 39 @@ -1723,7 +1722,7 @@ TEST_F(AvmExecutionTests, daGasLeft) auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.main_sel_op_dagasleft == 1; }); uint32_t expected_rem_gas = DEFAULT_INITIAL_DA_GAS - - static_cast(GAS_COST_TABLE.at(OpCode::ADD).base_da_gas_fixed_table) - + static_cast(GAS_COST_TABLE.at(OpCode::ADD_8).base_da_gas_fixed_table) - static_cast(GAS_COST_TABLE.at(OpCode::DAGASLEFT).base_da_gas_fixed_table); EXPECT_EQ(row->main_ia, expected_rem_gas); @@ -2279,15 +2278,15 @@ TEST_F(AvmExecutionTests, opGetContractInstanceOpcodes) // Negative test detecting an invalid opcode byte. TEST_F(AvmExecutionTests, invalidOpcode) { - std::string bytecode_hex = to_hex(OpCode::ADD) + // opcode ADD - "00" // Indirect flag - "02" // U16 - "00000007" // addr a 7 - "00000009" // addr b 9 - "00000001" // addr c 1 - "AB" // Invalid opcode byte - "00000000" // ret offset 0 - "00000000"; // ret size 0 + std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD + "00" // Indirect flag + "02" // U16 + "0007" // addr a 7 + "0009" // addr b 9 + "0001" // addr c 1 + "AB" // Invalid opcode byte + "00000000" // ret offset 0 + "00000000"; // ret size 0 auto bytecode = hex_to_bytes(bytecode_hex); EXPECT_THROW_WITH_MESSAGE(Deserialization::parse(bytecode), "Invalid opcode"); @@ -2296,12 +2295,12 @@ TEST_F(AvmExecutionTests, invalidOpcode) // Negative test detecting an invalid memmory instruction tag. TEST_F(AvmExecutionTests, invalidInstructionTag) { - std::string bytecode_hex = to_hex(OpCode::ADD) + // opcode ADD + std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD "00" // Indirect flag "00" // Wrong type - "00000007" // addr a 7 - "00000009" // addr b 9 - "00000001" // addr c 1 + "0007" // addr a 7 + "0009" // addr b 9 + "0001" // addr c 1 + to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag "00000000" // ret offset 0 @@ -2314,13 +2313,13 @@ TEST_F(AvmExecutionTests, invalidInstructionTag) // Negative test detecting an incomplete instruction: missing instruction tag TEST_F(AvmExecutionTests, truncatedInstructionNoTag) { - std::string bytecode_hex = to_hex(OpCode::ADD) + // opcode ADD - "00" // Indirect flag - "02" // U16 - "00000007" // addr a 7 - "00000009" // addr b 9 - "00000001" // addr c 1 - + to_hex(OpCode::SUB); // opcode SUB + std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD + "00" // Indirect flag + "02" // U16 + "0007" // addr a 7 + "0009" // addr b 9 + "0001" // addr c 1 + + to_hex(OpCode::SUB_8); // opcode SUB auto bytecode = hex_to_bytes(bytecode_hex); EXPECT_THROW_WITH_MESSAGE(Deserialization::parse(bytecode), "Operand is missing"); @@ -2329,17 +2328,17 @@ TEST_F(AvmExecutionTests, truncatedInstructionNoTag) // Negative test detecting an incomplete instruction: instruction tag present but an operand is missing TEST_F(AvmExecutionTests, truncatedInstructionNoOperand) { - std::string bytecode_hex = to_hex(OpCode::ADD) + // opcode ADD - "00" // Indirect flag - "02" // U16 - "00000007" // addr a 7 - "00000009" // addr b 9 - "00000001" // addr c 1 - + to_hex(OpCode::SUB) + // opcode SUB - "00" // Indirect flag - "04" // U64 - "AB2373E7" // addr a - "FFFFFFBB"; // addr b and missing address for c = a-b + std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD + "00" // Indirect flag + "02" // U16 + "0007" // addr a 7 + "0009" // addr b 9 + "0001" // addr c 1 + + to_hex(OpCode::SUB_8) + // opcode SUB + "00" // Indirect flag + "04" // U64 + "AB" // addr a + "FF"; // addr b and missing address for c = a-b auto bytecode = hex_to_bytes(bytecode_hex); EXPECT_THROW_WITH_MESSAGE(Deserialization::parse(bytecode), "Operand is missing"); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/memory.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/memory.test.cpp index ee95708b879c..4a48913c483c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/memory.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/memory.test.cpp @@ -270,7 +270,7 @@ TEST_F(AvmMemoryTests, consistentTagNoErrorViolation) trace_builder = AvmTraceBuilder(public_inputs, {}, 0, std::vector{ 84, 7 }); trace_builder.op_set(0, 2, 1, AvmMemoryTag::U32); trace_builder.op_calldata_copy(0, 0, 1, 0); - trace_builder.op_fdiv(0, 0, 1, 4); + trace_builder.op_fdiv(0, 0, 1, 4, AvmMemoryTag::FF); trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); @@ -297,7 +297,7 @@ TEST_F(AvmMemoryTests, noErrorTagWriteViolation) trace_builder = AvmTraceBuilder(public_inputs, {}, 0, { 84, 7 }); trace_builder.op_set(0, 2, 1, AvmMemoryTag::U32); trace_builder.op_calldata_copy(0, 0, 1, 0); - trace_builder.op_fdiv(0, 0, 1, 4); + trace_builder.op_fdiv(0, 0, 1, 4, AvmMemoryTag::FF); trace_builder.op_return(0, 0, 0); auto trace = trace_builder.finalize(); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp index c57d298b59c4..b305c233b854 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp @@ -1,5 +1,6 @@ #include "barretenberg/vm/avm/trace/alu_trace.hpp" #include "barretenberg/vm/avm/trace/gadgets/range_check.hpp" +#include "barretenberg/vm/avm/trace/opcode.hpp" namespace bb::avm_trace { @@ -117,7 +118,7 @@ FF AvmAluTraceBuilder::op_add(FF const& a, FF const& b, AvmMemoryTag in_tag, uin alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry{ .alu_clk = clk, - .opcode = OpCode::ADD, + .opcode = OpCode::ADD_8, // FIXME: take into account all opcodes. .tag = in_tag, .alu_ia = a, .alu_ib = b, @@ -161,7 +162,7 @@ FF AvmAluTraceBuilder::op_sub(FF const& a, FF const& b, AvmMemoryTag in_tag, uin alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry{ .alu_clk = clk, - .opcode = OpCode::SUB, + .opcode = OpCode::SUB_8, // FIXME: take into account all opcodes. .tag = in_tag, .alu_ia = a, .alu_ib = b, @@ -213,7 +214,7 @@ FF AvmAluTraceBuilder::op_mul(FF const& a, FF const& b, AvmMemoryTag in_tag, uin alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry{ .alu_clk = clk, - .opcode = OpCode::MUL, + .opcode = OpCode::MUL_8, // FIXME: take into account all opcodes. .tag = in_tag, .alu_ia = a, .alu_ib = b, @@ -266,7 +267,7 @@ FF AvmAluTraceBuilder::op_div(FF const& a, FF const& b, AvmMemoryTag in_tag, uin AvmAluTraceBuilder::AluTraceEntry row{ .alu_clk = clk, - .opcode = OpCode::DIV, + .opcode = OpCode::DIV_8, // FIXME: take into account all opcodes. .tag = in_tag, .alu_ia = a, .alu_ib = b, @@ -313,7 +314,7 @@ FF AvmAluTraceBuilder::op_eq(FF const& a, FF const& b, AvmMemoryTag in_tag, uint alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry{ .alu_clk = clk, - .opcode = OpCode::EQ, + .opcode = OpCode::EQ_8, // FIXME: take into account all opcodes. .tag = in_tag, .alu_ia = a, .alu_ib = b, @@ -349,7 +350,7 @@ FF AvmAluTraceBuilder::op_lt(FF const& a, FF const& b, AvmMemoryTag in_tag, uint // The subtlety is here that the circuit is designed as a GT(x,y) circuit, therefore we swap the inputs a & b AvmAluTraceBuilder::AluTraceEntry row{ .alu_clk = clk, - .opcode = OpCode::LT, + .opcode = OpCode::LT_8, // FIXME: take into account all opcodes. .tag = in_tag, .alu_ia = a, .alu_ib = b, @@ -384,7 +385,7 @@ FF AvmAluTraceBuilder::op_lte(FF const& a, FF const& b, AvmMemoryTag in_tag, uin // Construct the row that performs the lte check AvmAluTraceBuilder::AluTraceEntry row{ .alu_clk = clk, - .opcode = OpCode::LTE, + .opcode = OpCode::LTE_8, // FIXME: take into account all opcodes. .tag = in_tag, .alu_ia = a, .alu_ib = b, @@ -473,7 +474,7 @@ FF AvmAluTraceBuilder::op_shl(FF const& a, FF const& b, AvmMemoryTag in_tag, uin } alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry{ .alu_clk = clk, - .opcode = OpCode::SHL, + .opcode = OpCode::SHL_8, // FIXME: take into account all opcodes. .tag = in_tag, .alu_ia = a, .alu_ib = b, @@ -536,7 +537,7 @@ FF AvmAluTraceBuilder::op_shr(FF const& a, FF const& b, AvmMemoryTag in_tag, uin alu_trace.push_back(AvmAluTraceBuilder::AluTraceEntry{ .alu_clk = clk, - .opcode = OpCode::SHR, + .opcode = OpCode::SHR_8, // FIXME: take into account all opcodes. .tag = in_tag, .alu_ia = a, .alu_ib = b, @@ -616,9 +617,10 @@ bool AvmAluTraceBuilder::is_range_check_required() const */ bool AvmAluTraceBuilder::is_alu_row_enabled(const AvmAluTraceBuilder::AluTraceEntry& r) { - return (r.opcode == OpCode::ADD || r.opcode == OpCode::SUB || r.opcode == OpCode::MUL || r.opcode == OpCode::EQ || - r.opcode == OpCode::NOT || r.opcode == OpCode::LT || r.opcode == OpCode::LTE || r.opcode == OpCode::SHR || - r.opcode == OpCode::SHL || r.opcode == OpCode::CAST || r.opcode == OpCode::DIV); + return (r.opcode == OpCode::ADD_8 || r.opcode == OpCode::SUB_8 || r.opcode == OpCode::MUL_8 || + r.opcode == OpCode::EQ_8 || r.opcode == OpCode::NOT || r.opcode == OpCode::LT_8 || + r.opcode == OpCode::LTE_8 || r.opcode == OpCode::SHR_8 || r.opcode == OpCode::SHL_8 || + r.opcode == OpCode::CAST || r.opcode == OpCode::DIV_8); } /** @@ -635,17 +637,17 @@ void AvmAluTraceBuilder::finalize(std::vector>& main_trace) dest.alu_sel_alu = FF(1); if (src.opcode.has_value()) { - dest.alu_op_add = FF(src.opcode == OpCode::ADD ? 1 : 0); - dest.alu_op_sub = FF(src.opcode == OpCode::SUB ? 1 : 0); - dest.alu_op_mul = FF(src.opcode == OpCode::MUL ? 1 : 0); + dest.alu_op_add = FF(src.opcode == OpCode::ADD_8 || src.opcode == OpCode::ADD_16 ? 1 : 0); + dest.alu_op_sub = FF(src.opcode == OpCode::SUB_8 || src.opcode == OpCode::SUB_16 ? 1 : 0); + dest.alu_op_mul = FF(src.opcode == OpCode::MUL_8 || src.opcode == OpCode::MUL_16 ? 1 : 0); dest.alu_op_not = FF(src.opcode == OpCode::NOT ? 1 : 0); - dest.alu_op_eq = FF(src.opcode == OpCode::EQ ? 1 : 0); - dest.alu_op_lt = FF(src.opcode == OpCode::LT ? 1 : 0); - dest.alu_op_lte = FF(src.opcode == OpCode::LTE ? 1 : 0); + dest.alu_op_eq = FF(src.opcode == OpCode::EQ_8 || src.opcode == OpCode::EQ_16 ? 1 : 0); + dest.alu_op_lt = FF(src.opcode == OpCode::LT_8 || src.opcode == OpCode::LT_16 ? 1 : 0); + dest.alu_op_lte = FF(src.opcode == OpCode::LTE_8 || src.opcode == OpCode::LTE_16 ? 1 : 0); dest.alu_op_cast = FF(src.opcode == OpCode::CAST ? 1 : 0); - dest.alu_op_shr = FF(src.opcode == OpCode::SHR ? 1 : 0); - dest.alu_op_shl = FF(src.opcode == OpCode::SHL ? 1 : 0); - dest.alu_op_div = FF(src.opcode == OpCode::DIV ? 1 : 0); + dest.alu_op_shr = FF(src.opcode == OpCode::SHR_8 || src.opcode == OpCode::SHR_16 ? 1 : 0); + dest.alu_op_shl = FF(src.opcode == OpCode::SHL_8 || src.opcode == OpCode::SHL_16 ? 1 : 0); + dest.alu_op_div = FF(src.opcode == OpCode::DIV_8 || src.opcode == OpCode::DIV_16 ? 1 : 0); } if (src.tag.has_value()) { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp index 190a908adf0d..b7854957ac45 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp @@ -14,8 +14,11 @@ namespace bb::avm_trace { namespace { -const std::vector three_operand_format = { - OperandType::INDIRECT, OperandType::TAG, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32, +const std::vector three_operand_format8 = { + OperandType::INDIRECT, OperandType::TAG, OperandType::UINT8, OperandType::UINT8, OperandType::UINT8, +}; +const std::vector three_operand_format16 = { + OperandType::INDIRECT, OperandType::TAG, OperandType::UINT16, OperandType::UINT16, OperandType::UINT16, }; const std::vector kernel_input_operand_format = { OperandType::INDIRECT, OperandType::UINT32 }; @@ -39,22 +42,35 @@ const std::vector external_call_format = { OperandType::INDIRECT, const std::unordered_map> OPCODE_WIRE_FORMAT = { // Compute // Compute - Arithmetic - { OpCode::ADD, three_operand_format }, - { OpCode::SUB, three_operand_format }, - { OpCode::MUL, three_operand_format }, - { OpCode::DIV, three_operand_format }, - { OpCode::FDIV, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, - // Compute - Comparators - { OpCode::EQ, three_operand_format }, - { OpCode::LT, three_operand_format }, - { OpCode::LTE, three_operand_format }, + { OpCode::ADD_8, three_operand_format8 }, + { OpCode::ADD_16, three_operand_format16 }, + { OpCode::SUB_8, three_operand_format8 }, + { OpCode::SUB_16, three_operand_format16 }, + { OpCode::MUL_8, three_operand_format8 }, + { OpCode::MUL_16, three_operand_format16 }, + { OpCode::DIV_8, three_operand_format8 }, + { OpCode::DIV_16, three_operand_format16 }, + { OpCode::FDIV_8, three_operand_format8 }, + { OpCode::FDIV_16, three_operand_format16 }, + // Compute - Comparison + { OpCode::EQ_8, three_operand_format8 }, + { OpCode::EQ_16, three_operand_format16 }, + { OpCode::LT_8, three_operand_format8 }, + { OpCode::LT_16, three_operand_format16 }, + { OpCode::LTE_8, three_operand_format8 }, + { OpCode::LTE_16, three_operand_format16 }, // Compute - Bitwise - { OpCode::AND, three_operand_format }, - { OpCode::OR, three_operand_format }, - { OpCode::XOR, three_operand_format }, - { OpCode::NOT, { OperandType::INDIRECT, OperandType::TAG, OperandType::UINT32, OperandType::UINT32 } }, - { OpCode::SHL, three_operand_format }, - { OpCode::SHR, three_operand_format }, + { OpCode::AND_8, three_operand_format8 }, + { OpCode::AND_16, three_operand_format16 }, + { OpCode::OR_8, three_operand_format8 }, + { OpCode::OR_16, three_operand_format16 }, + { OpCode::XOR_8, three_operand_format8 }, + { OpCode::XOR_16, three_operand_format16 }, + { OpCode::NOT, { OperandType::INDIRECT, OperandType::TAG, OperandType::UINT8, OperandType::UINT8 } }, + { OpCode::SHL_8, three_operand_format8 }, + { OpCode::SHL_16, three_operand_format16 }, + { OpCode::SHR_8, three_operand_format8 }, + { OpCode::SHR_16, three_operand_format16 }, // Compute - Type Conversions { OpCode::CAST, { OperandType::INDIRECT, OperandType::TAG, OperandType::UINT32, OperandType::UINT32 } }, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp index 65ef5d0321a3..6c6904fcac98 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp @@ -402,84 +402,158 @@ std::vector Execution::gen_trace(std::vector const& instructio switch (inst.op_code) { // Compute // Compute - Arithmetic - case OpCode::ADD: + case OpCode::ADD_8: trace_builder.op_add(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; - case OpCode::SUB: + case OpCode::ADD_16: + trace_builder.op_add(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::SUB_8: trace_builder.op_sub(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; - case OpCode::MUL: + case OpCode::SUB_16: + trace_builder.op_sub(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::MUL_8: trace_builder.op_mul(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; - case OpCode::DIV: + case OpCode::MUL_16: + trace_builder.op_mul(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::DIV_8: trace_builder.op_div(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; - case OpCode::FDIV: + case OpCode::DIV_16: + trace_builder.op_div(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::FDIV_8: trace_builder.op_fdiv(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(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); break; - - // Compute - Comparators - case OpCode::EQ: + case OpCode::FDIV_16: + trace_builder.op_fdiv(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::EQ_8: trace_builder.op_eq(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::EQ_16: + trace_builder.op_eq(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::LT_8: + trace_builder.op_lt(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; - case OpCode::LT: + case OpCode::LT_16: trace_builder.op_lt(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; - case OpCode::LTE: + case OpCode::LTE_8: trace_builder.op_lte(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; - - // Compute - Bitwise - case OpCode::AND: + case OpCode::LTE_16: + trace_builder.op_lte(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::AND_8: trace_builder.op_and(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::AND_16: + trace_builder.op_and(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; - case OpCode::OR: + case OpCode::OR_8: trace_builder.op_or(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; - case OpCode::XOR: + case OpCode::OR_16: + trace_builder.op_or(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::XOR_8: trace_builder.op_xor(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::XOR_16: + trace_builder.op_xor(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; case OpCode::NOT: @@ -488,18 +562,32 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(3)), std::get(inst.operands.at(1))); break; - case OpCode::SHL: + case OpCode::SHL_8: trace_builder.op_shl(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::SHL_16: + trace_builder.op_shl(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; - case OpCode::SHR: + case OpCode::SHR_8: trace_builder.op_shr(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::SHR_16: + trace_builder.op_shr(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp index 5f4cbed17cb1..43005b685648 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp @@ -18,20 +18,33 @@ constexpr auto make_cost(uint16_t l2_base, uint16_t da_base, uint16_t l2_dyn, ui } const std::unordered_map GAS_COST_TABLE = { - { OpCode::ADD, make_cost(AVM_ADD_BASE_L2_GAS, 0, AVM_ADD_DYN_L2_GAS, 0) }, - { OpCode::SUB, make_cost(AVM_SUB_BASE_L2_GAS, 0, AVM_SUB_DYN_L2_GAS, 0) }, - { OpCode::MUL, make_cost(AVM_MUL_BASE_L2_GAS, 0, AVM_MUL_DYN_L2_GAS, 0) }, - { OpCode::DIV, make_cost(AVM_DIV_BASE_L2_GAS, 0, AVM_DIV_DYN_L2_GAS, 0) }, - { OpCode::FDIV, make_cost(AVM_FDIV_BASE_L2_GAS, 0, AVM_FDIV_DYN_L2_GAS, 0) }, - { OpCode::EQ, make_cost(AVM_EQ_BASE_L2_GAS, 0, AVM_EQ_DYN_L2_GAS, 0) }, - { OpCode::LT, make_cost(AVM_LT_BASE_L2_GAS, 0, AVM_LT_DYN_L2_GAS, 0) }, - { OpCode::LTE, make_cost(AVM_LTE_BASE_L2_GAS, 0, AVM_LTE_DYN_L2_GAS, 0) }, - { OpCode::AND, make_cost(AVM_AND_BASE_L2_GAS, 0, AVM_AND_DYN_L2_GAS, 0) }, - { OpCode::OR, make_cost(AVM_OR_BASE_L2_GAS, 0, AVM_OR_DYN_L2_GAS, 0) }, - { OpCode::XOR, make_cost(AVM_XOR_BASE_L2_GAS, 0, AVM_XOR_DYN_L2_GAS, 0) }, + { OpCode::ADD_8, make_cost(AVM_ADD_BASE_L2_GAS, 0, AVM_ADD_DYN_L2_GAS, 0) }, + { OpCode::ADD_16, make_cost(AVM_ADD_BASE_L2_GAS, 0, AVM_ADD_DYN_L2_GAS, 0) }, + { OpCode::SUB_8, make_cost(AVM_SUB_BASE_L2_GAS, 0, AVM_SUB_DYN_L2_GAS, 0) }, + { OpCode::SUB_16, make_cost(AVM_SUB_BASE_L2_GAS, 0, AVM_SUB_DYN_L2_GAS, 0) }, + { OpCode::MUL_8, make_cost(AVM_MUL_BASE_L2_GAS, 0, AVM_MUL_DYN_L2_GAS, 0) }, + { OpCode::MUL_16, make_cost(AVM_MUL_BASE_L2_GAS, 0, AVM_MUL_DYN_L2_GAS, 0) }, + { OpCode::DIV_8, make_cost(AVM_DIV_BASE_L2_GAS, 0, AVM_DIV_DYN_L2_GAS, 0) }, + { OpCode::DIV_16, make_cost(AVM_DIV_BASE_L2_GAS, 0, AVM_DIV_DYN_L2_GAS, 0) }, + { OpCode::FDIV_8, make_cost(AVM_FDIV_BASE_L2_GAS, 0, AVM_FDIV_DYN_L2_GAS, 0) }, + { OpCode::FDIV_16, make_cost(AVM_FDIV_BASE_L2_GAS, 0, AVM_FDIV_DYN_L2_GAS, 0) }, + { OpCode::EQ_8, make_cost(AVM_EQ_BASE_L2_GAS, 0, AVM_EQ_DYN_L2_GAS, 0) }, + { OpCode::EQ_16, make_cost(AVM_EQ_BASE_L2_GAS, 0, AVM_EQ_DYN_L2_GAS, 0) }, + { OpCode::LT_8, make_cost(AVM_LT_BASE_L2_GAS, 0, AVM_LT_DYN_L2_GAS, 0) }, + { OpCode::LT_16, make_cost(AVM_LT_BASE_L2_GAS, 0, AVM_LT_DYN_L2_GAS, 0) }, + { OpCode::LTE_8, make_cost(AVM_LTE_BASE_L2_GAS, 0, AVM_LTE_DYN_L2_GAS, 0) }, + { OpCode::LTE_16, make_cost(AVM_LTE_BASE_L2_GAS, 0, AVM_LTE_DYN_L2_GAS, 0) }, + { OpCode::AND_8, make_cost(AVM_AND_BASE_L2_GAS, 0, AVM_AND_DYN_L2_GAS, 0) }, + { OpCode::AND_16, make_cost(AVM_AND_BASE_L2_GAS, 0, AVM_AND_DYN_L2_GAS, 0) }, + { OpCode::OR_8, make_cost(AVM_OR_BASE_L2_GAS, 0, AVM_OR_DYN_L2_GAS, 0) }, + { OpCode::OR_16, make_cost(AVM_OR_BASE_L2_GAS, 0, AVM_OR_DYN_L2_GAS, 0) }, + { OpCode::XOR_8, make_cost(AVM_XOR_BASE_L2_GAS, 0, AVM_XOR_DYN_L2_GAS, 0) }, + { OpCode::XOR_16, make_cost(AVM_XOR_BASE_L2_GAS, 0, AVM_XOR_DYN_L2_GAS, 0) }, { OpCode::NOT, make_cost(AVM_NOT_BASE_L2_GAS, 0, AVM_NOT_DYN_L2_GAS, 0) }, - { OpCode::SHL, make_cost(AVM_SHL_BASE_L2_GAS, 0, AVM_SHL_DYN_L2_GAS, 0) }, - { OpCode::SHR, make_cost(AVM_SHR_BASE_L2_GAS, 0, AVM_SHR_DYN_L2_GAS, 0) }, + { OpCode::SHL_8, make_cost(AVM_SHL_BASE_L2_GAS, 0, AVM_SHL_DYN_L2_GAS, 0) }, + { OpCode::SHL_16, make_cost(AVM_SHL_BASE_L2_GAS, 0, AVM_SHL_DYN_L2_GAS, 0) }, + { OpCode::SHR_8, make_cost(AVM_SHR_BASE_L2_GAS, 0, AVM_SHR_DYN_L2_GAS, 0) }, + { OpCode::SHR_16, make_cost(AVM_SHR_BASE_L2_GAS, 0, AVM_SHR_DYN_L2_GAS, 0) }, { OpCode::CAST, make_cost(AVM_CAST_BASE_L2_GAS, 0, AVM_CAST_DYN_L2_GAS, 0) }, { OpCode::ADDRESS, make_cost(AVM_ADDRESS_BASE_L2_GAS, 0, AVM_ADDRESS_DYN_L2_GAS, 0) }, { OpCode::STORAGEADDRESS, make_cost(AVM_STORAGEADDRESS_BASE_L2_GAS, 0, AVM_STORAGEADDRESS_DYN_L2_GAS, 0) }, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp index 2b310b5d5ea4..cbee33a6dddb 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp @@ -25,37 +25,60 @@ std::string to_string(OpCode opcode) { switch (opcode) { // Compute - // Compute - Arithmetic - case OpCode::ADD: - return "ADD"; - case OpCode::SUB: - return "SUB"; - case OpCode::MUL: - return "MUL"; - case OpCode::DIV: - return "DIV"; - case OpCode::FDIV: - return "FDIV"; - // Compute - Comparators - case OpCode::EQ: - return "EQ"; - case OpCode::LT: - return "LT"; - case OpCode::LTE: - return "LTE"; - // Compute - Bitwise - case OpCode::AND: - return "AND"; - case OpCode::OR: - return "OR"; - case OpCode::XOR: - return "XOR"; + case OpCode::ADD_8: + return "ADD_8"; + case OpCode::ADD_16: + return "ADD_16"; + case OpCode::SUB_8: + return "SUB_8"; + case OpCode::SUB_16: + return "SUB_16"; + case OpCode::MUL_8: + return "MUL_8"; + case OpCode::MUL_16: + return "MUL_16"; + case OpCode::DIV_8: + return "DIV_8"; + case OpCode::DIV_16: + return "DIV_16"; + case OpCode::FDIV_8: + return "FDIV_8"; + case OpCode::FDIV_16: + return "FDIV_16"; + case OpCode::EQ_8: + return "EQ_8"; + case OpCode::EQ_16: + return "EQ_16"; + case OpCode::LT_8: + return "LT_8"; + case OpCode::LT_16: + return "LT_16"; + case OpCode::LTE_8: + return "LTE_8"; + case OpCode::LTE_16: + return "LTE_16"; + case OpCode::AND_8: + return "AND_8"; + case OpCode::AND_16: + return "AND_16"; + case OpCode::OR_8: + return "OR_8"; + case OpCode::OR_16: + return "OR_16"; + case OpCode::XOR_8: + return "XOR_8"; + case OpCode::XOR_16: + return "XOR_16"; case OpCode::NOT: return "NOT"; - case OpCode::SHL: - return "SHL"; - case OpCode::SHR: - return "SHR"; + case OpCode::SHL_8: + return "SHL_8"; + case OpCode::SHL_16: + return "SHL_16"; + case OpCode::SHR_8: + return "SHR_8"; + case OpCode::SHR_16: + return "SHR_16"; // Compute - Type Conversions case OpCode::CAST: return "CAST"; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp index a4e8f0cc167f..e27931cebf49 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp @@ -21,24 +21,33 @@ namespace bb::avm_trace { */ enum class OpCode : uint8_t { // Compute - // Compute - Arithmetic - ADD, - SUB, - MUL, - DIV, - FDIV, - // Compute - Comparators - EQ, - LT, - LTE, - // Compute - Bitwise - AND, - OR, - XOR, + ADD_8, + ADD_16, + SUB_8, + SUB_16, + MUL_8, + MUL_16, + DIV_8, + DIV_16, + FDIV_8, + FDIV_16, + EQ_8, + EQ_16, + LT_8, + LT_16, + LTE_8, + LTE_16, + AND_8, + AND_16, + OR_8, + OR_16, + XOR_8, + XOR_16, NOT, - SHL, - SHR, - // Compute - Type Conversions + SHL_8, + SHL_16, + SHR_8, + SHR_16, CAST, // Execution Environment diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index 260dcaff259d..459f790f8aee 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -322,7 +322,7 @@ void AvmTraceBuilder::op_add( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::ADD); + gas_trace_builder.constrain_gas(clk, OpCode::ADD_8); main_trace.push_back(Row{ .main_clk = clk, @@ -389,7 +389,7 @@ void AvmTraceBuilder::op_sub( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::SUB); + gas_trace_builder.constrain_gas(clk, OpCode::SUB_8); main_trace.push_back(Row{ .main_clk = clk, @@ -456,7 +456,7 @@ void AvmTraceBuilder::op_mul( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::MUL); + gas_trace_builder.constrain_gas(clk, OpCode::MUL_8); main_trace.push_back(Row{ .main_clk = clk, @@ -534,7 +534,7 @@ void AvmTraceBuilder::op_div( auto write_dst = constrained_write_to_memory(call_ptr, clk, resolved_dst, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::DIV); + gas_trace_builder.constrain_gas(clk, OpCode::DIV_8); main_trace.push_back(Row{ .main_clk = clk, @@ -576,7 +576,8 @@ void AvmTraceBuilder::op_div( * @param dst_offset An index in memory pointing to the output of the division. * @param in_tag The instruction memory tag of the operands. */ -void AvmTraceBuilder::op_fdiv(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset) +void AvmTraceBuilder::op_fdiv( + uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, [[maybe_unused]] AvmMemoryTag in_tag) { auto clk = static_cast(main_trace.size()) + 1; @@ -614,7 +615,7 @@ void AvmTraceBuilder::op_fdiv(uint8_t indirect, uint32_t a_offset, uint32_t b_of call_ptr, clk, resolved_c, c, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::FDIV); + gas_trace_builder.constrain_gas(clk, OpCode::FDIV_8); main_trace.push_back(Row{ .main_clk = clk, @@ -684,7 +685,7 @@ void AvmTraceBuilder::op_eq( constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U8, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::EQ); + gas_trace_builder.constrain_gas(clk, OpCode::EQ_8); main_trace.push_back(Row{ .main_clk = clk, @@ -736,7 +737,7 @@ void AvmTraceBuilder::op_lt( constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U8, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::LT); + gas_trace_builder.constrain_gas(clk, OpCode::LT_8); main_trace.push_back(Row{ .main_clk = clk, @@ -789,7 +790,7 @@ void AvmTraceBuilder::op_lte( constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U8, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::LTE); + gas_trace_builder.constrain_gas(clk, OpCode::LTE_8); main_trace.push_back(Row{ .main_clk = clk, @@ -845,7 +846,7 @@ void AvmTraceBuilder::op_and( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::AND); + gas_trace_builder.constrain_gas(clk, OpCode::AND_8); main_trace.push_back(Row{ .main_clk = clk, @@ -897,7 +898,7 @@ void AvmTraceBuilder::op_or( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::OR); + gas_trace_builder.constrain_gas(clk, OpCode::OR_8); main_trace.push_back(Row{ .main_clk = clk, @@ -950,7 +951,7 @@ void AvmTraceBuilder::op_xor( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::XOR); + gas_trace_builder.constrain_gas(clk, OpCode::XOR_8); main_trace.push_back(Row{ .main_clk = clk, @@ -1059,7 +1060,7 @@ void AvmTraceBuilder::op_shl( // Write into memory value c from intermediate register ic. auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::SHL); + gas_trace_builder.constrain_gas(clk, OpCode::SHL_8); main_trace.push_back(Row{ .main_clk = clk, @@ -1111,7 +1112,7 @@ void AvmTraceBuilder::op_shr( // Write into memory value c from intermediate register ic. auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::SHR); + gas_trace_builder.constrain_gas(clk, OpCode::SHR_8); main_trace.push_back(Row{ .main_clk = clk, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp index 2267006c7fe5..873d58210dbb 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp @@ -64,7 +64,7 @@ class AvmTraceBuilder { void op_sub(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); void op_mul(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); void op_div(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); - void op_fdiv(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset); + void op_fdiv(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); // Compute - Comparators void op_eq(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); diff --git a/yarn-project/simulator/src/avm/avm_gas.ts b/yarn-project/simulator/src/avm/avm_gas.ts index 486e58d5a3ec..43f5d48d782a 100644 --- a/yarn-project/simulator/src/avm/avm_gas.ts +++ b/yarn-project/simulator/src/avm/avm_gas.ts @@ -57,20 +57,33 @@ export const GasDimensions = ['l2Gas', 'daGas'] as const; /** Base gas costs for each instruction. Additional gas cost may be added on top due to memory or storage accesses, etc. */ const BaseGasCosts: Record = { - [Opcode.ADD]: makeCost(c.AVM_ADD_BASE_L2_GAS, 0), - [Opcode.SUB]: makeCost(c.AVM_SUB_BASE_L2_GAS, 0), - [Opcode.MUL]: makeCost(c.AVM_MUL_BASE_L2_GAS, 0), - [Opcode.DIV]: makeCost(c.AVM_DIV_BASE_L2_GAS, 0), - [Opcode.FDIV]: makeCost(c.AVM_FDIV_BASE_L2_GAS, 0), - [Opcode.EQ]: makeCost(c.AVM_EQ_BASE_L2_GAS, 0), - [Opcode.LT]: makeCost(c.AVM_LT_BASE_L2_GAS, 0), - [Opcode.LTE]: makeCost(c.AVM_LTE_BASE_L2_GAS, 0), - [Opcode.AND]: makeCost(c.AVM_AND_BASE_L2_GAS, 0), - [Opcode.OR]: makeCost(c.AVM_OR_BASE_L2_GAS, 0), - [Opcode.XOR]: makeCost(c.AVM_XOR_BASE_L2_GAS, 0), + [Opcode.ADD_8]: makeCost(c.AVM_ADD_BASE_L2_GAS, 0), + [Opcode.ADD_16]: makeCost(c.AVM_ADD_BASE_L2_GAS, 0), + [Opcode.SUB_8]: makeCost(c.AVM_SUB_BASE_L2_GAS, 0), + [Opcode.SUB_16]: makeCost(c.AVM_SUB_BASE_L2_GAS, 0), + [Opcode.MUL_8]: makeCost(c.AVM_MUL_BASE_L2_GAS, 0), + [Opcode.MUL_16]: makeCost(c.AVM_MUL_BASE_L2_GAS, 0), + [Opcode.DIV_8]: makeCost(c.AVM_DIV_BASE_L2_GAS, 0), + [Opcode.DIV_16]: makeCost(c.AVM_DIV_BASE_L2_GAS, 0), + [Opcode.FDIV_8]: makeCost(c.AVM_FDIV_BASE_L2_GAS, 0), + [Opcode.FDIV_16]: makeCost(c.AVM_FDIV_BASE_L2_GAS, 0), + [Opcode.EQ_8]: makeCost(c.AVM_EQ_BASE_L2_GAS, 0), + [Opcode.EQ_16]: makeCost(c.AVM_EQ_BASE_L2_GAS, 0), + [Opcode.LT_8]: makeCost(c.AVM_LT_BASE_L2_GAS, 0), + [Opcode.LT_16]: makeCost(c.AVM_LT_BASE_L2_GAS, 0), + [Opcode.LTE_8]: makeCost(c.AVM_LTE_BASE_L2_GAS, 0), + [Opcode.LTE_16]: makeCost(c.AVM_LTE_BASE_L2_GAS, 0), + [Opcode.AND_8]: makeCost(c.AVM_AND_BASE_L2_GAS, 0), + [Opcode.AND_16]: makeCost(c.AVM_AND_BASE_L2_GAS, 0), + [Opcode.OR_8]: makeCost(c.AVM_OR_BASE_L2_GAS, 0), + [Opcode.OR_16]: makeCost(c.AVM_OR_BASE_L2_GAS, 0), + [Opcode.XOR_8]: makeCost(c.AVM_XOR_BASE_L2_GAS, 0), + [Opcode.XOR_16]: makeCost(c.AVM_XOR_BASE_L2_GAS, 0), [Opcode.NOT]: makeCost(c.AVM_NOT_BASE_L2_GAS, 0), - [Opcode.SHL]: makeCost(c.AVM_SHL_BASE_L2_GAS, 0), - [Opcode.SHR]: makeCost(c.AVM_SHR_BASE_L2_GAS, 0), + [Opcode.SHL_8]: makeCost(c.AVM_SHL_BASE_L2_GAS, 0), + [Opcode.SHL_16]: makeCost(c.AVM_SHL_BASE_L2_GAS, 0), + [Opcode.SHR_8]: makeCost(c.AVM_SHR_BASE_L2_GAS, 0), + [Opcode.SHR_16]: makeCost(c.AVM_SHR_BASE_L2_GAS, 0), [Opcode.CAST]: makeCost(c.AVM_CAST_BASE_L2_GAS, 0), [Opcode.ADDRESS]: makeCost(c.AVM_ADDRESS_BASE_L2_GAS, 0), [Opcode.STORAGEADDRESS]: makeCost(c.AVM_STORAGEADDRESS_BASE_L2_GAS, 0), @@ -128,20 +141,33 @@ const BaseGasCosts: Record = { }; const DynamicGasCosts: Record = { - [Opcode.ADD]: makeCost(c.AVM_ADD_DYN_L2_GAS, 0), - [Opcode.SUB]: makeCost(c.AVM_SUB_DYN_L2_GAS, 0), - [Opcode.MUL]: makeCost(c.AVM_MUL_DYN_L2_GAS, 0), - [Opcode.DIV]: makeCost(c.AVM_DIV_DYN_L2_GAS, 0), - [Opcode.FDIV]: makeCost(c.AVM_FDIV_DYN_L2_GAS, 0), - [Opcode.EQ]: makeCost(c.AVM_EQ_DYN_L2_GAS, 0), - [Opcode.LT]: makeCost(c.AVM_LT_DYN_L2_GAS, 0), - [Opcode.LTE]: makeCost(c.AVM_LTE_DYN_L2_GAS, 0), - [Opcode.AND]: makeCost(c.AVM_AND_DYN_L2_GAS, 0), - [Opcode.OR]: makeCost(c.AVM_OR_DYN_L2_GAS, 0), - [Opcode.XOR]: makeCost(c.AVM_XOR_DYN_L2_GAS, 0), + [Opcode.ADD_8]: makeCost(c.AVM_ADD_DYN_L2_GAS, 0), + [Opcode.ADD_16]: makeCost(c.AVM_ADD_DYN_L2_GAS, 0), + [Opcode.SUB_8]: makeCost(c.AVM_SUB_DYN_L2_GAS, 0), + [Opcode.SUB_16]: makeCost(c.AVM_SUB_DYN_L2_GAS, 0), + [Opcode.MUL_8]: makeCost(c.AVM_MUL_DYN_L2_GAS, 0), + [Opcode.MUL_16]: makeCost(c.AVM_MUL_DYN_L2_GAS, 0), + [Opcode.DIV_8]: makeCost(c.AVM_DIV_DYN_L2_GAS, 0), + [Opcode.DIV_16]: makeCost(c.AVM_DIV_DYN_L2_GAS, 0), + [Opcode.FDIV_8]: makeCost(c.AVM_FDIV_DYN_L2_GAS, 0), + [Opcode.FDIV_16]: makeCost(c.AVM_FDIV_DYN_L2_GAS, 0), + [Opcode.EQ_8]: makeCost(c.AVM_EQ_DYN_L2_GAS, 0), + [Opcode.EQ_16]: makeCost(c.AVM_EQ_DYN_L2_GAS, 0), + [Opcode.LT_8]: makeCost(c.AVM_LT_DYN_L2_GAS, 0), + [Opcode.LT_16]: makeCost(c.AVM_LT_DYN_L2_GAS, 0), + [Opcode.LTE_8]: makeCost(c.AVM_LTE_DYN_L2_GAS, 0), + [Opcode.LTE_16]: makeCost(c.AVM_LTE_DYN_L2_GAS, 0), + [Opcode.AND_8]: makeCost(c.AVM_AND_DYN_L2_GAS, 0), + [Opcode.AND_16]: makeCost(c.AVM_AND_DYN_L2_GAS, 0), + [Opcode.OR_8]: makeCost(c.AVM_OR_DYN_L2_GAS, 0), + [Opcode.OR_16]: makeCost(c.AVM_OR_DYN_L2_GAS, 0), + [Opcode.XOR_8]: makeCost(c.AVM_XOR_DYN_L2_GAS, 0), + [Opcode.XOR_16]: makeCost(c.AVM_XOR_DYN_L2_GAS, 0), [Opcode.NOT]: makeCost(c.AVM_NOT_DYN_L2_GAS, 0), - [Opcode.SHL]: makeCost(c.AVM_SHL_DYN_L2_GAS, 0), - [Opcode.SHR]: makeCost(c.AVM_SHR_DYN_L2_GAS, 0), + [Opcode.SHL_8]: makeCost(c.AVM_SHL_DYN_L2_GAS, 0), + [Opcode.SHL_16]: makeCost(c.AVM_SHL_DYN_L2_GAS, 0), + [Opcode.SHR_8]: makeCost(c.AVM_SHR_DYN_L2_GAS, 0), + [Opcode.SHR_16]: makeCost(c.AVM_SHR_DYN_L2_GAS, 0), [Opcode.CAST]: makeCost(c.AVM_CAST_DYN_L2_GAS, 0), [Opcode.ADDRESS]: makeCost(c.AVM_ADDRESS_DYN_L2_GAS, 0), [Opcode.STORAGEADDRESS]: makeCost(c.AVM_STORAGEADDRESS_DYN_L2_GAS, 0), diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index 2918db3c1193..6bca1202516b 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -59,7 +59,10 @@ describe('AVM simulator: injected bytecode', () => { ), new Set(/*indirect*/ 0, TypeTag.UINT32, /*value*/ 2, /*dstOffset*/ 1).as(Opcode.SET_8, Set.wireFormat8), new CalldataCopy(/*indirect=*/ 0, /*cdOffset=*/ 0, /*copySize=*/ 1, /*dstOffset=*/ 0), - new Add(/*indirect=*/ 0, TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2), + new Add(/*indirect=*/ 0, TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2).as( + Opcode.ADD_8, + Add.wireFormat8, + ), new Return(/*indirect=*/ 0, /*returnOffset=*/ 2, /*copySize=*/ 1), ]); }); diff --git a/yarn-project/simulator/src/avm/bytecode_utils.ts b/yarn-project/simulator/src/avm/bytecode_utils.ts index 0cadac080754..68ed51179416 100644 --- a/yarn-project/simulator/src/avm/bytecode_utils.ts +++ b/yarn-project/simulator/src/avm/bytecode_utils.ts @@ -4,10 +4,10 @@ import { gunzip } from 'zlib'; import { Opcode } from './serialization/instruction_serialization.js'; const AVM_MAGIC_SUFFIX = Buffer.from([ - Opcode.MOV_8, // opcode + Opcode.MOV_16, // opcode 0x00, // indirect - ...Buffer.from('000018ca', 'hex'), // srcOffset - ...Buffer.from('000018ca', 'hex'), // dstOffset + ...Buffer.from('18ca', 'hex'), // srcOffset + ...Buffer.from('18ca', 'hex'), // dstOffset ]); export function markBytecodeAsAvm(bytecode: Buffer): Buffer { diff --git a/yarn-project/simulator/src/avm/opcodes/arithmetic.test.ts b/yarn-project/simulator/src/avm/opcodes/arithmetic.test.ts index 10c92d9588c1..3360317c3d6f 100644 --- a/yarn-project/simulator/src/avm/opcodes/arithmetic.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/arithmetic.test.ts @@ -1,6 +1,7 @@ import { type AvmContext } from '../avm_context.js'; import { Field, TypeTag, Uint8, Uint16, Uint32, Uint64, Uint128 } from '../avm_memory_types.js'; import { initContext } from '../fixtures/index.js'; +import { Opcode } from '../serialization/instruction_serialization.js'; import { Add, Div, FieldDiv, Mul, Sub } from './arithmetic.js'; describe('Arithmetic Instructions', () => { @@ -13,22 +14,22 @@ describe('Arithmetic Instructions', () => { describe('Add', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ - Add.opcode, // opcode + Opcode.ADD_16, // opcode 0x01, // indirect TypeTag.FIELD, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Add( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.FIELD, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.ADD_16, Add.wireFormat16); - expect(Add.deserialize(buf)).toEqual(inst); + expect(Add.as(Add.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -77,22 +78,22 @@ describe('Arithmetic Instructions', () => { describe('Sub', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ - Sub.opcode, // opcode + Opcode.SUB_16, // opcode 0x01, // indirect TypeTag.FIELD, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Sub( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.FIELD, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.SUB_16, Sub.wireFormat16); - expect(Sub.deserialize(buf)).toEqual(inst); + expect(Sub.as(Sub.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -147,22 +148,22 @@ describe('Arithmetic Instructions', () => { describe('Mul', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ - Mul.opcode, // opcode + Opcode.MUL_16, // opcode 0x01, // indirect TypeTag.FIELD, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Mul( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.FIELD, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.MUL_16, Mul.wireFormat16); - expect(Mul.deserialize(buf)).toEqual(inst); + expect(Mul.as(Mul.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -212,22 +213,22 @@ describe('Arithmetic Instructions', () => { describe('Div', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ - Div.opcode, // opcode + Opcode.DIV_16, // opcode 0x01, // indirect TypeTag.FIELD, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Div( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.FIELD, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.DIV_16, Div.wireFormat16); - expect(Div.deserialize(buf)).toEqual(inst); + expect(Div.as(Div.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -256,20 +257,22 @@ describe('Arithmetic Instructions', () => { describe('FDiv', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ - FieldDiv.opcode, // opcode + Opcode.FDIV_16, // opcode 0x01, // indirect - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + TypeTag.FIELD, // tag + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new FieldDiv( /*indirect=*/ 0x01, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*tag=*/ TypeTag.FIELD, + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.FDIV_16, FieldDiv.wireFormat16); - expect(FieldDiv.deserialize(buf)).toEqual(inst); + expect(FieldDiv.as(FieldDiv.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -280,7 +283,7 @@ describe('Arithmetic Instructions', () => { context.machineState.memory.set(0, a); context.machineState.memory.set(1, b); - await new Div( + await new FieldDiv( /*indirect=*/ 0, /*inTag=*/ TypeTag.FIELD, /*aOffset=*/ 0, diff --git a/yarn-project/simulator/src/avm/opcodes/arithmetic.ts b/yarn-project/simulator/src/avm/opcodes/arithmetic.ts index d918fbbd15cb..acffa20c85db 100644 --- a/yarn-project/simulator/src/avm/opcodes/arithmetic.ts +++ b/yarn-project/simulator/src/avm/opcodes/arithmetic.ts @@ -1,8 +1,7 @@ import type { AvmContext } from '../avm_context.js'; -import { type Field, type MemoryValue, TypeTag } from '../avm_memory_types.js'; -import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; +import { type Field, type MemoryValue } from '../avm_memory_types.js'; +import { Opcode } from '../serialization/instruction_serialization.js'; import { Addressing } from './addressing_mode.js'; -import { Instruction } from './instruction.js'; import { ThreeOperandInstruction } from './instruction_impl.js'; export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInstruction { @@ -32,7 +31,7 @@ export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInst export class Add extends ThreeOperandArithmeticInstruction { static readonly type: string = 'ADD'; - static readonly opcode = Opcode.ADD; + static readonly opcode = Opcode.ADD_8; // FIXME: needed for gas. protected compute(a: MemoryValue, b: MemoryValue): MemoryValue { return a.add(b); @@ -41,7 +40,7 @@ export class Add extends ThreeOperandArithmeticInstruction { export class Sub extends ThreeOperandArithmeticInstruction { static readonly type: string = 'SUB'; - static readonly opcode = Opcode.SUB; + static readonly opcode = Opcode.SUB_8; // FIXME: needed for gas. protected compute(a: MemoryValue, b: MemoryValue): MemoryValue { return a.sub(b); @@ -50,7 +49,7 @@ export class Sub extends ThreeOperandArithmeticInstruction { export class Mul extends ThreeOperandArithmeticInstruction { static type: string = 'MUL'; - static readonly opcode = Opcode.MUL; + static readonly opcode = Opcode.MUL_8; // FIXME: needed for gas. protected compute(a: MemoryValue, b: MemoryValue): MemoryValue { return a.mul(b); @@ -59,48 +58,20 @@ export class Mul extends ThreeOperandArithmeticInstruction { export class Div extends ThreeOperandArithmeticInstruction { static type: string = 'DIV'; - static readonly opcode = Opcode.DIV; + static readonly opcode = Opcode.DIV_8; // FIXME: needed for gas. protected compute(a: MemoryValue, b: MemoryValue): MemoryValue { return a.div(b); } } -export class FieldDiv extends Instruction { +// TODO: This class now temporarily has a tag, until all tags are removed. +export class FieldDiv extends ThreeOperandArithmeticInstruction { static type: string = 'FDIV'; - static readonly opcode = Opcode.FDIV; - - // Informs (de)serialization. See Instruction.deserialize. - static readonly wireFormat: OperandType[] = [ - OperandType.UINT8, - OperandType.UINT8, - OperandType.UINT32, - OperandType.UINT32, - OperandType.UINT32, - ]; - - constructor(private indirect: number, private aOffset: number, private bOffset: number, private dstOffset: number) { - super(); - } - - public async execute(context: AvmContext): Promise { - const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect }; - const memory = context.machineState.memory.track(this.type); - context.machineState.consumeGas(this.gasCost(memoryOperations)); - - const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve( - [this.aOffset, this.bOffset, this.dstOffset], - memory, - ); - memory.checkTags(TypeTag.FIELD, aOffset, bOffset); - - const a = memory.getAs(aOffset); - const b = memory.getAs(bOffset); + static readonly opcode = Opcode.FDIV_8; // FIXME: needed for gas. - const dest = a.fdiv(b); - memory.set(dstOffset, dest); - - memory.assert(memoryOperations); - context.machineState.incrementPc(); + protected compute(a: Field, b: Field): Field { + // return (a as Field).fdiv(b as Field); + return a.fdiv(b); } } diff --git a/yarn-project/simulator/src/avm/opcodes/bitwise.test.ts b/yarn-project/simulator/src/avm/opcodes/bitwise.test.ts index 2d8e5308cc62..ff6b355fa718 100644 --- a/yarn-project/simulator/src/avm/opcodes/bitwise.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/bitwise.test.ts @@ -1,6 +1,7 @@ import { type AvmContext } from '../avm_context.js'; import { TypeTag, Uint8, Uint16, Uint32 } from '../avm_memory_types.js'; import { initContext } from '../fixtures/index.js'; +import { Opcode } from '../serialization/instruction_serialization.js'; import { And, Not, Or, Shl, Shr, Xor } from './bitwise.js'; describe('Bitwise instructions', () => { @@ -13,22 +14,22 @@ describe('Bitwise instructions', () => { describe('AND', () => { it('Should deserialize correctly', () => { const buf = Buffer.from([ - And.opcode, // opcode + Opcode.AND_16, // opcode 0x01, // indirect TypeTag.UINT64, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new And( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.UINT64, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.AND_16, And.wireFormat16); - expect(And.deserialize(buf)).toEqual(inst); + expect(And.as(And.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -52,22 +53,22 @@ describe('Bitwise instructions', () => { describe('OR', () => { it('Should deserialize correctly', () => { const buf = Buffer.from([ - Or.opcode, // opcode + Opcode.OR_16, // opcode 0x01, // indirect TypeTag.UINT64, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Or( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.UINT64, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.OR_16, Or.wireFormat16); - expect(Or.deserialize(buf)).toEqual(inst); + expect(Or.as(Or.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -95,22 +96,22 @@ describe('Bitwise instructions', () => { describe('XOR', () => { it('Should deserialize correctly', () => { const buf = Buffer.from([ - Xor.opcode, // opcode + Opcode.XOR_16, // opcode 0x01, // indirect TypeTag.UINT64, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Xor( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.UINT64, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.XOR_16, Xor.wireFormat16); - expect(Xor.deserialize(buf)).toEqual(inst); + expect(Xor.as(Xor.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -138,22 +139,22 @@ describe('Bitwise instructions', () => { describe('SHR', () => { it('Should deserialize correctly', () => { const buf = Buffer.from([ - Shr.opcode, // opcode + Opcode.SHR_16, // opcode 0x01, // indirect TypeTag.UINT64, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Shr( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.UINT64, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.SHR_16, Shr.wireFormat16); - expect(Shr.deserialize(buf)).toEqual(inst); + expect(Shr.as(Shr.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -240,22 +241,22 @@ describe('Bitwise instructions', () => { describe('SHL', () => { it('Should deserialize correctly', () => { const buf = Buffer.from([ - Shl.opcode, // opcode + Opcode.SHL_16, // opcode 0x01, // indirect TypeTag.UINT64, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Shl( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.UINT64, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.SHL_16, Shl.wireFormat16); - expect(Shl.deserialize(buf)).toEqual(inst); + expect(Shl.as(Shl.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); diff --git a/yarn-project/simulator/src/avm/opcodes/bitwise.ts b/yarn-project/simulator/src/avm/opcodes/bitwise.ts index e43f36550b04..7ead46b1bee7 100644 --- a/yarn-project/simulator/src/avm/opcodes/bitwise.ts +++ b/yarn-project/simulator/src/avm/opcodes/bitwise.ts @@ -34,7 +34,7 @@ abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction { export class And extends ThreeOperandBitwiseInstruction { static readonly type: string = 'AND'; - static readonly opcode = Opcode.AND; + static readonly opcode = Opcode.AND_8; // FIXME: needed for gas. protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue { return a.and(b); @@ -43,7 +43,7 @@ export class And extends ThreeOperandBitwiseInstruction { export class Or extends ThreeOperandBitwiseInstruction { static readonly type: string = 'OR'; - static readonly opcode = Opcode.OR; + static readonly opcode = Opcode.OR_8; // FIXME: needed for gas. protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue { return a.or(b); @@ -52,7 +52,7 @@ export class Or extends ThreeOperandBitwiseInstruction { export class Xor extends ThreeOperandBitwiseInstruction { static readonly type: string = 'XOR'; - static readonly opcode = Opcode.XOR; + static readonly opcode = Opcode.XOR_8; // FIXME: needed for gas. protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue { return a.xor(b); @@ -61,7 +61,7 @@ export class Xor extends ThreeOperandBitwiseInstruction { export class Shl extends ThreeOperandBitwiseInstruction { static readonly type: string = 'SHL'; - static readonly opcode = Opcode.SHL; + static readonly opcode = Opcode.SHL_8; // FIXME: needed for gas. protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue { return a.shl(b); @@ -74,7 +74,7 @@ export class Shl extends ThreeOperandBitwiseInstruction { export class Shr extends ThreeOperandBitwiseInstruction { static readonly type: string = 'SHR'; - static readonly opcode = Opcode.SHR; + static readonly opcode = Opcode.SHR_8; // FIXME: needed for gas. protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue { return a.shr(b); diff --git a/yarn-project/simulator/src/avm/opcodes/comparators.test.ts b/yarn-project/simulator/src/avm/opcodes/comparators.test.ts index c9ae2d31fa53..7695478c68d4 100644 --- a/yarn-project/simulator/src/avm/opcodes/comparators.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/comparators.test.ts @@ -2,6 +2,7 @@ import { type AvmContext } from '../avm_context.js'; import { Field, TypeTag, Uint8, Uint16, Uint32 } from '../avm_memory_types.js'; import { TagCheckError } from '../errors.js'; import { initContext } from '../fixtures/index.js'; +import { Opcode } from '../serialization/instruction_serialization.js'; import { Eq, Lt, Lte } from './comparators.js'; describe('Comparators', () => { @@ -14,22 +15,22 @@ describe('Comparators', () => { describe('Eq', () => { it('Should deserialize correctly', () => { const buf = Buffer.from([ - Eq.opcode, // opcode + Opcode.EQ_16, // opcode 0x01, // indirect TypeTag.UINT64, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Eq( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.UINT64, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.EQ_16, Eq.wireFormat16); - expect(Eq.deserialize(buf)).toEqual(inst); + expect(Eq.as(Eq.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -86,22 +87,22 @@ describe('Comparators', () => { describe('Lt', () => { it('Should deserialize correctly', () => { const buf = Buffer.from([ - Lt.opcode, // opcode + Opcode.LT_16, // opcode 0x01, // indirect TypeTag.UINT64, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Lt( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.UINT64, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.LT_16, Lt.wireFormat16); - expect(Lt.deserialize(buf)).toEqual(inst); + expect(Lt.as(Lt.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); @@ -158,22 +159,22 @@ describe('Comparators', () => { describe('Lte', () => { it('Should deserialize correctly', () => { const buf = Buffer.from([ - Lte.opcode, // opcode + Opcode.LTE_16, // opcode 0x01, // indirect TypeTag.UINT64, // inTag - ...Buffer.from('12345678', 'hex'), // aOffset - ...Buffer.from('23456789', 'hex'), // bOffset - ...Buffer.from('3456789a', 'hex'), // dstOffset + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('2345', 'hex'), // bOffset + ...Buffer.from('3456', 'hex'), // dstOffset ]); const inst = new Lte( /*indirect=*/ 0x01, /*inTag=*/ TypeTag.UINT64, - /*aOffset=*/ 0x12345678, - /*bOffset=*/ 0x23456789, - /*dstOffset=*/ 0x3456789a, - ); + /*aOffset=*/ 0x1234, + /*bOffset=*/ 0x2345, + /*dstOffset=*/ 0x3456, + ).as(Opcode.LTE_16, Lte.wireFormat16); - expect(Lte.deserialize(buf)).toEqual(inst); + expect(Lte.as(Lte.wireFormat16).deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); diff --git a/yarn-project/simulator/src/avm/opcodes/comparators.ts b/yarn-project/simulator/src/avm/opcodes/comparators.ts index c3e90da54c39..be0b5c69c091 100644 --- a/yarn-project/simulator/src/avm/opcodes/comparators.ts +++ b/yarn-project/simulator/src/avm/opcodes/comparators.ts @@ -31,7 +31,7 @@ abstract class ComparatorInstruction extends ThreeOperandInstruction { export class Eq extends ComparatorInstruction { static readonly type: string = 'EQ'; - static readonly opcode = Opcode.EQ; + static readonly opcode = Opcode.EQ_8; // FIXME: needed for gas. protected compare(a: MemoryValue, b: MemoryValue): boolean { return a.equals(b); @@ -40,7 +40,7 @@ export class Eq extends ComparatorInstruction { export class Lt extends ComparatorInstruction { static readonly type: string = 'LT'; - static readonly opcode = Opcode.LT; + static readonly opcode = Opcode.LT_8; // FIXME: needed for gas. protected compare(a: MemoryValue, b: MemoryValue): boolean { return a.lt(b); @@ -49,7 +49,7 @@ export class Lt extends ComparatorInstruction { export class Lte extends ComparatorInstruction { static readonly type: string = 'LTE'; - static readonly opcode = Opcode.LTE; + static readonly opcode = Opcode.LTE_8; // FIXME: needed for gas. protected compare(a: MemoryValue, b: MemoryValue): boolean { return a.lt(b) || a.equals(b); diff --git a/yarn-project/simulator/src/avm/opcodes/instruction_impl.ts b/yarn-project/simulator/src/avm/opcodes/instruction_impl.ts index f5797d526f87..01166d42314d 100644 --- a/yarn-project/simulator/src/avm/opcodes/instruction_impl.ts +++ b/yarn-project/simulator/src/avm/opcodes/instruction_impl.ts @@ -14,13 +14,21 @@ export const TwoOperandWireFormat = [ ]; /** Wire format that informs deserialization for instructions with three operands. */ -export const ThreeOperandWireFormat = [ +export const ThreeOperandWireFormat8 = [ + OperandType.UINT8, + OperandType.UINT8, + OperandType.UINT8, OperandType.UINT8, OperandType.UINT8, OperandType.UINT8, - OperandType.UINT32, - OperandType.UINT32, - OperandType.UINT32, +]; +export const ThreeOperandWireFormat16 = [ + OperandType.UINT8, + OperandType.UINT8, + OperandType.UINT8, + OperandType.UINT16, + OperandType.UINT16, + OperandType.UINT16, ]; /** @@ -46,8 +54,8 @@ export abstract class TwoOperandInstruction extends Instruction { * indirect, inTag, and three UINT32s. */ export abstract class ThreeOperandInstruction extends Instruction { - // Informs (de)serialization. See Instruction.deserialize. - static readonly wireFormat: OperandType[] = ThreeOperandWireFormat; + static readonly wireFormat8: OperandType[] = ThreeOperandWireFormat8; + static readonly wireFormat16: OperandType[] = ThreeOperandWireFormat16; constructor( protected indirect: number, diff --git a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts index b5dd46cf4cc8..10354bcc4102 100644 --- a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts +++ b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts @@ -3,7 +3,7 @@ import { strict as assert } from 'assert'; import { Add, Address, Call, StaticCall, Sub } from '../opcodes/index.js'; import { type BufferCursor } from './buffer_cursor.js'; import { type InstructionSet, decodeFromBytecode, encodeToBytecode } from './bytecode_serialization.js'; -import { type Opcode } from './instruction_serialization.js'; +import { Opcode } from './instruction_serialization.js'; class InstA { constructor(private n: number) {} @@ -72,8 +72,14 @@ describe('Bytecode Serialization', () => { it('Should deserialize real instructions', () => { const instructions = [ - new Add(/*indirect=*/ 0, /*inTag=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2), - new Sub(/*indirect=*/ 0, /*inTag=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2), + new Add(/*indirect=*/ 0, /*inTag=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2).as( + Opcode.ADD_8, + Add.wireFormat8, + ), + new Sub(/*indirect=*/ 0, /*inTag=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2).as( + Opcode.SUB_8, + Sub.wireFormat8, + ), new Address(/*indirect=*/ 0, /*dstOffset=*/ 1), new Call( /*indirect=*/ 0x01, @@ -107,8 +113,14 @@ describe('Bytecode Serialization', () => { it('Should serialize real instructions', () => { const instructions = [ - new Add(/*indirect=*/ 0, /*inTag=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2), - new Sub(/*indirect=*/ 0, /*inTag=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2), + new Add(/*indirect=*/ 0, /*inTag=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2).as( + Opcode.ADD_8, + Add.wireFormat8, + ), + new Sub(/*indirect=*/ 0, /*inTag=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2).as( + Opcode.SUB_8, + Sub.wireFormat8, + ), new Address(/*indirect=*/ 0, /*dstOffset=*/ 1), new Call( /*indirect=*/ 0x01, diff --git a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts index 099357c888d5..3b435b0386a7 100644 --- a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts @@ -74,20 +74,33 @@ export type InstructionSet = Map; // This is a temporary solution until we solve the dependency cycle. const INSTRUCTION_SET = () => new Map([ - [Add.opcode, Instruction.deserialize.bind(Add)], - [Sub.opcode, Instruction.deserialize.bind(Sub)], - [Mul.opcode, Instruction.deserialize.bind(Mul)], - [Div.opcode, Instruction.deserialize.bind(Div)], - [FieldDiv.opcode, Instruction.deserialize.bind(FieldDiv)], - [Eq.opcode, Instruction.deserialize.bind(Eq)], - [Lt.opcode, Instruction.deserialize.bind(Lt)], - [Lte.opcode, Instruction.deserialize.bind(Lte)], - [And.opcode, Instruction.deserialize.bind(And)], - [Or.opcode, Instruction.deserialize.bind(Or)], - [Xor.opcode, Instruction.deserialize.bind(Xor)], + [Opcode.ADD_8, Add.as(Add.wireFormat8).deserialize], + [Opcode.ADD_16, Add.as(Add.wireFormat16).deserialize], + [Opcode.SUB_8, Sub.as(Sub.wireFormat8).deserialize], + [Opcode.SUB_16, Sub.as(Sub.wireFormat16).deserialize], + [Opcode.MUL_8, Mul.as(Mul.wireFormat8).deserialize], + [Opcode.MUL_16, Mul.as(Mul.wireFormat16).deserialize], + [Opcode.DIV_8, Div.as(Div.wireFormat8).deserialize], + [Opcode.DIV_16, Div.as(Div.wireFormat16).deserialize], + [Opcode.FDIV_8, FieldDiv.as(FieldDiv.wireFormat8).deserialize], + [Opcode.FDIV_16, FieldDiv.as(FieldDiv.wireFormat16).deserialize], + [Opcode.EQ_8, Eq.as(Eq.wireFormat8).deserialize], + [Opcode.EQ_16, Eq.as(Eq.wireFormat16).deserialize], + [Opcode.LT_8, Lt.as(Lt.wireFormat8).deserialize], + [Opcode.LT_16, Lt.as(Lt.wireFormat16).deserialize], + [Opcode.LTE_8, Lte.as(Lte.wireFormat8).deserialize], + [Opcode.LTE_16, Lte.as(Lte.wireFormat16).deserialize], + [Opcode.AND_8, And.as(And.wireFormat8).deserialize], + [Opcode.AND_16, And.as(And.wireFormat16).deserialize], + [Opcode.OR_8, Or.as(Or.wireFormat8).deserialize], + [Opcode.OR_16, Or.as(Or.wireFormat16).deserialize], + [Opcode.XOR_8, Xor.as(Xor.wireFormat8).deserialize], + [Opcode.XOR_16, Xor.as(Xor.wireFormat16).deserialize], [Not.opcode, Instruction.deserialize.bind(Not)], - [Shl.opcode, Instruction.deserialize.bind(Shl)], - [Shr.opcode, Instruction.deserialize.bind(Shr)], + [Opcode.SHL_8, Shl.as(Shl.wireFormat8).deserialize], + [Opcode.SHL_16, Shl.as(Shl.wireFormat16).deserialize], + [Opcode.SHR_8, Shr.as(Shr.wireFormat8).deserialize], + [Opcode.SHR_16, Shr.as(Shr.wireFormat16).deserialize], [Cast.opcode, Instruction.deserialize.bind(Cast)], [Address.opcode, Instruction.deserialize.bind(Address)], [StorageAddress.opcode, Instruction.deserialize.bind(StorageAddress)], diff --git a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts index 81564454e4dd..904c9001118f 100644 --- a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts @@ -8,20 +8,33 @@ import { BufferCursor } from './buffer_cursor.js'; */ export enum Opcode { // Compute - ADD, - SUB, - MUL, - DIV, - FDIV, - EQ, - LT, - LTE, - AND, - OR, - XOR, + ADD_8, + ADD_16, + SUB_8, + SUB_16, + MUL_8, + MUL_16, + DIV_8, + DIV_16, + FDIV_8, + FDIV_16, + EQ_8, + EQ_16, + LT_8, + LT_16, + LTE_8, + LTE_16, + AND_8, + AND_16, + OR_8, + OR_16, + XOR_8, + XOR_16, NOT, - SHL, - SHR, + SHL_8, + SHL_16, + SHR_8, + SHR_16, CAST, // Execution environment ADDRESS,