mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Merge branch 'develop-evmcc' of https://github.com/imapp-pl/ethereum into develop-evmcc
This commit is contained in:
commit
d56f60f768
15 changed files with 141 additions and 4 deletions
|
|
@ -431,6 +431,36 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Instruction::ADDMOD:
|
||||||
|
{
|
||||||
|
auto val1 = stack.pop();
|
||||||
|
auto val2 = stack.pop();
|
||||||
|
auto sum = builder.CreateAdd(val1, val2);
|
||||||
|
auto mod = stack.pop();
|
||||||
|
|
||||||
|
auto sum128 = builder.CreateTrunc(sum, Type::lowPrecision);
|
||||||
|
auto mod128 = builder.CreateTrunc(mod, Type::lowPrecision);
|
||||||
|
auto res128 = builder.CreateURem(sum128, mod128);
|
||||||
|
auto res256 = builder.CreateZExt(res128, Type::i256);
|
||||||
|
stack.push(res256);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Instruction::MULMOD:
|
||||||
|
{
|
||||||
|
auto val1 = stack.pop();
|
||||||
|
auto val2 = stack.pop();
|
||||||
|
auto prod = builder.CreateMul(val1, val2);
|
||||||
|
auto mod = stack.pop();
|
||||||
|
|
||||||
|
auto prod128 = builder.CreateTrunc(prod, Type::lowPrecision);
|
||||||
|
auto mod128 = builder.CreateTrunc(mod, Type::lowPrecision);
|
||||||
|
auto res128 = builder.CreateURem(prod128, mod128);
|
||||||
|
auto res256 = builder.CreateZExt(res128, Type::i256);
|
||||||
|
stack.push(res256);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Instruction::SHA3:
|
case Instruction::SHA3:
|
||||||
{
|
{
|
||||||
auto inOff = stack.pop();
|
auto inOff = stack.pop();
|
||||||
|
|
@ -657,6 +687,13 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Instruction::GAS:
|
||||||
|
{
|
||||||
|
auto value = builder.CreateLoad(gasMeter.getLLVMGasVar());
|
||||||
|
stack.push(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Instruction::ADDRESS:
|
case Instruction::ADDRESS:
|
||||||
{
|
{
|
||||||
auto value = ext.address();
|
auto value = ext.address();
|
||||||
|
|
@ -700,6 +737,38 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Instruction::CALLDATACOPY:
|
||||||
|
{
|
||||||
|
auto zero256 = ConstantInt::get(Type::i256, 0);
|
||||||
|
|
||||||
|
auto destMemIdx = stack.pop();
|
||||||
|
auto srcDataIdx = stack.pop();
|
||||||
|
auto reqBytes = stack.pop();
|
||||||
|
|
||||||
|
// FIXME: ensure memory size reqMemSize.
|
||||||
|
auto reqMemSize = builder.CreateAdd(destMemIdx, reqBytes, "req_mem_size");
|
||||||
|
memory.require(reqMemSize);
|
||||||
|
|
||||||
|
auto memPtr = memory.getData();
|
||||||
|
auto destPtr = builder.CreateGEP(memPtr, destMemIdx, "dest_mem_ptr");
|
||||||
|
|
||||||
|
auto calldataPtr = ext.calldata();
|
||||||
|
auto srcPtr = builder.CreateGEP(calldataPtr, srcDataIdx, "src_idx");
|
||||||
|
|
||||||
|
auto calldataSize = ext.calldatasize();
|
||||||
|
// remaining data bytes:
|
||||||
|
auto remDataSize = builder.CreateSub(calldataSize, srcDataIdx);
|
||||||
|
auto remSizeNegative = builder.CreateICmpSLT(remDataSize, zero256);
|
||||||
|
auto remDataBytes = builder.CreateSelect(remSizeNegative, zero256, remDataSize, "rem_data_bytes");
|
||||||
|
|
||||||
|
auto tooLittleDataBytes = builder.CreateICmpULT(remDataBytes, reqBytes);
|
||||||
|
auto bytesToCopy = builder.CreateSelect(tooLittleDataBytes, remDataBytes, reqBytes, "bytes_to_copy");
|
||||||
|
|
||||||
|
builder.CreateMemCpy(destPtr, srcPtr, bytesToCopy, 0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Instruction::CALLDATALOAD:
|
case Instruction::CALLDATALOAD:
|
||||||
{
|
{
|
||||||
auto index = stack.pop();
|
auto index = stack.pop();
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ using llvm::types::i;
|
||||||
using Linkage = llvm::GlobalValue::LinkageTypes;
|
using Linkage = llvm::GlobalValue::LinkageTypes;
|
||||||
using dev::h256;
|
using dev::h256;
|
||||||
using dev::u256;
|
using dev::u256;
|
||||||
|
|
||||||
namespace evmcc
|
namespace evmcc
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -70,7 +69,7 @@ Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module)
|
||||||
i256Ty, // i256 number;
|
i256Ty, // i256 number;
|
||||||
i256Ty, // i256 difficulty;
|
i256Ty, // i256 difficulty;
|
||||||
i256Ty, // i256 gaslimit;
|
i256Ty, // i256 gaslimit;
|
||||||
//m_builder.getInt8PtrTy()
|
m_builder.getInt8PtrTy() // byte* calldata
|
||||||
};
|
};
|
||||||
auto extDataTy = StructType::create(elements, "ext.Data");
|
auto extDataTy = StructType::create(elements, "ext.Data");
|
||||||
|
|
||||||
|
|
@ -125,6 +124,7 @@ Value* Ext::timestamp() { return getDataElem(8, "timestamp"); }
|
||||||
Value* Ext::number() { return getDataElem(9, "number"); }
|
Value* Ext::number() { return getDataElem(9, "number"); }
|
||||||
Value* Ext::difficulty() { return getDataElem(10, "difficulty"); }
|
Value* Ext::difficulty() { return getDataElem(10, "difficulty"); }
|
||||||
Value* Ext::gaslimit() { return getDataElem(11, "gaslimit"); }
|
Value* Ext::gaslimit() { return getDataElem(11, "gaslimit"); }
|
||||||
|
Value* Ext::calldata() { return getDataElem(12, "calldata"); }
|
||||||
|
|
||||||
Value* Ext::calldataload(Value* _index)
|
Value* Ext::calldataload(Value* _index)
|
||||||
{
|
{
|
||||||
|
|
@ -219,7 +219,7 @@ EXPORT void ext_init(ExtData* _extData)
|
||||||
_extData->number = eth2llvm(ext.currentBlock.number);
|
_extData->number = eth2llvm(ext.currentBlock.number);
|
||||||
_extData->difficulty = eth2llvm(ext.currentBlock.difficulty);
|
_extData->difficulty = eth2llvm(ext.currentBlock.difficulty);
|
||||||
_extData->gaslimit = eth2llvm(ext.currentBlock.gasLimit);
|
_extData->gaslimit = eth2llvm(ext.currentBlock.gasLimit);
|
||||||
//_extData->calldata = ext.data.data();
|
_extData->calldata = ext.data.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void ext_store(i256* _index, i256* _value)
|
EXPORT void ext_store(i256* _index, i256* _value)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ public:
|
||||||
llvm::Value* number();
|
llvm::Value* number();
|
||||||
llvm::Value* difficulty();
|
llvm::Value* difficulty();
|
||||||
llvm::Value* gaslimit();
|
llvm::Value* gaslimit();
|
||||||
|
llvm::Value* calldata();
|
||||||
|
|
||||||
llvm::Value* balance(llvm::Value* _address);
|
llvm::Value* balance(llvm::Value* _address);
|
||||||
void suicide(llvm::Value* _address);
|
void suicide(llvm::Value* _address);
|
||||||
|
|
|
||||||
|
|
@ -144,4 +144,9 @@ void GasMeter::checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilde
|
||||||
_builder.CreateCall(m_gasCheckFunc, cost);
|
_builder.CreateCall(m_gasCheckFunc, cost);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
llvm::GlobalVariable* GasMeter::getLLVMGasVar()
|
||||||
|
{
|
||||||
|
return m_gas;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ public:
|
||||||
/// Generate code that checks the cost of additional memory used by program
|
/// Generate code that checks the cost of additional memory used by program
|
||||||
void checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilder<>& _builder);
|
void checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilder<>& _builder);
|
||||||
|
|
||||||
|
llvm::GlobalVariable* getLLVMGasVar();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Cumulative gas cost of a block of instructions
|
/// Cumulative gas cost of a block of instructions
|
||||||
/// @TODO Handle overflow
|
/// @TODO Handle overflow
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,11 @@ void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word)
|
||||||
dump(0);
|
dump(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
llvm::Value* Memory::getData()
|
||||||
|
{
|
||||||
|
return m_builder.CreateLoad(m_data);
|
||||||
|
}
|
||||||
|
|
||||||
llvm::Value* Memory::getSize()
|
llvm::Value* Memory::getSize()
|
||||||
{
|
{
|
||||||
return m_builder.CreateLoad(m_size);
|
return m_builder.CreateLoad(m_size);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ public:
|
||||||
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);
|
||||||
void storeByte(llvm::Value* _addr, llvm::Value* _byte);
|
void storeByte(llvm::Value* _addr, llvm::Value* _byte);
|
||||||
|
llvm::Value* getData();
|
||||||
llvm::Value* getSize();
|
llvm::Value* getSize();
|
||||||
|
|
||||||
/// Requires this amount of memory. And counts gas fee for that memory.
|
/// Requires this amount of memory. And counts gas fee for that memory.
|
||||||
|
|
|
||||||
1
evmcc/test/arith/addmod.evm
Normal file
1
evmcc/test/arith/addmod.evm
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
60646107b760271460005560006001f2
|
||||||
12
evmcc/test/arith/addmod.lll
Normal file
12
evmcc/test/arith/addmod.lll
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
;; Should return (1975 + 39) `mod` 100 = 14 = 0x0e
|
||||||
|
(asm
|
||||||
|
100
|
||||||
|
1975
|
||||||
|
39
|
||||||
|
ADDMOD
|
||||||
|
0
|
||||||
|
MSTORE8
|
||||||
|
0
|
||||||
|
1
|
||||||
|
RETURN
|
||||||
|
)
|
||||||
1
evmcc/test/arith/mulmod.evm
Normal file
1
evmcc/test/arith/mulmod.evm
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
6064601b60251560005560006001f2
|
||||||
12
evmcc/test/arith/mulmod.lll
Normal file
12
evmcc/test/arith/mulmod.lll
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
;; Should return (27 * 37) `mod` 100 = 99 = 0x63
|
||||||
|
(asm
|
||||||
|
100
|
||||||
|
27
|
||||||
|
37
|
||||||
|
MULMOD
|
||||||
|
0
|
||||||
|
MSTORE8
|
||||||
|
0
|
||||||
|
1
|
||||||
|
RETURN
|
||||||
|
)
|
||||||
1
evmcc/test/ext/calldatacopy1.evm
Normal file
1
evmcc/test/ext/calldatacopy1.evm
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
60146000600a37600053600a6014f2
|
||||||
13
evmcc/test/ext/calldatacopy1.lll
Normal file
13
evmcc/test/ext/calldatacopy1.lll
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
(asm
|
||||||
|
20 ;; byte count
|
||||||
|
0 ;; source index in calldata array
|
||||||
|
10 ;; dest index in memory
|
||||||
|
CALLDATACOPY
|
||||||
|
|
||||||
|
0
|
||||||
|
MLOAD ;; to dump memory
|
||||||
|
|
||||||
|
10
|
||||||
|
20
|
||||||
|
RETURN
|
||||||
|
)
|
||||||
1
evmcc/test/ext/calldatacopy2.evm
Normal file
1
evmcc/test/ext/calldatacopy2.evm
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
606464e8d4a510006000376000536000600af2
|
||||||
13
evmcc/test/ext/calldatacopy2.lll
Normal file
13
evmcc/test/ext/calldatacopy2.lll
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
(asm
|
||||||
|
100 ;; byte count
|
||||||
|
1000000000000 ;; source index in calldata array
|
||||||
|
0 ;; dest index in memory
|
||||||
|
CALLDATACOPY
|
||||||
|
|
||||||
|
0
|
||||||
|
MLOAD ;; to dump memory
|
||||||
|
|
||||||
|
0
|
||||||
|
10
|
||||||
|
RETURN
|
||||||
|
)
|
||||||
Loading…
Reference in a new issue