Skip to content

Commit c9530d7

Browse files
authored
Store PC and FP as a field element in WOM and chips (#110)
1 parent db4a336 commit c9530d7

File tree

15 files changed

+336
-207
lines changed

15 files changed

+336
-207
lines changed

extensions/circuit/src/adapters/allocate_frame.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use struct_reflection::{StructReflection, StructReflectionHelper};
2626

2727
use crate::{
2828
FrameBridge, FrameBus, FrameState, VmAdapterChipWom, WomBridge, WomController, WomRecord,
29-
adapters::{compose, decompose, frame_allocator::FrameAllocator},
29+
adapters::{decompose, frame_allocator::FrameAllocator},
3030
};
3131

3232
use super::RV32_REGISTER_NUM_LIMBS;
@@ -89,8 +89,9 @@ pub struct AllocateFrameAdapterColsWom<T> {
8989
pub amount_imm: T,
9090
// 0 if imm, 1 if reg
9191
pub amount_imm_or_reg: T,
92-
// new frame pointer: provided by the prover
93-
pub next_frame_ptr: [T; RV32_REGISTER_NUM_LIMBS],
92+
// new frame pointer: provided by the prover.
93+
// Instead of four u8 limbs, we use the full field to store the fp as a single element
94+
pub next_frame_ptr: T,
9495
pub dest_reg: T,
9596
pub write_mult: T,
9697
}
@@ -144,7 +145,12 @@ impl<AB: InteractionBuilder> VmAdapterAir<AB> for AllocateFrameAdapterAirWom {
144145
self.wom_bridge
145146
.write(
146147
local.dest_reg + local.from_frame.fp,
147-
local.next_frame_ptr,
148+
[
149+
local.next_frame_ptr.into(),
150+
AB::Expr::ZERO,
151+
AB::Expr::ZERO,
152+
AB::Expr::ZERO,
153+
],
148154
local.write_mult,
149155
)
150156
.eval(builder, ctx.instruction.is_valid.clone());
@@ -216,7 +222,7 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for AllocateFrameAdapterChipWom {
216222
// Otherwise, we read the value from the register
217223
let fp_f = F::from_canonical_u32(fp);
218224
let (_, reg_data) = wom.read::<RV32_REGISTER_NUM_LIMBS>(amount_reg + fp_f);
219-
compose(reg_data)
225+
F::as_canonical_u32(&reg_data[0])
220226
};
221227
let amount_bytes = RV32_REGISTER_NUM_LIMBS as u32 * amount;
222228

@@ -260,9 +266,9 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for AllocateFrameAdapterChipWom {
260266
let mut write_result = None;
261267

262268
if enabled != F::ZERO {
263-
write_result = Some(wom.write(
269+
write_result = Some(wom.write_fe(
264270
target_reg + F::from_canonical_u32(from_frame.fp),
265-
decompose(read_record.allocated_ptr),
271+
F::from_canonical_u32(read_record.allocated_ptr),
266272
));
267273
}
268274

extensions/circuit/src/adapters/copy_into_frame.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use openvm_circuit::{
1010
program::ProgramBus,
1111
},
1212
};
13-
use openvm_circuit_primitives::utils::{compose, select};
13+
use openvm_circuit_primitives::utils::select;
1414
use openvm_circuit_primitives_derive::AlignedBorrow;
1515
use openvm_instructions::{LocalOpcode, instruction::Instruction, program::DEFAULT_PC_STEP};
1616
use openvm_stark_backend::{
@@ -27,7 +27,7 @@ use crate::{
2727
FrameBridge, FrameBus, FrameState, VmAdapterChipWom, WomBridge, WomController, WomRecord,
2828
};
2929

30-
use super::{RV32_REGISTER_NUM_LIMBS, compose as compose_as_u32, decompose};
30+
use super::RV32_REGISTER_NUM_LIMBS;
3131

3232
#[derive(Debug)]
3333
pub struct CopyIntoFrameAdapterChipWom<F: Field> {
@@ -58,7 +58,7 @@ impl<F: PrimeField32> CopyIntoFrameAdapterChipWom<F> {
5858
#[repr(C)]
5959
#[derive(Debug, Clone, Serialize, Deserialize)]
6060
pub struct CopyIntoFrameReadRecord<F> {
61-
pub rs1: Option<(WomRecord<F>, u32)>, // Value to copy
61+
pub rs1: Option<WomRecord<F>>, // Value to copy
6262
pub rs2: Option<(WomRecord<F>, u32)>, // Frame pointer
6363
}
6464

@@ -80,7 +80,8 @@ pub struct CopyIntoFrameAdapterColsWom<T> {
8080
pub src_reg: T,
8181
pub src: [T; RV32_REGISTER_NUM_LIMBS],
8282
pub other_fp_reg: T,
83-
pub other_fp: [T; RV32_REGISTER_NUM_LIMBS],
83+
// Instead of using u8 limbs, we use the full field to store the fp as a single element.
84+
pub other_fp: T,
8485
/// 0 if copy_from_frame
8586
/// 1 if copy_into_frame
8687
pub is_copy_into: T,
@@ -126,16 +127,24 @@ impl<AB: InteractionBuilder> VmAdapterAir<AB> for CopyIntoFrameAdapterAirWom {
126127
let local: &CopyIntoFrameAdapterColsWom<_> = local.borrow();
127128

128129
// fp read from register
129-
let other_fp: AB::Expr = compose(&local.other_fp, RV32_REGISTER_NUM_LIMBS);
130+
let other_fp = local.other_fp;
130131

131132
// TODO: constrain is_copy_into from opcode
132133

133-
let src_fp = select(local.is_copy_into, local.from_frame.fp, other_fp.clone());
134+
let src_fp = select(local.is_copy_into, local.from_frame.fp, other_fp);
134135
let target_fp = select(local.is_copy_into, other_fp, local.from_frame.fp);
135136

136137
// read other fp
137138
self.wom_bridge
138-
.read(local.other_fp_reg, local.other_fp)
139+
.read(
140+
local.other_fp_reg,
141+
[
142+
other_fp.into(),
143+
AB::Expr::ZERO,
144+
AB::Expr::ZERO,
145+
AB::Expr::ZERO,
146+
],
147+
)
139148
.eval(builder, ctx.instruction.is_valid.clone());
140149

141150
// read src reg
@@ -211,10 +220,10 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for CopyIntoFrameAdapterChipWom<F> {
211220
opcode.local_opcode_idx(CopyIntoFrameOpcode::CLASS_OFFSET),
212221
);
213222

214-
let other_fp = wom.read::<RV32_REGISTER_NUM_LIMBS>(c + fp_f);
223+
let other_fp_read = wom.read_fe(c + fp_f);
224+
let other_fp_f = other_fp_read.1;
215225

216-
let other_fp_u32 = compose_as_u32(other_fp.1);
217-
let other_fp_f = F::from_canonical_u32(other_fp_u32);
226+
let other_fp_u32 = F::as_canonical_u32(&other_fp_f);
218227

219228
memory.increment_timestamp();
220229

@@ -226,10 +235,10 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for CopyIntoFrameAdapterChipWom<F> {
226235
};
227236

228237
Ok((
229-
[value_to_copy.1, other_fp.1],
238+
[value_to_copy.1, [other_fp_f, F::ZERO, F::ZERO, F::ZERO]],
230239
CopyIntoFrameReadRecord {
231-
rs1: Some((value_to_copy.0, compose_as_u32(value_to_copy.1))),
232-
rs2: Some((other_fp.0, compose_as_u32(other_fp.1))),
240+
rs1: Some(value_to_copy.0),
241+
rs2: Some((other_fp_read.0, other_fp_u32)),
233242
},
234243
))
235244
}
@@ -260,13 +269,14 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for CopyIntoFrameAdapterChipWom<F> {
260269
let fp_f = F::from_canonical_u32(from_frame.fp);
261270

262271
if enabled != F::ZERO {
263-
let value = read_record.rs1.as_ref().unwrap().1;
272+
let value_data = read_record.rs1.as_ref().unwrap().data.clone();
273+
let value: [F; RV32_REGISTER_NUM_LIMBS] = value_data.try_into().unwrap();
264274
let other_fp = read_record.rs2.as_ref().unwrap().1;
265275
let other_fp_f = F::from_canonical_u32(other_fp);
266276

267277
write_result = Some(match local_opcode {
268-
CopyIntoFrameOpcode::COPY_INTO_FRAME => wom.write(a + other_fp_f, decompose(value)),
269-
CopyIntoFrameOpcode::COPY_FROM_FRAME => wom.write(a + fp_f, decompose(value)),
278+
CopyIntoFrameOpcode::COPY_INTO_FRAME => wom.write(a + other_fp_f, value),
279+
CopyIntoFrameOpcode::COPY_FROM_FRAME => wom.write(a + fp_f, value),
270280
});
271281
}
272282

0 commit comments

Comments
 (0)