o1vm/interpreters/mips/
column.rs1use crate::{
2 interpreters::mips::Instruction::{self, IType, JType, RType},
3 RelationColumnType,
4};
5use kimchi_msm::{
6 columns::{Column, ColumnIndexer},
7 witness::Witness,
8};
9use std::ops::{Index, IndexMut};
10use strum::EnumCount;
11
12use super::{ITypeInstruction, JTypeInstruction, RTypeInstruction};
13
14pub(crate) const SCRATCH_SIZE_WITHOUT_KECCAK: usize = 45;
15pub(crate) const MIPS_HASH_COUNTER_OFF: usize = SCRATCH_SIZE_WITHOUT_KECCAK;
17pub(crate) const MIPS_BYTE_COUNTER_OFF: usize = SCRATCH_SIZE_WITHOUT_KECCAK + 1;
19pub(crate) const MIPS_END_OF_PREIMAGE_OFF: usize = SCRATCH_SIZE_WITHOUT_KECCAK + 2;
21pub(crate) const MIPS_NUM_BYTES_READ_OFF: usize = SCRATCH_SIZE_WITHOUT_KECCAK + 3;
23pub(crate) const MIPS_PREIMAGE_CHUNK_OFF: usize = SCRATCH_SIZE_WITHOUT_KECCAK + 4;
26pub(crate) const MIPS_PREIMAGE_BYTES_OFF: usize = SCRATCH_SIZE_WITHOUT_KECCAK + 5;
29pub(crate) const MIPS_LENGTH_BYTES_OFF: usize = SCRATCH_SIZE_WITHOUT_KECCAK + 5 + 4;
31pub(crate) const MIPS_HAS_N_BYTES_OFF: usize = SCRATCH_SIZE_WITHOUT_KECCAK + 5 + 4 + 4;
33pub(crate) const MIPS_CHUNK_BYTES_LEN: usize = 4;
35pub(crate) const MIPS_PREIMAGE_KEY: usize = SCRATCH_SIZE_WITHOUT_KECCAK + 5 + 4 + 4 + 4;
37
38pub const SCRATCH_SIZE: usize = SCRATCH_SIZE_WITHOUT_KECCAK + 5 + 4 + 4 + 4 + 1;
41
42pub const SCRATCH_SIZE_INVERSE: usize = 12;
45
46pub const N_MIPS_REL_COLS: usize = SCRATCH_SIZE + SCRATCH_SIZE_INVERSE + 2;
48
49pub const N_MIPS_SEL_COLS: usize =
52 RTypeInstruction::COUNT + JTypeInstruction::COUNT + ITypeInstruction::COUNT + 1;
53
54pub const N_MIPS_COLS: usize = N_MIPS_REL_COLS + N_MIPS_SEL_COLS;
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
60pub enum ColumnAlias {
61 ScratchState(usize),
63 ScratchStateInverse(usize),
66 InstructionCounter,
67 Selector(usize),
68}
69
70impl From<ColumnAlias> for usize {
75 fn from(alias: ColumnAlias) -> usize {
76 match alias {
78 ColumnAlias::ScratchState(i) => {
79 assert!(i < SCRATCH_SIZE);
80 i
81 }
82 ColumnAlias::ScratchStateInverse(i) => {
83 assert!(i < SCRATCH_SIZE_INVERSE);
84 SCRATCH_SIZE + i
85 }
86 ColumnAlias::InstructionCounter => SCRATCH_SIZE + SCRATCH_SIZE_INVERSE,
87 ColumnAlias::Selector(s) => SCRATCH_SIZE + SCRATCH_SIZE_INVERSE + 1 + s,
88 }
89 }
90}
91
92impl From<Instruction> for usize {
94 fn from(instr: Instruction) -> usize {
95 match instr {
96 RType(rtype) => N_MIPS_REL_COLS + rtype as usize,
97 JType(jtype) => N_MIPS_REL_COLS + RTypeInstruction::COUNT + jtype as usize,
98 IType(itype) => {
99 N_MIPS_REL_COLS + RTypeInstruction::COUNT + JTypeInstruction::COUNT + itype as usize
100 }
101 Instruction::NoOp => {
102 N_MIPS_REL_COLS
103 + RTypeInstruction::COUNT
104 + JTypeInstruction::COUNT
105 + ITypeInstruction::COUNT
106 }
107 }
108 }
109}
110
111pub type MIPSWitness<T> = Witness<N_MIPS_COLS, T>;
138
139impl<T: Clone> Index<ColumnAlias> for MIPSWitness<T> {
142 type Output = T;
143
144 fn index(&self, index: ColumnAlias) -> &Self::Output {
146 &self.cols[usize::from(index)]
147 }
148}
149
150impl<T: Clone> IndexMut<ColumnAlias> for MIPSWitness<T> {
151 fn index_mut(&mut self, index: ColumnAlias) -> &mut Self::Output {
152 &mut self.cols[usize::from(index)]
153 }
154}
155
156impl ColumnIndexer<RelationColumnType> for ColumnAlias {
157 const N_COL: usize = N_MIPS_COLS;
158
159 fn to_column(self) -> Column<RelationColumnType> {
160 match self {
161 Self::ScratchState(ss) => {
162 assert!(
163 ss < SCRATCH_SIZE,
164 "The maximum index is {}, got {}",
165 SCRATCH_SIZE,
166 ss
167 );
168 Column::Relation(RelationColumnType::Scratch(ss))
169 }
170 Self::ScratchStateInverse(ss) => {
171 assert!(
172 ss < SCRATCH_SIZE_INVERSE,
173 "The maximum index is {}, got {}",
174 SCRATCH_SIZE_INVERSE,
175 ss
176 );
177 Column::Relation(RelationColumnType::ScratchInverse(ss))
178 }
179 Self::InstructionCounter => Column::Relation(RelationColumnType::InstructionCounter),
180 Self::Selector(s) => {
182 assert!(
183 s < N_MIPS_SEL_COLS,
184 "The maximum index is {}, got {}",
185 N_MIPS_SEL_COLS,
186 s
187 );
188 Column::DynamicSelector(s)
189 }
190 }
191 }
192}
193
194impl<T: Clone> Index<Instruction> for MIPSWitness<T> {
197 type Output = T;
198
199 fn index(&self, index: Instruction) -> &Self::Output {
201 &self.cols[usize::from(index)]
202 }
203}
204
205impl<T: Clone> IndexMut<Instruction> for MIPSWitness<T> {
206 fn index_mut(&mut self, index: Instruction) -> &mut Self::Output {
207 &mut self.cols[usize::from(index)]
208 }
209}
210
211impl ColumnIndexer<usize> for Instruction {
212 const N_COL: usize = N_MIPS_REL_COLS + N_MIPS_SEL_COLS;
213 fn to_column(self) -> Column<usize> {
214 Column::DynamicSelector(usize::from(self) - N_MIPS_REL_COLS)
215 }
216}