Browse Source

POP and DUP* instructions

cl-refactor
Paweł Bylica 10 years ago
parent
commit
3e01d183a0
  1. 42
      evmcc/Compiler.cpp
  2. 37
      evmcc/Stack.cpp
  3. 5
      evmcc/Stack.h
  4. 1
      evmcc/bytecode/stack_test.evm
  5. 22
      evmcc/lll/stack_test.lll

42
evmcc/Compiler.cpp

@ -59,6 +59,12 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
auto inst = static_cast<Instruction>(*pc);
switch (inst)
{
case Instruction::POP:
{
stack.pop();
break;
}
case Instruction::PUSH1:
case Instruction::PUSH2:
case Instruction::PUSH3:
@ -104,20 +110,32 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
stack.push(c);
break;
}
}
}
//uint64_t words[] = { 1, 2, 3, 4 };
//auto val = llvm::APInt(256, 4, words);
//auto c = ConstantInt::get(Types.word256, val);
//stack.push(c);
//stack.push(ConstantInt::get(Types.word256, 0x1122334455667788));
//auto top = stack.top();
//stack.push(top); // dup
case Instruction::DUP1:
case Instruction::DUP2:
case Instruction::DUP3:
case Instruction::DUP4:
case Instruction::DUP5:
case Instruction::DUP6:
case Instruction::DUP7:
case Instruction::DUP8:
case Instruction::DUP9:
case Instruction::DUP10:
case Instruction::DUP11:
case Instruction::DUP12:
case Instruction::DUP13:
case Instruction::DUP14:
case Instruction::DUP15:
case Instruction::DUP16:
{
auto index = static_cast<uint32_t>(inst) - static_cast<uint32_t>(Instruction::DUP1);
auto value = stack.get(index);
stack.push(value);
break;
}
//stack.pop();
}
}
builder.CreateRet(ConstantInt::get(Type::getInt32Ty(context), 0));

37
evmcc/Stack.cpp

@ -47,12 +47,14 @@ Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
m_stackPush = llvm::Function::Create(funcType,
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_push", _module);
m_stackTop = llvm::Function::Create(funcType,
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_top", _module);
m_stackPop = llvm::Function::Create(funcType,
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_pop", _module);
llvm::Type* getArgsTypes[] = {stackPtrTy, m_builder.getInt32Ty(), i256PtrTy};
auto getFuncType = llvm::FunctionType::get(voidTy, getArgsTypes);
m_stackGet = llvm::Function::Create(getFuncType,
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_get", _module);
m_args[0] = m_builder.CreateCall(stackCreate, "stack.ptr");
m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "stack.val");
}
@ -65,20 +67,27 @@ void Stack::push(llvm::Value* _value)
}
llvm::Value* Stack::top()
llvm::Value* Stack::pop()
{
m_builder.CreateCall(m_stackTop, m_args);
m_builder.CreateCall(m_stackPop, m_args);
return m_builder.CreateLoad(m_args[1]);
}
llvm::Value* Stack::pop()
llvm::Value* Stack::get(uint32_t _index)
{
m_builder.CreateCall(m_stackPop, m_args);
llvm::Value* args[] = {m_args[0], m_builder.getInt32(_index), m_args[1]};
m_builder.CreateCall(m_stackGet, args);
return m_builder.CreateLoad(m_args[1]);
}
llvm::Value* Stack::top()
{
return get(0);
}
void debugStack(const char* op, const i256& word)
{
std::cerr << "STACK " << std::setw(4) << std::setfill(' ') << op << ": "
@ -114,24 +123,24 @@ EXPORT void evmccrt_stack_push(void* _stack, void* _pWord)
stack->push_back(*word);
}
EXPORT void evmccrt_stack_top(void* _stack, void* _pWord)
EXPORT void evmccrt_stack_pop(void* _stack, void* _pWord)
{
auto stack = static_cast<StackImpl*>(_stack);
assert(!stack->empty());
auto word = &stack->back();
debugStack("top", *word);
debugStack("pop", *word);
auto outWord = static_cast<i256*>(_pWord);
stack->pop_back();
*outWord = *word;
}
EXPORT void evmccrt_stack_pop(void* _stack, void* _pWord)
EXPORT void evmccrt_stack_get(void* _stack, uint32_t _index, void* _pWord)
{
auto stack = static_cast<StackImpl*>(_stack);
assert(!stack->empty());
auto word = &stack->back();
debugStack("pop", *word);
assert(_index < stack->size());
auto word = &(*stack)[stack->size() - _index - 1];
debugStack("get", *word);
auto outWord = static_cast<i256*>(_pWord);
stack->pop_back();
*outWord = *word;
}

5
evmcc/Stack.h

@ -12,15 +12,16 @@ public:
Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module);
void push(llvm::Value* _value);
llvm::Value* top();
llvm::Value* pop();
llvm::Value* top();
llvm::Value* get(uint32_t _index);
private:
llvm::IRBuilder<>& m_builder;
llvm::Value* m_args[2];
llvm::Function* m_stackPush;
llvm::Function* m_stackTop;
llvm::Function* m_stackPop;
llvm::Function* m_stackGet;
};
}

1
evmcc/bytecode/stack_test.evm

@ -0,0 +1 @@
65372d0f1dca6e661925338e3e5c2b808280848184505050505050506104576108ae8182

22
evmcc/lll/stack_test.lll

@ -0,0 +1,22 @@
(asm
60666666666606
7077777777777707
DUP1
DUP3
DUP1
DUP5
DUP2
DUP5
POP
POP
POP
POP
POP
POP
POP
1111
2222
DUP2
DUP3
)
Loading…
Cancel
Save