Browse Source

PoC-7: Instruction set reform

cl-refactor
Gav Wood 10 years ago
parent
commit
2770e6ccc7
  1. 6
      libevm/VM.h
  2. 8
      libevmface/Instruction.cpp
  3. 17
      libevmface/Instruction.h
  4. 2
      liblll/Assembly.cpp
  5. 14
      liblll/CodeFragment.cpp

6
libevm/VM.h

@ -262,8 +262,8 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
case Instruction::PUSH31: case Instruction::PUSH31:
case Instruction::PUSH32: case Instruction::PUSH32:
break; break;
case Instruction::BNOT:
case Instruction::NOT: case Instruction::NOT:
case Instruction::ISZERO:
case Instruction::CALLDATALOAD: case Instruction::CALLDATALOAD:
case Instruction::EXTCODESIZE: case Instruction::EXTCODESIZE:
case Instruction::POP: case Instruction::POP:
@ -395,7 +395,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
m_stack.back() = (u256)boost::multiprecision::powm((bigint)base, (bigint)expon, bigint(2) << 256); m_stack.back() = (u256)boost::multiprecision::powm((bigint)base, (bigint)expon, bigint(2) << 256);
break; break;
} }
case Instruction::BNOT: case Instruction::NOT:
m_stack.back() = ~m_stack.back(); m_stack.back() = ~m_stack.back();
break; break;
case Instruction::LT: case Instruction::LT:
@ -418,7 +418,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
m_stack[m_stack.size() - 2] = m_stack.back() == m_stack[m_stack.size() - 2] ? 1 : 0; m_stack[m_stack.size() - 2] = m_stack.back() == m_stack[m_stack.size() - 2] ? 1 : 0;
m_stack.pop_back(); m_stack.pop_back();
break; break;
case Instruction::NOT: case Instruction::ISZERO:
m_stack.back() = m_stack.back() ? 0 : 1; m_stack.back() = m_stack.back() ? 0 : 1;
break; break;
case Instruction::AND: case Instruction::AND:

8
libevmface/Instruction.cpp

@ -39,13 +39,13 @@ const std::map<std::string, Instruction> dev::eth::c_instructions =
{ "MOD", Instruction::MOD }, { "MOD", Instruction::MOD },
{ "SMOD", Instruction::SMOD }, { "SMOD", Instruction::SMOD },
{ "EXP", Instruction::EXP }, { "EXP", Instruction::EXP },
{ "BNOT", Instruction::BNOT }, { "BNOT", Instruction::NOT },
{ "LT", Instruction::LT }, { "LT", Instruction::LT },
{ "GT", Instruction::GT }, { "GT", Instruction::GT },
{ "SLT", Instruction::SLT }, { "SLT", Instruction::SLT },
{ "SGT", Instruction::SGT }, { "SGT", Instruction::SGT },
{ "EQ", Instruction::EQ }, { "EQ", Instruction::EQ },
{ "NOT", Instruction::NOT }, { "NOT", Instruction::ISZERO },
{ "AND", Instruction::AND }, { "AND", Instruction::AND },
{ "OR", Instruction::OR }, { "OR", Instruction::OR },
{ "XOR", Instruction::XOR }, { "XOR", Instruction::XOR },
@ -172,13 +172,13 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::MOD, { "MOD", 0, 2, 1 } }, { Instruction::MOD, { "MOD", 0, 2, 1 } },
{ Instruction::SMOD, { "SMOD", 0, 2, 1 } }, { Instruction::SMOD, { "SMOD", 0, 2, 1 } },
{ Instruction::EXP, { "EXP", 0, 2, 1 } }, { Instruction::EXP, { "EXP", 0, 2, 1 } },
{ Instruction::BNOT, { "BNOT", 0, 1, 1 } }, { Instruction::NOT, { "BNOT", 0, 1, 1 } },
{ Instruction::LT, { "LT", 0, 2, 1 } }, { Instruction::LT, { "LT", 0, 2, 1 } },
{ Instruction::GT, { "GT", 0, 2, 1 } }, { Instruction::GT, { "GT", 0, 2, 1 } },
{ Instruction::SLT, { "SLT", 0, 2, 1 } }, { Instruction::SLT, { "SLT", 0, 2, 1 } },
{ Instruction::SGT, { "SGT", 0, 2, 1 } }, { Instruction::SGT, { "SGT", 0, 2, 1 } },
{ Instruction::EQ, { "EQ", 0, 2, 1 } }, { Instruction::EQ, { "EQ", 0, 2, 1 } },
{ Instruction::NOT, { "NOT", 0, 1, 1 } }, { Instruction::ISZERO, { "NOT", 0, 1, 1 } },
{ Instruction::AND, { "AND", 0, 2, 1 } }, { Instruction::AND, { "AND", 0, 2, 1 } },
{ Instruction::OR, { "OR", 0, 2, 1 } }, { Instruction::OR, { "OR", 0, 2, 1 } },
{ Instruction::XOR, { "XOR", 0, 2, 1 } }, { Instruction::XOR, { "XOR", 0, 2, 1 } },

