mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
parent
dafa5bc890
commit
7f8848744d
5 changed files with 38 additions and 1 deletions
|
|
@ -274,6 +274,15 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
break;
|
||||
}
|
||||
|
||||
case Instruction::EXP:
|
||||
{
|
||||
auto left = stack.pop();
|
||||
auto right = stack.pop();
|
||||
auto ret = ext.exp(left, right);
|
||||
stack.push(ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case Instruction::NEG:
|
||||
{
|
||||
auto top = stack.pop();
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module)
|
|||
m_call = Function::Create(FunctionType::get(m_builder.getVoidTy(), args, false), Linkage::ExternalLinkage, "ext_call", module);
|
||||
m_bswap = Intrinsic::getDeclaration(module, Intrinsic::bswap, i256Ty);
|
||||
m_sha3 = Function::Create(TypeBuilder<void(i<256>*, i<256>*, i<256>*), true>::get(ctx), Linkage::ExternalLinkage, "ext_sha3", module);
|
||||
m_exp = Function::Create(TypeBuilder<void(i<256>*, i<256>*, i<256>*), true>::get(ctx), Linkage::ExternalLinkage, "ext_exp", module);
|
||||
|
||||
|
||||
m_builder.CreateCall(m_init, m_data);
|
||||
|
|
@ -196,6 +197,15 @@ llvm::Value* Ext::sha3(llvm::Value* _inOff, llvm::Value* _inSize)
|
|||
return hash;
|
||||
}
|
||||
|
||||
llvm::Value* Ext::exp(llvm::Value* _left, llvm::Value* _right)
|
||||
{
|
||||
m_builder.CreateStore(_left, m_args[0]);
|
||||
m_builder.CreateStore(_right, m_arg2);
|
||||
llvm::Value* args[] = {m_args[0], m_arg2, m_args[1]};
|
||||
m_builder.CreateCall(m_exp, args);
|
||||
return m_builder.CreateLoad(m_args[1]);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
|
|
@ -308,6 +318,14 @@ EXPORT void ext_sha3(i256* _inOff, i256* _inSize, i256* _ret)
|
|||
*_ret = *reinterpret_cast<i256*>(&hash);
|
||||
}
|
||||
|
||||
EXPORT void ext_exp(i256* _left, i256* _right, i256* _ret)
|
||||
{
|
||||
dev::bigint left = llvm2eth(*_left);
|
||||
dev::bigint right = llvm2eth(*_right);
|
||||
auto ret = static_cast<u256>(boost::multiprecision::powm(left, right, dev::bigint(2) << 256));
|
||||
*_ret = eth2llvm(ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
llvm::Value* call(llvm::Value* _gas, llvm::Value* _receiveAddress, llvm::Value* _value, llvm::Value* _inOff, llvm::Value* _inSize, llvm::Value* _outOff, llvm::Value* _outSize);
|
||||
|
||||
llvm::Value* sha3(llvm::Value* _inOff, llvm::Value* _inSize);
|
||||
llvm::Value* exp(llvm::Value* _left, llvm::Value* _right);
|
||||
|
||||
private:
|
||||
llvm::Value* getDataElem(unsigned _index, const llvm::Twine& _name = "");
|
||||
|
|
@ -66,6 +67,7 @@ private:
|
|||
llvm::Function* m_call;
|
||||
llvm::Function* m_bswap;
|
||||
llvm::Function* m_sha3;
|
||||
llvm::Function* m_exp;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
60016001900160070260050160029004600490066021900560150160030260059007600303
|
||||
60016001900160070260050160029004600490066021900560150160030260059007600303600960110860005460086000f2
|
||||
|
|
|
|||
|
|
@ -26,4 +26,12 @@ SWAP1
|
|||
SMOD;; 3
|
||||
3
|
||||
SUB ;; 0
|
||||
9
|
||||
17
|
||||
EXP ;; 17^9
|
||||
0
|
||||
MSTORE
|
||||
8
|
||||
0
|
||||
RETURN
|
||||
)
|
||||
Loading…
Reference in a new issue