4 #include <llvm/IR/IntrinsicInst.h> 31 func = llvm::Function::Create(llvm::FunctionType::get(
Type::Void, argTypes,
false), llvm::Function::PrivateLinkage,
"mem.require",
getModule());
32 func->setDoesNotThrow();
34 auto iter = func->arg_begin();
35 llvm::Argument* mem = &(*iter++);
37 llvm::Argument* blkOffset = &(*iter++);
38 blkOffset->setName(
"blkOffset");
39 llvm::Argument* blkSize = &(*iter++);
40 blkSize->setName(
"blkSize");
41 llvm::Argument* jmpBuf = &(*iter++);
42 jmpBuf->setName(
"jmpBuf");
43 llvm::Argument* gas = &(*iter);
46 auto preBB = llvm::BasicBlock::Create(func->getContext(),
"Pre", func);
47 auto checkBB = llvm::BasicBlock::Create(func->getContext(),
"Check", func);
48 auto resizeBB = llvm::BasicBlock::Create(func->getContext(),
"Resize", func);
49 auto returnBB = llvm::BasicBlock::Create(func->getContext(),
"Return", func);
59 static const auto c_inputMax = uint64_t(1) << 33;
65 auto sizeReq0 =
m_builder.CreateNUWAdd(blkO, blkS,
"sizeReq0");
68 auto sizeOk =
m_builder.CreateICmpULE(sizeReq, sizeCur,
"sizeOk");
75 auto w1 =
m_builder.CreateLShr(sizeReq, 5);
76 auto w1s =
m_builder.CreateNUWMul(w1, w1);
78 auto w0 =
m_builder.CreateLShr(sizeCur, 5);
79 auto w0s =
m_builder.CreateNUWMul(w0, w0);
82 auto costOk =
m_builder.CreateAnd(blkOffsetOk, blkSizeOk,
"costOk");
102 auto name = _isStore ? isWord ?
"mstore" :
"mstore8" :
"mload";
103 auto funcType = _isStore ? llvm::FunctionType::get(
Type::Void, storeArgs,
false) : llvm::FunctionType::get(
Type::Word, loadArgs,
false);
104 auto func = llvm::Function::Create(funcType, llvm::Function::PrivateLinkage,
name,
getModule());
108 m_builder.SetInsertPoint(llvm::BasicBlock::Create(func->getContext(), {}, func));
110 auto iter = func->arg_begin();
111 llvm::Argument* mem = &(*iter++);
113 llvm::Argument* index = &(*iter++);
114 index->setName(
"index");
118 llvm::Argument* valueArg = &(*iter);
119 valueArg->setName(
"value");
122 auto valuePtr =
m_builder.CreateBitCast(memPtr, _valueType->getPointerTo(),
"valuePtr");
201 if (
auto constant = llvm::dyn_cast<llvm::ConstantInt>(_size))
203 if (!constant->getValue())
212 require(_destMemIdx, _reqBytes);
229 auto isOutsideData =
m_builder.CreateICmpUGE(_srcIdx, _srcSize);
232 auto dataLeftSize =
m_builder.CreateNUWSub(size64, idx64);
233 auto outOfBound =
m_builder.CreateICmpUGT(reqBytes, dataLeftSize);
234 auto bytesToCopyInner =
m_builder.CreateSelect(outOfBound, dataLeftSize, reqBytes);
235 auto bytesToCopy =
m_builder.CreateSelect(isOutsideData,
m_builder.getInt64(0), bytesToCopyInner,
"bytesToCopy");
236 auto bytesToZero =
m_builder.CreateNUWSub(reqBytes, bytesToCopy,
"bytesToZero");
238 auto src =
m_builder.CreateGEP(_srcPtr, idx64,
"src");
240 auto padIdx =
m_builder.CreateNUWAdd(dstIdx, bytesToCopy,
"padIdx");
243 m_builder.CreateMemCpy(dst, src, bytesToCopy, 0);
llvm::Value * getBytePtr(llvm::Value *_index)
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
llvm::Module * getModule()
Reference to the IR module being compiled.
llvm::Function * getRequireFunc()
llvm::Value * getGasPtr()
void countCopy(llvm::Value *_copyWords)
Count addional gas cost for memory copy.
llvm::Function * m_loadWord
llvm::Function * getStoreWordFunc()
Memory(RuntimeManager &_runtimeManager, GasMeter &_gasMeter)
assert(len-trim+(2 *lenIndices)<=WIDTH)
llvm::Value * loadWord(llvm::Value *_addr)
static llvm::Type * getType()
void require(llvm::Value *_offset, llvm::Value *_size)
Requires the amount of memory to for data defined by offset and size. And counts gas fee for that mem...
void copyBytes(llvm::Value *_srcPtr, llvm::Value *_srcSize, llvm::Value *_srcIndex, llvm::Value *_destMemIdx, llvm::Value *_byteCount)
static llvm::PointerType * BytePtr
static llvm::Value * toBE(IRBuilder &_builder, llvm::Value *_word)
void extend(llvm::Value *_arrayPtr, llvm::Value *_size)
static llvm::IntegerType * Word
void storeWord(llvm::Value *_addr, llvm::Value *_word)
static llvm::ConstantInt * get(int64_t _n)
Returns word-size constant.
static llvm::Value * toNative(IRBuilder &_builder, llvm::Value *_word)
llvm::Function * createFunc(bool _isStore, llvm::Type *_type)
llvm::Function * getLoadWordFunc()
static llvm::PointerType * GasPtr
llvm::Function * getStoreByteFunc()
llvm::Function * m_require
llvm::Function * m_storeWord
llvm::Function * m_storeByte
Compiler helper that depends on runtime data.
void storeByte(llvm::Value *_addr, llvm::Value *_byte)
void count(Instruction _inst)
Count step cost of instruction.
static llvm::IntegerType * Size
llvm::Value * getPtr(llvm::Value *_arrayPtr, llvm::Value *_index)
IRBuilder & m_builder
Reference to parent compiler IR builder.
llvm::Value * size(llvm::Value *_array=nullptr)
RuntimeManager & getRuntimeManager()
static llvm::MDNode * expectTrue
static llvm::IntegerType * Gas
static llvm::IntegerType * Byte
llvm::Value * getJmpBuf()