sp1_core_machine/program/
instruction.rs1use slop_algebra::PrimeField;
2use sp1_core_executor::{Instruction, Register};
3use sp1_derive::AlignedBorrow;
4use sp1_hypercube::Word;
5use std::{iter::once, mem::size_of, vec::IntoIter};
6
7pub const NUM_INSTRUCTION_COLS: usize = size_of::<InstructionCols<u8>>();
8
9#[derive(AlignedBorrow, Clone, Copy, Default, Debug)]
11#[repr(C)]
12pub struct InstructionCols<T> {
13 pub opcode: T,
15
16 pub op_a: T,
18
19 pub op_b: Word<T>,
21
22 pub op_c: Word<T>,
24
25 pub op_a_0: T,
27
28 pub imm_b: T,
30
31 pub imm_c: T,
33}
34
35impl<F: PrimeField> InstructionCols<F> {
36 pub fn populate(&mut self, instruction: &Instruction) {
37 self.opcode = instruction.opcode.as_field::<F>();
38 self.op_a = F::from_canonical_u8(instruction.op_a);
39 self.op_b = instruction.op_b.into();
40 self.op_c = instruction.op_c.into();
41
42 self.op_a_0 = F::from_bool(instruction.op_a == Register::X0 as u8);
43 self.imm_b = F::from_bool(instruction.imm_b);
44 self.imm_c = F::from_bool(instruction.imm_c);
45 }
46}
47
48impl<T> IntoIterator for InstructionCols<T> {
49 type Item = T;
50 type IntoIter = IntoIter<T>;
51
52 fn into_iter(self) -> Self::IntoIter {
53 once(self.opcode)
54 .chain(once(self.op_a))
55 .chain(self.op_b)
56 .chain(self.op_c)
57 .chain(once(self.op_a_0))
58 .chain(once(self.imm_b))
59 .chain(once(self.imm_c))
60 .collect::<Vec<_>>()
61 .into_iter()
62 }
63}