diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 7f34f90b..4c8a1173 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -23,7 +23,9 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/curve/secp256k1/moddiv.asm"), include_str!("asm/exp.asm"), include_str!("asm/halt.asm"), - include_str!("asm/memory.asm"), + include_str!("asm/memory/core.asm"), + include_str!("asm/memory/memcpy.asm"), + include_str!("asm/memory/txn_fields.asm"), include_str!("asm/rlp/encode.asm"), include_str!("asm/rlp/decode.asm"), include_str!("asm/rlp/read_to_memory.asm"), diff --git a/evm/src/cpu/kernel/asm/memory.asm b/evm/src/cpu/kernel/asm/memory/core.asm similarity index 64% rename from evm/src/cpu/kernel/asm/memory.asm rename to evm/src/cpu/kernel/asm/memory/core.asm index 81474d12..2c896345 100644 --- a/evm/src/cpu/kernel/asm/memory.asm +++ b/evm/src/cpu/kernel/asm/memory/core.asm @@ -26,10 +26,10 @@ // stack: (empty) %endmacro -// Load a single byte from kernel code. -%macro mload_kernel_code +// Load a single value from the given segment of kernel (context 0) memory. +%macro mload_kernel(segment) // stack: offset - PUSH @SEGMENT_CODE + PUSH $segment // stack: segment, offset PUSH 0 // kernel has context 0 // stack: context, segment, offset @@ -37,6 +37,24 @@ // stack: value %endmacro +// Store a single value from the given segment of kernel (context 0) memory. +%macro mstore_kernel(segment) + // stack: offset, value + PUSH $segment + // stack: segment, offset, value + PUSH 0 // kernel has context 0 + // stack: context, segment, offset, value + MSTORE_GENERAL + // stack: (empty) +%endmacro + +// Load a single byte from kernel code. +%macro mload_kernel_code + // stack: offset + %mload_kernel(@SEGMENT_CODE) + // stack: value +%endmacro + // Load a big-endian u32, consisting of 4 bytes (c_3, c_2, c_1, c_0), // from kernel code. %macro mload_kernel_code_u32 @@ -67,54 +85,9 @@ // stack: (((((c_3 << 8) | c_2) << 8) | c_1) << 8) | c_0 %endmacro -// 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: - JUMPDEST - // 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 - %add_const(1) - SWAP2 - // Increment src_addr. - SWAP5 - %add_const(1) - SWAP5 - // Decrement count. - SWAP6 - %sub_const(1) - SWAP6 - - // Continue the loop. - %jump(memcpy) - -memcpy_finish: - JUMPDEST - // stack: DST, SRC, count, retdest - %pop7 - // stack: retdest - JUMP +// Store a single byte to kernel code. +%macro mstore_kernel_code + // stack: offset, value + %mstore_kernel(@SEGMENT_CODE) + // stack: (empty) +%endmacro diff --git a/evm/src/cpu/kernel/asm/memory/memcpy.asm b/evm/src/cpu/kernel/asm/memory/memcpy.asm new file mode 100644 index 00000000..0a390736 --- /dev/null +++ b/evm/src/cpu/kernel/asm/memory/memcpy.asm @@ -0,0 +1,51 @@ +// 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: + JUMPDEST + // 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 + %add_const(1) + SWAP2 + // Increment src_addr. + SWAP5 + %add_const(1) + SWAP5 + // Decrement count. + SWAP6 + %sub_const(1) + SWAP6 + + // Continue the loop. + %jump(memcpy) + +memcpy_finish: + JUMPDEST + // stack: DST, SRC, count, retdest + %pop7 + // stack: retdest + JUMP diff --git a/evm/src/cpu/kernel/asm/memory/metadata.asm b/evm/src/cpu/kernel/asm/memory/metadata.asm new file mode 100644 index 00000000..22eb853f --- /dev/null +++ b/evm/src/cpu/kernel/asm/memory/metadata.asm @@ -0,0 +1,35 @@ +// Load the given global metadata field from memory. +%macro mload_global_metadata(field) + // stack: (empty) + PUSH $field + // stack: offset + %mload_kernel(@SEGMENT_GLOBAL_METADATA) + // stack: value +%endmacro + +// Store the given global metadata field to memory. +%macro mstore_global_metadata(field) + // stack: value + PUSH $field + // stack: offset, value + %mload_kernel(@SEGMENT_GLOBAL_METADATA) + // stack: (empty) +%endmacro + +// Load the given context metadata field from memory. +%macro mload_context_metadata(field) + // stack: (empty) + PUSH $field + // stack: offset + %mload_current(@SEGMENT_CONTEXT_METADATA) + // stack: value +%endmacro + +// Store the given context metadata field to memory. +%macro mstore_context_metadata(field) + // stack: value + PUSH $field + // stack: offset, value + %mload_current(@SEGMENT_CONTEXT_METADATA) + // stack: (empty) +%endmacro diff --git a/evm/src/cpu/kernel/asm/memory/txn_fields.asm b/evm/src/cpu/kernel/asm/memory/txn_fields.asm new file mode 100644 index 00000000..d15b7264 --- /dev/null +++ b/evm/src/cpu/kernel/asm/memory/txn_fields.asm @@ -0,0 +1,17 @@ +// Load the given normalized transaction field from memory. +%macro mload_txn_field(field) + // stack: (empty) + PUSH $field + // stack: offset + %mload_kernel(@SEGMENT_NORMALIZED_TXN) + // stack: value +%endmacro + +// Store the given normalized transaction field to memory. +%macro mstore_txn_field(field) + // stack: value + PUSH $field + // stack: offset, value + %mstore_kernel(@SEGMENT_NORMALIZED_TXN) + // stack: (empty) +%endmacro