mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 19:30:44 +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);
|
auto inst = static_cast<Instruction>(*pc);
|
||||||
switch (inst)
|
switch (inst)
|
||||||
{
|
{
|
||||||
|
case Instruction::POP:
|
||||||
|
{
|
||||||
|
stack.pop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Instruction::PUSH1:
|
case Instruction::PUSH1:
|
||||||
case Instruction::PUSH2:
|
case Instruction::PUSH2:
|
||||||
case Instruction::PUSH3:
|
case Instruction::PUSH3:
|
||||||
|
|
@ -104,21 +110,33 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
stack.push(c);
|
stack.push(c);
|
||||||
break;
|
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));
|
builder.CreateRet(ConstantInt::get(Type::getInt32Ty(context), 0));
|
||||||
|
|
||||||
return module;
|
return module;
|
||||||
|
|
|
||||||
|
|
@ -47,12 +47,14 @@ Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
|
||||||
m_stackPush = llvm::Function::Create(funcType,
|
m_stackPush = llvm::Function::Create(funcType,
|
||||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_push", _module);
|
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,
|
m_stackPop = llvm::Function::Create(funcType,
|
||||||
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_pop", _module);
|
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[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");
|
||||||
}
|
}
|
||||||
|
|
@ -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()
|
llvm::Value* Stack::pop()
|
||||||
{
|
{
|
||||||
m_builder.CreateCall(m_stackPop, m_args);
|
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)
|
void debugStack(const char* op, const i256& word)
|
||||||
{
|
{
|
||||||
std::cerr << "STACK " << std::setw(4) << std::setfill(' ') << op << ": "
|
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);
|
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)
|
EXPORT void evmccrt_stack_pop(void* _stack, void* _pWord)
|
||||||
{
|
{
|
||||||
auto stack = static_cast<StackImpl*>(_stack);
|
auto stack = static_cast<StackImpl*>(_stack);
|
||||||
|
|
@ -135,4 +134,14 @@ EXPORT void evmccrt_stack_pop(void* _stack, void* _pWord)
|
||||||
*outWord = *word;
|
*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"
|
} // extern "C"
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,16 @@ public:
|
||||||
Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module);
|
Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module);
|
||||||
|
|
||||||
void push(llvm::Value* _value);
|
void push(llvm::Value* _value);
|
||||||
llvm::Value* top();
|
|
||||||
llvm::Value* pop();
|
llvm::Value* pop();
|
||||||
|
llvm::Value* top();
|
||||||
|
llvm::Value* get(uint32_t _index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
llvm::IRBuilder<>& m_builder;
|
llvm::IRBuilder<>& m_builder;
|
||||||
llvm::Value* m_args[2];
|
llvm::Value* m_args[2];
|
||||||
llvm::Function* m_stackPush;
|
llvm::Function* m_stackPush;
|
||||||
llvm::Function* m_stackTop;
|
|
||||||
llvm::Function* m_stackPop;
|
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