134 lines
2.9 KiB
NASM
Raw Normal View History

// Copies `count` values from
// SRC = (src_ctx, src_segment, src_addr)
// to
// DST = (dst_ctx, dst_segment, dst_addr).
// These tuple definitions are used for brevity in the stack comments below.
global memcpy:
// stack: DST, SRC, count, retdest
DUP7
// stack: count, DST, SRC, count, retdest
ISZERO
// stack: count == 0, DST, SRC, count, retdest
%jumpi(memcpy_finish)
// stack: DST, SRC, count, retdest
// Copy the next value.
DUP6
DUP6
DUP6
// stack: SRC, DST, SRC, count, retdest
MLOAD_GENERAL
// stack: value, DST, SRC, count, retdest
DUP4
DUP4
DUP4
// stack: DST, value, DST, SRC, count, retdest
MSTORE_GENERAL
// stack: DST, SRC, count, retdest
// Increment dst_addr.
SWAP2
%increment
SWAP2
// Increment src_addr.
SWAP5
%increment
SWAP5
// Decrement count.
SWAP6
%decrement
SWAP6
// Continue the loop.
%jump(memcpy)
2023-04-25 17:19:44 -07:00
%macro memcpy
%stack (dst: 3, src: 3, count) -> (dst, src, count, %%after)
%jump(memcpy)
%%after:
%endmacro
2023-10-23 07:16:39 -04:00
// Similar logic to memcpy, but optimized for copying sequences of bytes.
global memcpy_bytes:
// stack: DST, SRC, count, retdest
2023-10-23 19:12:54 -04:00
// Handle empty case
DUP7
// stack: count, DST, SRC, count, retdest
ISZERO
// stack: count == 0, DST, SRC, count, retdest
2023-10-26 11:21:10 -04:00
%jumpi(memcpy_finish)
2023-10-23 19:12:54 -04:00
// stack: DST, SRC, count, retdest
// Handle small case
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
2023-10-26 11:21:10 -04:00
memcpy_finish:
// stack: DST, SRC, count, retdest
2023-10-23 19:12:54 -04:00
%pop7
// stack: retdest
JUMP
%macro memcpy_bytes
%stack (dst: 3, src: 3, count) -> (dst, src, count, %%after)
%jump(memcpy_bytes)
%%after:
2023-10-23 07:16:39 -04:00
%endmacro