Skip to content

Commit 9558236

Browse files
committed
fix: add memcpy to toolchain
1 parent b052ac5 commit 9558236

File tree

10 files changed

+500
-462
lines changed

10 files changed

+500
-462
lines changed

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ openvm-ecc-sw-macros = { path = "extensions/ecc/sw-macros", default-features = f
169169
openvm-pairing-circuit = { path = "extensions/pairing/circuit", default-features = false }
170170
openvm-pairing-transpiler = { path = "extensions/pairing/transpiler", default-features = false }
171171
openvm-pairing-guest = { path = "extensions/pairing/guest", default-features = false }
172+
openvm-memcpy-circuit = { path = "extensions/memcpy/circuit", default-features = false }
173+
openvm-memcpy-transpiler = { path = "extensions/memcpy/transpiler", default-features = false }
172174
openvm-verify-stark = { path = "guest-libs/verify_stark", default-features = false }
173175

174176
# Benchmarking

benchmarks/execute/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ openvm-pairing-guest.workspace = true
2424
openvm-pairing-transpiler.workspace = true
2525
openvm-keccak256-circuit.workspace = true
2626
openvm-keccak256-transpiler.workspace = true
27+
openvm-memcpy-circuit.workspace = true
28+
openvm-memcpy-transpiler.workspace = true
2729
openvm-rv32im-circuit.workspace = true
2830
openvm-rv32im-transpiler.workspace = true
2931
openvm-sha256-circuit.workspace = true

benchmarks/execute/benches/execute.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ use openvm_ecc_circuit::{EccCpuProverExt, WeierstrassExtension, WeierstrassExten
2626
use openvm_ecc_transpiler::EccTranspilerExtension;
2727
use openvm_keccak256_circuit::{Keccak256, Keccak256CpuProverExt, Keccak256Executor};
2828
use openvm_keccak256_transpiler::Keccak256TranspilerExtension;
29+
use openvm_memcpy_circuit::{Memcpy, MemcpyCpuProverExt, MemcpyExecutor};
30+
use openvm_memcpy_transpiler::MemcpyTranspilerExtension;
2931
use openvm_native_circuit::{NativeConfig, NativeCpuBuilder, NATIVE_MAX_TRACE_HEIGHTS};
3032
use openvm_pairing_circuit::{
3133
PairingCurve, PairingExtension, PairingExtensionExecutor, PairingProverExt,
@@ -91,6 +93,8 @@ pub struct ExecuteConfig {
9193
#[extension]
9294
pub keccak: Keccak256,
9395
#[extension]
96+
pub memcpy: Memcpy,
97+
#[extension]
9498
pub sha256: Sha256,
9599
#[extension]
96100
pub modular: ModularExtension,
@@ -112,6 +116,7 @@ impl Default for ExecuteConfig {
112116
io: Rv32Io,
113117
bigint: Int256::default(),
114118
keccak: Keccak256,
119+
memcpy: Memcpy,
115120
sha256: Sha256,
116121
modular: ModularExtension::new(vec![
117122
bn_config.modulus.clone(),
@@ -172,6 +177,7 @@ where
172177
&config.keccak,
173178
inventory,
174179
)?;
180+
VmProverExtension::<E, _, _>::extend_prover(&MemcpyCpuProverExt, &config.memcpy, inventory)?;
175181
VmProverExtension::<E, _, _>::extend_prover(&Sha2CpuProverExt, &config.sha256, inventory)?;
176182
VmProverExtension::<E, _, _>::extend_prover(
177183
&AlgebraCpuProverExt,
@@ -200,6 +206,7 @@ fn create_default_transpiler() -> Transpiler<BabyBear> {
200206
.with_extension(Rv32MTranspilerExtension)
201207
.with_extension(Int256TranspilerExtension)
202208
.with_extension(Keccak256TranspilerExtension)
209+
.with_extension(MemcpyTranspilerExtension)
203210
.with_extension(Sha256TranspilerExtension)
204211
.with_extension(ModularTranspilerExtension)
205212
.with_extension(Fp2TranspilerExtension)

crates/sdk/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ openvm-ecc-circuit = { workspace = true }
1818
openvm-ecc-transpiler = { workspace = true }
1919
openvm-keccak256-circuit = { workspace = true }
2020
openvm-keccak256-transpiler = { workspace = true }
21+
openvm-memcpy-circuit = { workspace = true }
22+
openvm-memcpy-transpiler = { workspace = true }
2123
openvm-sha256-circuit = { workspace = true }
2224
openvm-sha256-transpiler = { workspace = true }
2325
openvm-pairing-circuit = { workspace = true }

crates/sdk/src/config/global.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ use openvm_rv32im_circuit::{
3232
use openvm_rv32im_transpiler::{
3333
Rv32ITranspilerExtension, Rv32IoTranspilerExtension, Rv32MTranspilerExtension,
3434
};
35+
use openvm_memcpy_circuit::{Memcpy, MemcpyCpuProverExt, MemcpyExecutor};
36+
use openvm_memcpy_transpiler::MemcpyTranspilerExtension;
3537
use openvm_sha256_circuit::{Sha256, Sha256Executor, Sha2CpuProverExt};
3638
use openvm_sha256_transpiler::Sha256TranspilerExtension;
3739
use openvm_stark_backend::{
@@ -52,6 +54,7 @@ pub struct SdkVmConfig {
5254
pub rv32i: Option<UnitStruct>,
5355
pub io: Option<UnitStruct>,
5456
pub keccak: Option<UnitStruct>,
57+
pub memcpy: Option<UnitStruct>,
5558
pub sha256: Option<UnitStruct>,
5659
pub native: Option<UnitStruct>,
5760
pub castf: Option<UnitStruct>,
@@ -79,6 +82,8 @@ pub struct SdkVmConfigInner {
7982
pub io: Option<Rv32Io>,
8083
#[extension(executor = "Keccak256Executor")]
8184
pub keccak: Option<Keccak256>,
85+
#[extension(executor = "MemcpyExecutor")]
86+
pub memcpy: Option<Memcpy>,
8287
#[extension(executor = "Sha256Executor")]
8388
pub sha256: Option<Sha256>,
8489
#[extension(executor = "NativeExecutor<F>")]
@@ -115,6 +120,9 @@ impl SdkVmConfig {
115120
if self.keccak.is_some() {
116121
transpiler = transpiler.with_extension(Keccak256TranspilerExtension);
117122
}
123+
if self.memcpy.is_some() {
124+
transpiler = transpiler.with_extension(MemcpyTranspilerExtension);
125+
}
118126
if self.sha256.is_some() {
119127
transpiler = transpiler.with_extension(Sha256TranspilerExtension);
120128
}
@@ -166,6 +174,7 @@ impl SdkVmConfig {
166174
let rv32i = self.rv32i.map(|_| Rv32I);
167175
let io = self.io.map(|_| Rv32Io);
168176
let keccak = self.keccak.map(|_| Keccak256);
177+
let memcpy = self.memcpy.map(|_| Memcpy);
169178
let sha256 = self.sha256.map(|_| Sha256);
170179
let native = self.native.map(|_| Native);
171180
let castf = self.castf.map(|_| CastFExtension);
@@ -190,6 +199,7 @@ impl SdkVmConfig {
190199
rv32i,
191200
io,
192201
keccak,
202+
memcpy,
193203
sha256,
194204
native,
195205
castf,
@@ -256,6 +266,9 @@ where
256266
if let Some(keccak) = &config.keccak {
257267
VmProverExtension::<E, _, _>::extend_prover(&Keccak256CpuProverExt, keccak, inventory)?;
258268
}
269+
if let Some(memcpy) = &config.memcpy {
270+
VmProverExtension::<E, _, _>::extend_prover(&MemcpyCpuProverExt, memcpy, inventory)?;
271+
}
259272
if let Some(sha256) = &config.sha256 {
260273
VmProverExtension::<E, _, _>::extend_prover(&Sha2CpuProverExt, sha256, inventory)?;
261274
}
@@ -373,6 +386,12 @@ impl From<Keccak256> for UnitStruct {
373386
}
374387
}
375388

389+
impl From<Memcpy> for UnitStruct {
390+
fn from(_: Memcpy) -> Self {
391+
UnitStruct {}
392+
}
393+
}
394+
376395
impl From<Sha256> for UnitStruct {
377396
fn from(_: Sha256) -> Self {
378397
UnitStruct {}
@@ -399,6 +418,7 @@ struct SdkVmConfigWithDefaultDeser {
399418
pub rv32i: Option<UnitStruct>,
400419
pub io: Option<UnitStruct>,
401420
pub keccak: Option<UnitStruct>,
421+
pub memcpy: Option<UnitStruct>,
402422
pub sha256: Option<UnitStruct>,
403423
pub native: Option<UnitStruct>,
404424
pub castf: Option<UnitStruct>,
@@ -424,6 +444,7 @@ impl From<SdkVmConfigWithDefaultDeser> for SdkVmConfig {
424444
rv32i: config.rv32i,
425445
io: config.io,
426446
keccak: config.keccak,
447+
memcpy: config.memcpy,
427448
sha256: config.sha256,
428449
native: config.native,
429450
castf: config.castf,

crates/toolchain/openvm/src/memcpy.s

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@
205205
.attribute 4, 16
206206
.attribute 5, "rv32im"
207207
.file "musl_memcpy.c"
208+
209+
# Define memcpy_loop macro for custom instruction (U-type)
210+
.macro memcpy_loop shift
211+
.word 0x72000000 | (\shift << 12) # opcode 0x72 + shift in immediate field (bits 12-31)
212+
.endm
208213
.globl memcpy
209214
.p2align 2
210215
.type memcpy,@function

extensions/memcpy/circuit/src/core.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ pub type MemcpyLoopChip<F> = VmChipWrapper<F, MemcpyLoopFiller>;
311311
#[derive(AlignedBytesBorrow, Clone)]
312312
#[repr(C)]
313313
struct MemcpyLoopPreCompute {
314-
a: u8,
314+
c: u8,
315315
}
316316

317317
impl<F, RA> PreflightExecutor<F, RA> for MemcpyLoopExecutor
@@ -328,9 +328,9 @@ where
328328
state: VmStateMut<F, TracingMemory, RA>,
329329
instruction: &Instruction<F>,
330330
) -> Result<(), ExecutionError> {
331-
let Instruction { opcode, a, .. } = instruction;
331+
let Instruction { opcode, c, .. } = instruction;
332332
debug_assert_eq!(*opcode, Rv32MemcpyOpcode::MEMCPY_LOOP.global_opcode());
333-
let shift = a.as_canonical_u32() as u8;
333+
let shift = c.as_canonical_u32() as u8;
334334
debug_assert!([0, 1, 2, 3].contains(&shift));
335335
let mut record = state.ctx.alloc(EmptyMultiRowLayout::default());
336336

@@ -600,7 +600,7 @@ unsafe fn execute_e12_impl<F: PrimeField32, CTX: E1ExecutionCtx>(
600600
pre_compute: &MemcpyLoopPreCompute,
601601
vm_state: &mut VmExecState<F, GuestMemory, CTX>,
602602
) {
603-
let shift = pre_compute.a;
603+
let shift = pre_compute.c;
604604
let (dest, source) = if shift == 0 {
605605
(
606606
vm_state.vm_read::<u8, 4>(RV32_REGISTER_AS, A3_REGISTER_PTR as u32),
@@ -700,12 +700,12 @@ impl MemcpyLoopExecutor {
700700
inst: &Instruction<F>,
701701
data: &mut MemcpyLoopPreCompute,
702702
) -> Result<(), StaticProgramError> {
703-
let Instruction { opcode, a, .. } = inst;
704-
let a_u32 = a.as_canonical_u32();
705-
if ![0, 1, 2, 3].contains(&a_u32) {
703+
let Instruction { opcode, c, .. } = inst;
704+
let c_u32 = c.as_canonical_u32();
705+
if ![0, 1, 2, 3].contains(&c_u32) {
706706
return Err(StaticProgramError::InvalidInstruction(pc));
707707
}
708-
*data = MemcpyLoopPreCompute { a: a_u32 as u8 };
708+
*data = MemcpyLoopPreCompute { c: c_u32 as u8 };
709709
assert_eq!(*opcode, Rv32MemcpyOpcode::MEMCPY_LOOP.global_opcode());
710710
Ok(())
711711
}

0 commit comments

Comments
 (0)