mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 19:30:44 +00:00
Basic arithmetic, limited precision for MUL, DIV and MOD.
This commit is contained in:
parent
e53c0a4877
commit
58e03d5165
5 changed files with 171 additions and 0 deletions
|
|
@ -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();
|
||||
|
|
|
|||
1
evmcc/bytecode/arithmetic_test.evm
Normal file
1
evmcc/bytecode/arithmetic_test.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
60016001900160070260050160029004600490066021900560150160030260059007600303
|
||||
1
evmcc/bytecode/fib1.evm
Normal file
1
evmcc/bytecode/fib1.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
60016001818101818101818101818101818101818101818101818101818101818101818101818101818101818101818101818101818101
|
||||
29
evmcc/lll/arithmetic_test.lll
Normal file
29
evmcc/lll/arithmetic_test.lll
Normal 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
57
evmcc/lll/fib1.lll
Normal 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
|
||||
)
|
||||
Loading…
Reference in a new issue