Browse Source

store8 function added as implementation of MSTORE8

[#80191662]
cl-refactor
Paweł Bylica 10 years ago
parent
commit
5f1ea8f832
  1. 77
      evmcc/Memory.cpp
  2. 8
      evmcc/Memory.h

77
evmcc/Memory.cpp

@ -51,40 +51,48 @@ Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* _module)
m_size->setUnnamedAddr(true); // Address is not important m_size->setUnnamedAddr(true); // Address is not important
m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, Type::WordPtr, false), llvm::Function::ExternalLinkage, "mem_resize", _module); m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, Type::WordPtr, false), llvm::Function::ExternalLinkage, "mem_resize", _module);
m_storeWord = createStoreFunc(Type::i256, _module);
m_storeByte = createStoreFunc(Type::Byte, _module);
}
llvm::Function* Memory::createStoreFunc(llvm::Type* _valueType, llvm::Module* _module)
{
auto wordValue = _valueType == Type::i256;
llvm::Type* storeArgs[] = {Type::i256, Type::i256}; llvm::Type* storeArgs[] = {Type::i256, _valueType};
m_store = llvm::Function::Create(llvm::FunctionType::get(Type::Void, storeArgs, false), llvm::Function::PrivateLinkage, "mem.store", _module); auto name = wordValue ? "store" : "store8";
auto origBB = m_builder.GetInsertBlock(); auto storeFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, storeArgs, false), llvm::Function::PrivateLinkage, name, _module);
auto origPt = m_builder.GetInsertPoint();
auto checkBB = llvm::BasicBlock::Create(m_store->getContext(), "check", m_store); auto checkBB = llvm::BasicBlock::Create(storeFunc->getContext(), "check", storeFunc);
auto resizeBB = llvm::BasicBlock::Create(m_store->getContext(), "resize", m_store); auto resizeBB = llvm::BasicBlock::Create(storeFunc->getContext(), "resize", storeFunc);
auto storeBB = llvm::BasicBlock::Create(m_store->getContext(), "store", m_store); auto storeBB = llvm::BasicBlock::Create(storeFunc->getContext(), "store", storeFunc);
m_builder.SetInsertPoint(checkBB); llvm::IRBuilder<> builder(checkBB);
llvm::Value* index = m_store->arg_begin(); llvm::Value* index = storeFunc->arg_begin();
index->setName("index"); index->setName("index");
llvm::Value* value = ++m_store->arg_begin(); llvm::Value* value = ++storeFunc->arg_begin();
value->setName("value"); value->setName("value");
auto sizeRequired = m_builder.CreateAdd(index, m_builder.getIntN(256, 32), "sizeRequired"); auto valueSize = _valueType->getPrimitiveSizeInBits() / 8;
auto size = m_builder.CreateLoad(m_size, "size"); auto sizeRequired = builder.CreateAdd(index, builder.getIntN(256, valueSize), "sizeRequired");
auto resizeNeeded = m_builder.CreateICmpULE(sizeRequired, size, "resizeNeeded"); auto size = builder.CreateLoad(m_size, "size");
m_builder.CreateCondBr(resizeNeeded, resizeBB, storeBB); // OPT branch weights? auto resizeNeeded = builder.CreateICmpULE(sizeRequired, size, "resizeNeeded");
builder.CreateCondBr(resizeNeeded, resizeBB, storeBB); // OPT branch weights?
m_builder.SetInsertPoint(resizeBB);
m_builder.CreateStore(sizeRequired, m_size); builder.SetInsertPoint(resizeBB);
llvm::Value* data = m_builder.CreateCall(m_resize, m_size, "data"); builder.CreateStore(sizeRequired, m_size);
m_builder.CreateStore(data, m_data); auto newData = builder.CreateCall(m_resize, m_size, "newData");
m_builder.CreateBr(storeBB); builder.CreateStore(newData, m_data);
builder.CreateBr(storeBB);
m_builder.SetInsertPoint(storeBB);
data = m_builder.CreateLoad(m_data, "data"); builder.SetInsertPoint(storeBB);
auto ptr = m_builder.CreateGEP(data, index, "ptr"); auto data = builder.CreateLoad(m_data, "data");
ptr = m_builder.CreateBitCast(ptr, Type::WordPtr, "wordPtr"); auto ptr = builder.CreateGEP(data, index, "ptr");
m_builder.CreateStore(value, ptr); if (wordValue)
m_builder.CreateRetVoid(); ptr = builder.CreateBitCast(ptr, Type::WordPtr, "wordPtr");
builder.CreateStore(value, ptr);
m_builder.SetInsertPoint(origBB, origPt); builder.CreateRetVoid();
return storeFunc;
} }
@ -108,19 +116,15 @@ llvm::Value* Memory::loadWord(llvm::Value* _addr)
void Memory::storeWord(llvm::Value* _addr, llvm::Value* _word) void Memory::storeWord(llvm::Value* _addr, llvm::Value* _word)
{ {
m_builder.CreateCall2(m_store, _addr, _word); m_builder.CreateCall2(m_storeWord, _addr, _word);
dump(0); dump(0);
} }
void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word) void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word)
{ {
auto byte = m_builder.CreateTrunc(_word, m_builder.getInt8Ty(), "byte"); auto byte = m_builder.CreateTrunc(_word, Type::Byte, "byte");
auto index = m_builder.CreateTrunc(_addr, m_builder.getInt64Ty(), "index"); m_builder.CreateCall2(m_storeByte, _addr, byte);
auto base = m_builder.CreateCall(m_memRequire, index, "base");
auto ptr = m_builder.CreateGEP(base, index, "ptr");
m_builder.CreateStore(byte, ptr);
dump(0); dump(0);
} }
@ -152,7 +156,6 @@ extern "C"
EXPORT uint8_t* mem_resize(i256* _size) EXPORT uint8_t* mem_resize(i256* _size)
{ {
assert(false);
auto size = _size->a; // Trunc to 64-bit auto size = _size->a; // Trunc to 64-bit
auto& memory = Runtime::getMemory(); auto& memory = Runtime::getMemory();
memory.resize(size); memory.resize(size);

8
evmcc/Memory.h

@ -11,6 +11,8 @@ class Memory
{ {
public: public:
Memory(llvm::IRBuilder<>& _builder, llvm::Module* _module); Memory(llvm::IRBuilder<>& _builder, llvm::Module* _module);
Memory(const Memory&) = delete;
void operator=(Memory) = delete;
llvm::Value* loadWord(llvm::Value* _addr); llvm::Value* loadWord(llvm::Value* _addr);
void storeWord(llvm::Value* _addr, llvm::Value* _word); void storeWord(llvm::Value* _addr, llvm::Value* _word);
@ -19,13 +21,17 @@ public:
void dump(uint64_t _begin, uint64_t _end = 0); void dump(uint64_t _begin, uint64_t _end = 0);
private:
llvm::Function* createStoreFunc(llvm::Type* _type, llvm::Module* _module);
private: private:
llvm::IRBuilder<>& m_builder; llvm::IRBuilder<>& m_builder;
llvm::GlobalVariable* m_data; llvm::GlobalVariable* m_data;
llvm::GlobalVariable* m_size; llvm::GlobalVariable* m_size;
llvm::Function* m_store; llvm::Function* m_storeWord;
llvm::Function* m_storeByte;
llvm::Function* m_resize; llvm::Function* m_resize;
llvm::Function* m_memRequire; llvm::Function* m_memRequire;

Loading…
Cancel
Save