diff --git a/o1vm/src/interpreters/riscv32im/interpreter.rs b/o1vm/src/interpreters/riscv32im/interpreter.rs index 88aa412f97..a16cc82418 100644 --- a/o1vm/src/interpreters/riscv32im/interpreter.rs +++ b/o1vm/src/interpreters/riscv32im/interpreter.rs @@ -2235,7 +2235,34 @@ pub fn interpret_sbtype(env: &mut Env, instr: SBInstruction env.set_next_instruction_pointer(addr); } SBInstruction::BranchGreaterThanEqual => { - unimplemented!("BranchGreaterThanEqual") + // bge: if (x[rs1] >= x[rs2]) pc += sext(offset) + let local_rs1 = env.read_register(&rs1); + let local_rs2 = env.read_register(&rs2); + + let rd_scratch = env.alloc_scratch(); + + let less_than = + unsafe { env.test_less_than_signed(&local_rs1, &local_rs2, rd_scratch) }; + + let offset = + less_than.clone() * Env::constant(4) + (Env::constant(1) - less_than) * imm0_12; + // greater than equal is the negation of less than + let addr = { + let res_scratch = env.alloc_scratch(); + let overflow_scratch = env.alloc_scratch(); + let (res, _overflow) = unsafe { + env.add_witness( + &next_instruction_pointer, + &offset, + res_scratch, + overflow_scratch, + ) + }; + // FIXME: Requires a range check + res + }; + env.set_instruction_pointer(next_instruction_pointer); + env.set_next_instruction_pointer(addr); } SBInstruction::BranchLessThanUnsigned => { unimplemented!("BranchLessThanUnsigned")