mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 19:30:44 +00:00
SWAP* instructions
This commit is contained in:
parent
3e01d183a0
commit
e53c0a4877
5 changed files with 63 additions and 13 deletions
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1 +1 @@
|
||||||
65372d0f1dca6e661925338e3e5c2b808280848184505050505050506104576108ae8182
|
65372d0f1dca6e661925338e3e5c2b808280848184505050505050506104576108ae81819290
|
||||||
|
|
|
||||||
|
|
@ -18,5 +18,7 @@ POP
|
||||||
1111
|
1111
|
||||||
2222
|
2222
|
||||||
DUP2
|
DUP2
|
||||||
DUP3
|
DUP2
|
||||||
|
SWAP3
|
||||||
|
SWAP1
|
||||||
)
|
)
|
||||||
Loading…
Reference in a new issue