plonky2/evm/src/cpu/kernel/asm/memory/metadata.asm
2023-09-07 09:43:59 +01:00

383 lines
9.1 KiB
NASM

// 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
%mstore_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
%mstore_current(@SEGMENT_CONTEXT_METADATA)
// stack: (empty)
%endmacro
// Store the given context metadata field to memory.
%macro mstore_context_metadata(field, value)
PUSH $value
PUSH $field
// stack: offset, value
%mstore_current(@SEGMENT_CONTEXT_METADATA)
// stack: (empty)
%endmacro
%macro mstore_parent_context_metadata(field)
// stack: value
%mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT)
%stack (parent_ctx, value) ->
(parent_ctx, @SEGMENT_CONTEXT_METADATA, $field, value)
MSTORE_GENERAL
// stack: (empty)
%endmacro
%macro mstore_parent_context_metadata(field, value)
// stack: (empty)
%mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT)
%stack (parent_ctx) ->
(parent_ctx, @SEGMENT_CONTEXT_METADATA, $field, $value)
MSTORE_GENERAL
// stack: (empty)
%endmacro
%macro address
%mload_context_metadata(@CTX_METADATA_ADDRESS)
%endmacro
global sys_address:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%address
// stack: address, kexit_info
SWAP1
EXIT_KERNEL
%macro caller
%mload_context_metadata(@CTX_METADATA_CALLER)
%endmacro
global sys_caller:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%caller
// stack: caller, kexit_info
SWAP1
EXIT_KERNEL
%macro callvalue
%mload_context_metadata(@CTX_METADATA_CALL_VALUE)
%endmacro
%macro codesize
%mload_context_metadata(@CTX_METADATA_CODE_SIZE)
%endmacro
global sys_codesize:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%codesize
// stack: codesize, kexit_info
SWAP1
EXIT_KERNEL
global sys_callvalue:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%callvalue
// stack: callvalue, kexit_info
SWAP1
EXIT_KERNEL
%macro mem_words
%mload_context_metadata(@CTX_METADATA_MEM_WORDS)
%endmacro
%macro msize
%mem_words
%mul_const(32)
%endmacro
global sys_msize:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%msize
// stack: msize, kexit_info
SWAP1
EXIT_KERNEL
%macro calldatasize
%mload_context_metadata(@CTX_METADATA_CALLDATA_SIZE)
%endmacro
global sys_calldatasize:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%calldatasize
// stack: calldatasize, kexit_info
SWAP1
EXIT_KERNEL
%macro returndatasize
%mload_context_metadata(@CTX_METADATA_RETURNDATA_SIZE)
%endmacro
global sys_returndatasize:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%returndatasize
// stack: returndatasize, kexit_info
SWAP1
EXIT_KERNEL
%macro coinbase
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_BENEFICIARY)
%endmacro
global sys_coinbase:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%coinbase
// stack: coinbase, kexit_info
SWAP1
EXIT_KERNEL
%macro timestamp
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_TIMESTAMP)
%endmacro
global sys_timestamp:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%timestamp
// stack: timestamp, kexit_info
SWAP1
EXIT_KERNEL
%macro blocknumber
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_NUMBER)
%endmacro
global sys_number:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%blocknumber
// stack: blocknumber, kexit_info
SWAP1
EXIT_KERNEL
%macro blockgaslimit
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_LIMIT)
%endmacro
global sys_gaslimit:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%blockgaslimit
// stack: blockgaslimit, kexit_info
SWAP1
EXIT_KERNEL
%macro blockchainid
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_CHAIN_ID)
%endmacro
global sys_chainid:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%blockchainid
// stack: chain_id, kexit_info
SWAP1
EXIT_KERNEL
%macro basefee
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_BASE_FEE)
%endmacro
global sys_basefee:
// stack: kexit_info
%charge_gas_const(@GAS_BASE)
// stack: kexit_info
%basefee
// stack: basefee, kexit_info
SWAP1
EXIT_KERNEL
global sys_blockhash:
// stack: kexit_info, block_number
%charge_gas_const(@GAS_BLOCKHASH)
SWAP1
// stack: block_number, kexit_info
%blockhash
EXIT_KERNEL
global blockhash:
// stack: block_number, retdest
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_NUMBER)
// stack: cur_block_number, block_number, retdest
DUP1 DUP3 %increment GT %jumpi(zero_hash) // if block_number >= cur_block_number
// stack: cur_block_number, block_number, retdest
DUP2 PUSH 256 ADD
// stack: block_number+256, cur_block_number, block_number, retdest
DUP2 GT %jumpi(zero_hash) // if cur_block_number > block_number + 256
// If we are here, the provided block number is correct
SUB
// stack: cur_block_number - block_number, retdest
PUSH 256 SUB
// stack: block_hash_number, retdest
%mload_kernel(@SEGMENT_BLOCK_HASHES)
SWAP1 JUMP
JUMP
%macro blockhash
// stack: block_number
%stack (block_number) -> (block_number, %%after)
%jump(blockhash)
%%after:
%endmacro
zero_hash:
// stack: cur_block_number, block_number, retdest
%pop2
PUSH 0 SWAP1
JUMP
%macro update_mem_words
// stack: num_words, kexit_info
%mem_words
// stack: old_num_words, num_words, kexit_info
DUP2 DUP2 GT
// stack: old_num_words > num_words, old_num_words, num_words, kexit_info
%jumpi(%%no_update)
// stack: old_num_words, num_words, kexit_info
%memory_cost
// stack: old_cost, num_words, kexit_info
SWAP1
// stack: num_words, old_cost, kexit_info
DUP1 %mstore_context_metadata(@CTX_METADATA_MEM_WORDS)
// stack: num_words, old_cost, kexit_info
%memory_cost
// stack: new_cost, old_cost, kexit_info
SUB
// stack: additional_cost, kexit_info
%charge_gas
%jump(%%end)
%%no_update:
// stack: old_num_words, num_words, kexit_info
%pop2
%%end:
// stack: kexit_info
%endmacro
%macro update_mem_bytes
// stack: num_bytes, kexit_info
%num_bytes_to_num_words
// stack: num_words, kexit_info
%update_mem_words
// stack: kexit_info
%endmacro
%macro num_bytes_to_num_words
// stack: num_bytes
%add_const(31)
// stack: 31 + num_bytes
%div_const(32)
// stack: (num_bytes + 31) / 32
%endmacro
%macro memory_cost
// stack: num_words
DUP1
// stack: num_words, msize
%mul_const(@GAS_MEMORY)
// stack: num_words * GAS_MEMORY, msize
SWAP1
// stack: num_words, num_words * GAS_MEMORY
%square
%div_const(512)
// stack: num_words^2 / 512, num_words * GAS_MEMORY
ADD
// stack: cost = num_words^2 / 512 + num_words * GAS_MEMORY
%endmacro
// Faults if the given offset is "unreasonable", i.e. the associated memory expansion cost
// would exceed any reasonable block limit.
// We do this to avoid overflows in future gas-related calculations.
%macro ensure_reasonable_offset
// stack: offset
// The memory expansion cost, (50000000 / 32)^2 / 512, is around 2^32 gas,
// i.e. greater than any reasonable block limit.
%gt_const(50000000)
// stack: is_unreasonable
%jumpi(fault_exception)
// stack: (empty)
%endmacro
// Convenience macro for checking if the current context is static.
// Called before state-changing opcodes.
%macro check_static
%mload_context_metadata(@CTX_METADATA_STATIC)
%jumpi(fault_exception)
%endmacro
// Adds the two top elements of the stack, and faults in case of overflow.
%macro add_or_fault
// stack: x, y
DUP2 ADD
// stack: sum, y
DUP1 SWAP2
// stack: y, sum, sum
GT
// stack: is_overflow, sum
%jumpi(fault_exception)
// stack: sum
%endmacro
%macro call_depth
%mload_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%endmacro
%macro increment_call_depth
%mload_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%increment
%mstore_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%endmacro
%macro decrement_call_depth
%mload_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%decrement
%mstore_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%endmacro