From fe38de867e33f286138cace91b7a81866a97f29f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 6 Oct 2014 10:47:31 +0200 Subject: [PATCH] SHA3 instruction [Delivers #79534494] --- evmcc/Compiler.cpp | 8 ++++++++ evmcc/Ext.cpp | 23 +++++++++++++++++++++++ evmcc/Ext.h | 3 +++ evmcc/bytecode/ext_test.evm | 2 +- evmcc/lll/ext_test.lll | 9 +++++++++ 5 files changed, 44 insertions(+), 1 deletion(-) diff --git a/evmcc/Compiler.cpp b/evmcc/Compiler.cpp index 48b74e501..4fead05c0 100644 --- a/evmcc/Compiler.cpp +++ b/evmcc/Compiler.cpp @@ -421,6 +421,14 @@ std::unique_ptr Compiler::compile(const dev::bytes& bytecode) break; } + case Instruction::SHA3: + { + auto inOff = stack.pop(); + auto inSize = stack.pop(); + auto hash = ext.sha3(inOff, inSize); + stack.push(hash); + } + case Instruction::POP: { stack.pop(); diff --git a/evmcc/Ext.cpp b/evmcc/Ext.cpp index 9fad58fa7..8266bd728 100644 --- a/evmcc/Ext.cpp +++ b/evmcc/Ext.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include "Runtime.h" #ifdef _MSC_VER @@ -90,6 +92,7 @@ Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module) Type* args[] = {i256PtrTy, i256PtrTy, i256PtrTy, i256PtrTy, i256PtrTy, i256PtrTy, i256PtrTy, i256PtrTy}; 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*, i<256>*, i<256>*), true>::get(ctx), Linkage::ExternalLinkage, "ext_sha3", module); m_builder.CreateCall(m_init, m_data); @@ -182,6 +185,17 @@ llvm::Value* Ext::call(llvm::Value* _gas, llvm::Value* _receiveAddress, llvm::Va return m_builder.CreateLoad(m_args[1]); } +llvm::Value* Ext::sha3(llvm::Value* _inOff, llvm::Value* _inSize) +{ + m_builder.CreateStore(_inOff, m_args[0]); + m_builder.CreateStore(_inSize, m_arg2); + llvm::Value* args[] = {m_args[0], m_arg2, m_args[1]}; + m_builder.CreateCall(m_sha3, args); + Value* hash = m_builder.CreateLoad(m_args[1]); + hash = bswap(hash); // to LE + return hash; +} + extern "C" { @@ -285,6 +299,15 @@ EXPORT void ext_call(i256* _gas, h256* _receiveAddress, i256* _value, i256* _inO _ret->a = ret ? 1 : 0; } +EXPORT void ext_sha3(i256* _inOff, i256* _inSize, i256* _ret) +{ + auto inOff = static_cast(llvm2eth(*_inOff)); + auto inSize = static_cast(llvm2eth(*_inSize)); + auto dataRef = dev::bytesConstRef(Runtime::getMemory().data() + inOff, inSize); + auto hash = dev::eth::sha3(dataRef); + *_ret = *reinterpret_cast(&hash); +} + } } diff --git a/evmcc/Ext.h b/evmcc/Ext.h index c2c9f8455..7801d0540 100644 --- a/evmcc/Ext.h +++ b/evmcc/Ext.h @@ -38,6 +38,8 @@ public: llvm::Value* create(llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize); 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); + private: llvm::Value* getDataElem(unsigned _index, const llvm::Twine& _name = ""); @@ -63,6 +65,7 @@ private: llvm::Function* m_create; llvm::Function* m_call; llvm::Function* m_bswap; + llvm::Function* m_sha3; }; diff --git a/evmcc/bytecode/ext_test.evm b/evmcc/bytecode/ext_test.evm index 6c99e8fa0..580bd9675 100644 --- a/evmcc/bytecode/ext_test.evm +++ b/evmcc/bytecode/ext_test.evm @@ -1 +1 @@ -5a3031333234363a4041424344455a36600035602635601335387f1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffff600054602060006000f06020600060206000600030610bb8f130ff60016002f2 +5a3031333234363a4041424344455a36600035602635601335387f1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffff600054602060006000f06020600060206000600030610bb8f1600053611000545b60200260002030ff60016002f2 diff --git a/evmcc/lll/ext_test.lll b/evmcc/lll/ext_test.lll index 0625afadc..3287ae95f 100644 --- a/evmcc/lll/ext_test.lll +++ b/evmcc/lll/ext_test.lll @@ -38,6 +38,15 @@ CREATE ADDRESS 3000 CALL +0 +MLOAD +4096 +MSTORE +MSIZE +32 +MUL +0 +SHA3 ADDRESS SUICIDE 1