17
libevmface/Instruction.h

@ -43,22 +43,23 @@ enum class Instruction: uint8_t
SDIV, ///< signed integer division operation SDIV, ///< signed integer division operation
MOD, ///< modulo remainder operation MOD, ///< modulo remainder operation
SMOD, ///< signed modulo remainder operation SMOD, ///< signed modulo remainder operation
ADDMOD, ///< unsigned modular addition
MULMOD, ///< unsigned modular multiplication
EXP, ///< exponential operation EXP, ///< exponential operation
BNOT, ///< bitwise not SIGNEXTEND, ///< extend length of signed integer
LT, ///< less-than comparision
LT = 0x10, ///< less-than comparision
GT, ///< greater-than comparision GT, ///< greater-than comparision
SLT, ///< signed less-than comparision SLT, ///< signed less-than comparision
SGT, ///< signed greater-than comparision SGT, ///< signed greater-than comparision
EQ, ///< equality comparision EQ, ///< equality comparision
NOT, ///< simple not operator ISZERO, ///< simple not operator
AND, ///< bitwise AND operation
AND = 0x10, ///< bitwise AND operation
OR, ///< bitwise OR operation OR, ///< bitwise OR operation
XOR, ///< bitwise XOR operation XOR, ///< bitwise XOR operation
NOT, ///< bitwise NOT opertation
BYTE, ///< retrieve single byte from word BYTE, ///< retrieve single byte from word
ADDMOD, ///< unsigned modular addition
MULMOD, ///< unsigned modular multiplication
SIGNEXTEND, ///< extend length of signed integer
SHA3 = 0x20, ///< compute SHA3-256 hash SHA3 = 0x20, ///< compute SHA3-256 hash
ADDRESS = 0x30, ///< get address of currently executing account ADDRESS = 0x30, ///< get address of currently executing account

2
liblll/Assembly.cpp

@ -251,7 +251,7 @@ Assembly& Assembly::optimise(bool _enable)
{ { PushSub, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } }, { { PushSub, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
{ { PushSubSize, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } }, { { PushSubSize, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
{ { Push, PushTag, Instruction::JUMPI }, [](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].data()) return { m[1], Instruction::JUMP }; else return {}; } }, { { Push, PushTag, Instruction::JUMPI }, [](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].data()) return { m[1], Instruction::JUMP }; else return {}; } },
{ { Instruction::NOT, Instruction::NOT }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } }, { { Instruction::ISZERO, Instruction::ISZERO }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
}; };
for (auto const& i: c_simple) for (auto const& i: c_simple)

14
liblll/CodeFragment.cpp

