mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 03:10:48 +00:00
POP and DUP* instructions
This commit is contained in:
parent
4266ce54fc
commit
3e01d183a0
5 changed files with 85 additions and 34 deletions
|
|
@ -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,21 +110,33 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
stack.push(c);
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//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
|
||||
|
||||
//stack.pop();
|
||||
|
||||
builder.CreateRet(ConstantInt::get(Type::getInt32Ty(context), 0));
|
||||
|
||||
return module;
|
||||
|
|
|
|||
|
|
@ -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,13 +67,6 @@ void Stack::push(llvm::Value* _value)
|
|||
}
|
||||
|
||||
|
||||
llvm::Value* Stack::top()
|
||||
{
|
||||
m_builder.CreateCall(m_stackTop, m_args);
|
||||
return m_builder.CreateLoad(m_args[1]);
|
||||
}
|
||||
|
||||
|
||||
llvm::Value* Stack::pop()
|
||||
{
|
||||
m_builder.CreateCall(m_stackPop, m_args);
|
||||
|
|
@ -79,6 +74,20 @@ llvm::Value* Stack::pop()
|
|||
}
|
||||
|
||||
|
||||
llvm::Value* Stack::get(uint32_t _index)
|
||||
{
|
||||
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,16 +123,6 @@ EXPORT void evmccrt_stack_push(void* _stack, void* _pWord)
|
|||
stack->push_back(*word);
|
||||
}
|
||||
|
||||
EXPORT void evmccrt_stack_top(void* _stack, void* _pWord)
|
||||
{
|
||||
auto stack = static_cast<StackImpl*>(_stack);
|
||||
assert(!stack->empty());
|
||||
auto word = &stack->back();
|
||||
debugStack("top", *word);
|
||||
auto outWord = static_cast<i256*>(_pWord);
|
||||
*outWord = *word;
|
||||
}
|
||||
|
||||
EXPORT void evmccrt_stack_pop(void* _stack, void* _pWord)
|
||||
{
|
||||
auto stack = static_cast<StackImpl*>(_stack);
|
||||
|
|
@ -135,4 +134,14 @@ EXPORT void evmccrt_stack_pop(void* _stack, void* _pWord)
|
|||
*outWord = *word;
|
||||
}
|
||||
|
||||
EXPORT void evmccrt_stack_get(void* _stack, uint32_t _index, void* _pWord)
|
||||
{
|
||||
auto stack = static_cast<StackImpl*>(_stack);
|
||||
assert(_index < stack->size());
|
||||
auto word = &(*stack)[stack->size() - _index - 1];
|
||||
debugStack("get", *word);
|
||||
auto outWord = static_cast<i256*>(_pWord);
|
||||
*outWord = *word;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -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
Normal file
1
evmcc/bytecode/stack_test.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
65372d0f1dca6e661925338e3e5c2b808280848184505050505050506104576108ae8182
|
||||
22
evmcc/lll/stack_test.lll
Normal file
22
evmcc/lll/stack_test.lll
Normal file
|
|
@ -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…
Reference in a new issue