Skip to content

Commit eb595c9

Browse files
committed
fix jumps
1 parent 549d067 commit eb595c9

File tree

5 files changed

+55
-23
lines changed

5 files changed

+55
-23
lines changed

extensions/circuit/src/adapters/allocate_frame.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ impl AllocateFrameAdapterChipWom {
4949
_frame_bus: frame_bus,
5050
_memory_bridge: memory_bridge,
5151
},
52-
// Start from 4 because 0 is used by the startup code.
53-
next_fp: 4,
52+
// Start from 8 because 0 and 4 are used by the startup code.
53+
next_fp: 8,
5454
}
5555
}
5656
}
@@ -155,7 +155,9 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for AllocateFrameAdapterChipWom {
155155
memory.increment_timestamp();
156156

157157
let allocated_ptr = decompose(self.next_fp);
158+
println!("next_fp before allocation: {}", self.next_fp);
158159
self.next_fp += b.as_canonical_u32();
160+
println!("next_fp after allocation: {}", self.next_fp);
159161

160162
Ok(([allocated_ptr], AllocateFrameReadRecord {}))
161163
}
@@ -179,6 +181,7 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for AllocateFrameAdapterChipWom {
179181
// Write the allocated pointer to target register
180182
// For simplicity in the mock, we use absolute addressing for the write
181183
if let Some(allocated_ptr) = output.writes.first() {
184+
println!("Writing to local reg {a} with fp {}", from_frame.fp);
182185
let write_result = memory.write(
183186
F::ONE,
184187
a + F::from_canonical_u32(from_frame.fp),

extensions/circuit/src/adapters/jaaf.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for JaafAdapterChipWom<F> {
270270
fn preprocess(
271271
&mut self,
272272
memory: &mut MemoryController<F>,
273-
_fp: u32,
273+
fp: u32,
274274
instruction: &Instruction<F>,
275275
) -> Result<(
276276
<Self::Interface as VmAdapterInterface<F>>::Reads,
@@ -281,11 +281,13 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for JaafAdapterChipWom<F> {
281281
let local_opcode =
282282
JaafOpcode::from_usize(opcode.local_opcode_idx(JaafOpcode::CLASS_OFFSET));
283283

284+
let fp_f = F::from_canonical_u32(fp);
285+
284286
// Determine which registers to read based on opcode
285287
let (pc_source_record, pc_source_data) = match local_opcode {
286288
JaafOpcode::RET | JaafOpcode::CALL_INDIRECT => {
287289
// Read pc_source (c field) for target PC
288-
let pc_source = memory.read::<RV32_REGISTER_NUM_LIMBS>(F::ONE, c);
290+
let pc_source = memory.read::<RV32_REGISTER_NUM_LIMBS>(F::ONE, c + fp_f);
289291
(Some(pc_source.0), pc_source.1)
290292
}
291293
_ => {
@@ -296,7 +298,7 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for JaafAdapterChipWom<F> {
296298
};
297299

298300
// All opcodes always read fp_source (e field) for target FP
299-
let fp_source = memory.read::<RV32_REGISTER_NUM_LIMBS>(F::ONE, e);
301+
let fp_source = memory.read::<RV32_REGISTER_NUM_LIMBS>(F::ONE, e + fp_f);
300302

301303
Ok((
302304
[pc_source_data, fp_source.1],
@@ -325,6 +327,8 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for JaafAdapterChipWom<F> {
325327
..
326328
} = *instruction;
327329

330+
let to_fp = output.to_fp.unwrap();
331+
328332
let local_opcode =
329333
JaafOpcode::from_usize(opcode.local_opcode_idx(JaafOpcode::CLASS_OFFSET));
330334

@@ -340,13 +344,16 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for JaafAdapterChipWom<F> {
340344
JaafOpcode::JAAF_SAVE => {
341345
// Save fp to rd2 (b field)
342346
memory.increment_timestamp();
343-
let rd2 = memory.write(F::ONE, b, output.writes[1]);
347+
let rd2 =
348+
memory.write(F::ONE, b + F::from_canonical_u32(to_fp), output.writes[1]);
344349
(None, Some(rd2.0))
345350
}
346351
JaafOpcode::CALL | JaafOpcode::CALL_INDIRECT => {
347352
// Save both pc to rd1 (a field) and fp to rd2 (b field)
348-
let rd1 = memory.write(F::ONE, a, output.writes[0]);
349-
let rd2 = memory.write(F::ONE, b, output.writes[1]);
353+
let rd1 =
354+
memory.write(F::ONE, a + F::from_canonical_u32(to_fp), output.writes[0]);
355+
let rd2 =
356+
memory.write(F::ONE, b + F::from_canonical_u32(to_fp), output.writes[1]);
350357
(Some(rd1.0), Some(rd2.0))
351358
}
352359
}
@@ -361,7 +368,7 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for JaafAdapterChipWom<F> {
361368
pc: output.to_pc.unwrap_or(from_state.pc + DEFAULT_PC_STEP),
362369
timestamp: memory.timestamp(),
363370
},
364-
output.to_fp.unwrap_or(from_frame.fp),
371+
to_fp,
365372
Self::WriteRecord {
366373
from_state,
367374
from_frame,

extensions/circuit/src/adapters/jump.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for JumpAdapterChipWom<F> {
192192
fn preprocess(
193193
&mut self,
194194
memory: &mut MemoryController<F>,
195-
_fp: u32,
195+
fp: u32,
196196
instruction: &Instruction<F>,
197197
) -> Result<(
198198
<Self::Interface as VmAdapterInterface<F>>::Reads,
@@ -203,11 +203,13 @@ impl<F: PrimeField32> VmAdapterChipWom<F> for JumpAdapterChipWom<F> {
203203
let local_opcode =
204204
JumpOpcode::from_usize(opcode.local_opcode_idx(JumpOpcode::CLASS_OFFSET));
205205

206+
let fp_f = F::from_canonical_u32(fp);
207+
206208
// Determine which registers to read based on opcode
207209
let (condition_record, condition_data) = match local_opcode {
208210
JumpOpcode::JUMP_IF | JumpOpcode::JUMP_IF_ZERO => {
209211
// Read condition (b field) for conditional jumps
210-
let condition = memory.read::<RV32_REGISTER_NUM_LIMBS>(F::ONE, b);
212+
let condition = memory.read::<RV32_REGISTER_NUM_LIMBS>(F::ONE, b + fp_f);
211213
(Some(condition.0), condition.1)
212214
}
213215
_ => {

integration/src/instruction_builder.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,24 @@ pub fn reveal<F: PrimeField32>(rs1_data: usize, rd_index: usize) -> Instruction<
308308
)
309309
}
310310

311+
#[allow(dead_code)]
312+
pub fn reveal_imm<F: PrimeField32>(
313+
data_reg: usize,
314+
output_index_reg: usize,
315+
output_index_imm: usize,
316+
) -> Instruction<F> {
317+
Instruction::new(
318+
Rv32LoadStoreOpcode::STOREW.global_opcode(),
319+
F::from_canonical_usize(riscv::RV32_REGISTER_NUM_LIMBS * data_reg),
320+
F::from_canonical_usize(riscv::RV32_REGISTER_NUM_LIMBS * output_index_reg),
321+
F::from_canonical_usize(output_index_imm),
322+
F::ONE,
323+
F::from_canonical_usize(3),
324+
F::ONE,
325+
F::ZERO,
326+
)
327+
}
328+
311329
#[allow(dead_code)]
312330
pub fn halt<F: PrimeField32>() -> Instruction<F> {
313331
Instruction::new(

integration/src/womir_translation.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,37 +114,39 @@ fn create_startup_code<F>(ctx: &CommonProgram, entry_point: &LabelValue) -> Vec<
114114
where
115115
F: PrimeField32,
116116
{
117-
let mut code = vec![ib::allocate_frame_imm(
118-
0,
119-
entry_point.frame_size.unwrap() as usize,
120-
)];
117+
let fn_fp = 1;
118+
let zero_reg = 0;
119+
let mut code = vec![
120+
ib::allocate_frame_imm(fn_fp, entry_point.frame_size.unwrap() as usize),
121+
ib::const_32_imm(zero_reg, 0, 0),
122+
];
121123

122124
let entry_point_func_type = &ctx.get_func_type(entry_point.func_idx.unwrap()).ty;
123125

124126
// If the entry point function has arguments, we need to fill them with the result from read32
125127
let params = entry_point_func_type.params();
126128
let num_input_words = womir::word_count_types::<GenericIrSetting>(params);
127-
// This is a little hacky because we know the initial first allocated frame starts at 1,
129+
// This is a little hacky because we know the initial first allocated frame starts at 2,
128130
// so we can just write directly into it by calculating the offset.
129-
// address 1: reserved for return address
130-
// address 2: reserved for frame pointer
131-
// address 3: first argument
132-
// address 3 + i: i-th argument
133-
let mut ptr = 3;
131+
// address 2: reserved for return address
132+
// address 3: reserved for frame pointer
133+
// address 4: first argument
134+
// address 4 + i: i-th argument
135+
let mut ptr = 4;
134136
for _ in 0..num_input_words {
135137
//code.push(ib::read32(ptr as usize));
136138
code.push(ib::const_32_imm(ptr as usize, 10, 0));
137139
ptr += 1;
138140
}
139141

140-
code.push(ib::call(0, 1, entry_point.pc as usize, 0));
142+
code.push(ib::call(0, 1, entry_point.pc as usize, fn_fp));
141143

142144
// We can also read the return values directly from the function's frame, which happens
143145
// to be right after the arguments.
144146
let results = entry_point_func_type.results();
145147
let num_output_words = womir::word_count_types::<GenericIrSetting>(results);
146148
for i in 0..num_output_words {
147-
code.push(ib::reveal(ptr as usize, i as usize));
149+
code.push(ib::reveal_imm(ptr as usize, zero_reg, i as usize));
148150
ptr += 1;
149151
}
150152

0 commit comments

Comments
 (0)