mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 06:43:07 +00:00
Merge pull request #660 from mir-protocol/packing
Packing memory operations
This commit is contained in:
commit
68de3ee0c6
@ -25,6 +25,8 @@ pub(crate) fn combined_kernel() -> Kernel {
|
|||||||
include_str!("asm/halt.asm"),
|
include_str!("asm/halt.asm"),
|
||||||
include_str!("asm/memory/core.asm"),
|
include_str!("asm/memory/core.asm"),
|
||||||
include_str!("asm/memory/memcpy.asm"),
|
include_str!("asm/memory/memcpy.asm"),
|
||||||
|
include_str!("asm/memory/metadata.asm"),
|
||||||
|
include_str!("asm/memory/packing.asm"),
|
||||||
include_str!("asm/memory/txn_fields.asm"),
|
include_str!("asm/memory/txn_fields.asm"),
|
||||||
include_str!("asm/rlp/encode.asm"),
|
include_str!("asm/rlp/encode.asm"),
|
||||||
include_str!("asm/rlp/decode.asm"),
|
include_str!("asm/rlp/decode.asm"),
|
||||||
|
|||||||
45
evm/src/cpu/kernel/asm/memory/packing.asm
Normal file
45
evm/src/cpu/kernel/asm/memory/packing.asm
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Methods for encoding integers as bytes in memory, as well as the reverse,
|
||||||
|
// decoding bytes as integers. All big-endian.
|
||||||
|
|
||||||
|
global mload_packing:
|
||||||
|
// stack: context, segment, offset, len, retdest
|
||||||
|
// TODO
|
||||||
|
// stack: value
|
||||||
|
|
||||||
|
global mstore_unpacking:
|
||||||
|
// stack: context, segment, offset, value, len, retdest
|
||||||
|
// We will enumerate i in (32 - len)..32.
|
||||||
|
// That way BYTE(i, value) will give us the bytes we want.
|
||||||
|
DUP5 // len
|
||||||
|
PUSH 32
|
||||||
|
SUB
|
||||||
|
|
||||||
|
mstore_unpacking_loop:
|
||||||
|
// stack: i, context, segment, offset, value, len, retdest
|
||||||
|
// If i == 32, finish.
|
||||||
|
DUP1
|
||||||
|
%eq_const(32)
|
||||||
|
%jumpi(mstore_unpacking_finish)
|
||||||
|
|
||||||
|
// stack: i, context, segment, offset, value, len, retdest
|
||||||
|
DUP5 // value
|
||||||
|
DUP2 // i
|
||||||
|
BYTE
|
||||||
|
// stack: value[i], i, context, segment, offset, value, len, retdest
|
||||||
|
DUP5 DUP5 DUP5 // context, segment, offset
|
||||||
|
// stack: context, segment, offset, value[i], i, context, segment, offset, value, len, retdest
|
||||||
|
MSTORE_GENERAL
|
||||||
|
// stack: i, context, segment, offset, value, len, retdest
|
||||||
|
|
||||||
|
// Increment offset.
|
||||||
|
SWAP3 %add_const(1) SWAP3
|
||||||
|
// Increment i.
|
||||||
|
%add_const(1)
|
||||||
|
|
||||||
|
%jump(mstore_unpacking_loop)
|
||||||
|
|
||||||
|
mstore_unpacking_finish:
|
||||||
|
// stack: i, context, segment, offset, value, len, retdest
|
||||||
|
%pop6
|
||||||
|
// stack: retdest
|
||||||
|
JUMP
|
||||||
@ -196,7 +196,7 @@ impl<'a> Interpreter<'a> {
|
|||||||
0x17 => self.run_or(), // "OR",
|
0x17 => self.run_or(), // "OR",
|
||||||
0x18 => self.run_xor(), // "XOR",
|
0x18 => self.run_xor(), // "XOR",
|
||||||
0x19 => self.run_not(), // "NOT",
|
0x19 => self.run_not(), // "NOT",
|
||||||
0x1a => todo!(), // "BYTE",
|
0x1a => self.run_byte(), // "BYTE",
|
||||||
0x1b => self.run_shl(), // "SHL",
|
0x1b => self.run_shl(), // "SHL",
|
||||||
0x1c => todo!(), // "SHR",
|
0x1c => todo!(), // "SHR",
|
||||||
0x1d => todo!(), // "SAR",
|
0x1d => todo!(), // "SAR",
|
||||||
@ -380,6 +380,20 @@ impl<'a> Interpreter<'a> {
|
|||||||
self.push(!x);
|
self.push(!x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_byte(&mut self) {
|
||||||
|
dbg!("byte");
|
||||||
|
let i = self.pop();
|
||||||
|
let x = self.pop();
|
||||||
|
let result = if i > 32.into() {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
let mut bytes = [0; 32];
|
||||||
|
x.to_big_endian(&mut bytes);
|
||||||
|
bytes[i.as_usize()]
|
||||||
|
};
|
||||||
|
self.push(result.into());
|
||||||
|
}
|
||||||
|
|
||||||
fn run_shl(&mut self) {
|
fn run_shl(&mut self) {
|
||||||
let shift = self.pop();
|
let shift = self.pop();
|
||||||
let x = self.pop();
|
let x = self.pop();
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
mod curve_ops;
|
mod curve_ops;
|
||||||
mod ecrecover;
|
mod ecrecover;
|
||||||
mod exp;
|
mod exp;
|
||||||
|
mod packing;
|
||||||
mod rlp;
|
mod rlp;
|
||||||
mod transaction_parsing;
|
mod transaction_parsing;
|
||||||
|
|
||||||
|
|||||||
29
evm/src/cpu/kernel/tests/packing.rs
Normal file
29
evm/src/cpu/kernel/tests/packing.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use crate::cpu::kernel::aggregator::KERNEL;
|
||||||
|
use crate::cpu::kernel::interpreter::Interpreter;
|
||||||
|
use crate::memory::segments::Segment;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mstore_unpacking() -> Result<()> {
|
||||||
|
let mstore_unpacking = KERNEL.global_labels["mstore_unpacking"];
|
||||||
|
|
||||||
|
let retdest = 0xDEADBEEFu32.into();
|
||||||
|
let len = 4.into();
|
||||||
|
let value = 0xABCD1234u32.into();
|
||||||
|
let offset = 0.into();
|
||||||
|
let segment = (Segment::TxnData as u32).into();
|
||||||
|
let context = 0.into();
|
||||||
|
let initial_stack = vec![retdest, len, value, offset, segment, context];
|
||||||
|
|
||||||
|
let mut interpreter = Interpreter::new_with_kernel(mstore_unpacking, initial_stack);
|
||||||
|
|
||||||
|
interpreter.run()?;
|
||||||
|
assert_eq!(interpreter.stack(), vec![]);
|
||||||
|
assert_eq!(
|
||||||
|
&interpreter.get_txn_data(),
|
||||||
|
&[0xAB.into(), 0xCD.into(), 0x12.into(), 0x34.into()]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user