Browse Source

SWAP* instructions

cl-refactor
Paweł Bylica 10 years ago
parent
commit
2eabdb0ced
  1. 25
      evmcc/Compiler.cpp
  2. 43
      evmcc/Stack.cpp
  3. 2
      evmcc/Stack.h
  4. 2
      evmcc/bytecode/stack_test.evm
  5. 4
      evmcc/lll/stack_test.lll

25
evmcc/Compiler.cpp

@ -134,6 +134,31 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
break; break;
} }
case Instruction::SWAP1:
case Instruction::SWAP2:
case Instruction::SWAP3:
case Instruction::SWAP4:
case Instruction::SWAP5:
case Instruction::SWAP6:
case Instruction::SWAP7:
case Instruction::SWAP8:
case Instruction::SWAP9:
case Instruction::SWAP10:
case Instruction::SWAP11:
case Instruction::SWAP12:
case Instruction::SWAP13:
case Instruction::SWAP14:
case Instruction::SWAP15:
case Instruction::SWAP16:
{
auto index = static_cast<uint32_t>(inst) - static_cast<uint32_t>(Instruction::SWAP1) + 1;
auto loValue = stack.get(index);
auto hiValue = stack.get(0);
stack.set(index, hiValue);
stack.set(0, loValue);
break;
}
} }
} }

43
evmcc/Stack.cpp

@ -55,6 +55,9 @@ Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
m_stackGet = llvm::Function::Create(getFuncType, m_stackGet = llvm::Function::Create(getFuncType,
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_get", _module); llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_get", _module);
m_stackSet = llvm::Function::Create(getFuncType,
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_set", _module);
m_args[0] = m_builder.CreateCall(stackCreate, "stack.ptr"); m_args[0] = m_builder.CreateCall(stackCreate, "stack.ptr");
m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "stack.val"); m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "stack.val");
} }
@ -82,24 +85,33 @@ llvm::Value* Stack::get(uint32_t _index)
} }
void Stack::set(uint32_t _index, llvm::Value* _value)
{
m_builder.CreateStore(_value, m_args[1]); // copy value to memory
llvm::Value* args[] = {m_args[0], m_builder.getInt32(_index), m_args[1]};
m_builder.CreateCall(m_stackSet, args);
}
llvm::Value* Stack::top() llvm::Value* Stack::top()
{ {
return get(0); return get(0);
} }
void debugStack(const char* op, const i256& word) void debugStack(const char* _op, const i256& _word, uint32_t _index = 0)
{ {
std::cerr << "STACK " << std::setw(4) << std::setfill(' ') << op << ": " std::cerr << "STACK " << std::setw(4) << std::setfill(' ') << _op
<< std::dec << word.a << " [" << std::setw(2) << std::setfill('0') << _index << "] "
<< " HEX: " << std::hex << std::setfill('0'); << std::dec << _word.a
if (word.b || word.c || word.d) << " HEX: " << std::hex;
if (_word.b || _word.c || _word.d)
{ {
std::cerr << std::setw(16) << word.d << " " std::cerr << std::setw(16) << _word.d << " "
<< std::setw(16) << word.c << " " << std::setw(16) << _word.c << " "
<< std::setw(16) << word.b << " "; << std::setw(16) << _word.b << " ";
} }
std::cerr << std::setw(16) << word.a << "\n"; std::cerr << std::setw(16) << _word.a << "\n";
} }
} }
@ -138,10 +150,19 @@ EXPORT void evmccrt_stack_get(void* _stack, uint32_t _index, void* _pWord)
{ {
auto stack = static_cast<StackImpl*>(_stack); auto stack = static_cast<StackImpl*>(_stack);
assert(_index < stack->size()); assert(_index < stack->size());
auto word = &(*stack)[stack->size() - _index - 1]; auto word = stack->rbegin() + _index;
debugStack("get", *word); debugStack("get", *word, _index);
auto outWord = static_cast<i256*>(_pWord); auto outWord = static_cast<i256*>(_pWord);
*outWord = *word; *outWord = *word;
} }
EXPORT void evmccrt_stack_set(void* _stack, uint32_t _index, void* _pWord)
{
auto stack = static_cast<StackImpl*>(_stack);
auto word = static_cast<i256*>(_pWord);
assert(_index < stack->size());
*(stack->rbegin() + _index) = *word;
debugStack("set", *word, _index);
}
} // extern "C" } // extern "C"

2
evmcc/Stack.h

@ -15,6 +15,7 @@ public:
llvm::Value* pop(); llvm::Value* pop();
llvm::Value* top(); llvm::Value* top();
llvm::Value* get(uint32_t _index); llvm::Value* get(uint32_t _index);
void set(uint32_t _index, llvm::Value* _value);
private: private:
llvm::IRBuilder<>& m_builder; llvm::IRBuilder<>& m_builder;
@ -22,6 +23,7 @@ private:
llvm::Function* m_stackPush; llvm::Function* m_stackPush;
llvm::Function* m_stackPop; llvm::Function* m_stackPop;
llvm::Function* m_stackGet; llvm::Function* m_stackGet;
llvm::Function* m_stackSet;
}; };
} }

2
evmcc/bytecode/stack_test.evm

@ -1 +1 @@
65372d0f1dca6e661925338e3e5c2b808280848184505050505050506104576108ae8182 65372d0f1dca6e661925338e3e5c2b808280848184505050505050506104576108ae81819290

4
evmcc/lll/stack_test.lll

@ -18,5 +18,7 @@ POP
1111 1111
2222 2222
DUP2 DUP2
DUP3 DUP2
SWAP3
SWAP1
) )
Loading…
Cancel
Save