Skip to content

Commit 8f5ee88

Browse files
authored
Merge pull request ethereum#14779 from ethereum/mcopy
Yul builtin for `MCOPY`
2 parents 89a70c7 + bd76278 commit 8f5ee88

File tree

90 files changed

+1806
-11
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+1806
-11
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Language Features:
55
* Introduce global function ``blobhash(uint)`` for retrieving versioned hashes of blobs, akin to the homonymous Yul builtin.
66
* Yul: Introduce builtin ``blobbasefee()`` for retrieving the blob base fee of the current block.
77
* Yul: Introduce builtin ``blobhash()`` for retrieving versioned hashes of blobs associated with the transaction.
8+
* Yul: Introduce builtin ``mcopy()`` for cheaply copying data between memory areas.
89

910
Compiler Features:
1011
* EVM: Support for the EVM Version "Cancun".

docs/grammar/SolidityLexer.g4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ YulEVMBuiltin:
301301
| 'pop' | 'mload' | 'mstore' | 'mstore8' | 'sload' | 'sstore' | 'msize' | 'gas'
302302
| 'address' | 'balance' | 'selfbalance' | 'caller' | 'callvalue' | 'calldataload'
303303
| 'calldatasize' | 'calldatacopy' | 'extcodesize' | 'extcodecopy' | 'returndatasize'
304-
| 'returndatacopy' | 'extcodehash' | 'create' | 'create2' | 'call' | 'callcode'
304+
| 'returndatacopy' | 'mcopy' | 'extcodehash' | 'create' | 'create2' | 'call' | 'callcode'
305305
| 'delegatecall' | 'staticcall' | 'return' | 'revert' | 'selfdestruct' | 'invalid'
306306
| 'log0' | 'log1' | 'log2' | 'log3' | 'log4' | 'chainid' | 'origin' | 'gasprice'
307307
| 'blockhash' | 'blobhash' | 'coinbase' | 'timestamp' | 'number' | 'difficulty'

docs/using-the-compiler.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ at each version. Backward compatibility is not guaranteed between each version.
179179
- ``cancun``
180180
- The block's blob base fee (`EIP-7516 <https://eips.ethereum.org/EIPS/eip-7516>`_ and `EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_) can be accessed via the global ``block.blobbasefee`` or ``blobbasefee()`` in inline assembly.
181181
- Introduces ``blobhash()`` in inline assembly and a corresponding global function to retrieve versioned hashes of blobs associated with the transaction (see `EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_).
182+
- Opcode ``mcopy`` is available in assembly (see `EIP-5656 <https://eips.ethereum.org/EIPS/eip-5656>`_).
182183

183184
.. index:: ! standard JSON, ! --standard-json
184185
.. _compiler-api:

docs/yul.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,8 @@ the ``dup`` and ``swap`` instructions as well as ``jump`` instructions, labels a
865865
+-------------------------+-----+---+-----------------------------------------------------------------+
866866
| returndatacopy(t, f, s) | `-` | B | copy s bytes from returndata at position f to mem at position t |
867867
+-------------------------+-----+---+-----------------------------------------------------------------+
868+
| mcopy(t, f, s) | `-` | N | copy s bytes from mem at position f to mem at position t |
869+
+-------------------------+-----+---+-----------------------------------------------------------------+
868870
| extcodehash(a) | | C | code hash of address a |
869871
+-------------------------+-----+---+-----------------------------------------------------------------+
870872
| create(v, p, n) | | F | create new contract with code mem[p...(p+n)) and send v wei |

libevmasm/GasMeter.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
115115
gas += memoryGas(0, -2);
116116
gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-2));
117117
break;
118+
case Instruction::MCOPY:
119+
{
120+
GasConsumption memoryGasFromRead = memoryGas(-1, -2);
121+
GasConsumption memoryGasFromWrite = memoryGas(0, -2);
122+
123+
gas = runGas(_item.instruction(), m_evmVersion);
124+
gas += (memoryGasFromRead < memoryGasFromWrite ? memoryGasFromWrite : memoryGasFromRead);
125+
gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-2));
126+
break;
127+
}
118128
case Instruction::EXTCODESIZE:
119129
gas = GasCosts::extCodeGas(m_evmVersion);
120130
break;

