mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 19:30:44 +00:00
fixes for JUMP/JUMPI (generating final basic block)
implementation of NOT
This commit is contained in:
parent
ad2c4c4274
commit
fa76d7a4a0
4 changed files with 58 additions and 4 deletions
|
|
@ -60,6 +60,8 @@ llvm::BasicBlock* Compiler::getOrCreateBasicBlockAtPC(ProgramCounter pc)
|
||||||
|
|
||||||
void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
||||||
{
|
{
|
||||||
|
getOrCreateBasicBlockAtPC(0);
|
||||||
|
|
||||||
for (auto curr = bytecode.cbegin(); curr != bytecode.cend(); ++curr)
|
for (auto curr = bytecode.cbegin(); curr != bytecode.cend(); ++curr)
|
||||||
{
|
{
|
||||||
using dev::eth::Instruction;
|
using dev::eth::Instruction;
|
||||||
|
|
@ -168,7 +170,6 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
|
|
||||||
// Create the basic blocks.
|
// Create the basic blocks.
|
||||||
auto entryBlock = BasicBlock::Create(context, "entry", mainFunc);
|
auto entryBlock = BasicBlock::Create(context, "entry", mainFunc);
|
||||||
basicBlocks[0] = entryBlock;
|
|
||||||
builder.SetInsertPoint(entryBlock);
|
builder.SetInsertPoint(entryBlock);
|
||||||
createBasicBlocks(bytecode);
|
createBasicBlocks(bytecode);
|
||||||
|
|
||||||
|
|
@ -189,11 +190,12 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
ProgramCounter currentPC = pc - bytecode.cbegin();
|
ProgramCounter currentPC = pc - bytecode.cbegin();
|
||||||
|
|
||||||
auto blockIter = basicBlocks.find(currentPC);
|
auto blockIter = basicBlocks.find(currentPC);
|
||||||
if (currentPC > 0 && blockIter != basicBlocks.end())
|
if (blockIter != basicBlocks.end())
|
||||||
{
|
{
|
||||||
auto nextBlock = blockIter->second;
|
auto nextBlock = blockIter->second;
|
||||||
// Terminate the current block by jumping to the next one.
|
// Terminate the current block by jumping to the next one.
|
||||||
builder.CreateBr(nextBlock);
|
if (currentBlock != nullptr)
|
||||||
|
builder.CreateBr(nextBlock);
|
||||||
// Insert the next block into the main function.
|
// Insert the next block into the main function.
|
||||||
mainFunc->getBasicBlockList().push_back(nextBlock);
|
mainFunc->getBasicBlockList().push_back(nextBlock);
|
||||||
builder.SetInsertPoint(nextBlock);
|
builder.SetInsertPoint(nextBlock);
|
||||||
|
|
@ -284,6 +286,16 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Instruction::NOT:
|
||||||
|
{
|
||||||
|
auto top = stack.pop();
|
||||||
|
auto zero = ConstantInt::get(Types.word256, 0);
|
||||||
|
auto nonzero = builder.CreateICmpNE(top, zero, "nonzero");
|
||||||
|
auto result = builder.CreateZExt(nonzero, Types.word256);
|
||||||
|
stack.push(result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Instruction::POP:
|
case Instruction::POP:
|
||||||
{
|
{
|
||||||
stack.pop();
|
stack.pop();
|
||||||
|
|
@ -453,7 +465,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
stack.pop();
|
stack.pop();
|
||||||
|
|
||||||
auto top = stack.pop();
|
auto top = stack.pop();
|
||||||
auto cond = builder.CreateTrunc(top, builder.getInt1Ty(), "cond");
|
auto zero = ConstantInt::get(Types.word256, 0);
|
||||||
|
auto cond = builder.CreateICmpNE(top, zero, "nonzero");
|
||||||
auto targetBlock = jumpTargets[currentPC];
|
auto targetBlock = jumpTargets[currentPC];
|
||||||
auto followBlock = basicBlocks[currentPC + 1];
|
auto followBlock = basicBlocks[currentPC + 1];
|
||||||
builder.CreateCondBr(cond, targetBlock, followBlock);
|
builder.CreateCondBr(cond, targetBlock, followBlock);
|
||||||
|
|
@ -551,6 +564,20 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate final basic block (may be jumped to).
|
||||||
|
auto finalPC = bytecode.size();
|
||||||
|
auto it = basicBlocks.find(finalPC);
|
||||||
|
if (it != basicBlocks.end())
|
||||||
|
{
|
||||||
|
auto finalBlock = it->second;
|
||||||
|
|
||||||
|
if (currentBlock != nullptr)
|
||||||
|
builder.CreateBr(finalBlock);
|
||||||
|
|
||||||
|
mainFunc->getBasicBlockList().push_back(finalBlock);
|
||||||
|
builder.SetInsertPoint(finalBlock);
|
||||||
|
}
|
||||||
|
|
||||||
if (!userRet)
|
if (!userRet)
|
||||||
builder.CreateRet(builder.getInt64(0));
|
builder.CreateRet(builder.getInt64(0));
|
||||||
|
|
||||||
|
|
|
||||||
1
evmcc/bytecode/if1.evm
Normal file
1
evmcc/bytecode/if1.evm
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
600160805460006080530b6016596003608054601b586002608054
|
||||||
21
evmcc/lll/if1.asm
Normal file
21
evmcc/lll/if1.asm
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
.code:
|
||||||
|
PUSH 1
|
||||||
|
PUSH 128
|
||||||
|
MSTORE
|
||||||
|
PUSH 0
|
||||||
|
PUSH 128
|
||||||
|
MLOAD
|
||||||
|
GT
|
||||||
|
PUSH [tag0]
|
||||||
|
JUMPI
|
||||||
|
PUSH 3
|
||||||
|
PUSH 128
|
||||||
|
MSTORE
|
||||||
|
PUSH [tag1]
|
||||||
|
JUMP
|
||||||
|
tag0:
|
||||||
|
PUSH 2
|
||||||
|
PUSH 128
|
||||||
|
MSTORE
|
||||||
|
tag1:
|
||||||
|
|
||||||
5
evmcc/lll/if1.lll
Normal file
5
evmcc/lll/if1.lll
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
[i] 1
|
||||||
|
|
||||||
|
( if (> @i 0) [i] 2 [i] 3 )
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue