Browse Source

- fixes for RETURN and STOP

- codegen for SLT, SGT, EQ and NEG
cl-refactor
artur-zawlocki 10 years ago
parent
commit
f075b7b227
  1. 83
      evmcc/Compiler.cpp
  2. 1
      evmcc/bytecode/return1.evm
  3. 6
      evmcc/lll/return1.lll

83
evmcc/Compiler.cpp

@ -61,6 +61,7 @@ llvm::BasicBlock* Compiler::getOrCreateBasicBlockAtPC(ProgramCounter pc)
void Compiler::createBasicBlocks(const dev::bytes& bytecode) void Compiler::createBasicBlocks(const dev::bytes& bytecode)
{ {
getOrCreateBasicBlockAtPC(0); getOrCreateBasicBlockAtPC(0);
getOrCreateBasicBlockAtPC(bytecode.size());
for (auto curr = bytecode.cbegin(); curr != bytecode.cend(); ++curr) for (auto curr = bytecode.cbegin(); curr != bytecode.cend(); ++curr)
{ {
@ -147,6 +148,18 @@ void Compiler::createBasicBlocks(const dev::bytes& bytecode)
std::exit(1); std::exit(1);
} }
case Instruction::RETURN:
case Instruction::STOP:
{
// Create a basic block starting at the following instruction.
if (curr + 1 < bytecode.cend())
{
ProgramCounter nextPC = (curr + 1 - bytecode.cbegin());
getOrCreateBasicBlockAtPC(nextPC);
}
break;
}
default: default:
break; break;
} }
@ -178,12 +191,9 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
auto memory = Memory(builder, module.get()); auto memory = Memory(builder, module.get());
auto ext = Ext(builder, module.get()); auto ext = Ext(builder, module.get());
auto userRet = false;
auto finished = false;
BasicBlock* currentBlock = entryBlock; BasicBlock* currentBlock = entryBlock;
for (auto pc = bytecode.cbegin(); pc != bytecode.cend() && !finished; ++pc) for (auto pc = bytecode.cbegin(); pc != bytecode.cend(); ++pc)
{ {
using dev::eth::Instruction; using dev::eth::Instruction;
@ -286,6 +296,15 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
break; break;
} }
case Instruction::NEG:
{
auto top = stack.pop();
auto zero = ConstantInt::get(Types.word256, 0);
auto res = builder.CreateSub(zero, top);
stack.push(res);
break;
}
case Instruction::LT: case Instruction::LT:
{ {
auto lhs = stack.pop(); auto lhs = stack.pop();
@ -306,6 +325,36 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
break; break;
} }
case Instruction::SLT:
{
auto lhs = stack.pop();
auto rhs = stack.pop();
auto res1 = builder.CreateICmpSLT(lhs, rhs);
auto res256 = builder.CreateZExt(res1, Types.word256);
stack.push(res256);
break;
}
case Instruction::SGT:
{
auto lhs = stack.pop();
auto rhs = stack.pop();
auto res1 = builder.CreateICmpSGT(lhs, rhs);
auto res256 = builder.CreateZExt(res1, Types.word256);
stack.push(res256);
break;
}
case Instruction::EQ:
{
auto lhs = stack.pop();
auto rhs = stack.pop();
auto res1 = builder.CreateICmpEQ(lhs, rhs);
auto res256 = builder.CreateZExt(res1, Types.word256);
stack.push(res256);
break;
}
case Instruction::NOT: case Instruction::NOT:
{ {
auto top = stack.pop(); auto top = stack.pop();
@ -682,36 +731,32 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
ret = builder.CreateOr(ret, size); ret = builder.CreateOr(ret, size);
builder.CreateRet(ret); builder.CreateRet(ret);
finished = true; currentBlock = nullptr;
userRet = true;
break; break;
} }
case Instruction::STOP: case Instruction::STOP:
{ {
finished = true; builder.CreateRet(builder.getInt64(0));
currentBlock = nullptr;
break; break;
} }
} }
} }
// Generate final basic block (may be jumped to). // Generate the final basic block.
auto finalPC = bytecode.size(); auto finalPC = bytecode.size();
auto it = basicBlocks.find(finalPC); auto it = basicBlocks.find(finalPC);
if (it != basicBlocks.end()) assert(it != basicBlocks.end());
{ auto finalBlock = it->second;
auto finalBlock = it->second;
if (currentBlock != nullptr) if (currentBlock != nullptr)
builder.CreateBr(finalBlock); builder.CreateBr(finalBlock);
mainFunc->getBasicBlockList().push_back(finalBlock);
builder.SetInsertPoint(finalBlock);
}
if (!userRet) mainFunc->getBasicBlockList().push_back(finalBlock);
builder.CreateRet(builder.getInt64(0)); builder.SetInsertPoint(finalBlock);
builder.CreateRet(builder.getInt64(0));
return module; return module;
} }

1
evmcc/bytecode/return1.evm

@ -0,0 +1 @@
600160805460006080530b601b59600160005460206000f2602a58602760005460206000f26002608054

6
evmcc/lll/return1.lll

@ -0,0 +1,6 @@
;; code should return 39
;; i should remain 1
{
[i] 1
( if (> @i 0) { (return 39) [i] 2 } (return 1) )
}
Loading…
Cancel
Save