diff --git a/.github/workflows/o1vm-ci.yml b/.github/workflows/o1vm-ci.yml index f657d3c879..23dca57e53 100644 --- a/.github/workflows/o1vm-ci.yml +++ b/.github/workflows/o1vm-ci.yml @@ -89,4 +89,4 @@ jobs: eval $(opam env) cd o1vm unzip -q -o /tmp/o1vm-e2e-testing-cache.zip -d ./ - RUN_WITH_CACHED_DATA="y" FILENAME="env-for-latest-l2-block.sh" O1VM_FLAVOR="pickles" STOP_AT="=3000000" ./run-code.sh + RUST_LOG=debug RUN_WITH_CACHED_DATA="y" FILENAME="env-for-latest-l2-block.sh" O1VM_FLAVOR="pickles" STOP_AT="=3000000" ./run-code.sh diff --git a/o1vm/src/interpreters/mips/column.rs b/o1vm/src/interpreters/mips/column.rs index 781f997493..ecc4b83edc 100644 --- a/o1vm/src/interpreters/mips/column.rs +++ b/o1vm/src/interpreters/mips/column.rs @@ -47,8 +47,9 @@ pub const SCRATCH_SIZE_INVERSE: usize = 12; pub const N_MIPS_REL_COLS: usize = SCRATCH_SIZE + SCRATCH_SIZE_INVERSE + 2; /// The number of witness columns used to store the instruction selectors. +/// NOTE: The +1 is coming from the NoOp instruction. pub const N_MIPS_SEL_COLS: usize = - RTypeInstruction::COUNT + JTypeInstruction::COUNT + ITypeInstruction::COUNT; + RTypeInstruction::COUNT + JTypeInstruction::COUNT + ITypeInstruction::COUNT + 1; /// All the witness columns used in MIPS pub const N_MIPS_COLS: usize = N_MIPS_REL_COLS + N_MIPS_SEL_COLS; @@ -97,6 +98,12 @@ impl From for usize { IType(itype) => { N_MIPS_REL_COLS + RTypeInstruction::COUNT + JTypeInstruction::COUNT + itype as usize } + Instruction::NoOp => { + N_MIPS_REL_COLS + + RTypeInstruction::COUNT + + JTypeInstruction::COUNT + + ITypeInstruction::COUNT + } } } } diff --git a/o1vm/src/interpreters/mips/interpreter.rs b/o1vm/src/interpreters/mips/interpreter.rs index 5ba96d9885..8604af7986 100644 --- a/o1vm/src/interpreters/mips/interpreter.rs +++ b/o1vm/src/interpreters/mips/interpreter.rs @@ -31,6 +31,7 @@ pub enum Instruction { RType(RTypeInstruction), JType(JTypeInstruction), IType(ITypeInstruction), + NoOp, } #[derive( @@ -153,6 +154,7 @@ impl IntoIterator for Instruction { } iter_contents.into_iter() } + Instruction::NoOp => vec![Instruction::NoOp].into_iter(), } } } @@ -970,9 +972,34 @@ pub fn interpret_instruction(env: &mut Env, instr: Instruct Instruction::RType(instr) => interpret_rtype(env, instr), Instruction::JType(instr) => interpret_jtype(env, instr), Instruction::IType(instr) => interpret_itype(env, instr), + Instruction::NoOp => interpret_noop(env), } } +pub fn interpret_noop(env: &mut Env) { + let instruction_pointer = env.get_instruction_pointer(); + let instruction = { + let v0 = env.read_memory(&instruction_pointer); + let v1 = env.read_memory(&(instruction_pointer.clone() + Env::constant(1))); + let v2 = env.read_memory(&(instruction_pointer.clone() + Env::constant(2))); + let v3 = env.read_memory(&(instruction_pointer.clone() + Env::constant(3))); + (v0 * Env::constant(1 << 24)) + + (v1 * Env::constant(1 << 16)) + + (v2 * Env::constant(1 << 8)) + + v3 + }; + let opcode = { + let pos = env.alloc_scratch(); + unsafe { env.bitmask(&instruction, 32, 26, pos) } + }; + + env.range_check8(&opcode, 6); + env.assert_is_zero(opcode); + let next_instruction_pointer = env.get_next_instruction_pointer(); + env.set_instruction_pointer(next_instruction_pointer.clone()); + env.set_next_instruction_pointer(next_instruction_pointer + Env::constant(4u32)); +} + pub fn interpret_rtype(env: &mut Env, instr: RTypeInstruction) { let instruction_pointer = env.get_instruction_pointer(); let next_instruction_pointer = env.get_next_instruction_pointer(); diff --git a/o1vm/src/interpreters/mips/tests.rs b/o1vm/src/interpreters/mips/tests.rs index 1b212077d1..0ede2b9e71 100644 --- a/o1vm/src/interpreters/mips/tests.rs +++ b/o1vm/src/interpreters/mips/tests.rs @@ -342,7 +342,8 @@ fn test_regression_selectors_for_instructions() { constraints.len() - 1, // We could use N_MIPS_SEL_COLS, but sanity check in case this value is // changed. - RTypeInstruction::COUNT + JTypeInstruction::COUNT + ITypeInstruction::COUNT + // the +1 is coming from NoOp instruction + RTypeInstruction::COUNT + JTypeInstruction::COUNT + ITypeInstruction::COUNT + 1 ); // All instructions are degree 1 or 2. constraints diff --git a/o1vm/src/interpreters/mips/witness.rs b/o1vm/src/interpreters/mips/witness.rs index c2081262ee..a318a662cc 100644 --- a/o1vm/src/interpreters/mips/witness.rs +++ b/o1vm/src/interpreters/mips/witness.rs @@ -1076,7 +1076,13 @@ impl Env { let opcode = { match instruction >> 26 { 0x00 => match instruction & 0x3F { - 0x00 => Instruction::RType(RTypeInstruction::ShiftLeftLogical), + 0x00 => { + if instruction == 0 { + Instruction::NoOp + } else { + Instruction::RType(RTypeInstruction::ShiftLeftLogical) + } + } 0x02 => Instruction::RType(RTypeInstruction::ShiftRightLogical), 0x03 => Instruction::RType(RTypeInstruction::ShiftRightArithmetic), 0x04 => Instruction::RType(RTypeInstruction::ShiftLeftLogicalVariable), diff --git a/o1vm/src/pickles/mod.rs b/o1vm/src/pickles/mod.rs index 193162e90b..b557473fe3 100644 --- a/o1vm/src/pickles/mod.rs +++ b/o1vm/src/pickles/mod.rs @@ -31,7 +31,7 @@ pub const DEGREE_QUOTIENT_POLYNOMIAL: u64 = 7; /// Total number of constraints for all instructions, including the constraints /// added for the selectors. -pub const TOTAL_NUMBER_OF_CONSTRAINTS: usize = 464; +pub const TOTAL_NUMBER_OF_CONSTRAINTS: usize = 466; #[cfg(test)] mod tests;