use p3_field::PrimeField;
use sp1_derive::AlignedBorrow;
use std::mem::size_of;
use std::{iter::once, vec::IntoIter};
use crate::runtime::Register;
use crate::{air::Word, runtime::Instruction};
pub const NUM_INSTRUCTION_COLS: usize = size_of::<InstructionCols<u8>>();
#[derive(AlignedBorrow, Clone, Copy, Default, Debug)]
#[repr(C)]
pub struct InstructionCols<T> {
pub opcode: T,
pub op_a: Word<T>,
pub op_b: Word<T>,
pub op_c: Word<T>,
pub op_a_0: T,
}
impl<F: PrimeField> InstructionCols<F> {
pub fn populate(&mut self, instruction: Instruction) {
self.opcode = instruction.opcode.as_field::<F>();
self.op_a = instruction.op_a.into();
self.op_b = instruction.op_b.into();
self.op_c = instruction.op_c.into();
self.op_a_0 = F::from_bool(instruction.op_a == Register::X0 as u32);
}
}
impl<T> IntoIterator for InstructionCols<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
once(self.opcode)
.chain(self.op_a)
.chain(self.op_b)
.chain(self.op_c)
.chain(once(self.op_a_0))
.collect::<Vec<_>>()
.into_iter()
}
}