Skip to content

Commit

Permalink
Merge pull request #1392 from o1-labs/feature/next-instruction-pointer
Browse files Browse the repository at this point in the history
Respect the 'branch delay slot' in the zkVM
  • Loading branch information
dannywillems authored Dec 5, 2023
2 parents df81b55 + c548dfb commit 6800e29
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 13 deletions.
31 changes: 19 additions & 12 deletions optimism/src/mips/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,10 @@ pub trait InterpreterEnv {

fn get_instruction_pointer(&self) -> Self::Variable;

fn set_next_instruction_pointer(&mut self, ip: Self::Variable);

fn get_next_instruction_pointer(&self) -> Self::Variable;

fn constant(x: u32) -> Self::Variable;

/// Extract the bits from the variable `x` between `highest_bit` and `lowest_bit`, and store
Expand Down Expand Up @@ -480,8 +484,9 @@ pub fn interpret_rtype<Env: InterpreterEnv>(env: &mut Env, instr: RTypeInstructi
}

pub fn interpret_jtype<Env: InterpreterEnv>(env: &mut Env, instr: JTypeInstruction) {
let instruction_pointer = env.get_instruction_pointer();
let next_instruction_pointer = env.get_next_instruction_pointer();
let instruction = {
let instruction_pointer = env.get_instruction_pointer();
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)));
Expand Down Expand Up @@ -509,7 +514,8 @@ pub fn interpret_jtype<Env: InterpreterEnv>(env: &mut Env, instr: JTypeInstructi
// > bits (which would always be 00, since addresses are always
// > divisible by 4).
// Source: https://max.cs.kzoo.edu/cs230/Resources/MIPS/MachineXL/InstructionFormats.html
env.set_instruction_pointer(addr * Env::constant(4));
env.set_instruction_pointer(next_instruction_pointer);
env.set_next_instruction_pointer(addr * Env::constant(4));
// REMOVEME: when all jtype instructions are implemented.
return;
}
Expand All @@ -520,12 +526,13 @@ pub fn interpret_jtype<Env: InterpreterEnv>(env: &mut Env, instr: JTypeInstructi
}

pub fn interpret_itype<Env: InterpreterEnv>(env: &mut Env, instr: ITypeInstruction) {
let instruction_pointer = env.get_instruction_pointer();
let next_instruction_pointer = env.get_next_instruction_pointer();
let instruction = {
let instruction_pointer = env.get_instruction_pointer();
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 + Env::constant(3)));
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))
Expand Down Expand Up @@ -560,8 +567,8 @@ pub fn interpret_itype<Env: InterpreterEnv>(env: &mut Env, instr: ITypeInstructi
let register_rs = env.read_register(&rs);
let res = register_rs + immediate;
env.write_register(&rt, res);
env.set_instruction_pointer(env.get_instruction_pointer() + Env::constant(4u32));
// TODO: update next_instruction_pointer
env.set_instruction_pointer(next_instruction_pointer.clone());
env.set_next_instruction_pointer(next_instruction_pointer + Env::constant(4u32));
// REMOVEME: when all itype instructions are implemented.
return;
}
Expand All @@ -570,8 +577,8 @@ pub fn interpret_itype<Env: InterpreterEnv>(env: &mut Env, instr: ITypeInstructi
let register_rs = env.read_register(&rs);
let res = register_rs + immediate;
env.write_register(&rt, res);
env.set_instruction_pointer(env.get_instruction_pointer() + Env::constant(4u32));
// TODO: update next_instruction_pointer
env.set_instruction_pointer(next_instruction_pointer.clone());
env.set_next_instruction_pointer(next_instruction_pointer + Env::constant(4u32));
// REMOVEME: when all itype instructions are implemented.
return;
}
Expand All @@ -584,8 +591,8 @@ pub fn interpret_itype<Env: InterpreterEnv>(env: &mut Env, instr: ITypeInstructi
// lui $reg, [most significant 16 bits of immediate]
let immediate_value = immediate * Env::constant(1 << 16);
env.write_register(&rt, immediate_value);
env.set_instruction_pointer(env.get_instruction_pointer() + Env::constant(4u32));
// TODO: update next_instruction_pointer
env.set_instruction_pointer(next_instruction_pointer.clone());
env.set_next_instruction_pointer(next_instruction_pointer + Env::constant(4u32));
// REMOVEME: when all itype instructions are implemented.
return;
}
Expand Down Expand Up @@ -617,8 +624,8 @@ pub fn interpret_itype<Env: InterpreterEnv>(env: &mut Env, instr: ITypeInstructi
value
);
env.write_register(&dest, value);
env.set_instruction_pointer(env.get_instruction_pointer() + Env::constant(4u32));
// TODO: update next_instruction_pointer
env.set_instruction_pointer(next_instruction_pointer.clone());
env.set_next_instruction_pointer(next_instruction_pointer + Env::constant(4u32));
// REMOVEME: when all itype instructions are implemented.
return;
}
Expand Down
9 changes: 8 additions & 1 deletion optimism/src/mips/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,20 @@ impl<Fp: Field> InterpreterEnv for Env<Fp> {

fn set_instruction_pointer(&mut self, ip: Self::Variable) {
self.instruction_pointer = ip;
// Set next instruction pointer?
}

fn get_instruction_pointer(&self) -> Self::Variable {
self.instruction_pointer
}

fn set_next_instruction_pointer(&mut self, ip: Self::Variable) {
self.next_instruction_pointer = ip;
}

fn get_next_instruction_pointer(&self) -> Self::Variable {
self.next_instruction_pointer
}

fn constant(x: u32) -> Self::Variable {
x
}
Expand Down

0 comments on commit 6800e29

Please sign in to comment.