use p3_field::{AbstractField, Field};
use sp1_core::runtime::MemoryAccessPosition;
use crate::{
air::{BlockBuilder, SP1RecursionAirBuilder},
cpu::{CpuChip, CpuCols},
memory::MemoryCols,
};
impl<F: Field, const L: usize> CpuChip<F, L> {
pub fn eval_operands<AB>(&self, builder: &mut AB, local: &CpuCols<AB::Var>)
where
AB: SP1RecursionAirBuilder<F = F>,
{
builder
.when(local.instruction.imm_b)
.assert_block_eq::<AB::Var, AB::Var>(*local.b.value(), local.instruction.op_b);
builder
.when(local.instruction.imm_c)
.assert_block_eq::<AB::Var, AB::Var>(*local.c.value(), local.instruction.op_c);
let a_addr = local.fp.into() + local.instruction.op_a.into();
builder.recursion_eval_memory_access(
local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::A as u32),
a_addr,
&local.a,
local.is_real.into(),
);
let is_op_a_read_only = self.is_op_a_read_only_instruction::<AB>(local);
builder
.when(is_op_a_read_only)
.assert_block_eq(*local.a.prev_value(), *local.a.value());
builder.recursion_eval_memory_access(
local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::B as u32),
local.fp.into() + local.instruction.op_b[0].into(),
&local.b,
AB::Expr::one() - local.instruction.imm_b.into(),
);
builder.recursion_eval_memory_access(
local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::C as u32),
local.fp.into() + local.instruction.op_c[0].into(),
&local.c,
AB::Expr::one() - local.instruction.imm_c.into(),
);
}
}