@@ -8,12 +8,13 @@ use p3_symmetric::Permutation;
88use poseidon16:: Poseidon2_16Instruction ;
99use poseidon24:: Poseidon2_24Instruction ;
1010
11- use super :: operand:: { MemOrConstant , MemOrFp , MemOrFpOrConstant } ;
11+ use super :: operand:: MemOrFpOrConstant ;
1212use crate :: {
1313 air:: constant:: {
14- COL_INDEX_ADD , COL_INDEX_AUX , COL_INDEX_DEREF , COL_INDEX_FLAG_A , COL_INDEX_FLAG_B ,
15- COL_INDEX_FLAG_C , COL_INDEX_JUZ , COL_INDEX_MUL , COL_INDEX_OPERAND_A , COL_INDEX_OPERAND_B ,
16- COL_INDEX_OPERAND_C , N_INSTRUCTION_COLUMNS ,
14+ COL_INDEX_ADD , COL_INDEX_AUX , COL_INDEX_DEREF , COL_INDEX_DOT_PRODUCT , COL_INDEX_FLAG_A ,
15+ COL_INDEX_FLAG_B , COL_INDEX_FLAG_C , COL_INDEX_JUZ , COL_INDEX_MUL ,
16+ COL_INDEX_MULTILINEAR_EVAL , COL_INDEX_OPERAND_A , COL_INDEX_OPERAND_B , COL_INDEX_OPERAND_C ,
17+ COL_INDEX_POSEIDON_16 , COL_INDEX_POSEIDON_24 , N_INSTRUCTION_COLUMNS ,
1718 } ,
1819 bytecode:: operation:: Operation ,
1920 constant:: { DIMENSION , F } ,
@@ -161,26 +162,18 @@ impl Instruction {
161162 Self :: Computation ( ComputationInstruction {
162163 operation,
163164 arg_a,
164- arg_b ,
165+ arg_c ,
165166 res,
166167 } ) => {
167168 // Set the appropriate opcode flag for ADD or MUL.
168169 match operation {
169170 Operation :: Add => repr[ COL_INDEX_ADD ] = F :: ONE ,
170171 Operation :: Mul => repr[ COL_INDEX_MUL ] = F :: ONE ,
171172 }
172- // Convert operands to their field and flag representations.
173- let ( op_a, flag_a) = op_to_field ( arg_a) ;
174- let ( op_b, flag_b) = op_to_field_fp ( arg_b) ;
175- let ( op_c, flag_c) = op_to_field ( res) ;
176-
177- // Populate the representation vector.
178- repr[ COL_INDEX_OPERAND_A ] = op_a;
179- repr[ COL_INDEX_FLAG_A ] = flag_a;
180- repr[ COL_INDEX_OPERAND_B ] = op_b;
181- repr[ COL_INDEX_FLAG_B ] = flag_b;
182- repr[ COL_INDEX_OPERAND_C ] = op_c;
183- repr[ COL_INDEX_FLAG_C ] = flag_c;
173+ // Convert operands to their field and flag representations using the helper methods.
174+ ( repr[ COL_INDEX_OPERAND_A ] , repr[ COL_INDEX_FLAG_A ] ) = arg_a. to_field_and_flag ( ) ;
175+ ( repr[ COL_INDEX_OPERAND_B ] , repr[ COL_INDEX_FLAG_B ] ) = res. to_field_and_flag ( ) ;
176+ ( repr[ COL_INDEX_OPERAND_C ] , repr[ COL_INDEX_FLAG_C ] ) = arg_c. to_field_and_flag ( ) ;
184177 }
185178 Self :: Deref ( DerefInstruction {
186179 shift_0,
@@ -221,37 +214,58 @@ impl Instruction {
221214 // Set the JUZ opcode flag.
222215 repr[ COL_INDEX_JUZ ] = F :: ONE ;
223216 // Convert operands to their field and flag representations.
224- let ( op_a, flag_a) = op_to_field ( condition) ;
225- let ( op_b, flag_b) = op_to_field_fp ( updated_fp) ;
226- let ( op_c, flag_c) = op_to_field ( dest) ;
227-
228- // Populate the representation vector.
229- repr[ COL_INDEX_OPERAND_A ] = op_a;
230- repr[ COL_INDEX_FLAG_A ] = flag_a;
231- repr[ COL_INDEX_OPERAND_B ] = op_b;
232- repr[ COL_INDEX_FLAG_B ] = flag_b;
233- repr[ COL_INDEX_OPERAND_C ] = op_c;
234- repr[ COL_INDEX_FLAG_C ] = flag_c;
217+ ( repr[ COL_INDEX_OPERAND_A ] , repr[ COL_INDEX_FLAG_A ] ) = condition. to_field_and_flag ( ) ;
218+ ( repr[ COL_INDEX_OPERAND_B ] , repr[ COL_INDEX_FLAG_B ] ) =
219+ updated_fp. to_field_and_flag ( ) ;
220+ ( repr[ COL_INDEX_OPERAND_C ] , repr[ COL_INDEX_FLAG_C ] ) = dest. to_field_and_flag ( ) ;
221+ }
222+ Self :: Poseidon2_16 ( Poseidon2_16Instruction { arg_a, arg_b, res } ) => {
223+ // Set the Poseidon16 opcode flag.
224+ repr[ COL_INDEX_POSEIDON_16 ] = F :: ONE ;
225+ // Convert operands to their field and flag representations.
226+ ( repr[ COL_INDEX_OPERAND_A ] , repr[ COL_INDEX_FLAG_A ] ) = arg_a. to_field_and_flag ( ) ;
227+ ( repr[ COL_INDEX_OPERAND_B ] , repr[ COL_INDEX_FLAG_B ] ) = arg_b. to_field_and_flag ( ) ;
228+ ( repr[ COL_INDEX_OPERAND_C ] , repr[ COL_INDEX_FLAG_C ] ) = res. to_field_and_flag ( ) ;
229+ }
230+ Self :: Poseidon2_24 ( Poseidon2_24Instruction { arg_a, arg_b, res } ) => {
231+ // Set the Poseidon24 opcode flag.
232+ repr[ COL_INDEX_POSEIDON_24 ] = F :: ONE ;
233+ // Convert operands to their field and flag representations.
234+ ( repr[ COL_INDEX_OPERAND_A ] , repr[ COL_INDEX_FLAG_A ] ) = arg_a. to_field_and_flag ( ) ;
235+ ( repr[ COL_INDEX_OPERAND_B ] , repr[ COL_INDEX_FLAG_B ] ) = arg_b. to_field_and_flag ( ) ;
236+ ( repr[ COL_INDEX_OPERAND_C ] , repr[ COL_INDEX_FLAG_C ] ) = res. to_field_and_flag ( ) ;
237+ }
238+ Self :: DotProduct ( DotProductInstruction {
239+ arg0,
240+ arg1,
241+ res,
242+ size,
243+ } ) => {
244+ // Set the DotProduct opcode flag.
245+ repr[ COL_INDEX_DOT_PRODUCT ] = F :: ONE ;
246+ // Convert operands to their field and flag representations.
247+ ( repr[ COL_INDEX_OPERAND_A ] , repr[ COL_INDEX_FLAG_A ] ) = arg0. to_field_and_flag ( ) ;
248+ ( repr[ COL_INDEX_OPERAND_B ] , repr[ COL_INDEX_FLAG_B ] ) = arg1. to_field_and_flag ( ) ;
249+ ( repr[ COL_INDEX_OPERAND_C ] , repr[ COL_INDEX_FLAG_C ] ) = res. to_field_and_flag ( ) ;
250+ // Use the AUX column to store the size of the vectors.
251+ repr[ COL_INDEX_AUX ] = F :: from_usize ( * size) ;
252+ }
253+ Self :: MultilinearEval ( MultilinearEvalInstruction {
254+ coeffs,
255+ point,
256+ res,
257+ n_vars,
258+ } ) => {
259+ // Set the MultilinearEval opcode flag.
260+ repr[ COL_INDEX_MULTILINEAR_EVAL ] = F :: ONE ;
261+ // Convert operands to their field and flag representations.
262+ ( repr[ COL_INDEX_OPERAND_A ] , repr[ COL_INDEX_FLAG_A ] ) = coeffs. to_field_and_flag ( ) ;
263+ ( repr[ COL_INDEX_OPERAND_B ] , repr[ COL_INDEX_FLAG_B ] ) = point. to_field_and_flag ( ) ;
264+ ( repr[ COL_INDEX_OPERAND_C ] , repr[ COL_INDEX_FLAG_C ] ) = res. to_field_and_flag ( ) ;
265+ // Use the AUX column to store the number of variables.
266+ repr[ COL_INDEX_AUX ] = F :: from_usize ( * n_vars) ;
235267 }
236- // Precompiles do not set flags in the main instruction columns.
237- _ => { }
238268 }
239269 repr
240270 }
241271}
242-
243- /// Helper to convert a `MemOrConstant` operand into its (value, flag) pair.
244- fn op_to_field ( op : & MemOrConstant ) -> ( F , F ) {
245- match op {
246- MemOrConstant :: Constant ( c) => ( * c, F :: ONE ) ,
247- MemOrConstant :: MemoryAfterFp { offset } => ( F :: from_usize ( * offset) , F :: ZERO ) ,
248- }
249- }
250-
251- /// Helper to convert a `MemOrFp` operand into its (value, flag) pair.
252- fn op_to_field_fp ( op : & MemOrFp ) -> ( F , F ) {
253- match op {
254- MemOrFp :: Fp => ( F :: ZERO , F :: ONE ) , // Represents the `fp` register itself.
255- MemOrFp :: MemoryAfterFp { offset } => ( F :: from_usize ( * offset) , F :: ZERO ) ,
256- }
257- }
0 commit comments