Basic arithmetic, limited precision for MUL, DIV and MOD.

This commit is contained in:
Paweł Bylica 2014-09-30 11:26:58 +02:00
parent e53c0a4877
commit 58e03d5165
5 changed files with 171 additions and 0 deletions

View file

@ -19,6 +19,7 @@ struct
llvm::Type* word256arr;
llvm::Type* size;
llvm::Type* Void;
llvm::Type* WordLowPrecision;
} Types;
Compiler::Compiler()
@ -31,6 +32,9 @@ Compiler::Compiler()
Types.word256arr = llvm::ArrayType::get(Types.word256, 100);
Types.size = llvm::Type::getInt64Ty(context);
Types.Void = llvm::Type::getVoidTy(context);
// TODO: Use 64-bit for now. In 128-bit compiler-rt library functions are required
Types.WordLowPrecision = llvm::Type::getIntNTy(context, 64);
}
@ -59,6 +63,85 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
auto inst = static_cast<Instruction>(*pc);
switch (inst)
{
case Instruction::ADD:
{
auto lhs = stack.pop();
auto rhs = stack.pop();
auto result = builder.CreateAdd(lhs, rhs);
stack.push(result);
break;
}
case Instruction::SUB:
{
auto lhs = stack.pop();
auto rhs = stack.pop();
auto result = builder.CreateSub(lhs, rhs);
stack.push(result);
break;
}
case Instruction::MUL:
{
auto lhs256 = stack.pop();
auto rhs256 = stack.pop();
auto lhs128 = builder.CreateTrunc(lhs256, Types.WordLowPrecision);
auto rhs128 = builder.CreateTrunc(rhs256, Types.WordLowPrecision);
auto res128 = builder.CreateMul(lhs128, rhs128);
auto res256 = builder.CreateZExt(res128, Types.word256);
stack.push(res256);
break;
}
case Instruction::DIV:
{
auto lhs256 = stack.pop();
auto rhs256 = stack.pop();
auto lhs128 = builder.CreateTrunc(lhs256, Types.WordLowPrecision);
auto rhs128 = builder.CreateTrunc(rhs256, Types.WordLowPrecision);
auto res128 = builder.CreateUDiv(lhs128, rhs128);
auto res256 = builder.CreateZExt(res128, Types.word256);
stack.push(res256);
break;
}
case Instruction::SDIV:
{
auto lhs256 = stack.pop();
auto rhs256 = stack.pop();
auto lhs128 = builder.CreateTrunc(lhs256, Types.WordLowPrecision);
auto rhs128 = builder.CreateTrunc(rhs256, Types.WordLowPrecision);
auto res128 = builder.CreateSDiv(lhs128, rhs128);
auto res256 = builder.CreateSExt(res128, Types.word256);
stack.push(res256);
break;
}
case Instruction::MOD:
{
auto lhs256 = stack.pop();
auto rhs256 = stack.pop();
auto lhs128 = builder.CreateTrunc(lhs256, Types.WordLowPrecision);
auto rhs128 = builder.CreateTrunc(rhs256, Types.WordLowPrecision);
auto res128 = builder.CreateURem(lhs128, rhs128);
auto res256 = builder.CreateZExt(res128, Types.word256);
stack.push(res256);
break;
}
case Instruction::SMOD:
{
auto lhs256 = stack.pop();
auto rhs256 = stack.pop();
auto lhs128 = builder.CreateTrunc(lhs256, Types.WordLowPrecision);
auto rhs128 = builder.CreateTrunc(rhs256, Types.WordLowPrecision);
auto res128 = builder.CreateSRem(lhs128, rhs128);
auto res256 = builder.CreateSExt(res128, Types.word256);
stack.push(res256);
break;
}
case Instruction::POP:
{
stack.pop();

View file

@ -0,0 +1 @@
60016001900160070260050160029004600490066021900560150160030260059007600303

1
evmcc/bytecode/fib1.evm Normal file
View file

@ -0,0 +1 @@
60016001818101818101818101818101818101818101818101818101818101818101818101818101818101818101818101818101818101

View file

@ -0,0 +1,29 @@
(asm
1
1
SWAP1
ADD ;; 2
7
MUL ;; 14
5
ADD ;; 19
2
SWAP1
DIV ;; 9
4
SWAP1
MOD ;; 1
33
SWAP1
SDIV;; 0
21
ADD ;; 21
3
MUL ;; 63
5
SWAP1
SMOD;; 3
3
SUB ;; 0
)

57
evmcc/lll/fib1.lll Normal file
View file

@ -0,0 +1,57 @@
;; Fibbonacci unrolled
(asm
1
1
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
DUP2
DUP2
ADD
)