mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #2541 from ethereum/asm-bitshift
Add bit shifting opcodes (EIP145)
This commit is contained in:
commit
2abc5be7e6
@ -206,6 +206,12 @@ 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 |
|
| byte(n, x) | | F | nth byte of x, where the most significant byte is the 0th byte |
|
||||||
+-------------------------+-----+---+-----------------------------------------------------------------+
|
+-------------------------+-----+---+-----------------------------------------------------------------+
|
||||||
|
| shl(x, y) | | C | logical shift left y by x bits |
|
||||||
|
+-------------------------+-----+---+-----------------------------------------------------------------+
|
||||||
|
| shr(x, y) | | C | logical shift right y by x bits |
|
||||||
|
+-------------------------+-----+---+-----------------------------------------------------------------+
|
||||||
|
| sar(x, y) | | C | arithmetic shift right y by x bits |
|
||||||
|
+-------------------------+-----+---+-----------------------------------------------------------------+
|
||||||
| addmod(x, y, m) | | F | (x + y) % m with arbitrary precision arithmetics |
|
| addmod(x, y, m) | | F | (x + y) % m with arbitrary precision arithmetics |
|
||||||
+-------------------------+-----+---+-----------------------------------------------------------------+
|
+-------------------------+-----+---+-----------------------------------------------------------------+
|
||||||
| mulmod(x, y, m) | | F | (x * y) % m with arbitrary precision arithmetics |
|
| mulmod(x, y, m) | | F | (x * y) % m with arbitrary precision arithmetics |
|
||||||
|
@ -50,6 +50,9 @@ const std::map<std::string, Instruction> dev::solidity::c_instructions =
|
|||||||
{ "OR", Instruction::OR },
|
{ "OR", Instruction::OR },
|
||||||
{ "XOR", Instruction::XOR },
|
{ "XOR", Instruction::XOR },
|
||||||
{ "BYTE", Instruction::BYTE },
|
{ "BYTE", Instruction::BYTE },
|
||||||
|
{ "SHL", Instruction::SHL },
|
||||||
|
{ "SHR", Instruction::SHR },
|
||||||
|
{ "SAR", Instruction::SAR },
|
||||||
{ "ADDMOD", Instruction::ADDMOD },
|
{ "ADDMOD", Instruction::ADDMOD },
|
||||||
{ "MULMOD", Instruction::MULMOD },
|
{ "MULMOD", Instruction::MULMOD },
|
||||||
{ "SIGNEXTEND", Instruction::SIGNEXTEND },
|
{ "SIGNEXTEND", Instruction::SIGNEXTEND },
|
||||||
@ -190,6 +193,9 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
|
|||||||
{ Instruction::OR, { "OR", 0, 2, 1, false, Tier::VeryLow } },
|
{ Instruction::OR, { "OR", 0, 2, 1, false, Tier::VeryLow } },
|
||||||
{ Instruction::XOR, { "XOR", 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::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::ADDMOD, { "ADDMOD", 0, 3, 1, false, Tier::Mid } },
|
{ Instruction::ADDMOD, { "ADDMOD", 0, 3, 1, false, Tier::Mid } },
|
||||||
{ Instruction::MULMOD, { "MULMOD", 0, 3, 1, false, Tier::Mid } },
|
{ Instruction::MULMOD, { "MULMOD", 0, 3, 1, false, Tier::Mid } },
|
||||||
{ Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false, Tier::Low } },
|
{ Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false, Tier::Low } },
|
||||||
|
@ -59,8 +59,11 @@ enum class Instruction: uint8_t
|
|||||||
AND, ///< bitwise AND operation
|
AND, ///< bitwise AND operation
|
||||||
OR, ///< bitwise OR operation
|
OR, ///< bitwise OR operation
|
||||||
XOR, ///< bitwise XOR operation
|
XOR, ///< bitwise XOR operation
|
||||||
NOT, ///< bitwise NOT opertation
|
NOT, ///< bitwise NOT operation
|
||||||
BYTE, ///< retrieve single byte from word
|
BYTE, ///< retrieve single byte from word
|
||||||
|
SHL, ///< bitwise SHL operation
|
||||||
|
SHR, ///< bitwise SHR operation
|
||||||
|
SAR, ///< bitwise SAR operation
|
||||||
|
|
||||||
KECCAK256 = 0x20, ///< compute KECCAK-256 hash
|
KECCAK256 = 0x20, ///< compute KECCAK-256 hash
|
||||||
|
|
||||||
|
@ -548,6 +548,20 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio
|
|||||||
"the Metropolis hard fork. Before that it acts as an invalid instruction."
|
"the Metropolis hard fork. Before that it acts as an invalid instruction."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static set<solidity::Instruction> experimentalInstructions{
|
||||||
|
solidity::Instruction::SHL,
|
||||||
|
solidity::Instruction::SHR,
|
||||||
|
solidity::Instruction::SAR
|
||||||
|
};
|
||||||
|
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)
|
if (_instr == solidity::Instruction::JUMP || _instr == solidity::Instruction::JUMPI || _instr == solidity::Instruction::JUMPDEST)
|
||||||
m_errorReporter.warning(
|
m_errorReporter.warning(
|
||||||
_location,
|
_location,
|
||||||
|
@ -774,6 +774,20 @@ BOOST_AUTO_TEST_CASE(create2)
|
|||||||
BOOST_CHECK(successAssemble("{ pop(create2(10, 0x123, 32, 64)) }"));
|
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)
|
BOOST_AUTO_TEST_CASE(jump_warning)
|
||||||
{
|
{
|
||||||
CHECK_PARSE_WARNING("{ 1 jump }", Warning, "Jump instructions");
|
CHECK_PARSE_WARNING("{ 1 jump }", Warning, "Jump instructions");
|
||||||
|
Loading…
Reference in New Issue
Block a user