openvm_rv32im_circuit/adapters/
mod.rs
1use std::ops::Mul;
2
3use openvm_circuit::system::memory::{MemoryController, RecordId};
4use openvm_stark_backend::p3_field::{FieldAlgebra, PrimeField32};
5
6mod alu;
7mod branch;
8mod jalr;
9mod loadstore;
10mod mul;
11mod rdwrite;
12
13pub use alu::*;
14pub use branch::*;
15pub use jalr::*;
16pub use loadstore::*;
17pub use mul::*;
18pub use openvm_instructions::riscv::{RV32_CELL_BITS, RV32_REGISTER_NUM_LIMBS};
19pub use rdwrite::*;
20
21pub const INT256_NUM_LIMBS: usize = 32;
23
24pub const RV_IS_TYPE_IMM_BITS: usize = 12;
26
27pub const RV_B_TYPE_IMM_BITS: usize = 13;
29
30pub const RV_J_TYPE_IMM_BITS: usize = 21;
31
32pub fn compose<F: PrimeField32>(ptr_data: [F; RV32_REGISTER_NUM_LIMBS]) -> u32 {
35 let mut val = 0;
36 for (i, limb) in ptr_data.map(|x| x.as_canonical_u32()).iter().enumerate() {
37 val += limb << (i * 8);
38 }
39 val
40}
41
42pub fn decompose<F: PrimeField32>(value: u32) -> [F; RV32_REGISTER_NUM_LIMBS] {
44 std::array::from_fn(|i| {
45 F::from_canonical_u32((value >> (RV32_CELL_BITS * i)) & ((1 << RV32_CELL_BITS) - 1))
46 })
47}
48
49pub fn read_rv32_register<F: PrimeField32>(
53 memory: &mut MemoryController<F>,
54 address_space: F,
55 pointer: F,
56) -> (RecordId, u32) {
57 debug_assert_eq!(address_space, F::ONE);
58 let record = memory.read::<RV32_REGISTER_NUM_LIMBS>(address_space, pointer);
59 let val = compose(record.1);
60 (record.0, val)
61}
62
63pub fn unsafe_read_rv32_register<F: PrimeField32>(memory: &MemoryController<F>, pointer: F) -> u32 {
65 let data = memory.unsafe_read::<RV32_REGISTER_NUM_LIMBS>(F::ONE, pointer);
66 compose(data)
67}
68
69pub fn abstract_compose<T: FieldAlgebra, V: Mul<T, Output = T>>(
70 data: [V; RV32_REGISTER_NUM_LIMBS],
71) -> T {
72 data.into_iter()
73 .enumerate()
74 .fold(T::ZERO, |acc, (i, limb)| {
75 acc + limb * T::from_canonical_u32(1 << (i * RV32_CELL_BITS))
76 })
77}