aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2016-12-01 06:44:33 +0800
committerchriseth <c@ethdev.com>2016-12-12 00:57:15 +0800
commit1bf412d9fd9a4d55802ebe4eb006cf835d371d90 (patch)
tree9004fda5db82b79dc349e1cb89de090cf42cfc0d /libsolidity
parent4abc8ab5a9c1d2505cf781796f65de457028514d (diff)
downloaddexon-solidity-1bf412d9fd9a4d55802ebe4eb006cf835d371d90.tar.gz
dexon-solidity-1bf412d9fd9a4d55802ebe4eb006cf835d371d90.tar.zst
dexon-solidity-1bf412d9fd9a4d55802ebe4eb006cf835d371d90.zip
Implement CompilerUtils::memoryCopy using inline assembly
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp27
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;
}