@ -328,7 +328,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
std::map<std::string, Instruction> const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD }, { "&", Instruction::AND }, { "|", Instruction::OR }, { "^", Instruction::XOR } }; std::map<std::string, Instruction> const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD }, { "&", Instruction::AND }, { "|", Instruction::OR }, { "^", Instruction::XOR } };
std::map<std::string, pair<Instruction, bool>> const c_binary = { { "<", { Instruction::LT, false } }, { "<=", { Instruction::GT, true } }, { ">", { Instruction::GT, false } }, { ">=", { Instruction::LT, true } }, { "S<", { Instruction::SLT, false } }, { "S<=", { Instruction::SGT, true } }, { "S>", { Instruction::SGT, false } }, { "S>=", { Instruction::SLT, true } }, { "=", { Instruction::EQ, false } }, { "!=", { Instruction::EQ, true } } }; std::map<std::string, pair<Instruction, bool>> const c_binary = { { "<", { Instruction::LT, false } }, { "<=", { Instruction::GT, true } }, { ">", { Instruction::GT, false } }, { ">=", { Instruction::LT, true } }, { "S<", { Instruction::SLT, false } }, { "S<=", { Instruction::SGT, true } }, { "S>", { Instruction::SGT, false } }, { "S>=", { Instruction::SLT, true } }, { "=", { Instruction::EQ, false } }, { "!=", { Instruction::EQ, true } } };
std::map<std::string, Instruction> const c_unary = { { "!", Instruction::NOT } }; std::map<std::string, Instruction> const c_unary = { { "!", Instruction::ISZERO } };
vector<CodeFragment> code; vector<CodeFragment> code;
CompilerState ns = _s; CompilerState ns = _s;
@ -403,7 +403,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
m_asm.append(code[0].m_asm, 1); m_asm.append(code[0].m_asm, 1);
m_asm.append(it->second.first); m_asm.append(it->second.first);
if (it->second.second) if (it->second.second)
m_asm.append(Instruction::NOT); m_asm.append(Instruction::ISZERO);
} }
else if (c_unary.count(us)) else if (c_unary.count(us))
{ {
@ -437,7 +437,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
m_asm.append(code[0].m_asm); m_asm.append(code[0].m_asm);
if (us == "WHEN") if (us == "WHEN")
m_asm.append(Instruction::NOT); m_asm.append(Instruction::ISZERO);
auto end = m_asm.appendJumpI(); auto end = m_asm.appendJumpI();
m_asm.onePath(); m_asm.onePath();
m_asm.otherPath(); m_asm.otherPath();
@ -452,7 +452,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
auto begin = m_asm.append(); auto begin = m_asm.append();
m_asm.append(code[0].m_asm); m_asm.append(code[0].m_asm);
m_asm.append(Instruction::NOT); m_asm.append(Instruction::ISZERO);
auto end = m_asm.appendJumpI(); auto end = m_asm.appendJumpI();
m_asm.append(code[1].m_asm, 0); m_asm.append(code[1].m_asm, 0);
m_asm.appendJump(begin); m_asm.appendJump(begin);
@ -466,7 +466,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
m_asm.append(code[0].m_asm, 0); m_asm.append(code[0].m_asm, 0);
auto begin = m_asm.append(); auto begin = m_asm.append();
m_asm.append(code[1].m_asm); m_asm.append(code[1].m_asm);
m_asm.append(Instruction::NOT); m_asm.append(Instruction::ISZERO);
auto end = m_asm.appendJumpI(); auto end = m_asm.appendJumpI();
m_asm.append(code[3].m_asm, 0); m_asm.append(code[3].m_asm, 0);
m_asm.append(code[2].m_asm, 0); m_asm.append(code[2].m_asm, 0);
@ -502,7 +502,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
requireDeposit(2, 1); requireDeposit(2, 1);
m_asm.append(code[2].m_asm, 1); m_asm.append(code[2].m_asm, 1);
m_asm.append(Instruction::LT); m_asm.append(Instruction::LT);
m_asm.append(Instruction::NOT); m_asm.append(Instruction::ISZERO);
m_asm.append(Instruction::MUL); m_asm.append(Instruction::MUL);
m_asm.append(Instruction::DUP1); m_asm.append(Instruction::DUP1);
} }
@ -525,7 +525,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
// Check if true - predicate // Check if true - predicate
m_asm.append(code[i - 1].m_asm, 1); m_asm.append(code[i - 1].m_asm, 1);
if (us == "&&") if (us == "&&")
m_asm.append(Instruction::NOT); m_asm.append(Instruction::ISZERO);
m_asm.appendJumpI(end); m_asm.appendJumpI(end);
} }
m_asm.append(Instruction::POP); m_asm.append(Instruction::POP);

Loading…
Cancel
Save