Browse Source

fixes for JUMP/JUMPI (generating final basic block)

implementation of NOT
cl-refactor
artur-zawlocki 10 years ago
parent
commit
d843ec660a
  1. 33
      evmcc/Compiler.cpp
  2. 1
      evmcc/bytecode/if1.evm
  3. 21
      evmcc/lll/if1.asm
  4. 5
      evmcc/lll/if1.lll

33
evmcc/Compiler.cpp

@ -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,10 +190,11 @@ 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.
if (currentBlock != nullptr)
builder.CreateBr(nextBlock); 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);
@ -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

@ -0,0 +1 @@
600160805460006080530b6016596003608054601b586002608054

21
evmcc/lll/if1.asm

@ -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

@ -0,0 +1,5 @@
{
[i] 1
( if (> @i 0) [i] 2 [i] 3 )
}
Loading…
Cancel
Save