From 59e6ea601b90577e39fe22a4c504f09e862dc40e Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 6 Feb 2017 22:14:17 +0000 Subject: Add bitwise shift operators to libevmasm (EIP145) --- libevmasm/Instruction.cpp | 10 ++++++++++ libevmasm/Instruction.h | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index b38981d2..c25c9653 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -50,6 +50,11 @@ const std::map dev::solidity::c_instructions = { "OR", Instruction::OR }, { "XOR", Instruction::XOR }, { "BYTE", Instruction::BYTE }, + { "SHL", Instruction::SHL }, + { "SHR", Instruction::SHR }, + { "SAR", Instruction::SAR }, + { "ROL", Instruction::ROL }, + { "ROR", Instruction::ROR }, { "ADDMOD", Instruction::ADDMOD }, { "MULMOD", Instruction::MULMOD }, { "SIGNEXTEND", Instruction::SIGNEXTEND }, @@ -190,6 +195,11 @@ static const std::map c_instructionInfo = { Instruction::OR, { "OR", 0, 2, 1, false, Tier::VeryLow } }, { Instruction::XOR, { "XOR", 0, 2, 1, false, Tier::VeryLow } }, { Instruction::BYTE, { "BYTE", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::SHL, { "SHL", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::SHR, { "SHR", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::SAR, { "SAR", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::ROL, { "ROL", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::ROR, { "ROR", 0, 2, 1, false, Tier::VeryLow } }, { Instruction::ADDMOD, { "ADDMOD", 0, 3, 1, false, Tier::Mid } }, { Instruction::MULMOD, { "MULMOD", 0, 3, 1, false, Tier::Mid } }, { Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false, Tier::Low } }, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index d9c53900..e56d4c9a 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -59,8 +59,13 @@ enum class Instruction: uint8_t AND, ///< bitwise AND operation OR, ///< bitwise OR operation XOR, ///< bitwise XOR operation - NOT, ///< bitwise NOT opertation + NOT, ///< bitwise NOT operation BYTE, ///< retrieve single byte from word + SHL, ///< bitwise SHL operation + SHR, ///< bitwise SHR operation + SAR, ///< bitwise SAR operation + ROL, ///< bitwise ROL operation + ROR, ///< bitwise ROR operation KECCAK256 = 0x20, ///< compute KECCAK-256 hash -- cgit v1.2.3 From 9e0446a22c78e8a293a742492f2d2d7cd67af4bd Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 6 Feb 2017 22:42:27 +0000 Subject: Document bitwise shift operators in assembly --- docs/assembly.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/assembly.rst b/docs/assembly.rst index 46416142..245b5383 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -206,6 +206,16 @@ In the grammar, opcodes are represented as pre-defined identifiers. +-------------------------+-----+---+-----------------------------------------------------------------+ | byte(n, x) | | F | nth byte of x, where the most significant byte is the 0th byte | +-------------------------+-----+---+-----------------------------------------------------------------+ +| shl(x, y) | | C | logical shift left x by y bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| shr(x, y) | | C | logical shift right x by y bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| sar(x, y) | | C | arithmetic shift right x by y bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| ror(x, y) | | C | rotate right x by y bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| rol(x, y) | | C | rotate left x by y bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ | addmod(x, y, m) | | F | (x + y) % m with arbitrary precision arithmetics | +-------------------------+-----+---+-----------------------------------------------------------------+ | mulmod(x, y, m) | | F | (x * y) % m with arbitrary precision arithmetics | -- cgit v1.2.3 From 468d0f6199e71f0c7f4b8bd667c8f31feba41a9d Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 15 Jun 2017 12:14:14 +0100 Subject: Warn on using shift instructions --- libsolidity/inlineasm/AsmAnalysis.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index a05ac57d..7653ee51 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -548,6 +548,22 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio "the Metropolis hard fork. Before that it acts as an invalid instruction." ); + static set experimentalInstructions{ + solidity::Instruction::SHL, + solidity::Instruction::SHR, + solidity::Instruction::SAR, + solidity::Instruction::ROL, + solidity::Instruction::ROR + }; + if (experimentalInstructions.count(_instr)) + m_errorReporter.warning( + _location, + "The \"" + + boost::to_lower_copy(instructionInfo(_instr).name) + + "\" instruction is only available after " + + "the Constantinople hard fork. Before that it acts as an invalid instruction." + ); + if (_instr == solidity::Instruction::JUMP || _instr == solidity::Instruction::JUMPI || _instr == solidity::Instruction::JUMPDEST) m_errorReporter.warning( _location, -- cgit v1.2.3 From afa4a48e3770630a744ef98ccd518601e1f35c86 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sun, 9 Jul 2017 08:42:54 +0100 Subject: Remove ROL/ROR as they are not part of EIP145 anymore --- docs/assembly.rst | 4 ---- libevmasm/Instruction.cpp | 4 ---- libevmasm/Instruction.h | 2 -- libsolidity/inlineasm/AsmAnalysis.cpp | 4 +--- 4 files changed, 1 insertion(+), 13 deletions(-) diff --git a/docs/assembly.rst b/docs/assembly.rst index 245b5383..9eabc99e 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -212,10 +212,6 @@ In the grammar, opcodes are represented as pre-defined identifiers. +-------------------------+-----+---+-----------------------------------------------------------------+ | sar(x, y) | | C | arithmetic shift right x by y bits | +-------------------------+-----+---+-----------------------------------------------------------------+ -| ror(x, y) | | C | rotate right x by y bits | -+-------------------------+-----+---+-----------------------------------------------------------------+ -| rol(x, y) | | C | rotate left x by y bits | -+-------------------------+-----+---+-----------------------------------------------------------------+ | addmod(x, y, m) | | F | (x + y) % m with arbitrary precision arithmetics | +-------------------------+-----+---+-----------------------------------------------------------------+ | mulmod(x, y, m) | | F | (x * y) % m with arbitrary precision arithmetics | diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index c25c9653..a677a631 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -53,8 +53,6 @@ const std::map dev::solidity::c_instructions = { "SHL", Instruction::SHL }, { "SHR", Instruction::SHR }, { "SAR", Instruction::SAR }, - { "ROL", Instruction::ROL }, - { "ROR", Instruction::ROR }, { "ADDMOD", Instruction::ADDMOD }, { "MULMOD", Instruction::MULMOD }, { "SIGNEXTEND", Instruction::SIGNEXTEND }, @@ -198,8 +196,6 @@ static const std::map c_instructionInfo = { Instruction::SHL, { "SHL", 0, 2, 1, false, Tier::VeryLow } }, { Instruction::SHR, { "SHR", 0, 2, 1, false, Tier::VeryLow } }, { Instruction::SAR, { "SAR", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::ROL, { "ROL", 0, 2, 1, false, Tier::VeryLow } }, - { Instruction::ROR, { "ROR", 0, 2, 1, false, Tier::VeryLow } }, { Instruction::ADDMOD, { "ADDMOD", 0, 3, 1, false, Tier::Mid } }, { Instruction::MULMOD, { "MULMOD", 0, 3, 1, false, Tier::Mid } }, { Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false, Tier::Low } }, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index e56d4c9a..be788ddb 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -64,8 +64,6 @@ enum class Instruction: uint8_t SHL, ///< bitwise SHL operation SHR, ///< bitwise SHR operation SAR, ///< bitwise SAR operation - ROL, ///< bitwise ROL operation - ROR, ///< bitwise ROR operation KECCAK256 = 0x20, ///< compute KECCAK-256 hash diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 7653ee51..1030523a 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -551,9 +551,7 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio static set experimentalInstructions{ solidity::Instruction::SHL, solidity::Instruction::SHR, - solidity::Instruction::SAR, - solidity::Instruction::ROL, - solidity::Instruction::ROR + solidity::Instruction::SAR }; if (experimentalInstructions.count(_instr)) m_errorReporter.warning( -- cgit v1.2.3 From 317e017849e3ada43842c1e0268338e54c0c4d8e Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 5 Jan 2018 00:29:14 +0000 Subject: Shift operands were swapped in accepted EIP145 --- docs/assembly.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/assembly.rst b/docs/assembly.rst index 9eabc99e..cf9bf840 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -206,11 +206,11 @@ In the grammar, opcodes are represented as pre-defined identifiers. +-------------------------+-----+---+-----------------------------------------------------------------+ | byte(n, x) | | F | nth byte of x, where the most significant byte is the 0th byte | +-------------------------+-----+---+-----------------------------------------------------------------+ -| shl(x, y) | | C | logical shift left x by y bits | +| shl(x, y) | | C | logical shift left y by x bits | +-------------------------+-----+---+-----------------------------------------------------------------+ -| shr(x, y) | | C | logical shift right x by y bits | +| shr(x, y) | | C | logical shift right y by x bits | +-------------------------+-----+---+-----------------------------------------------------------------+ -| sar(x, y) | | C | arithmetic shift right x by y bits | +| sar(x, y) | | C | arithmetic shift right y by x bits | +-------------------------+-----+---+-----------------------------------------------------------------+ | addmod(x, y, m) | | F | (x + y) % m with arbitrary precision arithmetics | +-------------------------+-----+---+-----------------------------------------------------------------+ -- cgit v1.2.3 From 73c5d99bfaa4d17a97d4554a89d1005b25e62f98 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 27 Feb 2018 12:09:22 +0100 Subject: Add basic test for shift opcodes --- test/libsolidity/InlineAssembly.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 45fb54f8..ea120657 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -774,6 +774,20 @@ BOOST_AUTO_TEST_CASE(create2) BOOST_CHECK(successAssemble("{ pop(create2(10, 0x123, 32, 64)) }")); } +BOOST_AUTO_TEST_CASE(shift) +{ + BOOST_CHECK(successAssemble("{ pop(shl(10, 32)) }")); + BOOST_CHECK(successAssemble("{ pop(shr(10, 32)) }")); + BOOST_CHECK(successAssemble("{ pop(sar(10, 32)) }")); +} + +BOOST_AUTO_TEST_CASE(shift_constantinople_warning) +{ + CHECK_PARSE_WARNING("{ pop(shl(10, 32)) }", Warning, "The \"shl\" instruction is only available after the Constantinople hard fork"); + CHECK_PARSE_WARNING("{ pop(shr(10, 32)) }", Warning, "The \"shr\" instruction is only available after the Constantinople hard fork"); + CHECK_PARSE_WARNING("{ pop(sar(10, 32)) }", Warning, "The \"sar\" instruction is only available after the Constantinople hard fork"); +} + BOOST_AUTO_TEST_CASE(jump_warning) { CHECK_PARSE_WARNING("{ 1 jump }", Warning, "Jump instructions"); -- cgit v1.2.3