diff --git a/evm/src/cpu/kernel/asm/memory/memcpy.asm b/evm/src/cpu/kernel/asm/memory/memcpy.asm index fafec70465..cc872b1088 100644 --- a/evm/src/cpu/kernel/asm/memory/memcpy.asm +++ b/evm/src/cpu/kernel/asm/memory/memcpy.asm @@ -53,3 +53,74 @@ memcpy_finish: %jump(memcpy) %%after: %endmacro + +// Similar logic than memcpy, but optimized for copying sequences of bytes. +global memcpy_bytes: + // stack: DST, SRC, count, retdest + DUP7 + // stack: count, DST, SRC, count, retdest + %lt_const(0x20) + // stack: count < 32, DST, SRC, count, retdest + %jumpi(memcpy_bytes_finish) + + // We will pack 32 bytes into a U256 from the source, and then unpack it at the destination. + // Copy the next chunk of bytes. + PUSH 32 + DUP1 + DUP8 + DUP8 + DUP8 + // stack: SRC, 32, 32, DST, SRC, count, retdest + MLOAD_32BYTES + // stack: value, 32, DST, SRC, count, retdest + DUP5 + DUP5 + DUP5 + // stack: DST, value, 32, DST, SRC, count, retdest + MSTORE_32BYTES + // stack: DST, SRC, count, retdest + + // Increment dst_addr by 32. + SWAP2 + %add_const(0x20) + SWAP2 + // Increment src_addr by 32. + SWAP5 + %add_const(0x20) + SWAP5 + // Decrement count by 32. + SWAP6 + %sub_const(0x20) + SWAP6 + + // Continue the loop. + %jump(memcpy_bytes) + +memcpy_bytes_finish: + // stack: DST, SRC, count, retdest + + // Copy the last chunk of `count` bytes. + DUP7 + DUP1 + DUP8 + DUP8 + DUP8 + // stack: SRC, count, count, DST, SRC, count, retdest + MLOAD_32BYTES + // stack: value, count, DST, SRC, count, retdest + DUP5 + DUP5 + DUP5 + // stack: DST, value, count, DST, SRC, count, retdest + MSTORE_32BYTES + // stack: DST, SRC, count, retdest + + %pop7 + // stack: retdest + JUMP + +%macro memcpy_bytes + %stack (dst: 3, src: 3, count) -> (dst, src, count, %%after) + %jump(memcpy_bytes) +%%after: +%endmacro \ No newline at end of file diff --git a/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm b/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm index 8935b7f3f9..767927fbc6 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm @@ -116,7 +116,7 @@ global encode_txn: 0, @SEGMENT_TRIE_DATA, txn_rlp_ptr, // src addr. Kernel has context 0 txn_rlp_len, // mcpy len txn_rlp_len, rlp_pos) - %memcpy + %memcpy_bytes ADD // stack new_rlp_pos, retdest SWAP1 diff --git a/evm/src/cpu/kernel/asm/transactions/router.asm b/evm/src/cpu/kernel/asm/transactions/router.asm index c01216fb11..109334dd0d 100644 --- a/evm/src/cpu/kernel/asm/transactions/router.asm +++ b/evm/src/cpu/kernel/asm/transactions/router.asm @@ -57,7 +57,7 @@ global update_txn_trie: 0, @SEGMENT_RLP_RAW, 0, // src addr. Kernel has context 0 txn_rlp_len, // mcpy len txn_rlp_len, rlp_start, txn_counter, num_nibbles, value_ptr) - %memcpy + %memcpy_bytes ADD %set_trie_data_size // stack: txn_counter, num_nibbles, value_ptr, retdest