libevmasm/Instruction.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ std::map<std::string, Instruction> const solidity::evmasm::c_instructions =
7070
{ "EXTCODECOPY", Instruction::EXTCODECOPY },
7171
{ "RETURNDATASIZE", Instruction::RETURNDATASIZE },
7272
{ "RETURNDATACOPY", Instruction::RETURNDATACOPY },
73+
{ "MCOPY", Instruction::MCOPY },
7374
{ "EXTCODEHASH", Instruction::EXTCODEHASH },
7475
{ "BLOCKHASH", Instruction::BLOCKHASH },
7576
{ "BLOBHASH", Instruction::BLOBHASH },
@@ -222,6 +223,7 @@ static std::map<Instruction, InstructionInfo> const c_instructionInfo =
222223
{ Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::ExtCode } },
223224
{ Instruction::RETURNDATASIZE, {"RETURNDATASIZE", 0, 0, 1, false, Tier::Base } },
224225
{ Instruction::RETURNDATACOPY, {"RETURNDATACOPY", 0, 3, 0, true, Tier::VeryLow } },
226+
{ Instruction::MCOPY, { "MCOPY", 0, 3, 0, true, Tier::VeryLow } },
225227
{ Instruction::EXTCODEHASH, { "EXTCODEHASH", 0, 1, 1, false, Tier::Balance } },
226228
{ Instruction::BLOCKHASH, { "BLOCKHASH", 0, 1, 1, false, Tier::Ext } },
227229
{ Instruction::BLOBHASH, { "BLOBHASH", 0, 1, 1, false, Tier::VeryLow } },

libevmasm/Instruction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ enum class Instruction: uint8_t
104104
MSIZE, ///< get the size of active memory
105105
GAS, ///< get the amount of available gas
106106
JUMPDEST, ///< set a potential jump destination
107+
MCOPY = 0x5e, ///< copy between memory areas
107108

108109
PUSH0 = 0x5f, ///< place the value 0 on stack
109110
PUSH1 = 0x60, ///< place 1 byte item on stack

libevmasm/SemanticInformation.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,25 @@ std::vector<SemanticInformation::Operation> SemanticInformation::readWriteOperat
104104
op.lengthParameter = 2;
105105
return {op};
106106
}
107+
case Instruction::MCOPY:
108+
{
109+
assertThrow(memory(_instruction) != Effect::None, OptimizerException, "");
110+
assertThrow(storage(_instruction) == Effect::None, OptimizerException, "");
111+
112+
Operation readOperation;
113+
readOperation.effect = Read;
114+
readOperation.location = Location::Memory;
115+
readOperation.startParameter = 1;
116+
readOperation.lengthParameter = 2;
117+
118+
Operation writeOperation;
119+
writeOperation.effect = Write;
120+
writeOperation.location = Location::Memory;
121+
writeOperation.startParameter = 0;
122+
writeOperation.lengthParameter = 2;
123+
124+
return {readOperation, writeOperation};
125+
}
107126
case Instruction::STATICCALL:
108127
case Instruction::CALL:
109128
case Instruction::CALLCODE:
@@ -188,7 +207,7 @@ bool SemanticInformation::breaksCSEAnalysisBlock(AssemblyItem const& _item, bool
188207
))
189208
return false;
190209
//@todo: We do not handle the following memory instructions for now:
191-
// calldatacopy, codecopy, extcodecopy, mstore8,
210+
// calldatacopy, codecopy, extcodecopy, mcopy, mstore8,
192211
// msize (note that msize also depends on memory read access)
193212

194213
// the second requirement will be lifted once it is implemented
@@ -363,6 +382,7 @@ SemanticInformation::Effect SemanticInformation::memory(Instruction _instruction
363382
case Instruction::CODECOPY:
364383
case Instruction::EXTCODECOPY:
365384
case Instruction::RETURNDATACOPY:
385+
case Instruction::MCOPY:
366386
case Instruction::MSTORE:
367387
case Instruction::MSTORE8:
368388
case Instruction::CALL:

libevmasm/SimplificationRule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ struct EVMBuiltins
117117
static auto constexpr EXTCODECOPY = PatternGenerator<Instruction::EXTCODECOPY>{};
118118
static auto constexpr RETURNDATASIZE = PatternGenerator<Instruction::RETURNDATASIZE>{};
119119
static auto constexpr RETURNDATACOPY = PatternGenerator<Instruction::RETURNDATACOPY>{};
120+
static auto constexpr MCOPY = PatternGenerator<Instruction::MCOPY>{};
120121
static auto constexpr EXTCODEHASH = PatternGenerator<Instruction::EXTCODEHASH>{};
121122
static auto constexpr BLOCKHASH = PatternGenerator<Instruction::BLOCKHASH>{};
122123
static auto constexpr BLOBHASH = PatternGenerator<Instruction::BLOBHASH>{};

liblangutil/EVMVersion.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ bool EVMVersion::hasOpcode(Instruction _opcode) const
5353
return hasBlobHash();
5454
case Instruction::BLOBBASEFEE:
5555
return hasBlobBaseFee();
56+
case Instruction::MCOPY:
57+
return hasMcopy();
5658
default:
5759
return true;
5860
}

0 commit comments

Comments
 (0)