diff options
author | Alex Beregszaszi <alex@rtfs.hu> | 2016-12-01 06:44:33 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2016-12-12 00:57:15 +0800 |
commit | 1bf412d9fd9a4d55802ebe4eb006cf835d371d90 (patch) | |
tree | 9004fda5db82b79dc349e1cb89de090cf42cfc0d /libsolidity/codegen/CompilerUtils.cpp | |
parent | 4abc8ab5a9c1d2505cf781796f65de457028514d (diff) | |
download | dexon-solidity-1bf412d9fd9a4d55802ebe4eb006cf835d371d90.tar.gz dexon-solidity-1bf412d9fd9a4d55802ebe4eb006cf835d371d90.tar.zst dexon-solidity-1bf412d9fd9a4d55802ebe4eb006cf835d371d90.zip |
Implement CompilerUtils::memoryCopy using inline assembly
Diffstat (limited to 'libsolidity/codegen/CompilerUtils.cpp')
-rw-r--r-- | libsolidity/codegen/CompilerUtils.cpp | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 461803fa..634474a1 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -304,7 +304,32 @@ void CompilerUtils::memoryCopy(bool _useIdentityPrecompile) if (!_useIdentityPrecompile) { - // FIXME + m_context.appendInlineAssembly(R"( + { + // expects three locals: src, dst, len + + // copy 32 bytes at once + start32: + jumpi(end32, lt(len, 32)) + mstore(dst, mload(src)) + dst := add(dst, 32) + src := add(src, 32) + len := sub(len, 32) + jump(start32) + end32: + + // copy the remainder (0 < len < 32) + let mask := sub(exp(256, sub(32, len)), 1) + let srcpart := and(mload(src), not(mask)) + let dstpart := and(mload(dst), mask) + mstore(dst, or(srcpart, dstpart)) + } + )", + { "len", "dst", "src" } + ); + m_context << Instruction::POP; + m_context << Instruction::POP; + m_context << Instruction::POP; return; } |